GameDef compiles
authorPerttu Ahola <celeron55@gmail.com>
Mon, 14 Nov 2011 19:41:30 +0000 (21:41 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 29 Nov 2011 17:13:42 +0000 (19:13 +0200)
52 files changed:
src/CMakeLists.txt
src/camera.cpp
src/camera.h
src/client.cpp
src/client.h
src/collision.cpp
src/collision.h
src/content_mapblock.cpp
src/content_mapblock.h
src/content_mapnode.cpp
src/content_mapnode.h
src/content_sao.cpp
src/content_tool.cpp
src/content_tool.h
src/environment.cpp
src/environment.h
src/game.cpp
src/gamedef.h
src/inventory.cpp
src/main.cpp
src/map.cpp
src/map.h
src/mapblock.cpp
src/mapblock.h
src/mapblock_mesh.cpp
src/mapblock_mesh.h
src/mapgen.cpp
src/mapgen.h
src/mapnode.cpp
src/mapnode.h
src/mapnode_contentfeatures.cpp [deleted file]
src/mapnode_contentfeatures.h [deleted file]
src/mapsector.cpp
src/mapsector.h
src/materials.cpp
src/materials.h
src/nodedef.cpp [new file with mode: 0644]
src/nodedef.h [new file with mode: 0644]
src/player.cpp
src/player.h
src/server.cpp
src/server.h
src/servermain.cpp
src/test.cpp
src/tile.cpp
src/tile.h
src/tool.cpp [deleted file]
src/tool.h [deleted file]
src/tooldef.cpp [new file with mode: 0644]
src/tooldef.h [new file with mode: 0644]
src/voxel.cpp
src/voxel.h

index 550bd1f55cf2449d698f38ef5d1b0dede2b38734..0f6c567c32761e741f1f6f787e8ee09550ac38be 100644 (file)
@@ -95,8 +95,8 @@ configure_file(
 
 set(common_SRCS
        content_tool.cpp
-       tool.cpp
-       mapnode_contentfeatures.cpp
+       tooldef.cpp
+       nodedef.cpp
        luaentity_common.cpp
        scriptapi.cpp
        script.cpp
index d001f8916bac1701d1b8930711ef68552d1f6e2a..74ecd6cecebce53808feea5b02a2f7bac7c1316a 100644 (file)
@@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <cmath>
 #include <SAnimatedMesh.h>
 #include "settings.h"
-#include "mapnode_contentfeatures.h" // For wield visualization
+#include "nodedef.h" // For wield visualization
 
 Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
        m_smgr(smgr),
@@ -449,8 +449,11 @@ void Camera::updateSettings()
        m_wanted_frametime = 1.0 / wanted_fps;
 }
 
-void Camera::wield(const InventoryItem* item, ITextureSource *tsrc)
+void Camera::wield(const InventoryItem* item, IGameDef *gamedef)
 {
+       ITextureSource *tsrc = gamedef->tsrc();
+       INodeDefManager *ndef = gamedef->ndef();
+
        if (item != NULL)
        {
                bool isCube = false;
@@ -461,9 +464,9 @@ void Camera::wield(const InventoryItem* item, ITextureSource *tsrc)
                        // A block-type material
                        MaterialItem* mat_item = (MaterialItem*) item;
                        content_t content = mat_item->getMaterial();
-                       if (content_features(content).solidness || content_features(content).visual_solidness)
+                       if (ndef->get(content).solidness || ndef->get(content).visual_solidness)
                        {
-                               m_wieldnode->setCube(content_features(content).tiles);
+                               m_wieldnode->setCube(ndef->get(content).tiles);
                                m_wieldnode->setScale(v3f(30));
                                isCube = true;
                        }
index 29b9fbdaa193a64196be28c605f7abe1621cf929..8321a1f0dd7b16c70bee0a7107a98ccc025315a0 100644 (file)
@@ -31,7 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 class LocalPlayer;
 class MapDrawControl;
 class ExtrudedSpriteSceneNode;
-class ITextureSource;
+class IGameDef;
 
 /*
        Client camera class, manages the player and camera scene nodes, the viewing distance
@@ -116,7 +116,7 @@ public:
        void updateSettings();
 
        // Replace the wielded item mesh
-       void wield(const InventoryItem* item, ITextureSource *tsrc);
+       void wield(const InventoryItem* item, IGameDef *gamedef);
 
        // Start digging animation
        // Pass 0 for left click, 1 for right click
index 876d22e8bed70bd8134c3499f767454576cf05ba..d0e5cd405dee7a363ee86ed75dadbb41643baf07 100644 (file)
@@ -32,6 +32,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "profiler.h"
 #include "log.h"
 #include "nodemetadata.h"
+#include "nodedef.h"
+#include "tooldef.h"
 
 /*
        QueuedMeshUpdate
@@ -160,7 +162,7 @@ void * MeshUpdateThread::Thread()
                ScopeProfiler sp(g_profiler, "Client: Mesh making");
 
                scene::SMesh *mesh_new = NULL;
-               mesh_new = makeMapBlockMesh(q->data, m_tsrc);
+               mesh_new = makeMapBlockMesh(q->data, m_gamedef);
 
                MeshUpdateResult r;
                r.p = q->p;
@@ -186,11 +188,14 @@ Client::Client(
                const char *playername,
                std::string password,
                MapDrawControl &control,
-               ITextureSource *tsrc,
-               IToolDefManager *toolmgr):
+               IWritableTextureSource *tsrc,
+               IWritableToolDefManager *tooldef,
+               IWritableNodeDefManager *nodedef
+):
        m_tsrc(tsrc),
-       m_toolmgr(toolmgr),
-       m_mesh_update_thread(tsrc),
+       m_tooldef(tooldef),
+       m_nodedef(nodedef),
+       m_mesh_update_thread(this),
        m_env(
                new ClientMap(this, this, control,
                        device->getSceneManager()->getRootSceneNode(),
@@ -214,18 +219,22 @@ Client::Client(
        m_playerpos_send_timer = 0.0;
        m_ignore_damage_timer = 0.0;
 
-       //m_env_mutex.Init();
-       //m_con_mutex.Init();
+       // Build main texture atlas, now that the GameDef exists (that is, us)
+       if(g_settings->getBool("enable_texture_atlas"))
+               tsrc->buildMainAtlas(this);
+       else
+               infostream<<"Not building texture atlas."<<std::endl;
 
+       // NOTE: This should be done only after getting possible dynamic
+       // game definitions from the server, or at least shut down and
+       // restarted when doing so
        m_mesh_update_thread.Start();
 
        /*
                Add local player
        */
        {
-               //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
-
-               Player *player = new LocalPlayer();
+               Player *player = new LocalPlayer(this);
 
                player->updateName(playername);
 
@@ -827,7 +836,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                //TimeTaker t1("TOCLIENT_ADDNODE");
 
                MapNode n;
-               n.deSerialize(&data[8], ser_version);
+               n.deSerialize(&data[8], ser_version, m_nodedef);
                
                addNode(p, n);
        }
@@ -868,7 +877,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                                Update an existing block
                        */
                        //infostream<<"Updating"<<std::endl;
-                       block->deSerialize(istr, ser_version, this);
+                       block->deSerialize(istr, ser_version);
                }
                else
                {
@@ -876,8 +885,8 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                                Create a new block
                        */
                        //infostream<<"Creating new"<<std::endl;
-                       block = new MapBlock(&m_env.getMap(), p);
-                       block->deSerialize(istr, ser_version, this);
+                       block = new MapBlock(&m_env.getMap(), p, this);
+                       block->deSerialize(istr, ser_version);
                        sector->insertBlock(block);
 
                        //DEBUG
@@ -1041,7 +1050,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                                // Create a player if it doesn't exist
                                if(player == NULL)
                                {
-                                       player = new RemotePlayer(
+                                       player = new RemotePlayer(this,
                                                        m_device->getSceneManager()->getRootSceneNode(),
                                                        m_device,
                                                        -1);
@@ -2047,7 +2056,7 @@ void Client::setTempMod(v3s16 p, NodeMod mod)
                        i = affected_blocks.getIterator();
                        i.atEnd() == false; i++)
        {
-               i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio(), m_tsrc);
+               i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio());
        }
 }
 
@@ -2064,7 +2073,7 @@ void Client::clearTempMod(v3s16 p)
                        i = affected_blocks.getIterator();
                        i.atEnd() == false; i++)
        {
-               i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio(), m_tsrc);
+               i.getNode()->getValue()->updateMesh(m_env.getDayNightRatio());
        }
 }
 
@@ -2173,3 +2182,18 @@ float Client::getRTT(void)
        }
 }
 
+// IGameDef interface
+// Under envlock
+IToolDefManager* Client::getToolDefManager()
+{
+       return m_tooldef;
+}
+INodeDefManager* Client::getNodeDefManager()
+{
+       return m_nodedef;
+}
+ITextureSource* Client::getTextureSource()
+{
+       return m_tsrc;
+}
+
index d41603c9d788a82a6834db15fa3510f25f282697..abbbed2f8d50b44b2e6b20bf0c01677b7835774e 100644 (file)
@@ -32,6 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "gamedef.h"
 
 struct MeshMakeData;
+class IGameDef;
+class IWritableToolDefManager;
+class IWritableNodeDefManager;
 
 class ClientNotReadyException : public BaseException
 {
@@ -99,8 +102,8 @@ class MeshUpdateThread : public SimpleThread
 {
 public:
 
-       MeshUpdateThread(ITextureSource *tsrc):
-               m_tsrc(tsrc)
+       MeshUpdateThread(IGameDef *gamedef):
+               m_gamedef(gamedef)
        {
        }
 
@@ -110,7 +113,7 @@ public:
 
        MutexedQueue<MeshUpdateResult> m_queue_out;
 
-       ITextureSource *m_tsrc;
+       IGameDef *m_gamedef;
 };
 
 enum ClientEventType
@@ -155,8 +158,9 @@ public:
                        const char *playername,
                        std::string password,
                        MapDrawControl &control,
-                       ITextureSource *tsrc,
-                       IToolDefManager *toolmgr
+                       IWritableTextureSource *tsrc,
+                       IWritableToolDefManager *tooldef,
+                       IWritableNodeDefManager *nodedef
        );
        
        ~Client();
@@ -311,10 +315,9 @@ public:
 
        // IGameDef interface
        // Under envlock
-       virtual IToolDefManager* getToolDefManager()
-               { return m_toolmgr; }
-       virtual INodeDefManager* getNodeDefManager()
-               { assert(0); return NULL; } // TODO
+       virtual IToolDefManager* getToolDefManager();
+       virtual INodeDefManager* getNodeDefManager();
+       virtual ITextureSource* getTextureSource();
 
 private:
        
@@ -338,8 +341,9 @@ private:
        float m_ignore_damage_timer; // Used after server moves player
        IntervalLimiter m_map_timer_and_unload_interval;
 
-       ITextureSource *m_tsrc;
-       IToolDefManager *m_toolmgr;
+       IWritableTextureSource *m_tsrc;
+       IWritableToolDefManager *m_tooldef;
+       IWritableNodeDefManager *m_nodedef;
        MeshUpdateThread m_mesh_update_thread;
        ClientEnvironment m_env;
        con::Connection m_con;
index 2380b1627a5bbfd366ea0b213bc89977d3d413dc..674cf4ed4881224f9a282667120db0c05fa44e2b 100644 (file)
@@ -20,10 +20,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "collision.h"
 #include "mapblock.h"
 #include "map.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
+#include "gamedef.h"
 
-collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
-               const core::aabbox3d<f32> &box_0,
+collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
+               f32 pos_max_d, const core::aabbox3d<f32> &box_0,
                f32 dtime, v3f &pos_f, v3f &speed_f)
 {
        collisionMoveResult result;
@@ -80,7 +81,7 @@ collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
                try{
                        // Object collides into walkable nodes
                        MapNode n = map->getNode(v3s16(x,y,z));
-                       if(content_features(n).walkable == false)
+                       if(gamedef->getNodeDefManager()->get(n).walkable == false)
                                continue;
                }
                catch(InvalidPositionException &e)
@@ -184,8 +185,8 @@ collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
        return result;
 }
 
-collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
-               const core::aabbox3d<f32> &box_0,
+collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
+               f32 pos_max_d, const core::aabbox3d<f32> &box_0,
                f32 dtime, v3f &pos_f, v3f &speed_f)
 {
        collisionMoveResult final_result;
@@ -226,8 +227,8 @@ collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
                        dtime_downcount = 0;
                }
 
-               collisionMoveResult result = collisionMoveSimple(map, pos_max_d,
-                               box_0, dtime_part, pos_f, speed_f);
+               collisionMoveResult result = collisionMoveSimple(map, gamedef,
+                               pos_max_d, box_0, dtime_part, pos_f, speed_f);
 
                if(result.touching_ground)
                        final_result.touching_ground = true;
index 6d167bb7be415debaa192e61a3111f46b331ed32..3354ea09a3392eda6923e320bd33d459c9671fb6 100644 (file)
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "common_irrlicht.h"
 
 class Map;
+class IGameDef;
 
 struct collisionMoveResult
 {
@@ -34,13 +35,13 @@ struct collisionMoveResult
 };
 
 // Moves using a single iteration; speed should not exceed pos_max_d/dtime
-collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
-               const core::aabbox3d<f32> &box_0,
+collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
+               f32 pos_max_d, const core::aabbox3d<f32> &box_0,
                f32 dtime, v3f &pos_f, v3f &speed_f);
 
 // Moves using as many iterations as needed
-collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
-               const core::aabbox3d<f32> &box_0,
+collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
+               f32 pos_max_d, const core::aabbox3d<f32> &box_0,
                f32 dtime, v3f &pos_f, v3f &speed_f);
 
 enum CollisionType
index ebb40247597b9591e612d3c2caadca76daac6d2b..ff6215a540abd08653fd3499ce7d4955619c34be 100644 (file)
@@ -23,7 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mineral.h"
 #include "mapblock_mesh.h" // For MapBlock_LightColor()
 #include "settings.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
+#include "gamedef.h"
 
 #ifndef SERVER
 // Create a cuboid.
@@ -122,8 +123,11 @@ void makeCuboid(video::SMaterial &material, MeshCollector *collector,
 
 #ifndef SERVER
 void mapblock_mesh_generate_special(MeshMakeData *data,
-               MeshCollector &collector, ITextureSource *tsrc)
+               MeshCollector &collector, IGameDef *gamedef)
 {
+       ITextureSource *tsrc = gamedef->tsrc();
+       INodeDefManager *nodedef = gamedef->ndef();
+
        // 0ms
        //TimeTaker timer("mapblock_mesh_generate_special()");
 
@@ -316,7 +320,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                        = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
                        material.setTexture(0, ap.atlas);
 
-                       u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+                       u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
                        video::SColor c = MapBlock_LightColor(255, l);
                                
                        float d = (float)BS/16;
@@ -360,34 +364,34 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                /*
                        Add flowing liquid to mesh
                */
-               else if(content_features(n).liquid_type == LIQUID_FLOWING)
+               else if(nodedef->get(n).liquid_type == LIQUID_FLOWING)
                {
-                       assert(content_features(n).special_material);
+                       assert(nodedef->get(n).special_material);
                        video::SMaterial &liquid_material =
-                                       *content_features(n).special_material;
+                                       *nodedef->get(n).special_material;
                        video::SMaterial &liquid_material_bfculled =
-                                       *content_features(n).special_material2;
+                                       *nodedef->get(n).special_material2;
 
-                       assert(content_features(n).special_atlas);
+                       assert(nodedef->get(n).special_atlas);
                        AtlasPointer &pa_liquid1 =
-                                       *content_features(n).special_atlas;
+                                       *nodedef->get(n).special_atlas;
 
                        bool top_is_same_liquid = false;
                        MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
-                       content_t c_flowing = content_features(n).liquid_alternative_flowing;
-                       content_t c_source = content_features(n).liquid_alternative_source;
+                       content_t c_flowing = nodedef->get(n).liquid_alternative_flowing;
+                       content_t c_source = nodedef->get(n).liquid_alternative_source;
                        if(ntop.getContent() == c_flowing || ntop.getContent() == c_source)
                                top_is_same_liquid = true;
                        
                        u8 l = 0;
                        // Use the light of the node on top if possible
-                       if(content_features(ntop).param_type == CPT_LIGHT)
-                               l = decode_light(ntop.getLightBlend(data->m_daynight_ratio));
+                       if(nodedef->get(ntop).param_type == CPT_LIGHT)
+                               l = decode_light(ntop.getLightBlend(data->m_daynight_ratio, nodedef));
                        // Otherwise use the light of this node (the liquid)
                        else
-                               l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+                               l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
                        video::SColor c = MapBlock_LightColor(
-                                       content_features(n).vertex_alpha, l);
+                                       nodedef->get(n).vertex_alpha, l);
                        
                        // Neighbor liquid levels (key = relative position)
                        // Includes current node
@@ -520,7 +524,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                        continue;
 
                                content_t neighbor_content = neighbor_contents[dir];
-                               ContentFeatures &n_feat = content_features(neighbor_content);
+                               const ContentFeatures &n_feat = nodedef->get(neighbor_content);
                                
                                // Don't draw face if neighbor is blocking the view
                                if(n_feat.solidness == 2)
@@ -654,15 +658,15 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                /*
                        Add water sources to mesh if using new style
                */
-               else if(content_features(n).liquid_type == LIQUID_SOURCE
+               else if(nodedef->get(n).liquid_type == LIQUID_SOURCE
                                && new_style_water)
                {
-                       assert(content_features(n).special_material);
+                       assert(nodedef->get(n).special_material);
                        video::SMaterial &liquid_material =
-                                       *content_features(n).special_material;
-                       assert(content_features(n).special_atlas);
+                                       *nodedef->get(n).special_material;
+                       assert(nodedef->get(n).special_atlas);
                        AtlasPointer &pa_liquid1 =
-                                       *content_features(n).special_atlas;
+                                       *nodedef->get(n).special_atlas;
 
                        bool top_is_air = false;
                        MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
@@ -672,9 +676,9 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        if(top_is_air == false)
                                continue;
 
-                       u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+                       u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
                        video::SColor c = MapBlock_LightColor(
-                                       content_features(n).vertex_alpha, l);
+                                       nodedef->get(n).vertex_alpha, l);
                        
                        video::S3DVertex vertices[4] =
                        {
@@ -703,8 +707,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                */
                else if(n.getContent() == CONTENT_LEAVES && new_style_leaves)
                {
-                       /*u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));*/
-                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+                       /*u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));*/
+                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
                        video::SColor c = MapBlock_LightColor(255, l);
 
                        for(u32 j=0; j<6; j++)
@@ -767,7 +771,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                */
                else if(n.getContent() == CONTENT_GLASS)
                {
-                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
                        video::SColor c = MapBlock_LightColor(255, l);
 
                        for(u32 j=0; j<6; j++)
@@ -830,7 +834,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                */
                else if(n.getContent() == CONTENT_FENCE)
                {
-                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
                        video::SColor c = MapBlock_LightColor(255, l);
 
                        const f32 post_rad=(f32)BS/10;
@@ -907,7 +911,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                /*
                        Add stones with minerals if stone is invisible
                */
-               else if(n.getContent() == CONTENT_STONE && invisible_stone && n.getMineral() != MINERAL_NONE)
+               else if(n.getContent() == CONTENT_STONE && invisible_stone && n.getMineral(nodedef) != MINERAL_NONE)
                {
                        for(u32 j=0; j<6; j++)
                        {
@@ -915,15 +919,15 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                v3s16 dir = g_6dirs[j];
                                /*u8 l = 0;
                                MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + dir);
-                               if(content_features(n2).param_type == CPT_LIGHT)
-                                       l = decode_light(n2.getLightBlend(data->m_daynight_ratio));
+                               if(nodedef->get(n2).param_type == CPT_LIGHT)
+                                       l = decode_light(n2.getLightBlend(data->m_daynight_ratio, nodedef));
                                else
                                        l = 255;*/
                                u8 l = 255;
                                video::SColor c = MapBlock_LightColor(255, l);
                                
                                // Get the right texture
-                               TileSpec ts = n.getTile(dir, tsrc);
+                               TileSpec ts = n.getTile(dir, tsrc, nodedef);
                                AtlasPointer ap = ts.texture;
                                material_general.setTexture(0, ap.atlas);
 
@@ -974,7 +978,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
 #endif
                else if(n.getContent() == CONTENT_PAPYRUS)
                {
-                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
                        video::SColor c = MapBlock_LightColor(255, l);
 
                        for(u32 j=0; j<4; j++)
@@ -1024,7 +1028,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                }
                else if(n.getContent() == CONTENT_JUNGLEGRASS)
                {
-                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
                        video::SColor c = MapBlock_LightColor(255, l);
 
                        for(u32 j=0; j<4; j++)
@@ -1121,7 +1125,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                        = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
                        material_rail.setTexture(0, ap.atlas);
 
-                       u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+                       u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
                        video::SColor c = MapBlock_LightColor(255, l);
 
                        float d = (float)BS/16;
@@ -1193,7 +1197,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        material_ladder.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
                        material_ladder.setTexture(0, ap.atlas);
 
-                       u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
+                       u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));
                        video::SColor c(255,l,l,l);
 
                        float d = (float)BS/16;
@@ -1237,7 +1241,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                }
                else if(n.getContent() == CONTENT_APPLE)
                {
-                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
                        video::SColor c = MapBlock_LightColor(255, l);
 
                        for(u32 j=0; j<4; j++)
@@ -1286,7 +1290,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        }
                }
                else if(n.getContent() == CONTENT_SAPLING) {
-                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef)));
                        video::SColor c = MapBlock_LightColor(255, l);
 
                        for(u32 j=0; j<4; j++)
index 6eb63af4fe727aae3aca31bdee4d635d7f58813e..eaf74b142623fc65c6e1668725de50106a3ef89f 100644 (file)
@@ -23,9 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef SERVER
        #include "mapblock_mesh.h"
        #include "utility.h"
-class ITextureSource;
+class IGameDef;
 void mapblock_mesh_generate_special(MeshMakeData *data,
-               MeshCollector &collector, ITextureSource *tsrc);
+               MeshCollector &collector, IGameDef *gamedef);
 #endif
 
 #endif
index eff80f8af1d98ee519bf64da7ba0305269c6c162..507d34065ba82efea3cd088a03bcb25954277d7d 100644 (file)
@@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapnode.h"
 #include "content_nodemeta.h"
 #include "settings.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
 
 #define WATER_ALPHA 160
 
@@ -156,7 +156,7 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version)
 }
 
 // See header for description
-void content_mapnode_init(ITextureSource *tsrc)
+void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr)
 {
        if(tsrc == NULL)
                dstream<<"INFO: Initial run of content_mapnode_init with "
@@ -177,7 +177,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        ContentFeatures *f = NULL;
 
        i = CONTENT_STONE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "stone.png");
        f->setInventoryTextureCube("stone.png", "stone.png", "stone.png", tsrc);
        f->param_type = CPT_MINERAL;
@@ -189,7 +189,7 @@ void content_mapnode_init(ITextureSource *tsrc)
                f->solidness = 0; // For debugging, hides regular stone
        
        i = CONTENT_GRASS;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "mud.png^grass_side.png");
        f->setTexture(tsrc, 0, "grass.png");
        f->setTexture(tsrc, 1, "mud.png");
@@ -199,7 +199,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setDirtLikeMaterialProperties(f->material, 1.0);
        
        i = CONTENT_GRASS_FOOTSTEPS;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "mud.png^grass_side.png");
        f->setTexture(tsrc, 0, "grass_footsteps.png");
        f->setTexture(tsrc, 1, "mud.png");
@@ -209,7 +209,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setDirtLikeMaterialProperties(f->material, 1.0);
        
        i = CONTENT_MUD;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "mud.png");
        f->setInventoryTextureCube("mud.png", "mud.png", "mud.png", tsrc);
        f->param_type = CPT_MINERAL;
@@ -218,7 +218,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setDirtLikeMaterialProperties(f->material, 1.0);
        
        i = CONTENT_SAND;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "sand.png");
        f->setInventoryTextureCube("sand.png", "sand.png", "sand.png", tsrc);
        f->param_type = CPT_MINERAL;
@@ -227,7 +227,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setDirtLikeMaterialProperties(f->material, 1.0);
        
        i = CONTENT_GRAVEL;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "gravel.png");
        f->setInventoryTextureCube("gravel.png", "gravel.png", "gravel.png", tsrc);
        f->param_type = CPT_MINERAL;
@@ -236,7 +236,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setGravelLikeMaterialProperties(f->material, 1.0);
        
        i = CONTENT_SANDSTONE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "sandstone.png");
        f->setInventoryTextureCube("sandstone.png", "sandstone.png", "sandstone.png", tsrc);
        f->param_type = CPT_MINERAL;
@@ -245,7 +245,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setDirtLikeMaterialProperties(f->material, 1.0);
 
        i = CONTENT_CLAY;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "clay.png");
        f->setInventoryTextureCube("clay.png", "clay.png", "clay.png", tsrc);
        f->param_type = CPT_MINERAL;
@@ -254,7 +254,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setDirtLikeMaterialProperties(f->material, 1.0);
 
        i = CONTENT_BRICK;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "brick.png");
        f->setInventoryTextureCube("brick.png", "brick.png", "brick.png", tsrc);
        f->param_type = CPT_MINERAL;
@@ -263,7 +263,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setStoneLikeMaterialProperties(f->material, 1.0);
 
        i = CONTENT_TREE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "tree.png");
        f->setTexture(tsrc, 0, "tree_top.png");
        f->setTexture(tsrc, 1, "tree_top.png");
@@ -273,7 +273,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setWoodLikeMaterialProperties(f->material, 1.0);
        
        i = CONTENT_JUNGLETREE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "jungletree.png");
        f->setTexture(tsrc, 0, "jungletree_top.png");
        f->setTexture(tsrc, 1, "jungletree_top.png");
@@ -283,9 +283,9 @@ void content_mapnode_init(ITextureSource *tsrc)
        setWoodLikeMaterialProperties(f->material, 1.0);
        
        i = CONTENT_JUNGLEGRASS;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setInventoryTexture("junglegrass.png", tsrc);
-       f->used_texturenames["junglegrass.png"] = true;
+       f->used_texturenames.insert("junglegrass.png"); // Add to atlas
        f->light_propagates = true;
        f->param_type = CPT_LIGHT;
        //f->is_ground_content = true;
@@ -296,7 +296,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setLeavesLikeMaterialProperties(f->material, 1.0);
 
        i = CONTENT_LEAVES;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->light_propagates = true;
        //f->param_type = CPT_MINERAL;
        f->param_type = CPT_LIGHT;
@@ -318,7 +318,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setLeavesLikeMaterialProperties(f->material, 1.0);
 
        i = CONTENT_CACTUS;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "cactus_side.png");
        f->setTexture(tsrc, 0, "cactus_top.png");
        f->setTexture(tsrc, 1, "cactus_top.png");
@@ -329,9 +329,9 @@ void content_mapnode_init(ITextureSource *tsrc)
        setWoodLikeMaterialProperties(f->material, 0.75);
 
        i = CONTENT_PAPYRUS;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setInventoryTexture("papyrus.png", tsrc);
-       f->used_texturenames["papyrus.png"] = true;
+       f->used_texturenames.insert("papyrus.png"); // Add to atlas
        f->light_propagates = true;
        f->param_type = CPT_LIGHT;
        f->is_ground_content = true;
@@ -341,7 +341,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setLeavesLikeMaterialProperties(f->material, 0.5);
 
        i = CONTENT_BOOKSHELF;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "bookshelf.png");
        f->setTexture(tsrc, 0, "wood.png");
        f->setTexture(tsrc, 1, "wood.png");
@@ -353,7 +353,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setWoodLikeMaterialProperties(f->material, 0.75);
 
        i = CONTENT_GLASS;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->light_propagates = true;
        f->sunlight_propagates = true;
        f->param_type = CPT_LIGHT;
@@ -366,7 +366,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setGlassLikeMaterialProperties(f->material, 1.0);
 
        i = CONTENT_FENCE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->light_propagates = true;
        f->param_type = CPT_LIGHT;
        f->is_ground_content = true;
@@ -374,13 +374,13 @@ void content_mapnode_init(ITextureSource *tsrc)
        f->solidness = 0; // drawn separately, makes no faces
        f->air_equivalent = true; // grass grows underneath
        f->setInventoryTexture("fence.png", tsrc);
-       f->used_texturenames["fence.png"] = true;
+       f->used_texturenames.insert("fence.png"); // Add to atlas
        setWoodLikeMaterialProperties(f->material, 0.75);
 
        i = CONTENT_RAIL;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setInventoryTexture("rail.png", tsrc);
-       f->used_texturenames["rail.png"] = true;
+       f->used_texturenames.insert("rail.png"); // Add to atlas
        f->light_propagates = true;
        f->param_type = CPT_LIGHT;
        f->is_ground_content = true;
@@ -392,9 +392,9 @@ void content_mapnode_init(ITextureSource *tsrc)
        setDirtLikeMaterialProperties(f->material, 0.75);
 
        i = CONTENT_LADDER;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setInventoryTexture("ladder.png", tsrc);
-       f->used_texturenames["ladder.png"] = true;
+       f->used_texturenames.insert("ladder.png"); // Add to atlas
        f->light_propagates = true;
        f->param_type = CPT_LIGHT;
        f->is_ground_content = true;
@@ -409,13 +409,13 @@ void content_mapnode_init(ITextureSource *tsrc)
 
        // Deprecated
        i = CONTENT_COALSTONE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "stone.png^mineral_coal.png");
        f->is_ground_content = true;
        setStoneLikeMaterialProperties(f->material, 1.5);
        
        i = CONTENT_WOOD;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "wood.png");
        f->setInventoryTextureCube("wood.png", "wood.png", "wood.png", tsrc);
        f->is_ground_content = true;
@@ -423,7 +423,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setWoodLikeMaterialProperties(f->material, 0.75);
        
        i = CONTENT_MESE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "mese.png");
        f->setInventoryTextureCube("mese.png", "mese.png", "mese.png", tsrc);
        f->is_ground_content = true;
@@ -431,14 +431,14 @@ void content_mapnode_init(ITextureSource *tsrc)
        setStoneLikeMaterialProperties(f->material, 0.5);
        
        i = CONTENT_CLOUD;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "cloud.png");
        f->setInventoryTextureCube("cloud.png", "cloud.png", "cloud.png", tsrc);
        f->is_ground_content = true;
        f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
        
        i = CONTENT_AIR;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->param_type = CPT_LIGHT;
        f->light_propagates = true;
        f->sunlight_propagates = true;
@@ -450,7 +450,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        f->air_equivalent = true;
        
        i = CONTENT_WATER;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setInventoryTextureCube("water.png", "water.png", "water.png", tsrc);
        f->param_type = CPT_LIGHT;
        f->light_propagates = true;
@@ -492,7 +492,7 @@ void content_mapnode_init(ITextureSource *tsrc)
 #endif
        
        i = CONTENT_WATERSOURCE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        //f->setInventoryTexture("water.png", tsrc);
        f->setInventoryTextureCube("water.png", "water.png", "water.png", tsrc);
        if(new_style_water)
@@ -547,9 +547,9 @@ void content_mapnode_init(ITextureSource *tsrc)
 #endif
        
        i = CONTENT_LAVA;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setInventoryTextureCube("lava.png", "lava.png", "lava.png", tsrc);
-       f->used_texturenames["lava.png"] = true;
+       f->used_texturenames.insert("lava.png"); // Add to atlas
        f->param_type = CPT_LIGHT;
        f->light_propagates = false;
        f->light_source = LIGHT_MAX-1;
@@ -591,9 +591,9 @@ void content_mapnode_init(ITextureSource *tsrc)
 #endif
        
        i = CONTENT_LAVASOURCE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setInventoryTextureCube("lava.png", "lava.png", "lava.png", tsrc);
-       f->used_texturenames["ladder.png"] = true;
+       f->used_texturenames.insert("ladder.png"); // Add to atlas
        if(new_style_water)
        {
                f->solidness = 0; // drawn separately, makes no faces
@@ -646,12 +646,11 @@ void content_mapnode_init(ITextureSource *tsrc)
 #endif
        
        i = CONTENT_TORCH;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setInventoryTexture("torch_on_floor.png", tsrc);
-       f->used_texturenames["torch_on_floor.png"] = true;
-       f->used_texturenames["torch_on_ceiling.png"] = true;
-       f->used_texturenames["torch_on_floor.png"] = true;
-       f->used_texturenames["torch.png"] = true;
+       f->used_texturenames.insert("torch_on_floor.png"); // Add to atlas
+       f->used_texturenames.insert("torch_on_ceiling.png"); // Add to atlas
+       f->used_texturenames.insert("torch.png"); // Add to atlas
        f->param_type = CPT_LIGHT;
        f->light_propagates = true;
        f->sunlight_propagates = true;
@@ -671,9 +670,9 @@ void content_mapnode_init(ITextureSource *tsrc)
        setConstantMaterialProperties(f->material, 0.0);
        
        i = CONTENT_SIGN_WALL;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setInventoryTexture("sign_wall.png", tsrc);
-       f->used_texturenames["sign_wall.png"] = true;
+       f->used_texturenames.insert("sign_wall.png"); // Add to atlas
        f->param_type = CPT_LIGHT;
        f->light_propagates = true;
        f->sunlight_propagates = true;
@@ -688,7 +687,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        f->selection_box.type = NODEBOX_WALLMOUNTED;
        
        i = CONTENT_CHEST;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->param_type = CPT_FACEDIR_SIMPLE;
        f->setAllTextures(tsrc, "chest_side.png");
        f->setTexture(tsrc, 0, "chest_top.png");
@@ -702,7 +701,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setWoodLikeMaterialProperties(f->material, 1.0);
        
        i = CONTENT_LOCKABLE_CHEST;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->param_type = CPT_FACEDIR_SIMPLE;
        f->setAllTextures(tsrc, "chest_side.png");
        f->setTexture(tsrc, 0, "chest_top.png");
@@ -716,7 +715,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setWoodLikeMaterialProperties(f->material, 1.0);
 
        i = CONTENT_FURNACE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->param_type = CPT_FACEDIR_SIMPLE;
        f->setAllTextures(tsrc, "furnace_side.png");
        f->setTexture(tsrc, 5, "furnace_front.png"); // Z-
@@ -728,7 +727,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setStoneLikeMaterialProperties(f->material, 3.0);
        
        i = CONTENT_COBBLE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "cobble.png");
        f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png", tsrc);
        f->param_type = CPT_NONE;
@@ -737,7 +736,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setStoneLikeMaterialProperties(f->material, 0.9);
 
        i = CONTENT_MOSSYCOBBLE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "mossycobble.png");
        f->setInventoryTextureCube("mossycobble.png", "mossycobble.png", "mossycobble.png", tsrc);
        f->param_type = CPT_NONE;
@@ -746,7 +745,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setStoneLikeMaterialProperties(f->material, 0.8);
        
        i = CONTENT_STEEL;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "steel_block.png");
        f->setInventoryTextureCube("steel_block.png", "steel_block.png",
                        "steel_block.png", tsrc);
@@ -756,7 +755,7 @@ void content_mapnode_init(ITextureSource *tsrc)
        setStoneLikeMaterialProperties(f->material, 5.0);
        
        i = CONTENT_NC;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->param_type = CPT_FACEDIR_SIMPLE;
        f->setAllTextures(tsrc, "nc_side.png");
        f->setTexture(tsrc, 5, "nc_front.png"); // Z-
@@ -766,18 +765,18 @@ void content_mapnode_init(ITextureSource *tsrc)
        setStoneLikeMaterialProperties(f->material, 3.0);
        
        i = CONTENT_NC_RB;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setAllTextures(tsrc, "nc_rb.png");
        f->setInventoryTexture("nc_rb.png", tsrc);
        f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
        setStoneLikeMaterialProperties(f->material, 3.0);
 
        i = CONTENT_SAPLING;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->param_type = CPT_LIGHT;
        f->setAllTextures(tsrc, "sapling.png");
        f->setInventoryTexture("sapling.png", tsrc);
-       f->used_texturenames["sapling.png"] = true;
+       f->used_texturenames.insert("sapling.png"); // Add to atlas
        f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
        f->light_propagates = true;
        f->air_equivalent = false;
@@ -786,9 +785,9 @@ void content_mapnode_init(ITextureSource *tsrc)
        setConstantMaterialProperties(f->material, 0.0);
        
        i = CONTENT_APPLE;
-       f = &content_features(i);
+       f = nodemgr->getModifiable(i);
        f->setInventoryTexture("apple.png", tsrc);
-       f->used_texturenames["apple.png"] = true;
+       f->used_texturenames.insert("apple.png"); // Add to atlas
        f->param_type = CPT_LIGHT;
        f->light_propagates = true;
        f->sunlight_propagates = true;
index 3946c1e4db87cfed5b79851cbd318a66c3273177..ace30be7b89ec81103226a6ba38056604a7b0f47 100644 (file)
@@ -22,9 +22,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "mapnode.h"
 class ITextureSource;
+class IWritableNodeDefManager;
 
 /*
-       Fills stuff to the global ContentFeatures lookup table.
+       Initialize default node definitions
 
        This accesses tsrc; if it is non-NULL, textures are set
        for the nodes.
@@ -35,7 +36,7 @@ class ITextureSource;
 
        Server only calls this once with tsrc=NULL.
 */
-void content_mapnode_init(ITextureSource *tsrc);
+void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr);
 
 // Backwards compatibility for non-extended content types in v19
 extern content_t trans_table_19[21][2];
index 9c48e07072f154483410b7dca647798a30f914fd..a7cee83ab1807e9f0e741304521c381717683f63 100644 (file)
@@ -159,8 +159,9 @@ void ItemSAO::step(float dtime, bool send_recommended)
                m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
        v3f pos_f = getBasePosition();
        v3f pos_f_old = pos_f;
-       moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
-                       box, dtime, pos_f, m_speed_f);
+       IGameDef *gamedef = m_env->getGameDef();
+       moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
+                       pos_max_d, box, dtime, pos_f, m_speed_f);
        
        if(send_recommended == false)
                return;
@@ -402,8 +403,9 @@ void RatSAO::step(float dtime, bool send_recommended)
                m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
        v3f pos_f = getBasePosition();
        v3f pos_f_old = pos_f;
-       moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
-                       box, dtime, pos_f, m_speed_f);
+       IGameDef *gamedef = m_env->getGameDef();
+       moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
+                       pos_max_d, box, dtime, pos_f, m_speed_f);
        m_touching_ground = moveresult.touching_ground;
        
        setBasePosition(pos_f);
@@ -639,8 +641,9 @@ void Oerkki1SAO::step(float dtime, bool send_recommended)
                m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);*/
        v3f pos_f = getBasePosition();
        v3f pos_f_old = pos_f;
-       moveresult = collisionMovePrecise(&m_env->getMap(), pos_max_d,
-                       box, dtime, pos_f, m_speed_f);
+       IGameDef *gamedef = m_env->getGameDef();
+       moveresult = collisionMovePrecise(&m_env->getMap(), gamedef,
+                       pos_max_d, box, dtime, pos_f, m_speed_f);
        m_touching_ground = moveresult.touching_ground;
        
        // Do collision damage
@@ -887,8 +890,9 @@ void FireflySAO::step(float dtime, bool send_recommended)
                m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
        v3f pos_f = getBasePosition();
        v3f pos_f_old = pos_f;
-       moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
-                       box, dtime, pos_f, m_speed_f);
+       IGameDef *gamedef = m_env->getGameDef();
+       moveresult = collisionMoveSimple(&m_env->getMap(), gamedef,
+                       pos_max_d, box, dtime, pos_f, m_speed_f);
        m_touching_ground = moveresult.touching_ground;
        
        setBasePosition(pos_f);
index c7c5504f5f851726d56e1f735f356cc5a6d98400..d46401e54a1c334ab9b493946124bc031d285345 100644 (file)
@@ -18,9 +18,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "content_tool.h"
-#include "tool.h"
+#include "tooldef.h"
 
-void content_tool_init(IToolDefManager *mgr)
+void content_tool_init(IWritableToolDefManager *mgr)
 {
        mgr->registerTool("WPick",
                        ToolDefinition("tool_woodpick.png",
@@ -62,7 +62,7 @@ void content_tool_init(IToolDefManager *mgr)
                        ToolDefinition("tool_steelsword.png",
                        ToolDiggingProperties(2.0, 3,0,1,-1, 300, 0,0,0,0)));
        mgr->registerTool("",
-                       ToolDefinition("tool_hand.png",
+                       ToolDefinition("tooldef.hand.png",
                        ToolDiggingProperties(0.5, 1,0,-1,0, 50, 0,0,0,0)));
 }
 
index 66529d3ed206821d1b02b69ec70a546d1598c129..c7f14be3144a418da10a1808f7d1e341671be425 100644 (file)
@@ -17,8 +17,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-class IToolDefManager;
+class IWritableToolDefManager;
 
 // Add default tools to manager
-void content_tool_init(IToolDefManager *mgr);
+void content_tool_init(IWritableToolDefManager *mgr);
 
index a7439e7bcb501bd661b20e890a45239dbe09065f..e03007341978a9fd564b94b9b017901afb801dc9 100644 (file)
@@ -30,9 +30,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "log.h"
 #include "profiler.h"
 #include "scriptapi.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
 #include "nodemetadata.h"
 #include "main.h" // For g_settings, g_profiler
+#include "gamedef.h"
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
 
@@ -324,7 +325,7 @@ void ServerEnvironment::serializePlayers(const std::string &savedir)
                                infostream<<"Failed to read "<<path<<std::endl;
                                continue;
                        }
-                       testplayer.deSerialize(is, m_gamedef);
+                       testplayer.deSerialize(is);
                }
 
                //infostream<<"Loaded test player with name "<<testplayer.getName()<<std::endl;
@@ -438,7 +439,7 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
                                infostream<<"Failed to read "<<path<<std::endl;
                                continue;
                        }
-                       testplayer.deSerialize(is, m_gamedef);
+                       testplayer.deSerialize(is);
                }
 
                if(!string_allowed(testplayer.getName(), PLAYERNAME_ALLOWED_CHARS))
@@ -472,7 +473,7 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir)
                                infostream<<"Failed to read "<<path<<std::endl;
                                continue;
                        }
-                       player->deSerialize(is, m_gamedef);
+                       player->deSerialize(is);
                }
 
                if(newplayer)
@@ -557,9 +558,9 @@ void spawnRandomObjects(MapBlock *block)
                        MapNode n = block->getNodeNoEx(p);
                        if(n.getContent() == CONTENT_IGNORE)
                                continue;
-                       if(content_features(n).liquid_type != LIQUID_NONE)
+                       if(m_gamedef->ndef()->get(n).liquid_type != LIQUID_NONE)
                                continue;
-                       if(content_features(n).walkable)
+                       if(m_gamedef->ndef()->get(n).walkable)
                        {
                                last_node_walkable = true;
                                continue;
@@ -567,7 +568,7 @@ void spawnRandomObjects(MapBlock *block)
                        if(last_node_walkable)
                        {
                                // If block contains light information
-                               if(content_features(n).param_type == CPT_LIGHT)
+                               if(m_gamedef->ndef()->get(n).param_type == CPT_LIGHT)
                                {
                                        if(n.getLight(LIGHTBANK_DAY) <= 5)
                                        {
@@ -641,8 +642,8 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
                        if(dtime_s > 300)
                        {
                                MapNode n_top = block->getNodeNoEx(p0+v3s16(0,1,0));
-                               if(content_features(n_top).air_equivalent &&
-                                               n_top.getLight(LIGHTBANK_DAY) >= 13)
+                               if(m_gamedef->ndef()->get(n_top).air_equivalent &&
+                                               n_top.getLight(LIGHTBANK_DAY, m_gamedef->ndef()) >= 13)
                                {
                                        n.setContent(CONTENT_GRASS);
                                        m_map->addNodeWithEvent(p, n);
@@ -1012,8 +1013,9 @@ void ServerEnvironment::step(float dtime)
                                        if(myrand()%20 == 0)
                                        {
                                                MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
-                                               if(content_features(n_top).air_equivalent &&
-                                                               n_top.getLightBlend(getDayNightRatio()) >= 13)
+                                               if(m_gamedef->ndef()->get(n_top).air_equivalent &&
+                                                               n_top.getLightBlend(getDayNightRatio(),
+                                                                               m_gamedef->ndef()) >= 13)
                                                {
                                                        n.setContent(CONTENT_GRASS);
                                                        m_map->addNodeWithEvent(p, n);
@@ -1028,7 +1030,7 @@ void ServerEnvironment::step(float dtime)
                                        //if(myrand()%20 == 0)
                                        {
                                                MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
-                                               if(content_features(n_top).air_equivalent == false)
+                                               if(m_gamedef->ndef()->get(n_top).air_equivalent == false)
                                                {
                                                        n.setContent(CONTENT_MUD);
                                                        m_map->addNodeWithEvent(p, n);
@@ -1066,7 +1068,8 @@ void ServerEnvironment::step(float dtime)
                                        {
                                                v3s16 p1 = p + v3s16(0,1,0);
                                                MapNode n1a = m_map->getNodeNoEx(p1+v3s16(0,0,0));
-                                               if(n1a.getLightBlend(getDayNightRatio()) <= 3){
+                                               if(n1a.getLightBlend(getDayNightRatio(),
+                                                               m_gamedef->ndef()) <= 3){
                                                        MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,1,0));
                                                        if(n1a.getContent() == CONTENT_AIR &&
                                                                        n1b.getContent() == CONTENT_AIR)
@@ -2069,11 +2072,11 @@ void ClientEnvironment::step(float dtime)
 
                u32 damage_per_second = 0;
                damage_per_second = MYMAX(damage_per_second,
-                               content_features(n1).damage_per_second);
+                               m_gamedef->ndef()->get(n1).damage_per_second);
                damage_per_second = MYMAX(damage_per_second,
-                               content_features(n2).damage_per_second);
+                               m_gamedef->ndef()->get(n2).damage_per_second);
                damage_per_second = MYMAX(damage_per_second,
-                               content_features(n3).damage_per_second);
+                               m_gamedef->ndef()->get(n3).damage_per_second);
                
                if(damage_per_second != 0)
                {
@@ -2109,7 +2112,7 @@ void ClientEnvironment::step(float dtime)
                        // Get node at head
                        v3s16 p = player->getLightPosition();
                        MapNode n = m_map->getNode(p);
-                       light = n.getLightBlend(getDayNightRatio());
+                       light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef());
                }
                catch(InvalidPositionException &e) {}
                player->updateLight(light);
@@ -2164,7 +2167,7 @@ void ClientEnvironment::step(float dtime)
                                // Get node at head
                                v3s16 p = obj->getLightPosition();
                                MapNode n = m_map->getNode(p);
-                               light = n.getLightBlend(getDayNightRatio());
+                               light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef());
                        }
                        catch(InvalidPositionException &e) {}
                        obj->updateLight(light);
@@ -2172,9 +2175,9 @@ void ClientEnvironment::step(float dtime)
        }
 }
 
-void ClientEnvironment::updateMeshes(v3s16 blockpos, ITextureSource *tsrc)
+void ClientEnvironment::updateMeshes(v3s16 blockpos)
 {
-       m_map->updateMeshes(blockpos, getDayNightRatio(), tsrc);
+       m_map->updateMeshes(blockpos, getDayNightRatio());
 }
 
 void ClientEnvironment::expireMeshes(bool only_daynight_diffed)
index 754b63979657c727dbfa396e36c6bdd60af8d2cb..a8213ea6de8fadf02b32260efcb47d6fa3b74b40 100644 (file)
@@ -377,7 +377,7 @@ public:
        LocalPlayer * getLocalPlayer();
        
        // Slightly deprecated
-       void updateMeshes(v3s16 blockpos, ITextureSource *tsrc);
+       void updateMeshes(v3s16 blockpos);
        void expireMeshes(bool only_daynight_diffed);
 
        void setTimeOfDay(u32 time)
index 43d09b316c30d3d591658d95acec79603c0ad75b..a0bc5ac15f721a799f2ab2d6bc512371f0d8146e 100644 (file)
@@ -44,12 +44,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "log.h"
 #include "filesys.h"
 // Needed for determining pointing to nodes
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
 #include "nodemetadata.h"
 #include "main.h" // For g_settings
 #include "content_mapnode.h" // For content_mapnode_init
-#include "tool.h"
-#include "content_tool.h" // For content_tool_init
+#include "tooldef.h"
+#include "content_tool.h" // Default tools
+#include "content_mapnode.h" // Default nodes
 
 /*
        Setting this to 1 enables a special camera mode that forces
@@ -321,7 +322,7 @@ void getPointedNode(Client *client, v3f player_position,
                try
                {
                        n = client->getNode(v3s16(x,y,z));
-                       if(content_pointable(n.getContent()) == false)
+                       if(client->getNodeDefManager()->get(n).pointable == false)
                                continue;
                }
                catch(InvalidPositionException &e)
@@ -343,7 +344,7 @@ void getPointedNode(Client *client, v3f player_position,
                        v3s16(-1,0,0), // left
                };
                
-               ContentFeatures &f = content_features(n);
+               const ContentFeatures &f = client->getNodeDefManager()->get(n);
                
                if(f.selection_box.type == NODEBOX_FIXED)
                {
@@ -592,20 +593,17 @@ void the_game(
 
        draw_load_screen(L"Loading...", driver, font);
        
-       // Create tool manager
-       IToolDefManager *toolmgr = createToolDefManager();
-
+       // Create tool definition manager
+       IWritableToolDefManager *tooldef = createToolDefManager();
        // Create texture source
-       TextureSource *tsrc = new TextureSource(device);
-
-       // Initialize mapnode again to enable changed graphics settings
-       // Initialize content feature table with textures
-       init_contentfeatures(tsrc);
-       // Fill content feature table with default definitions
-       content_mapnode_init(tsrc);
+       IWritableTextureSource *tsrc = createTextureSource(device);
+       // Create node definition manager
+       IWritableNodeDefManager *nodedef = createNodeDefManager(tsrc);
 
-       // Initialize default tool definitions
-       content_tool_init(toolmgr);
+       // Fill node feature table with default definitions
+       content_mapnode_init(tsrc, nodedef);
+       // Set default tool definitions
+       content_tool_init(tooldef);
 
        /*
                Create server.
@@ -625,9 +623,14 @@ void the_game(
 
        draw_load_screen(L"Creating client...", driver, font);
        infostream<<"Creating client"<<std::endl;
+       
        MapDrawControl draw_control;
+
        Client client(device, playername.c_str(), password, draw_control,
-                       tsrc, toolmgr);
+                       tsrc, tooldef, nodedef);
+       
+       // Client acts as our GameDef
+       IGameDef *gamedef = &client;
                        
        draw_load_screen(L"Resolving address...", driver, font);
        Address connect_address(0,0,0,0, port);
@@ -1694,9 +1697,9 @@ void the_game(
                                        // Get digging properties for material and tool
                                        content_t material = n.getContent();
                                        ToolDiggingProperties tp =
-                                                       toolmgr->getDiggingProperties(toolname);
+                                                       tooldef->getDiggingProperties(toolname);
                                        DiggingProperties prop =
-                                                       getDiggingProperties(material, &tp);
+                                                       getDiggingProperties(material, &tp, nodedef);
                                        
                                        float dig_time_complete = 0.0;
 
@@ -2102,7 +2105,7 @@ void the_game(
                        InventoryItem *item = NULL;
                        if(mlist != NULL)
                                item = mlist->getItem(g_selected_item);
-                       camera.wield(item, tsrc);
+                       camera.wield(item, gamedef);
                }
                
                /*
@@ -2294,7 +2297,7 @@ void the_game(
                gui_shuttingdowntext->remove();*/
        }
 
-       delete toolmgr;
+       delete tooldef;
        delete tsrc;
 }
 
index 86fd1e80f9c5f71fa992e5cecd23c6154d9b0347..79f5d188e304199269bda07c9bf7c0936e3ae708 100644 (file)
@@ -21,9 +21,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define GAMEDEF_HEADER
 
 class IToolDefManager;
-class INodeDefManager; //TODO
+class INodeDefManager;
 //class IItemDefManager; //TODO
 // Mineral too?
+class ITextureSource;
 
 /*
        An interface for fetching game-global definitions like tool and
@@ -33,9 +34,20 @@ class INodeDefManager; //TODO
 class IGameDef
 {
 public:
+       // These are thread-safe IF they are not edited while running threads.
+       // Thus, first they are set up and then they are only read.
        virtual IToolDefManager* getToolDefManager()=0;
        virtual INodeDefManager* getNodeDefManager()=0;
        //virtual IItemDefManager* getItemDefManager()=0;
+
+       // This is always thread-safe, but referencing the irrlicht texture
+       // pointers in other threads than main thread will make things explode.
+       virtual ITextureSource* getTextureSource()=0;
+
+       // Shorthands
+       IToolDefManager* tdef(){return getToolDefManager();}
+       INodeDefManager* ndef(){return getNodeDefManager();}
+       ITextureSource* tsrc(){return getTextureSource();}
 };
 
 #endif
index 4ac2453ded127e9d281883872fb1be6b8da69f42..8ddbd3ac8add37e1ad0e83b170ee76a357a3fddf 100644 (file)
@@ -29,8 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "content_sao.h"
 #include "player.h"
 #include "log.h"
-#include "mapnode_contentfeatures.h"
-#include "tool.h"
+#include "nodedef.h"
+#include "tooldef.h"
 #include "gamedef.h"
 
 /*
@@ -152,7 +152,7 @@ ServerActiveObject* InventoryItem::createSAO(ServerEnvironment *env, u16 id, v3f
 #ifndef SERVER
 video::ITexture * MaterialItem::getImage(ITextureSource *tsrc) const
 {
-       return content_features(m_content).inventory_texture;
+       return m_gamedef->getNodeDefManager()->get(m_content).inventory_texture;
 }
 #endif
 
index 63dc949559daa6057090251fc5fe42356523ce4c..c94e903a55840b0a1108c908b62c5bea6d586a11 100644 (file)
@@ -434,7 +434,7 @@ Doing currently:
 #include "settings.h"
 #include "profiler.h"
 #include "log.h"
-#include "mapnode_contentfeatures.h" // For init_contentfeatures
+#include "nodedef.h" // For init_contentfeatures
 #include "content_mapnode.h" // For content_mapnode_init
 
 /*
@@ -1272,10 +1272,6 @@ int main(int argc, char *argv[])
                These are needed for unit tests at least.
        */
        
-       // Initialize content feature table without textures
-       init_contentfeatures(NULL);
-       // Initialize mapnode content without textures
-       content_mapnode_init(NULL);
        // Must be called before texturesource is created
        // (for texture atlas making)
        init_mineral();
index 6b2142dbae63956c3ba816aca7249472b9d08340..2dfbbbb33d9108f451180b86f02f009bbc5152b2 100644 (file)
@@ -37,7 +37,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "settings.h"
 #include "log.h"
 #include "profiler.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
+#include "gamedef.h"
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
 
@@ -234,6 +235,8 @@ void Map::unspreadLight(enum LightBank bank,
                core::map<v3s16, bool> & light_sources,
                core::map<v3s16, MapBlock*>  & modified_blocks)
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        v3s16 dirs[6] = {
                v3s16(0,0,1), // back
                v3s16(0,1,0), // top
@@ -330,19 +333,20 @@ void Map::unspreadLight(enum LightBank bank,
                                        If the neighbor is dimmer than what was specified
                                        as oldlight (the light of the previous node)
                                */
-                               if(n2.getLight(bank) < oldlight)
+                               if(n2.getLight(bank, nodemgr) < oldlight)
                                {
                                        /*
                                                And the neighbor is transparent and it has some light
                                        */
-                                       if(n2.light_propagates() && n2.getLight(bank) != 0)
+                                       if(nodemgr->get(n2).light_propagates
+                                                       && n2.getLight(bank, nodemgr) != 0)
                                        {
                                                /*
                                                        Set light to 0 and add to queue
                                                */
 
-                                               u8 current_light = n2.getLight(bank);
-                                               n2.setLight(bank, 0);
+                                               u8 current_light = n2.getLight(bank, nodemgr);
+                                               n2.setLight(bank, 0, nodemgr);
                                                block->setNode(relpos, n2);
 
                                                unlighted_nodes.insert(n2pos, current_light);
@@ -416,6 +420,8 @@ void Map::spreadLight(enum LightBank bank,
                core::map<v3s16, bool> & from_nodes,
                core::map<v3s16, MapBlock*> & modified_blocks)
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        const v3s16 dirs[6] = {
                v3s16(0,0,1), // back
                v3s16(0,1,0), // top
@@ -474,7 +480,7 @@ void Map::spreadLight(enum LightBank bank,
                // Get node straight from the block
                MapNode n = block->getNode(relpos);
 
-               u8 oldlight = n.getLight(bank);
+               u8 oldlight = n.getLight(bank, nodemgr);
                u8 newlight = diminish_light(oldlight);
 
                // Loop through 6 neighbors
@@ -512,7 +518,7 @@ void Map::spreadLight(enum LightBank bank,
                                        If the neighbor is brighter than the current node,
                                        add to list (it will light up this node on its turn)
                                */
-                               if(n2.getLight(bank) > undiminish_light(oldlight))
+                               if(n2.getLight(bank, nodemgr) > undiminish_light(oldlight))
                                {
                                        lighted_nodes.insert(n2pos, true);
                                        //lighted_nodes.push_back(n2pos);
@@ -522,11 +528,11 @@ void Map::spreadLight(enum LightBank bank,
                                        If the neighbor is dimmer than how much light this node
                                        would spread on it, add to list
                                */
-                               if(n2.getLight(bank) < newlight)
+                               if(n2.getLight(bank, nodemgr) < newlight)
                                {
-                                       if(n2.light_propagates())
+                                       if(nodemgr->get(n2).light_propagates)
                                        {
-                                               n2.setLight(bank, newlight);
+                                               n2.setLight(bank, newlight, nodemgr);
                                                block->setNode(relpos, n2);
                                                lighted_nodes.insert(n2pos, true);
                                                //lighted_nodes.push_back(n2pos);
@@ -575,6 +581,8 @@ void Map::lightNeighbors(enum LightBank bank,
 
 v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        v3s16 dirs[6] = {
                v3s16(0,0,1), // back
                v3s16(0,1,0), // top
@@ -600,8 +608,8 @@ v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
                {
                        continue;
                }
-               if(n2.getLight(bank) > brightest_light || found_something == false){
-                       brightest_light = n2.getLight(bank);
+               if(n2.getLight(bank, nodemgr) > brightest_light || found_something == false){
+                       brightest_light = n2.getLight(bank, nodemgr);
                        brightest_pos = n2pos;
                        found_something = true;
                }
@@ -624,6 +632,8 @@ v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p)
 s16 Map::propagateSunlight(v3s16 start,
                core::map<v3s16, MapBlock*> & modified_blocks)
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        s16 y = start.Y;
        for(; ; y--)
        {
@@ -642,9 +652,9 @@ s16 Map::propagateSunlight(v3s16 start,
                v3s16 relpos = pos - blockpos*MAP_BLOCKSIZE;
                MapNode n = block->getNode(relpos);
 
-               if(n.sunlight_propagates())
+               if(nodemgr->get(n).sunlight_propagates)
                {
-                       n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
+                       n.setLight(LIGHTBANK_DAY, LIGHT_SUN, nodemgr);
                        block->setNode(relpos, n);
 
                        modified_blocks.insert(blockpos, block);
@@ -670,6 +680,8 @@ void Map::updateLighting(enum LightBank bank,
                core::map<v3s16, MapBlock*> & a_blocks,
                core::map<v3s16, MapBlock*> & modified_blocks)
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        /*m_dout<<DTIME<<"Map::updateLighting(): "
                        <<a_blocks.size()<<" blocks."<<std::endl;*/
 
@@ -713,8 +725,8 @@ void Map::updateLighting(enum LightBank bank,
                                try{
                                        v3s16 p(x,y,z);
                                        MapNode n = block->getNode(v3s16(x,y,z));
-                                       u8 oldlight = n.getLight(bank);
-                                       n.setLight(bank, 0);
+                                       u8 oldlight = n.getLight(bank, nodemgr);
+                                       n.setLight(bank, 0, nodemgr);
                                        block->setNode(v3s16(x,y,z), n);
 
                                        // Collect borders for unlighting
@@ -865,11 +877,11 @@ void Map::updateLighting(enum LightBank bank,
 
                {
                        //TimeTaker timer("unSpreadLight");
-                       vmanip.unspreadLight(bank, unlight_from, light_sources);
+                       vmanip.unspreadLight(bank, unlight_from, light_sources, nodemgr);
                }
                {
                        //TimeTaker timer("spreadLight");
-                       vmanip.spreadLight(bank, light_sources);
+                       vmanip.spreadLight(bank, light_sources, nodemgr);
                }
                {
                        //TimeTaker timer("blitBack");
@@ -905,6 +917,8 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
 void Map::addNodeAndUpdate(v3s16 p, MapNode n,
                core::map<v3s16, MapBlock*> &modified_blocks, std::string &player_name)
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        /*PrintInfo(m_dout);
        m_dout<<DTIME<<"Map::addNodeAndUpdate(): p=("
                        <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
@@ -931,7 +945,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
        try{
                MapNode topnode = getNode(toppos);
 
-               if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
+               if(topnode.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN)
                        node_under_sunlight = false;
        }
        catch(InvalidPositionException &e)
@@ -942,7 +956,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
        /*
                If the new node is solid and there is grass below, change it to mud
        */
-       if(content_features(n).walkable == true)
+       if(nodemgr->get(n).walkable == true)
        {
                try{
                        MapNode bottomnode = getNode(bottompos);
@@ -984,7 +998,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
        {
                enum LightBank bank = banks[i];
 
-               u8 lightwas = getNode(p).getLight(bank);
+               u8 lightwas = getNode(p).getLight(bank, nodemgr);
 
                // Add the block of the added node to modified_blocks
                v3s16 blockpos = getNodeBlockPos(p);
@@ -1001,16 +1015,16 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
                // light again into this.
                unLightNeighbors(bank, p, lightwas, light_sources, modified_blocks);
 
-               n.setLight(bank, 0);
+               n.setLight(bank, 0, nodemgr);
        }
 
        /*
                If node lets sunlight through and is under sunlight, it has
                sunlight too.
        */
-       if(node_under_sunlight && content_features(n).sunlight_propagates)
+       if(node_under_sunlight && nodemgr->get(n).sunlight_propagates)
        {
-               n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
+               n.setLight(LIGHTBANK_DAY, LIGHT_SUN, nodemgr);
        }
 
        /*
@@ -1023,7 +1037,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
                Add intial metadata
        */
 
-       NodeMetadata *meta_proto = content_features(n).initial_metadata;
+       NodeMetadata *meta_proto = nodemgr->get(n).initial_metadata;
        if(meta_proto)
        {
                NodeMetadata *meta = meta_proto->clone(m_gamedef);
@@ -1038,7 +1052,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
                TODO: This could be optimized by mass-unlighting instead
                          of looping
        */
-       if(node_under_sunlight && !content_features(n).sunlight_propagates)
+       if(node_under_sunlight && !nodemgr->get(n).sunlight_propagates)
        {
                s16 y = p.Y - 1;
                for(;; y--){
@@ -1054,12 +1068,12 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
                                break;
                        }
 
-                       if(n2.getLight(LIGHTBANK_DAY) == LIGHT_SUN)
+                       if(n2.getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN)
                        {
                                unLightNeighbors(LIGHTBANK_DAY,
-                                               n2pos, n2.getLight(LIGHTBANK_DAY),
+                                               n2pos, n2.getLight(LIGHTBANK_DAY, nodemgr),
                                                light_sources, modified_blocks);
-                               n2.setLight(LIGHTBANK_DAY, 0);
+                               n2.setLight(LIGHTBANK_DAY, 0, nodemgr);
                                setNode(n2pos, n2);
                        }
                        else
@@ -1109,7 +1123,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
                v3s16 p2 = p + dirs[i];
 
                MapNode n2 = getNode(p2);
-               if(content_liquid(n2.getContent()) || n2.getContent() == CONTENT_AIR)
+               if(nodemgr->get(n2).isLiquid() || n2.getContent() == CONTENT_AIR)
                {
                        m_transforming_liquid.push_back(p2);
                }
@@ -1125,6 +1139,8 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
 void Map::removeNodeAndUpdate(v3s16 p,
                core::map<v3s16, MapBlock*> &modified_blocks)
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        /*PrintInfo(m_dout);
        m_dout<<DTIME<<"Map::removeNodeAndUpdate(): p=("
                        <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
@@ -1143,7 +1159,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
        try{
                MapNode topnode = getNode(toppos);
 
-               if(topnode.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
+               if(topnode.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN)
                        node_under_sunlight = false;
        }
        catch(InvalidPositionException &e)
@@ -1165,7 +1181,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
                        Unlight neighbors (in case the node is a light source)
                */
                unLightNeighbors(bank, p,
-                               getNode(p).getLight(bank),
+                               getNode(p).getLight(bank, nodemgr),
                                light_sources, modified_blocks);
        }
 
@@ -1227,7 +1243,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
                // TODO: Is this needed? Lighting is cleared up there already.
                try{
                        MapNode n = getNode(p);
-                       n.setLight(LIGHTBANK_DAY, 0);
+                       n.setLight(LIGHTBANK_DAY, 0, nodemgr);
                        setNode(p, n);
                }
                catch(InvalidPositionException &e)
@@ -1283,7 +1299,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
                v3s16 p2 = p + dirs[i];
 
                MapNode n2 = getNode(p2);
-               if(content_liquid(n2.getContent()) || n2.getContent() == CONTENT_AIR)
+               if(nodemgr->get(n2).isLiquid() || n2.getContent() == CONTENT_AIR)
                {
                        m_transforming_liquid.push_back(p2);
                }
@@ -1580,6 +1596,8 @@ struct NodeNeighbor {
 
 void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        DSTACK(__FUNCTION_NAME);
        //TimeTaker timer("transformLiquids()");
 
@@ -1614,11 +1632,11 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
                 */
                s8 liquid_level = -1;
                u8 liquid_kind = CONTENT_IGNORE;
-               LiquidType liquid_type = content_features(n0.getContent()).liquid_type;
+               LiquidType liquid_type = nodemgr->get(n0).liquid_type;
                switch (liquid_type) {
                        case LIQUID_SOURCE:
                                liquid_level = LIQUID_LEVEL_SOURCE;
-                               liquid_kind = content_features(n0.getContent()).liquid_alternative_flowing;
+                               liquid_kind = nodemgr->get(n0).liquid_alternative_flowing;
                                break;
                        case LIQUID_FLOWING:
                                liquid_level = (n0.param2 & LIQUID_LEVEL_MASK);
@@ -1658,7 +1676,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
                        }
                        v3s16 npos = p0 + dirs[i];
                        NodeNeighbor nb = {getNodeNoEx(npos), nt, npos};
-                       switch (content_features(nb.n.getContent()).liquid_type) {
+                       switch (nodemgr->get(nb.n.getContent()).liquid_type) {
                                case LIQUID_NONE:
                                        if (nb.n.getContent() == CONTENT_AIR) {
                                                airs[num_airs++] = nb;
@@ -1678,8 +1696,8 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
                                case LIQUID_SOURCE:
                                        // if this node is not (yet) of a liquid type, choose the first liquid type we encounter 
                                        if (liquid_kind == CONTENT_AIR)
-                                               liquid_kind = content_features(nb.n.getContent()).liquid_alternative_flowing;
-                                       if (content_features(nb.n.getContent()).liquid_alternative_flowing !=liquid_kind) {
+                                               liquid_kind = nodemgr->get(nb.n.getContent()).liquid_alternative_flowing;
+                                       if (nodemgr->get(nb.n.getContent()).liquid_alternative_flowing !=liquid_kind) {
                                                neutrals[num_neutrals++] = nb;
                                        } else {
                                                sources[num_sources++] = nb;
@@ -1688,8 +1706,8 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
                                case LIQUID_FLOWING:
                                        // if this node is not (yet) of a liquid type, choose the first liquid type we encounter
                                        if (liquid_kind == CONTENT_AIR)
-                                               liquid_kind = content_features(nb.n.getContent()).liquid_alternative_flowing;
-                                       if (content_features(nb.n.getContent()).liquid_alternative_flowing != liquid_kind) {
+                                               liquid_kind = nodemgr->get(nb.n.getContent()).liquid_alternative_flowing;
+                                       if (nodemgr->get(nb.n.getContent()).liquid_alternative_flowing != liquid_kind) {
                                                neutrals[num_neutrals++] = nb;
                                        } else {
                                                flows[num_flows++] = nb;
@@ -1710,7 +1728,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
                        // liquid_kind will be set to either the flowing alternative of the node (if it's a liquid)
                        // or the flowing alternative of the first of the surrounding sources (if it's air), so
                        // it's perfectly safe to use liquid_kind here to determine the new node content.
-                       new_node_content = content_features(liquid_kind).liquid_alternative_source;
+                       new_node_content = nodemgr->get(liquid_kind).liquid_alternative_source;
                } else if (num_sources == 1 && sources[0].t != NEIGHBOR_LOWER) {
                        // liquid_kind is set properly, see above
                        new_node_content = liquid_kind;
@@ -1739,7 +1757,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
                                }
                        }
 
-                       u8 viscosity = content_features(liquid_kind).liquid_viscosity;
+                       u8 viscosity = nodemgr->get(liquid_kind).liquid_viscosity;
                        if (viscosity > 1 && max_node_level != liquid_level) {
                                // amount to gain, limited by viscosity
                                // must be at least 1 in absolute value
@@ -1765,7 +1783,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
                /*
                        check if anything has changed. if not, just continue with the next node.
                 */
-               if (new_node_content == n0.getContent() && (content_features(n0.getContent()).liquid_type != LIQUID_FLOWING ||
+               if (new_node_content == n0.getContent() && (nodemgr->get(n0.getContent()).liquid_type != LIQUID_FLOWING ||
                                                                                 ((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level &&
                                                                                 ((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK)
                                                                                 == flowing_down)))
@@ -1776,7 +1794,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
                        update the current node
                 */
                //bool flow_down_enabled = (flowing_down && ((n0.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK));
-               if (content_features(new_node_content).liquid_type == LIQUID_FLOWING) {
+               if (nodemgr->get(new_node_content).liquid_type == LIQUID_FLOWING) {
                        // set level to last 3 bits, flowing down bit to 4th bit
                        n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK);
                } else {
@@ -1790,14 +1808,14 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
                if(block != NULL) {
                        modified_blocks.insert(blockpos, block);
                        // If node emits light, MapBlock requires lighting update
-                       if(content_features(n0).light_source != 0)
+                       if(nodemgr->get(n0).light_source != 0)
                                lighting_modified_blocks[block->getPos()] = block;
                }
 
                /*
                        enqueue neighbors for update if neccessary
                 */
-               switch (content_features(n0.getContent()).liquid_type) {
+               switch (nodemgr->get(n0.getContent()).liquid_type) {
                        case LIQUID_SOURCE:
                        case LIQUID_FLOWING:
                                // make sure source flows into all neighboring nodes
@@ -2082,6 +2100,7 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
        data->no_op = false;
        data->seed = m_seed;
        data->blockpos = blockpos;
+       data->nodemgr = m_gamedef->ndef();
 
        /*
                Create the whole area of this and the neighboring blocks
@@ -2389,7 +2408,7 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d)
                Generate blank sector
        */
        
-       sector = new ServerMapSector(this, p2d);
+       sector = new ServerMapSector(this, p2d, m_gamedef);
        
        // Sector position on map in nodes
        v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
@@ -3054,7 +3073,7 @@ MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load
                                        <<fullpath<<" doesn't exist but directory does."
                                        <<" Continuing with a sector with no metadata."
                                        <<std::endl;*/
-                       sector = new ServerMapSector(this, p2d);
+                       sector = new ServerMapSector(this, p2d, m_gamedef);
                        m_sectors.insert(p2d, sector);
                }
                else
@@ -3065,7 +3084,7 @@ MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load
        else
        {
                sector = ServerMapSector::deSerialize
-                               (is, this, p2d, m_sectors);
+                               (is, this, p2d, m_sectors, m_gamedef);
                if(save_after_load)
                        saveSectorMeta(sector);
        }
@@ -3310,7 +3329,7 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto
                }
                
                // Read basic data
-               block->deSerialize(is, version, m_gamedef);
+               block->deSerialize(is, version);
 
                // Read extra data stored on disk
                block->deSerializeDiskExtra(is, version);
@@ -3380,7 +3399,7 @@ void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool
                }
                
                // Read basic data
-               block->deSerialize(is, version, m_gamedef);
+               block->deSerialize(is, version);
 
                // Read extra data stored on disk
                block->deSerializeDiskExtra(is, version);
@@ -3567,7 +3586,7 @@ MapSector * ClientMap::emergeSector(v2s16 p2d)
        }
        
        // Create a sector
-       ClientMapSector *sector = new ClientMapSector(this, p2d);
+       ClientMapSector *sector = new ClientMapSector(this, p2d, m_gamedef);
        
        {
                //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
@@ -3617,7 +3636,7 @@ void ClientMap::OnRegisterSceneNode()
 }
 
 static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
-               float start_off, float end_off, u32 needed_count)
+               float start_off, float end_off, u32 needed_count, INodeDefManager *nodemgr)
 {
        float d0 = (float)BS * p0.getDistanceFrom(p1);
        v3s16 u0 = p1 - p0;
@@ -3630,7 +3649,7 @@ static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
                v3s16 p = floatToInt(pf, BS);
                MapNode n = map->getNodeNoEx(p);
                bool is_transparent = false;
-               ContentFeatures &f = content_features(n);
+               const ContentFeatures &f = nodemgr->get(n);
                if(f.solidness == 0)
                        is_transparent = (f.visual_solidness != 2);
                else
@@ -3647,6 +3666,8 @@ static bool isOccluded(Map *map, v3s16 p0, v3s16 p1, float step, float stepfac,
 
 void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        //m_dout<<DTIME<<"Rendering map..."<<std::endl;
        DSTACK(__FUNCTION_NAME);
 
@@ -3855,23 +3876,23 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                        u32 needed_count = 1;
                        if(
                                isOccluded(this, spn, cpn + v3s16(0,0,0),
-                                               step, stepfac, startoff, endoff, needed_count) &&
+                                       step, stepfac, startoff, endoff, needed_count, nodemgr) &&
                                isOccluded(this, spn, cpn + v3s16(bs2,bs2,bs2),
-                                               step, stepfac, startoff, endoff, needed_count) &&
+                                       step, stepfac, startoff, endoff, needed_count, nodemgr) &&
                                isOccluded(this, spn, cpn + v3s16(bs2,bs2,-bs2),
-                                               step, stepfac, startoff, endoff, needed_count) &&
+                                       step, stepfac, startoff, endoff, needed_count, nodemgr) &&
                                isOccluded(this, spn, cpn + v3s16(bs2,-bs2,bs2),
-                                               step, stepfac, startoff, endoff, needed_count) &&
+                                       step, stepfac, startoff, endoff, needed_count, nodemgr) &&
                                isOccluded(this, spn, cpn + v3s16(bs2,-bs2,-bs2),
-                                               step, stepfac, startoff, endoff, needed_count) &&
+                                       step, stepfac, startoff, endoff, needed_count, nodemgr) &&
                                isOccluded(this, spn, cpn + v3s16(-bs2,bs2,bs2),
-                                               step, stepfac, startoff, endoff, needed_count) &&
+                                       step, stepfac, startoff, endoff, needed_count, nodemgr) &&
                                isOccluded(this, spn, cpn + v3s16(-bs2,bs2,-bs2),
-                                               step, stepfac, startoff, endoff, needed_count) &&
+                                       step, stepfac, startoff, endoff, needed_count, nodemgr) &&
                                isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,bs2),
-                                               step, stepfac, startoff, endoff, needed_count) &&
+                                       step, stepfac, startoff, endoff, needed_count, nodemgr) &&
                                isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,-bs2),
-                                               step, stepfac, startoff, endoff, needed_count)
+                                       step, stepfac, startoff, endoff, needed_count, nodemgr)
                        )
                        {
                                blocks_occlusion_culled++;
@@ -4016,6 +4037,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
 
 void ClientMap::renderPostFx()
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        // Sadly ISceneManager has no "post effects" render pass, in that case we
        // could just register for that and handle it in renderMap().
 
@@ -4027,7 +4050,7 @@ void ClientMap::renderPostFx()
 
        // - If the player is in a solid node, make everything black.
        // - If the player is in liquid, draw a semi-transparent overlay.
-       ContentFeatures& features = content_features(n);
+       const ContentFeatures& features = nodemgr->get(n);
        video::SColor post_effect_color = features.post_effect_color;
        if(features.solidness == 2 && g_settings->getBool("free_move") == false)
        {
@@ -4170,15 +4193,14 @@ void ClientMap::expireMeshes(bool only_daynight_diffed)
        }
 }
 
-void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio,
-               ITextureSource *tsrc)
+void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio)
 {
        assert(mapType() == MAPTYPE_CLIENT);
 
        try{
                v3s16 p = blockpos + v3s16(0,0,0);
                MapBlock *b = getBlockNoCreate(p);
-               b->updateMesh(daynight_ratio, tsrc);
+               b->updateMesh(daynight_ratio);
                //b->setMeshExpired(true);
        }
        catch(InvalidPositionException &e){}
@@ -4186,21 +4208,21 @@ void ClientMap::updateMeshes(v3s16 blockpos, u32 daynight_ratio,
        try{
                v3s16 p = blockpos + v3s16(-1,0,0);
                MapBlock *b = getBlockNoCreate(p);
-               b->updateMesh(daynight_ratio, tsrc);
+               b->updateMesh(daynight_ratio);
                //b->setMeshExpired(true);
        }
        catch(InvalidPositionException &e){}
        try{
                v3s16 p = blockpos + v3s16(0,-1,0);
                MapBlock *b = getBlockNoCreate(p);
-               b->updateMesh(daynight_ratio, tsrc);
+               b->updateMesh(daynight_ratio);
                //b->setMeshExpired(true);
        }
        catch(InvalidPositionException &e){}
        try{
                v3s16 p = blockpos + v3s16(0,0,-1);
                MapBlock *b = getBlockNoCreate(p);
-               b->updateMesh(daynight_ratio, tsrc);
+               b->updateMesh(daynight_ratio);
                //b->setMeshExpired(true);
        }
        catch(InvalidPositionException &e){}
index 6eb208be9034038f15888995d4b23a35be28d084..3def571b8189a5c3c65127032ba20f53d9fbf689 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -590,8 +590,7 @@ public:
                Update the faces of the given block and blocks on the
                leading edge, without threading. Rarely used.
        */
-       void updateMeshes(v3s16 blockpos, u32 daynight_ratio,
-                       ITextureSource *tsrc);
+       void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
        
        // Update meshes that touch the node
        //void updateNodeMeshes(v3s16 nodepos, u32 daynight_ratio);
index 944d62230de38558089e202ac8f4d9933e89c828..dcafaae73888f2661e8c30e41e35ec793e919d3e 100644 (file)
@@ -23,17 +23,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "main.h"
 #include "light.h"
 #include <sstream>
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
 #include "nodemetadata.h"
+#include "gamedef.h"
 
 /*
        MapBlock
 */
 
-MapBlock::MapBlock(Map *parent, v3s16 pos, bool dummy):
+MapBlock::MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy):
                m_node_metadata(new NodeMetadataList),
                m_parent(parent),
                m_pos(pos),
+               m_gamedef(gamedef),
                m_modified(MOD_STATE_WRITE_NEEDED),
                is_underground(false),
                m_lighting_expired(true),
@@ -138,7 +140,7 @@ MapNode MapBlock::getNodeParentNoEx(v3s16 p)
 #ifndef SERVER
 
 #if 1
-void MapBlock::updateMesh(u32 daynight_ratio, ITextureSource *tsrc)
+void MapBlock::updateMesh(u32 daynight_ratio)
 {
 #if 0
        /*
@@ -154,7 +156,7 @@ void MapBlock::updateMesh(u32 daynight_ratio, ITextureSource *tsrc)
        MeshMakeData data;
        data.fill(daynight_ratio, this);
        
-       scene::SMesh *mesh_new = makeMapBlockMesh(&data, tsrc);
+       scene::SMesh *mesh_new = makeMapBlockMesh(&data, m_gamedef);
        
        /*
                Replace the mesh
@@ -229,6 +231,8 @@ void MapBlock::replaceMesh(scene::SMesh *mesh_new)
 bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
                bool remove_light, bool *black_air_left)
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        // Whether the sunlight at the top of the bottom block is valid
        bool block_below_is_valid = true;
        
@@ -249,7 +253,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
                                        // Trust heuristics
                                        no_sunlight = is_underground;
                                }
-                               else if(n.getLight(LIGHTBANK_DAY) != LIGHT_SUN)
+                               else if(n.getLight(LIGHTBANK_DAY, m_gamedef->ndef()) != LIGHT_SUN)
                                {
                                        no_sunlight = true;
                                }
@@ -268,7 +272,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
                                {
                                        MapNode n = getNode(v3s16(x, MAP_BLOCKSIZE-1, z));
                                        //if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE)
-                                       if(content_features(n).sunlight_propagates == false)
+                                       if(m_gamedef->ndef()->get(n).sunlight_propagates == false)
                                        {
                                                no_sunlight = true;
                                        }
@@ -317,11 +321,11 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
                                {
                                        // Do nothing
                                }
-                               else if(current_light == LIGHT_SUN && n.sunlight_propagates())
+                               else if(current_light == LIGHT_SUN && nodemgr->get(n).sunlight_propagates)
                                {
                                        // Do nothing: Sunlight is continued
                                }
-                               else if(n.light_propagates() == false)
+                               else if(nodemgr->get(n).light_propagates == false)
                                {
                                        /*// DEPRECATED TODO: REMOVE
                                        if(grow_grass)
@@ -355,11 +359,11 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
                                        current_light = diminish_light(current_light);
                                }
 
-                               u8 old_light = n.getLight(LIGHTBANK_DAY);
+                               u8 old_light = n.getLight(LIGHTBANK_DAY, nodemgr);
 
                                if(current_light > old_light || remove_light)
                                {
-                                       n.setLight(LIGHTBANK_DAY, current_light);
+                                       n.setLight(LIGHTBANK_DAY, current_light, nodemgr);
                                }
                                
                                if(diminish_light(current_light) != 0)
@@ -392,12 +396,12 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
                        if(block_below_is_valid)
                        {
                                MapNode n = getNodeParent(v3s16(x, -1, z));
-                               if(n.light_propagates())
+                               if(nodemgr->get(n).light_propagates)
                                {
-                                       if(n.getLight(LIGHTBANK_DAY) == LIGHT_SUN
+                                       if(n.getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN
                                                        && sunlight_should_go_down == false)
                                                block_below_is_valid = false;
-                                       else if(n.getLight(LIGHTBANK_DAY) != LIGHT_SUN
+                                       else if(n.getLight(LIGHTBANK_DAY, nodemgr) != LIGHT_SUN
                                                        && sunlight_should_go_down == true)
                                                block_below_is_valid = false;
                                }
@@ -438,6 +442,8 @@ void MapBlock::copyFrom(VoxelManipulator &dst)
 
 void MapBlock::updateDayNightDiff()
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        if(data == NULL)
        {
                m_day_night_differs = false;
@@ -452,7 +458,7 @@ void MapBlock::updateDayNightDiff()
        for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
        {
                MapNode &n = data[i];
-               if(n.getLight(LIGHTBANK_DAY) != n.getLight(LIGHTBANK_NIGHT))
+               if(n.getLight(LIGHTBANK_DAY, nodemgr) != n.getLight(LIGHTBANK_NIGHT, nodemgr))
                {
                        differs = true;
                        break;
@@ -493,7 +499,7 @@ s16 MapBlock::getGroundLevel(v2s16 p2d)
                for(; y>=0; y--)
                {
                        MapNode n = getNodeRef(p2d.X, y, p2d.Y);
-                       if(content_features(n).walkable)
+                       if(m_gamedef->ndef()->get(n).walkable)
                        {
                                if(y == MAP_BLOCKSIZE-1)
                                        return -2;
@@ -655,8 +661,10 @@ void MapBlock::serialize(std::ostream &os, u8 version)
        }
 }
 
-void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
+void MapBlock::deSerialize(std::istream &is, u8 version)
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        if(!ser_ver_supported(version))
                throw VersionMismatchException("ERROR: MapBlock format not supported");
 
@@ -690,7 +698,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
                        if(is.gcount() != len)
                                throw SerializationError
                                                ("MapBlock::deSerialize: no enough input data");
-                       data[i].deSerialize(*d, version);
+                       data[i].deSerialize(*d, version, nodemgr);
                }
        }
        else if(version <= 10)
@@ -772,7 +780,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
                        buf[0] = s[i];
                        buf[1] = s[i+nodecount];
                        buf[2] = s[i+nodecount*2];
-                       data[i].deSerialize(buf, version);
+                       data[i].deSerialize(buf, version, m_gamedef->getNodeDefManager());
                }
                
                /*
@@ -786,7 +794,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
                                {
                                        std::string data = deSerializeString(is);
                                        std::istringstream iss(data, std::ios_base::binary);
-                                       m_node_metadata->deSerialize(iss, gamedef);
+                                       m_node_metadata->deSerialize(iss, m_gamedef);
                                }
                                else
                                {
@@ -794,7 +802,7 @@ void MapBlock::deSerialize(std::istream &is, u8 version, IGameDef *gamedef)
                                        std::ostringstream oss(std::ios_base::binary);
                                        decompressZlib(is, oss);
                                        std::istringstream iss(oss.str(), std::ios_base::binary);
-                                       m_node_metadata->deSerialize(iss, gamedef);
+                                       m_node_metadata->deSerialize(iss, m_gamedef);
                                }
                        }
                        catch(SerializationError &e)
index 75e146665390c279cfea2d81c07edee7881b5032..e7fd932b8e2395e7613a53a8f91bdc98fd69fefd 100644 (file)
@@ -38,7 +38,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 class Map;
 class NodeMetadataList;
-class ITextureSource;
 class IGameDef;
 
 #define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff
@@ -120,7 +119,7 @@ public:
 class MapBlock /*: public NodeContainer*/
 {
 public:
-       MapBlock(Map *parent, v3s16 pos, bool dummy=false);
+       MapBlock(Map *parent, v3s16 pos, IGameDef *gamedef, bool dummy=false);
        ~MapBlock();
        
        /*virtual u16 nodeContainerId() const
@@ -393,12 +392,13 @@ public:
                                getNodeParentNoEx(p + face_dir),
                                face_dir);
        }*/
-       u8 getFaceLight2(u32 daynight_ratio, v3s16 p, v3s16 face_dir)
+       u8 getFaceLight2(u32 daynight_ratio, v3s16 p, v3s16 face_dir,
+                       INodeDefManager *nodemgr)
        {
                return getFaceLight(daynight_ratio,
                                getNodeParentNoEx(p),
                                getNodeParentNoEx(p + face_dir),
-                               face_dir);
+                               face_dir, nodemgr);
        }
        
 #ifndef SERVER // Only on client
@@ -409,7 +409,7 @@ public:
                NOTE: Prefer generating the mesh separately and then using
                replaceMesh().
        */
-       void updateMesh(u32 daynight_ratio, ITextureSource *tsrc);
+       void updateMesh(u32 daynight_ratio);
 #endif
        // Replace the mesh with a new one
        void replaceMesh(scene::SMesh *mesh_new);
@@ -539,7 +539,7 @@ public:
        
        // These don't write or read version by itself
        void serialize(std::ostream &os, u8 version);
-       void deSerialize(std::istream &is, u8 version, IGameDef *gamedef);
+       void deSerialize(std::istream &is, u8 version);
        // Used after the basic ones when writing on disk (serverside)
        void serializeDiskExtra(std::ostream &os, u8 version);
        void deSerializeDiskExtra(std::istream &is, u8 version);
@@ -589,6 +589,8 @@ private:
        Map *m_parent;
        // Position in blocks on parent
        v3s16 m_pos;
+
+       IGameDef *m_gamedef;
        
        /*
                If NULL, block is a dummy block.
index 2f9f9ce434283482b5215f91326813de6d9c2ae8..5d8c0b737474cf322a9c0b88d43839a53e361bf3 100644 (file)
@@ -22,11 +22,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapblock.h"
 #include "map.h"
 #include "main.h" // For g_settings and g_texturesource
-#include "content_mapblock.h"
 #include "settings.h"
 #include "profiler.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
 #include "tile.h"
+#include "gamedef.h"
+#include "content_mapblock.h"
 
 void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block)
 {
@@ -84,7 +85,7 @@ void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block)
 /*
        vertex_dirs: v3s16[4]
 */
-void getNodeVertexDirs(v3s16 dir, v3s16 *vertex_dirs)
+static void getNodeVertexDirs(v3s16 dir, v3s16 *vertex_dirs)
 {
        /*
                If looked from outside the node towards the face, the corners are:
@@ -170,7 +171,7 @@ struct FastFace
        video::S3DVertex vertices[4]; // Precalculated vertices
 };
 
-void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
+static void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
                v3s16 dir, v3f scale, v3f posRelative_f,
                core::array<FastFace> &dest)
 {
@@ -252,11 +253,11 @@ void makeFastFace(TileSpec tile, u8 li0, u8 li1, u8 li2, u8 li3, v3f p,
        Gets node tile from any place relative to block.
        Returns TILE_NODE if doesn't exist or should not be drawn.
 */
-TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
-               NodeModMap &temp_mods, ITextureSource *tsrc)
+static TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
+               NodeModMap &temp_mods, ITextureSource *tsrc, INodeDefManager *ndef)
 {
        TileSpec spec;
-       spec = mn.getTile(face_dir, tsrc);
+       spec = mn.getTile(face_dir, tsrc, ndef);
        
        /*
                Check temporary modifications on this node
@@ -273,7 +274,7 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
                if(mod.type == NODEMOD_CHANGECONTENT)
                {
                        MapNode mn2(mod.param);
-                       spec = mn2.getTile(face_dir, tsrc);
+                       spec = mn2.getTile(face_dir, tsrc, ndef);
                }
                if(mod.type == NODEMOD_CRACK)
                {
@@ -304,7 +305,7 @@ TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
        return spec;
 }
 
-content_t getNodeContent(v3s16 p, MapNode mn, NodeModMap &temp_mods)
+static content_t getNodeContent(v3s16 p, MapNode mn, NodeModMap &temp_mods)
 {
        /*
                Check temporary modifications on this node
@@ -354,7 +355,8 @@ v3s16 dirs8[8] = {
 };
 
 // Calculate lighting at the XYZ- corner of p
-u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio)
+static u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio,
+               INodeDefManager *ndef)
 {
        u16 ambient_occlusion = 0;
        u16 light = 0;
@@ -362,11 +364,11 @@ u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio)
        for(u32 i=0; i<8; i++)
        {
                MapNode n = vmanip.getNodeNoEx(p - dirs8[i]);
-               if(content_features(n).param_type == CPT_LIGHT
+               if(ndef->get(n).param_type == CPT_LIGHT
                                // Fast-style leaves look better this way
-                               && content_features(n).solidness != 2)
+                               && ndef->get(n).solidness != 2)
                {
-                       light += decode_light(n.getLightBlend(daynight_ratio));
+                       light += decode_light(n.getLightBlend(daynight_ratio, ndef));
                        light_count++;
                }
                else
@@ -391,8 +393,8 @@ u8 getSmoothLight(v3s16 p, VoxelManipulator &vmanip, u32 daynight_ratio)
 }
 
 // Calculate lighting at the given corner of p
-u8 getSmoothLight(v3s16 p, v3s16 corner,
-               VoxelManipulator &vmanip, u32 daynight_ratio)
+static u8 getSmoothLight(v3s16 p, v3s16 corner,
+               VoxelManipulator &vmanip, u32 daynight_ratio, INodeDefManager *ndef)
 {
        if(corner.X == 1) p.X += 1;
        else              assert(corner.X == -1);
@@ -401,10 +403,10 @@ u8 getSmoothLight(v3s16 p, v3s16 corner,
        if(corner.Z == 1) p.Z += 1;
        else              assert(corner.Z == -1);
        
-       return getSmoothLight(p, vmanip, daynight_ratio);
+       return getSmoothLight(p, vmanip, daynight_ratio, ndef);
 }
 
-void getTileInfo(
+static void getTileInfo(
                // Input:
                v3s16 blockpos_nodes,
                v3s16 p,
@@ -413,7 +415,7 @@ void getTileInfo(
                VoxelManipulator &vmanip,
                NodeModMap &temp_mods,
                bool smooth_lighting,
-               ITextureSource *tsrc,
+               IGameDef *gamedef,
                // Output:
                bool &makes_face,
                v3s16 &p_corrected,
@@ -422,16 +424,19 @@ void getTileInfo(
                TileSpec &tile
        )
 {
+       ITextureSource *tsrc = gamedef->tsrc();
+       INodeDefManager *ndef = gamedef->ndef();
+
        MapNode n0 = vmanip.getNodeNoEx(blockpos_nodes + p);
        MapNode n1 = vmanip.getNodeNoEx(blockpos_nodes + p + face_dir);
-       TileSpec tile0 = getNodeTile(n0, p, face_dir, temp_mods, tsrc);
-       TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods, tsrc);
+       TileSpec tile0 = getNodeTile(n0, p, face_dir, temp_mods, tsrc, ndef);
+       TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir, temp_mods, tsrc, ndef);
        
        // This is hackish
        content_t content0 = getNodeContent(p, n0, temp_mods);
        content_t content1 = getNodeContent(p + face_dir, n1, temp_mods);
        bool equivalent = false;
-       u8 mf = face_contents(content0, content1, &equivalent);
+       u8 mf = face_contents(content0, content1, &equivalent, ndef);
 
        if(mf == 0)
        {
@@ -461,7 +466,7 @@ void getTileInfo(
        if(smooth_lighting == false)
        {
                lights[0] = lights[1] = lights[2] = lights[3] =
-                               decode_light(getFaceLight(daynight_ratio, n0, n1, face_dir));
+                               decode_light(getFaceLight(daynight_ratio, n0, n1, face_dir, ndef));
        }
        else
        {
@@ -470,7 +475,7 @@ void getTileInfo(
                for(u16 i=0; i<4; i++)
                {
                        lights[i] = getSmoothLight(blockpos_nodes + p_corrected,
-                                       vertex_dirs[i], vmanip, daynight_ratio);
+                                       vertex_dirs[i], vmanip, daynight_ratio, ndef);
                }
        }
        
@@ -482,7 +487,7 @@ void getTileInfo(
        translate_dir: unit vector with only one of x, y or z
        face_dir: unit vector with only one of x, y or z
 */
-void updateFastFaceRow(
+static void updateFastFaceRow(
                u32 daynight_ratio,
                v3f posRelative_f,
                v3s16 startpos,
@@ -496,7 +501,7 @@ void updateFastFaceRow(
                VoxelManipulator &vmanip,
                v3s16 blockpos_nodes,
                bool smooth_lighting,
-               ITextureSource *tsrc)
+               IGameDef *gamedef)
 {
        v3s16 p = startpos;
        
@@ -508,7 +513,7 @@ void updateFastFaceRow(
        u8 lights[4] = {0,0,0,0};
        TileSpec tile;
        getTileInfo(blockpos_nodes, p, face_dir, daynight_ratio,
-                       vmanip, temp_mods, smooth_lighting, tsrc,
+                       vmanip, temp_mods, smooth_lighting, gamedef,
                        makes_face, p_corrected, face_dir_corrected, lights, tile);
 
        for(u16 j=0; j<length; j++)
@@ -531,7 +536,7 @@ void updateFastFaceRow(
                        p_next = p + translate_dir;
                        
                        getTileInfo(blockpos_nodes, p_next, face_dir, daynight_ratio,
-                                       vmanip, temp_mods, smooth_lighting, tsrc,
+                                       vmanip, temp_mods, smooth_lighting, gamedef,
                                        next_makes_face, next_p_corrected,
                                        next_face_dir_corrected, next_lights,
                                        next_tile);
@@ -644,7 +649,7 @@ void updateFastFaceRow(
        }
 }
 
-scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
+scene::SMesh* makeMapBlockMesh(MeshMakeData *data, IGameDef *gamedef)
 {
        // 4-21ms for MAP_BLOCKSIZE=16
        // 24-155ms for MAP_BLOCKSIZE=32
@@ -692,7 +697,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
                                                data->m_vmanip,
                                                blockpos_nodes,
                                                smooth_lighting,
-                                               tsrc);
+                                               gamedef);
                        }
                }
                /*
@@ -711,7 +716,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
                                                data->m_vmanip,
                                                blockpos_nodes,
                                                smooth_lighting,
-                                               tsrc);
+                                               gamedef);
                        }
                }
                /*
@@ -730,7 +735,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
                                                data->m_vmanip,
                                                blockpos_nodes,
                                                smooth_lighting,
-                                               tsrc);
+                                               gamedef);
                        }
                }
        }
@@ -795,7 +800,7 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc)
                - whatever
        */
 
-       mapblock_mesh_generate_special(data, collector, tsrc);
+       mapblock_mesh_generate_special(data, collector, gamedef);
        
        /*
                Add stuff from collector to mesh
index ea6a73122c765414b4814fa9c2fd0f84de5b67c4..36cc9be24d271c6fc6222aa0df9139f9af08e8d3 100644 (file)
@@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapblock_nodemod.h"
 #include "voxel.h"
 
+class IGameDef;
+
 /*
        Mesh making stuff
 */
@@ -141,7 +143,7 @@ struct MeshMakeData
 };
 
 // This is the highest-level function in here
-scene::SMesh* makeMapBlockMesh(MeshMakeData *data, ITextureSource *tsrc);
+scene::SMesh* makeMapBlockMesh(MeshMakeData *data, IGameDef *gamedef);
 
 #endif
 
index 8fc568f36b226da59dda3a5528cd6d869b3e114f..2b8050260666718f15a1d2e8062eaaceaf91c24e 100644 (file)
@@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mineral.h"
 //#include "serverobject.h"
 #include "content_sao.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
 
 namespace mapgen
 {
@@ -1417,9 +1417,9 @@ void add_random_objects(MapBlock *block)
                        MapNode n = block->getNodeNoEx(p);
                        if(n.getContent() == CONTENT_IGNORE)
                                continue;
-                       if(content_features(n).liquid_type != LIQUID_NONE)
+                       if(data->nodemgr->get(n)->liquid_type != LIQUID_NONE)
                                continue;
-                       if(content_features(n).walkable)
+                       if(data->nodemgr->get(n)->walkable)
                        {
                                last_node_walkable = true;
                                continue;
@@ -1478,6 +1478,9 @@ void make_block(BlockMakeData *data)
                return;
        }
 
+       assert(data->vmanip);
+       assert(data->nodemgr);
+
        v3s16 blockpos = data->blockpos;
        
        /*dstream<<"makeBlock(): ("<<blockpos.X<<","<<blockpos.Y<<","
@@ -2185,7 +2188,7 @@ void make_block(BlockMakeData *data)
                                {
                                        u32 i = data->vmanip->m_area.index(p);
                                        MapNode *n = &data->vmanip->m_data[i];
-                                       if(content_features(*n).is_ground_content
+                                       if(data->nodemgr->get(*n).is_ground_content
                                                        || n->getContent() == CONTENT_JUNGLETREE)
                                        {
                                                found = true;
@@ -2284,7 +2287,8 @@ void make_block(BlockMakeData *data)
 BlockMakeData::BlockMakeData():
        no_op(false),
        vmanip(NULL),
-       seed(0)
+       seed(0),
+       nodemgr(NULL)
 {}
 
 BlockMakeData::~BlockMakeData()
index f848389a8491a97d59292d8c2788f16786c84567..5caee2efa608865a7c08978344d527f410166212 100644 (file)
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 struct BlockMakeData;
 class MapBlock;
 class ManualMapVoxelManipulator;
+class INodeDefManager;
 
 namespace mapgen
 {
@@ -54,10 +55,11 @@ namespace mapgen
        struct BlockMakeData
        {
                bool no_op;
-               ManualMapVoxelManipulator *vmanip;
+               ManualMapVoxelManipulator *vmanip; // Destructor deletes
                u64 seed;
                v3s16 blockpos;
                UniqueQueue<v3s16> transforming_liquid;
+               INodeDefManager *nodemgr; // Destructor deletes
 
                BlockMakeData();
                ~BlockMakeData();
index 829147839cbb4cd210de468fecba156cdcc7bab0..9aceab17ea058cef6966316c1eb3374cf07e856c 100644 (file)
@@ -23,7 +23,7 @@ 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
 
 /*
@@ -33,8 +33,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 +46,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 +63,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;
        }
        
@@ -147,28 +152,10 @@ v3s16 unpackDir(u8 b)
        MapNode
 */
 
-// These four are DEPRECATED.
-bool MapNode::light_propagates()
-{
-       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;
-}
-
-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 +171,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,32 +184,33 @@ 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)
+TileSpec MapNode::getTile(v3s16 dir, ITextureSource *tsrc,
+               INodeDefManager *nodemgr) const
 {
-       if(content_features(*this).param_type == CPT_FACEDIR_SIMPLE)
+       if(nodemgr->get(*this).param_type == CPT_FACEDIR_SIMPLE)
                dir = facedir_rotate(param1, dir);
        
        TileSpec spec;
@@ -246,16 +234,16 @@ TileSpec MapNode::getTile(v3s16 dir, ITextureSource *tsrc)
        
        if(dir_i == -1)
                // Non-directional
-               spec = content_features(*this).tiles[0];
+               spec = nodemgr->get(*this).tiles[0];
        else 
-               spec = content_features(*this).tiles[dir_i];
+               spec = nodemgr->get(*this).tiles[dir_i];
        
        /*
                If it contains some mineral, change texture id
        */
-       if(content_features(*this).param_type == CPT_MINERAL && tsrc)
+       if(nodemgr->get(*this).param_type == CPT_MINERAL && tsrc)
        {
-               u8 mineral = getMineral();
+               u8 mineral = getMineral(nodemgr);
                std::string mineral_texture_name = mineral_block_texture(mineral);
                if(mineral_texture_name != "")
                {
@@ -273,9 +261,9 @@ TileSpec MapNode::getTile(v3s16 dir, ITextureSource *tsrc)
 }
 #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;
        }
@@ -332,7 +320,7 @@ void MapNode::serialize(u8 *dest, u8 version)
                dest[2] = n_foreign.param2;
        }
 }
-void MapNode::deSerialize(u8 *source, u8 version)
+void MapNode::deSerialize(u8 *source, u8 version, INodeDefManager *nodemgr)
 {
        if(!ser_ver_supported(version))
                throw VersionMismatchException("ERROR: MapNode format not supported");
@@ -345,7 +333,7 @@ void MapNode::deSerialize(u8 *source, u8 version)
        {
                param0 = source[0];
                // This version doesn't support saved lighting
-               if(light_propagates() || light_source() > 0)
+               if(nodemgr->get(*this).light_propagates || nodemgr->get(*this).light_source > 0)
                        param1 = 0;
                else
                        param1 = source[1];
@@ -402,12 +390,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
index 62815dad126cbe06138dcd3f4c7a802fe9083b14..70a7638d258b88ee37b8a1363ebb34bcdcc33f56 100644 (file)
@@ -29,6 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "tile.h"
 #endif
 
+class INodeDefManager;
+
 /*
        Naming scheme:
        - Material = irrlicht's Material class
@@ -68,7 +70,8 @@ typedef u16 content_t;
                2: Face uses m2's content
        equivalent: Whether the blocks share the same face (eg. water and glass)
 */
-u8 face_contents(content_t m1, content_t m2, bool *equivalent);
+u8 face_contents(content_t m1, content_t m2, bool *equivalent,
+               INodeDefManager *nodemgr);
 
 /*
        Packs directions like (1,0,0), (1,-1,0) in six bits.
@@ -157,7 +160,7 @@ struct MapNode
        }
        
        // To be used everywhere
-       content_t getContent()
+       content_t getContent() const
        {
                if(param0 < 0x80)
                        return param0;
@@ -180,27 +183,19 @@ struct MapNode
                }
        }
        
-       /*
-               These four are DEPRECATED I guess. -c55
-       */
-       bool light_propagates();
-       bool sunlight_propagates();
-       u8 solidness();
-       u8 light_source();
-
-       void setLight(enum LightBank bank, u8 a_light);
-       u8 getLight(enum LightBank bank);
-       u8 getLightBanksWithSource();
+       void setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr);
+       u8 getLight(enum LightBank bank, INodeDefManager *nodemgr) const;
+       u8 getLightBanksWithSource(INodeDefManager *nodemgr) const;
        
        // 0 <= daylight_factor <= 1000
        // 0 <= return value <= LIGHT_SUN
-       u8 getLightBlend(u32 daylight_factor)
+       u8 getLightBlend(u32 daylight_factor, INodeDefManager *nodemgr) const
        {
-               u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY)
-                       + (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT))
+               u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY, nodemgr)
+                       + (1000-daylight_factor) * getLight(LIGHTBANK_NIGHT, nodemgr))
                        )/1000;
                u8 max = LIGHT_MAX;
-               if(getLight(LIGHTBANK_DAY) == LIGHT_SUN)
+               if(getLight(LIGHTBANK_DAY, nodemgr) == LIGHT_SUN)
                        max = LIGHT_SUN;
                if(l > max)
                        l = max;
@@ -208,10 +203,10 @@ struct MapNode
        }
        /*// 0 <= daylight_factor <= 1000
        // 0 <= return value <= 255
-       u8 getLightBlend(u32 daylight_factor)
+       u8 getLightBlend(u32 daylight_factor, INodeDefManager *nodemgr)
        {
-               u8 daylight = decode_light(getLight(LIGHTBANK_DAY));
-               u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT));
+               u8 daylight = decode_light(getLight(LIGHTBANK_DAY, nodemgr));
+               u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT, nodemgr));
                u8 mix = ((daylight_factor * daylight
                        + (1000-daylight_factor) * nightlight)
                        )/1000;
@@ -226,14 +221,15 @@ struct MapNode
                Returns: TileSpec. Can contain miscellaneous texture coordinates,
                         which must be obeyed so that the texture atlas can be used.
        */
-       TileSpec getTile(v3s16 dir, ITextureSource *tsrc);
+       TileSpec getTile(v3s16 dir, ITextureSource *tsrc,
+                       INodeDefManager *nodemgr) const;
 #endif
        
        /*
                Gets mineral content of node, if there is any.
                MINERAL_NONE if doesn't contain or isn't able to contain mineral.
        */
-       u8 getMineral();
+       u8 getMineral(INodeDefManager *nodemgr) const;
        
        /*
                Serialization functions
@@ -241,7 +237,7 @@ struct MapNode
 
        static u32 serializedLength(u8 version);
        void serialize(u8 *dest, u8 version);
-       void deSerialize(u8 *source, u8 version);
+       void deSerialize(u8 *source, u8 version, INodeDefManager *nodemgr);
        
 };
 
@@ -262,7 +258,7 @@ struct MapNode
        returns encoded light value.
 */
 u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
-               v3s16 face_dir);
+               v3s16 face_dir, INodeDefManager *nodemgr);
 
 #endif
 
diff --git a/src/mapnode_contentfeatures.cpp b/src/mapnode_contentfeatures.cpp
deleted file mode 100644 (file)
index 6bafa73..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
-Minetest-c55
-Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "mapnode_contentfeatures.h"
-
-#include "main.h" // For g_settings
-#include "nodemetadata.h"
-#ifndef SERVER
-#include "tile.h"
-#endif
-
-struct ContentFeatures g_content_features[MAX_CONTENT+1];
-
-/*
-       Initialize content feature table.
-
-       Must be called before accessing the table.
-*/
-void init_contentfeatures(ITextureSource *tsrc)
-{
-#ifndef SERVER
-       /*
-               Set initial material type to same in all tiles, so that the
-               same material can be used in more stuff.
-               This is set according to the leaves because they are the only
-               differing material to which all materials can be changed to
-               get this optimization.
-       */
-       u8 initial_material_type = MATERIAL_ALPHA_SIMPLE;
-       /*if(new_style_leaves)
-               initial_material_type = MATERIAL_ALPHA_SIMPLE;
-       else
-               initial_material_type = MATERIAL_ALPHA_NONE;*/
-       for(u16 i=0; i<MAX_CONTENT+1; i++)
-       {
-               ContentFeatures *f = &g_content_features[i];
-               // Re-initialize
-               f->reset();
-
-               for(u16 j=0; j<6; j++)
-                       f->tiles[j].material_type = initial_material_type;
-       }
-#endif
-
-       /*
-               Initially set every block to be shown as an unknown block.
-               Don't touch CONTENT_IGNORE or CONTENT_AIR.
-       */
-       for(u16 i=0; i<MAX_CONTENT+1; i++)
-       {
-               if(i == CONTENT_IGNORE || i == CONTENT_AIR)
-                       continue;
-               ContentFeatures *f = &g_content_features[i];
-               f->setAllTextures(tsrc, "unknown_block.png");
-               f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
-       }
-
-       // Make CONTENT_IGNORE to not block the view when occlusion culling
-       content_features(CONTENT_IGNORE).solidness = 0;
-
-}
-
-ContentFeatures::~ContentFeatures()
-{
-       delete initial_metadata;
-#ifndef SERVER
-       delete special_material;
-       delete special_atlas;
-#endif
-}
-
-#ifndef SERVER
-void ContentFeatures::setTexture(ITextureSource *tsrc,
-               u16 i, std::string name, u8 alpha)
-{
-       used_texturenames[name] = true;
-       
-       if(tsrc)
-       {
-               tiles[i].texture = tsrc->getTexture(name);
-       }
-       
-       if(alpha != 255)
-       {
-               tiles[i].alpha = alpha;
-               tiles[i].material_type = MATERIAL_ALPHA_VERTEX;
-       }
-
-       if(inventory_texture == NULL)
-               setInventoryTexture(name, tsrc);
-}
-
-void ContentFeatures::setInventoryTexture(std::string imgname,
-               ITextureSource *tsrc)
-{
-       if(tsrc == NULL)
-               return;
-       
-       imgname += "^[forcesingle";
-       
-       inventory_texture = tsrc->getTextureRaw(imgname);
-}
-
-void ContentFeatures::setInventoryTextureCube(std::string top,
-               std::string left, std::string right, ITextureSource *tsrc)
-{
-       if(tsrc == NULL)
-               return;
-       
-       str_replace_char(top, '^', '&');
-       str_replace_char(left, '^', '&');
-       str_replace_char(right, '^', '&');
-
-       std::string imgname_full;
-       imgname_full += "[inventorycube{";
-       imgname_full += top;
-       imgname_full += "{";
-       imgname_full += left;
-       imgname_full += "{";
-       imgname_full += right;
-       inventory_texture = tsrc->getTextureRaw(imgname_full);
-}
-#endif
-
-ContentFeatures & content_features(content_t i)
-{
-       return g_content_features[i];
-}
-ContentFeatures & content_features(MapNode &n)
-{
-       return content_features(n.getContent());
-}
-
-
diff --git a/src/mapnode_contentfeatures.h b/src/mapnode_contentfeatures.h
deleted file mode 100644 (file)
index 0f7e358..0000000
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
-Minetest-c55
-Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef MAPNODE_CONTENTFEATURES_HEADER
-#define MAPNODE_CONTENTFEATURES_HEADER
-
-#include "common_irrlicht.h"
-#include <string>
-#include "mapnode.h"
-#ifndef SERVER
-#include "tile.h"
-#endif
-#include "materials.h" // MaterialProperties
-class ITextureSource;
-
-/*
-       Content feature list
-       
-       Used for determining properties of MapNodes by content type without
-       storing such properties in the nodes itself.
-*/
-
-/*
-       Initialize content feature table.
-
-       Must be called before accessing the table.
-*/
-void init_contentfeatures(ITextureSource *tsrc);
-
-enum ContentParamType
-{
-       CPT_NONE,
-       CPT_LIGHT,
-       CPT_MINERAL,
-       // Direction for chests and furnaces and such
-       CPT_FACEDIR_SIMPLE
-};
-
-enum LiquidType
-{
-       LIQUID_NONE,
-       LIQUID_FLOWING,
-       LIQUID_SOURCE
-};
-
-enum NodeBoxType
-{
-       NODEBOX_REGULAR, // Regular block; allows buildable_to
-       NODEBOX_FIXED, // Static separately defined box
-       NODEBOX_WALLMOUNTED, // Box for wall_mounted nodes; (top, bottom, side)
-};
-
-struct NodeBox
-{
-       enum NodeBoxType type;
-       // NODEBOX_REGULAR (no parameters)
-       // NODEBOX_FIXED
-       core::aabbox3d<f32> fixed;
-       // NODEBOX_WALLMOUNTED
-       core::aabbox3d<f32> wall_top;
-       core::aabbox3d<f32> wall_bottom;
-       core::aabbox3d<f32> wall_side; // being at the -X side
-
-       NodeBox():
-               type(NODEBOX_REGULAR),
-               // default is rail-like
-               fixed(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2),
-               // default is sign/ladder-like
-               wall_top(-BS/2, BS/2-BS/16., -BS/2, BS/2, BS/2, BS/2),
-               wall_bottom(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2),
-               wall_side(-BS/2, -BS/2, -BS/2, -BS/2+BS/16., BS/2, BS/2)
-       {}
-};
-
-struct MapNode;
-class NodeMetadata;
-
-struct ContentFeatures
-{
-#ifndef SERVER
-       /*
-               0: up
-               1: down
-               2: right
-               3: left
-               4: back
-               5: front
-       */
-       TileSpec tiles[6];
-       
-       video::ITexture *inventory_texture;
-
-       // Used currently for flowing liquids
-       u8 vertex_alpha;
-       // Post effect color, drawn when the camera is inside the node.
-       video::SColor post_effect_color;
-       // Special irrlicht material, used sometimes
-       video::SMaterial *special_material;
-       video::SMaterial *special_material2;
-       AtlasPointer *special_atlas;
-#endif
-
-       // List of all block textures that have been used (value is dummy)
-       // Used for texture atlas making.
-       // Exists on server too for cleaner code in content_mapnode.cpp.
-       core::map<std::string, bool> used_texturenames;
-       
-       // Type of MapNode::param1
-       ContentParamType param_type;
-       // True for all ground-like things like stone and mud, false for eg. trees
-       bool is_ground_content;
-       bool light_propagates;
-       bool sunlight_propagates;
-       u8 solidness; // Used when choosing which face is drawn
-       u8 visual_solidness; // When solidness=0, this tells how it looks like
-       // This is used for collision detection.
-       // Also for general solidness queries.
-       bool walkable;
-       // Player can point to these
-       bool pointable;
-       // Player can dig these
-       bool diggable;
-       // Player can climb these
-       bool climbable;
-       // Player can build on these
-       bool buildable_to;
-       // If true, param2 is set to direction when placed. Used for torches.
-       // NOTE: the direction format is quite inefficient and should be changed
-       bool wall_mounted;
-       // If true, node is equivalent to air. Torches are, air is. Water is not.
-       // Is used for example to check whether a mud block can have grass on.
-       bool air_equivalent;
-       // Whether this content type often contains mineral.
-       // Used for texture atlas creation.
-       // Currently only enabled for CONTENT_STONE.
-       bool often_contains_mineral;
-       
-       // Inventory item string as which the node appears in inventory when dug.
-       // Mineral overrides this.
-       std::string dug_item;
-
-       // Extra dug item and its rarity
-       std::string extra_dug_item;
-       s32 extra_dug_item_rarity;
-
-       // Initial metadata is cloned from this
-       NodeMetadata *initial_metadata;
-       
-       // Whether the node is non-liquid, source liquid or flowing liquid
-       enum LiquidType liquid_type;
-       // If the content is liquid, this is the flowing version of the liquid.
-       content_t liquid_alternative_flowing;
-       // If the content is liquid, this is the source version of the liquid.
-       content_t liquid_alternative_source;
-       // Viscosity for fluid flow, ranging from 1 to 7, with
-       // 1 giving almost instantaneous propagation and 7 being
-       // the slowest possible
-       u8 liquid_viscosity;
-       
-       // Amount of light the node emits
-       u8 light_source;
-       
-       u32 damage_per_second;
-
-       NodeBox selection_box;
-
-       MaterialProperties material;
-       
-       // NOTE: Move relevant properties to here from elsewhere
-
-       void reset()
-       {
-#ifndef SERVER
-               inventory_texture = NULL;
-               
-               vertex_alpha = 255;
-               post_effect_color = video::SColor(0, 0, 0, 0);
-               special_material = NULL;
-               special_material2 = NULL;
-               special_atlas = NULL;
-#endif
-               param_type = CPT_NONE;
-               is_ground_content = false;
-               light_propagates = false;
-               sunlight_propagates = false;
-               solidness = 2;
-               visual_solidness = 0;
-               walkable = true;
-               pointable = true;
-               diggable = true;
-               climbable = false;
-               buildable_to = false;
-               wall_mounted = false;
-               air_equivalent = false;
-               often_contains_mineral = false;
-               dug_item = "";
-               initial_metadata = NULL;
-               liquid_type = LIQUID_NONE;
-               liquid_alternative_flowing = CONTENT_IGNORE;
-               liquid_alternative_source = CONTENT_IGNORE;
-               liquid_viscosity = 0;
-               light_source = 0;
-               damage_per_second = 0;
-               selection_box = NodeBox();
-               material = MaterialProperties();
-       }
-
-       ContentFeatures()
-       {
-               reset();
-       }
-
-       ~ContentFeatures();
-       
-       /*
-               Quickhands for simple materials
-       */
-       
-#ifdef SERVER
-       void setTexture(ITextureSource *tsrc, u16 i, std::string name,
-                       u8 alpha=255)
-       {}
-       void setAllTextures(ITextureSource *tsrc, std::string name, u8 alpha=255)
-       {}
-#else
-       void setTexture(ITextureSource *tsrc,
-                       u16 i, std::string name, u8 alpha=255);
-
-       void setAllTextures(ITextureSource *tsrc,
-                       std::string name, u8 alpha=255)
-       {
-               for(u16 i=0; i<6; i++)
-               {
-                       setTexture(tsrc, i, name, alpha);
-               }
-               // Force inventory texture too
-               setInventoryTexture(name, tsrc);
-       }
-#endif
-
-#ifndef SERVER
-       void setTile(u16 i, const TileSpec &tile)
-       {
-               tiles[i] = tile;
-       }
-       void setAllTiles(const TileSpec &tile)
-       {
-               for(u16 i=0; i<6; i++)
-               {
-                       setTile(i, tile);
-               }
-       }
-#endif
-
-#ifdef SERVER
-       void setInventoryTexture(std::string imgname,
-                       ITextureSource *tsrc)
-       {}
-       void setInventoryTextureCube(std::string top,
-                       std::string left, std::string right, ITextureSource *tsrc)
-       {}
-#else
-       void setInventoryTexture(std::string imgname, ITextureSource *tsrc);
-       
-       void setInventoryTextureCube(std::string top,
-                       std::string left, std::string right, ITextureSource *tsrc);
-#endif
-};
-
-/*
-       Call this to access the ContentFeature list
-*/
-ContentFeatures & content_features(content_t i);
-ContentFeatures & content_features(MapNode &n);
-
-/*
-       Here is a bunch of DEPRECATED functions.
-*/
-
-/*
-       If true, the material allows light propagation and brightness is stored
-       in param.
-       NOTE: Don't use, use "content_features(m).whatever" instead
-*/
-inline bool light_propagates_content(content_t m)
-{
-       return content_features(m).light_propagates;
-}
-/*
-       If true, the material allows lossless sunlight propagation.
-       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(content_t m)
-{
-       return content_features(m).sunlight_propagates;
-}
-/*
-       On a node-node surface, the material of the node with higher solidness
-       is used for drawing.
-       0: Invisible
-       1: Transparent
-       2: Opaque
-       NOTE: Don't use, use "content_features(m).whatever" instead
-*/
-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(content_t m)
-{
-       return content_features(m).walkable;
-}
-// NOTE: Don't use, use "content_features(m).whatever" instead
-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(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(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 content_t make_liquid_flowing(content_t m)
-{
-       u8 c = content_features(m).liquid_alternative_flowing;
-       assert(c != CONTENT_IGNORE);
-       return c;
-}
-// Pointable contents can be pointed to in the map
-// NOTE: Don't use, use "content_features(m).whatever" instead
-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(content_t m)
-{
-       return content_features(m).diggable;
-}
-// NOTE: Don't use, use "content_features(m).whatever" instead
-inline bool content_buildable_to(content_t m)
-{
-       return content_features(m).buildable_to;
-}
-
-
-#endif
-
index 4a526c412539ad0ce83304f6df2f70f88560a91f..9b54328076ba69a1c8f4cfb88e299726768ed7c4 100644 (file)
@@ -23,10 +23,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "exceptions.h"
 #include "mapblock.h"
 
-MapSector::MapSector(Map *parent, v2s16 pos):
+MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
                differs_from_disk(false),
                m_parent(parent),
                m_pos(pos),
+               m_gamedef(gamedef),
                m_block_cache(NULL)
 {
 }
@@ -89,7 +90,7 @@ MapBlock * MapSector::createBlankBlockNoInsert(s16 y)
 
        v3s16 blockpos_map(m_pos.X, y, m_pos.Y);
        
-       MapBlock *block = new MapBlock(m_parent, blockpos_map);
+       MapBlock *block = new MapBlock(m_parent, blockpos_map, m_gamedef);
        
        return block;
 }
@@ -151,8 +152,8 @@ void MapSector::getBlocks(core::list<MapBlock*> &dest)
        ServerMapSector
 */
 
-ServerMapSector::ServerMapSector(Map *parent, v2s16 pos):
-               MapSector(parent, pos)
+ServerMapSector::ServerMapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
+               MapSector(parent, pos, gamedef)
 {
 }
 
@@ -186,7 +187,8 @@ ServerMapSector* ServerMapSector::deSerialize(
                std::istream &is,
                Map *parent,
                v2s16 p2d,
-               core::map<v2s16, MapSector*> & sectors
+               core::map<v2s16, MapSector*> & sectors,
+               IGameDef *gamedef
        )
 {
        /*
@@ -229,7 +231,7 @@ ServerMapSector* ServerMapSector::deSerialize(
        }
        else
        {
-               sector = new ServerMapSector(parent, p2d);
+               sector = new ServerMapSector(parent, p2d, gamedef);
                sectors.insert(p2d, sector);
        }
 
@@ -247,8 +249,8 @@ ServerMapSector* ServerMapSector::deSerialize(
        ClientMapSector
 */
 
-ClientMapSector::ClientMapSector(Map *parent, v2s16 pos):
-               MapSector(parent, pos)
+ClientMapSector::ClientMapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
+               MapSector(parent, pos, gamedef)
 {
 }
 
index 44f45d8f03ec98fd971307ef44d2510f2392955a..be9243e67bf49b25bc421fc9732061ab462d3103 100644 (file)
@@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 class MapBlock;
 class Map;
+class IGameDef;
 
 /*
        This is an Y-wise stack of MapBlocks.
@@ -43,7 +44,7 @@ class MapSector
 {
 public:
        
-       MapSector(Map *parent, v2s16 pos);
+       MapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
        virtual ~MapSector();
 
        virtual u32 getId() const = 0;
@@ -76,7 +77,9 @@ protected:
        Map *m_parent;
        // Position on parent (in MapBlock widths)
        v2s16 m_pos;
-       
+
+       IGameDef *m_gamedef;
+       
        // Last-used block is cached here for quicker access.
        // Be sure to set this to NULL when the cached block is deleted 
        MapBlock *m_block_cache;
@@ -92,7 +95,7 @@ protected:
 class ServerMapSector : public MapSector
 {
 public:
-       ServerMapSector(Map *parent, v2s16 pos);
+       ServerMapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
        ~ServerMapSector();
        
        u32 getId() const
@@ -111,7 +114,8 @@ public:
                        std::istream &is,
                        Map *parent,
                        v2s16 p2d,
-                       core::map<v2s16, MapSector*> & sectors
+                       core::map<v2s16, MapSector*> & sectors,
+                       IGameDef *gamedef
                );
                
 private:
@@ -121,7 +125,7 @@ private:
 class ClientMapSector : public MapSector
 {
 public:
-       ClientMapSector(Map *parent, v2s16 pos);
+       ClientMapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
        ~ClientMapSector();
        
        u32 getId() const
index e990371ee2c88bf4ca6764ff1650368f2e750c07..d89b1e07950aced430c3cff2730f15dfdac422dc 100644 (file)
@@ -1,12 +1,13 @@
 #include "materials.h"
 #include "mapnode.h"
-#include "mapnode_contentfeatures.h"
-#include "tool.h"
+#include "nodedef.h"
+#include "tooldef.h"
 
-DiggingProperties getDiggingProperties(u16 material, ToolDiggingProperties *tp)
+DiggingProperties getDiggingProperties(u16 content, ToolDiggingProperties *tp,
+               INodeDefManager *nodemgr)
 {
        assert(tp);
-       MaterialProperties &mp = content_features(material).material;
+       const MaterialProperties &mp = nodemgr->get(content).material;
        if(mp.diggability == DIGGABLE_NOT)
                return DiggingProperties(false, 0, 0);
        if(mp.diggability == DIGGABLE_CONSTANT)
index 4f0fd687129356221db6c4e86e86aa0dbdd68d5f..62bce16694a677f672db290b0405a7fd9eda6eb5 100644 (file)
@@ -89,8 +89,10 @@ struct DiggingProperties
 };
 
 class ToolDiggingProperties;
+class INodeDefManager;
 
-DiggingProperties getDiggingProperties(u16 material, ToolDiggingProperties *tp);
+DiggingProperties getDiggingProperties(u16 content, ToolDiggingProperties *tp,
+               INodeDefManager *nodemgr);
 
 #endif
 
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
new file mode 100644 (file)
index 0000000..74d8253
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+Minetest-c55
+Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "nodedef.h"
+
+#include "main.h" // For g_settings
+#include "nodemetadata.h"
+#ifndef SERVER
+#include "tile.h"
+#endif
+#include "log.h"
+
+ContentFeatures::~ContentFeatures()
+{
+       delete initial_metadata;
+#ifndef SERVER
+       delete special_material;
+       delete special_atlas;
+#endif
+}
+
+#ifndef SERVER
+void ContentFeatures::setTexture(ITextureSource *tsrc,
+               u16 i, std::string name, u8 alpha)
+{
+       used_texturenames.insert(name);
+       
+       if(tsrc)
+       {
+               tiles[i].texture = tsrc->getTexture(name);
+       }
+       
+       if(alpha != 255)
+       {
+               tiles[i].alpha = alpha;
+               tiles[i].material_type = MATERIAL_ALPHA_VERTEX;
+       }
+
+       if(inventory_texture == NULL)
+               setInventoryTexture(name, tsrc);
+}
+
+void ContentFeatures::setInventoryTexture(std::string imgname,
+               ITextureSource *tsrc)
+{
+       if(tsrc == NULL)
+               return;
+       
+       imgname += "^[forcesingle";
+       
+       inventory_texture = tsrc->getTextureRaw(imgname);
+}
+
+void ContentFeatures::setInventoryTextureCube(std::string top,
+               std::string left, std::string right, ITextureSource *tsrc)
+{
+       if(tsrc == NULL)
+               return;
+       
+       str_replace_char(top, '^', '&');
+       str_replace_char(left, '^', '&');
+       str_replace_char(right, '^', '&');
+
+       std::string imgname_full;
+       imgname_full += "[inventorycube{";
+       imgname_full += top;
+       imgname_full += "{";
+       imgname_full += left;
+       imgname_full += "{";
+       imgname_full += right;
+       inventory_texture = tsrc->getTextureRaw(imgname_full);
+}
+#endif
+
+class CNodeDefManager: public IWritableNodeDefManager
+{
+public:
+       CNodeDefManager(ITextureSource *tsrc)
+       {
+#ifndef SERVER
+               /*
+                       Set initial material type to same in all tiles, so that the
+                       same material can be used in more stuff.
+                       This is set according to the leaves because they are the only
+                       differing material to which all materials can be changed to
+                       get this optimization.
+               */
+               u8 initial_material_type = MATERIAL_ALPHA_SIMPLE;
+               /*if(new_style_leaves)
+                       initial_material_type = MATERIAL_ALPHA_SIMPLE;
+               else
+                       initial_material_type = MATERIAL_ALPHA_NONE;*/
+               for(u16 i=0; i<=MAX_CONTENT; i++)
+               {
+                       ContentFeatures *f = &m_content_features[i];
+                       // Re-initialize
+                       f->reset();
+
+                       for(u16 j=0; j<6; j++)
+                               f->tiles[j].material_type = initial_material_type;
+               }
+#endif
+               /*
+                       Initially set every block to be shown as an unknown block.
+                       Don't touch CONTENT_IGNORE or CONTENT_AIR.
+               */
+               for(u16 i=0; i<=MAX_CONTENT; i++)
+               {
+                       if(i == CONTENT_IGNORE || i == CONTENT_AIR)
+                               continue;
+                       ContentFeatures *f = &m_content_features[i];
+                       f->setAllTextures(tsrc, "unknown_block.png");
+                       f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
+               }
+               // Make CONTENT_IGNORE to not block the view when occlusion culling
+               m_content_features[CONTENT_IGNORE].solidness = 0;
+       }
+       virtual ~CNodeDefManager()
+       {
+       }
+       virtual IWritableNodeDefManager* clone()
+       {
+               CNodeDefManager *mgr = new CNodeDefManager(NULL);
+               for(u16 i=0; i<=MAX_CONTENT; i++)
+               {
+                       mgr->set(i, get(i));
+               }
+               return mgr;
+       }
+       virtual const ContentFeatures& get(content_t c) const
+       {
+               assert(c <= MAX_CONTENT);
+               return m_content_features[c];
+       }
+       virtual const ContentFeatures& get(const MapNode &n) const
+       {
+               return get(n.getContent());
+       }
+       // Writable
+       virtual void set(content_t c, const ContentFeatures &def)
+       {
+               infostream<<"registerNode: registering content \""<<c<<"\""<<std::endl;
+               assert(c <= MAX_CONTENT);
+               m_content_features[c] = def;
+       }
+       virtual ContentFeatures* getModifiable(content_t c)
+       {
+               assert(c <= MAX_CONTENT);
+               return &m_content_features[c];
+       }
+private:
+       ContentFeatures m_content_features[MAX_CONTENT+1];
+};
+
+IWritableNodeDefManager* createNodeDefManager(ITextureSource *tsrc)
+{
+       return new CNodeDefManager(tsrc);
+}
+
diff --git a/src/nodedef.h b/src/nodedef.h
new file mode 100644 (file)
index 0000000..dece63f
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef NODEDEF_HEADER
+#define NODEDEF_HEADER
+
+#include "common_irrlicht.h"
+#include <string>
+#include <set>
+#include "mapnode.h"
+#ifndef SERVER
+#include "tile.h"
+#endif
+#include "materials.h" // MaterialProperties
+class ITextureSource;
+
+/*
+       TODO: Rename to nodedef.h
+*/
+
+#if 0
+
+/*
+       Content feature list
+       
+       Used for determining properties of MapNodes by content type without
+       storing such properties in the nodes itself.
+*/
+
+/*
+       Initialize content feature table.
+
+       Must be called before accessing the table.
+*/
+void init_contentfeatures(ITextureSource *tsrc);
+
+#endif
+
+enum ContentParamType
+{
+       CPT_NONE,
+       CPT_LIGHT,
+       CPT_MINERAL,
+       // Direction for chests and furnaces and such
+       CPT_FACEDIR_SIMPLE
+};
+
+enum LiquidType
+{
+       LIQUID_NONE,
+       LIQUID_FLOWING,
+       LIQUID_SOURCE
+};
+
+enum NodeBoxType
+{
+       NODEBOX_REGULAR, // Regular block; allows buildable_to
+       NODEBOX_FIXED, // Static separately defined box
+       NODEBOX_WALLMOUNTED, // Box for wall_mounted nodes; (top, bottom, side)
+};
+
+struct NodeBox
+{
+       enum NodeBoxType type;
+       // NODEBOX_REGULAR (no parameters)
+       // NODEBOX_FIXED
+       core::aabbox3d<f32> fixed;
+       // NODEBOX_WALLMOUNTED
+       core::aabbox3d<f32> wall_top;
+       core::aabbox3d<f32> wall_bottom;
+       core::aabbox3d<f32> wall_side; // being at the -X side
+
+       NodeBox():
+               type(NODEBOX_REGULAR),
+               // default is rail-like
+               fixed(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2),
+               // default is sign/ladder-like
+               wall_top(-BS/2, BS/2-BS/16., -BS/2, BS/2, BS/2, BS/2),
+               wall_bottom(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2),
+               wall_side(-BS/2, -BS/2, -BS/2, -BS/2+BS/16., BS/2, BS/2)
+       {}
+};
+
+struct MapNode;
+class NodeMetadata;
+
+struct ContentFeatures
+{
+#ifndef SERVER
+       /*
+               0: up
+               1: down
+               2: right
+               3: left
+               4: back
+               5: front
+       */
+       TileSpec tiles[6];
+       
+       video::ITexture *inventory_texture;
+
+       // Used currently for flowing liquids
+       u8 vertex_alpha;
+       // Post effect color, drawn when the camera is inside the node.
+       video::SColor post_effect_color;
+       // Special irrlicht material, used sometimes
+       video::SMaterial *special_material;
+       video::SMaterial *special_material2;
+       AtlasPointer *special_atlas;
+#endif
+
+       // List of all block textures that have been used (value is dummy)
+       // Used for texture atlas making.
+       // Exists on server too for cleaner code in content_mapnode.cpp.
+       std::set<std::string> used_texturenames;
+       
+       // Type of MapNode::param1
+       ContentParamType param_type;
+       // True for all ground-like things like stone and mud, false for eg. trees
+       bool is_ground_content;
+       bool light_propagates;
+       bool sunlight_propagates;
+       u8 solidness; // Used when choosing which face is drawn
+       u8 visual_solidness; // When solidness=0, this tells how it looks like
+       // This is used for collision detection.
+       // Also for general solidness queries.
+       bool walkable;
+       // Player can point to these
+       bool pointable;
+       // Player can dig these
+       bool diggable;
+       // Player can climb these
+       bool climbable;
+       // Player can build on these
+       bool buildable_to;
+       // If true, param2 is set to direction when placed. Used for torches.
+       // NOTE: the direction format is quite inefficient and should be changed
+       bool wall_mounted;
+       // If true, node is equivalent to air. Torches are, air is. Water is not.
+       // Is used for example to check whether a mud block can have grass on.
+       bool air_equivalent;
+       // Whether this content type often contains mineral.
+       // Used for texture atlas creation.
+       // Currently only enabled for CONTENT_STONE.
+       bool often_contains_mineral;
+       
+       // Inventory item string as which the node appears in inventory when dug.
+       // Mineral overrides this.
+       std::string dug_item;
+
+       // Extra dug item and its rarity
+       std::string extra_dug_item;
+       s32 extra_dug_item_rarity;
+
+       // Initial metadata is cloned from this
+       NodeMetadata *initial_metadata;
+       
+       // Whether the node is non-liquid, source liquid or flowing liquid
+       enum LiquidType liquid_type;
+       // If the content is liquid, this is the flowing version of the liquid.
+       content_t liquid_alternative_flowing;
+       // If the content is liquid, this is the source version of the liquid.
+       content_t liquid_alternative_source;
+       // Viscosity for fluid flow, ranging from 1 to 7, with
+       // 1 giving almost instantaneous propagation and 7 being
+       // the slowest possible
+       u8 liquid_viscosity;
+       
+       // Amount of light the node emits
+       u8 light_source;
+       
+       u32 damage_per_second;
+
+       NodeBox selection_box;
+
+       MaterialProperties material;
+       
+       // NOTE: Move relevant properties to here from elsewhere
+
+       void reset()
+       {
+#ifndef SERVER
+               inventory_texture = NULL;
+               
+               vertex_alpha = 255;
+               post_effect_color = video::SColor(0, 0, 0, 0);
+               special_material = NULL;
+               special_material2 = NULL;
+               special_atlas = NULL;
+#endif
+               used_texturenames.clear();
+               param_type = CPT_NONE;
+               is_ground_content = false;
+               light_propagates = false;
+               sunlight_propagates = false;
+               solidness = 2;
+               visual_solidness = 0;
+               walkable = true;
+               pointable = true;
+               diggable = true;
+               climbable = false;
+               buildable_to = false;
+               wall_mounted = false;
+               air_equivalent = false;
+               often_contains_mineral = false;
+               dug_item = "";
+               initial_metadata = NULL;
+               liquid_type = LIQUID_NONE;
+               liquid_alternative_flowing = CONTENT_IGNORE;
+               liquid_alternative_source = CONTENT_IGNORE;
+               liquid_viscosity = 0;
+               light_source = 0;
+               damage_per_second = 0;
+               selection_box = NodeBox();
+               material = MaterialProperties();
+       }
+
+       ContentFeatures()
+       {
+               reset();
+       }
+
+       ~ContentFeatures();
+       
+       /*
+               Quickhands for simple materials
+       */
+       
+#ifdef SERVER
+       void setTexture(ITextureSource *tsrc, u16 i, std::string name,
+                       u8 alpha=255)
+       {}
+       void setAllTextures(ITextureSource *tsrc, std::string name, u8 alpha=255)
+       {}
+#else
+       void setTexture(ITextureSource *tsrc,
+                       u16 i, std::string name, u8 alpha=255);
+
+       void setAllTextures(ITextureSource *tsrc,
+                       std::string name, u8 alpha=255)
+       {
+               for(u16 i=0; i<6; i++)
+               {
+                       setTexture(tsrc, i, name, alpha);
+               }
+               // Force inventory texture too
+               setInventoryTexture(name, tsrc);
+       }
+#endif
+
+#ifndef SERVER
+       void setTile(u16 i, const TileSpec &tile)
+       { tiles[i] = tile; }
+       void setAllTiles(const TileSpec &tile)
+       { for(u16 i=0; i<6; i++) setTile(i, tile); }
+#endif
+
+#ifdef SERVER
+       void setInventoryTexture(std::string imgname,
+                       ITextureSource *tsrc)
+       {}
+       void setInventoryTextureCube(std::string top,
+                       std::string left, std::string right, ITextureSource *tsrc)
+       {}
+#else
+       void setInventoryTexture(std::string imgname, ITextureSource *tsrc);
+       
+       void setInventoryTextureCube(std::string top,
+                       std::string left, std::string right, ITextureSource *tsrc);
+#endif
+
+       /*
+               Some handy methods
+       */
+       bool isLiquid() const{
+               return (liquid_type != LIQUID_NONE);
+       }
+       bool sameLiquid(const ContentFeatures &f) const{
+               if(!isLiquid() || !f.isLiquid()) return false;
+               return (liquid_alternative_flowing == f.liquid_alternative_flowing);
+       }
+};
+
+class INodeDefManager
+{
+public:
+       INodeDefManager(){}
+       virtual ~INodeDefManager(){}
+       // Get node definition
+       virtual const ContentFeatures& get(content_t c) const=0;
+       virtual const ContentFeatures& get(const MapNode &n) const=0;
+};
+
+class IWritableNodeDefManager : public INodeDefManager
+{
+public:
+       IWritableNodeDefManager(){}
+       virtual ~IWritableNodeDefManager(){}
+       virtual IWritableNodeDefManager* clone()=0;
+       // Get node definition
+       virtual const ContentFeatures& get(content_t c) const=0;
+       virtual const ContentFeatures& get(const MapNode &n) const=0;
+               
+       // Register node definition
+       virtual void set(content_t c, const ContentFeatures &def)=0;
+       virtual ContentFeatures* getModifiable(content_t c)=0;
+};
+
+// If textures not actually available (server), tsrc can be NULL
+IWritableNodeDefManager* createNodeDefManager(ITextureSource *tsrc);
+
+
+#endif
+
index a1edb829961552183b44ec82272641a9adf2c9df..8e73f350150edb3f318b5a98fc7ceb6795acd283 100644 (file)
@@ -27,9 +27,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #endif
 #include "main.h" // For g_settings
 #include "settings.h"
-#include "mapnode_contentfeatures.h"
+#include "nodedef.h"
+#include "environment.h"
+#include "gamedef.h"
 
-Player::Player():
+Player::Player(IGameDef *gamedef):
        touching_ground(false),
        in_water(false),
        in_water_stable(false),
@@ -39,6 +41,8 @@ Player::Player():
        craftresult_is_preview(true),
        hp(20),
        peer_id(PEER_ID_INEXISTENT),
+// protected
+       m_gamedef(gamedef),
        m_selected_item(0),
        m_pitch(0),
        m_yaw(0),
@@ -129,7 +133,7 @@ void Player::serialize(std::ostream &os)
                inventory.serialize(os);
 }
 
-void Player::deSerialize(std::istream &is, IGameDef *gamedef)
+void Player::deSerialize(std::istream &is)
 {
        Settings args;
        
@@ -163,13 +167,28 @@ void Player::deSerialize(std::istream &is, IGameDef *gamedef)
                hp = 20;
        }
 
-       inventory.deSerialize(is, gamedef);
+       inventory.deSerialize(is, m_gamedef);
 }
 
 /*
        ServerRemotePlayer
 */
 
+ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env):
+       Player(env->getGameDef()),
+       ServerActiveObject(env, v3f(0,0,0))
+{
+}
+ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
+               const char *name_):
+       Player(env->getGameDef()),
+       ServerActiveObject(env, pos_)
+{
+       setPosition(pos_);
+       peer_id = peer_id_;
+       updateName(name_);
+}
+
 /* ServerActiveObject interface */
 
 InventoryItem* ServerRemotePlayer::getWieldedItem()
@@ -237,9 +256,11 @@ s16 ServerRemotePlayer::getHP()
 #ifndef SERVER
 
 RemotePlayer::RemotePlayer(
+               IGameDef *gamedef,
                scene::ISceneNode* parent,
                IrrlichtDevice *device,
                s32 id):
+       Player(gamedef),
        scene::ISceneNode(parent, (device==NULL)?NULL:device->getSceneManager(), id),
        m_text(NULL)
 {
@@ -354,7 +375,8 @@ void RemotePlayer::move(f32 dtime, Map &map, f32 pos_max_d)
        LocalPlayer
 */
 
-LocalPlayer::LocalPlayer():
+LocalPlayer::LocalPlayer(IGameDef *gamedef):
+       Player(gamedef),
        m_sneak_node(32767,32767,32767),
        m_sneak_node_exists(false)
 {
@@ -370,6 +392,8 @@ LocalPlayer::~LocalPlayer()
 void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
                core::list<CollisionInfo> *collision_info)
 {
+       INodeDefManager *nodemgr = m_gamedef->ndef();
+
        v3f position = getPosition();
        v3f oldpos = position;
        v3s16 oldpos_i = floatToInt(oldpos, BS);
@@ -407,13 +431,13 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
                if(in_water)
                {
                        v3s16 pp = floatToInt(position + v3f(0,BS*0.1,0), BS);
-                       in_water = content_liquid(map.getNode(pp).getContent());
+                       in_water = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
                }
                // If not in water, the threshold of going in is at lower y
                else
                {
                        v3s16 pp = floatToInt(position + v3f(0,BS*0.5,0), BS);
-                       in_water = content_liquid(map.getNode(pp).getContent());
+                       in_water = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
                }
        }
        catch(InvalidPositionException &e)
@@ -426,7 +450,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
        */
        try{
                v3s16 pp = floatToInt(position + v3f(0,0,0), BS);
-               in_water_stable = content_liquid(map.getNode(pp).getContent());
+               in_water_stable = nodemgr->get(map.getNode(pp).getContent()).isLiquid();
        }
        catch(InvalidPositionException &e)
        {
@@ -438,14 +462,14 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
        */
 
        try {
-               v3s16 pp = floatToInt(position + v3f(0,0.5*BS,0), BS);
+               v3s16 pp = floatToInt(position + v3f(0,0.5*BS,0), BS);
                v3s16 pp2 = floatToInt(position + v3f(0,-0.2*BS,0), BS);
-               is_climbing = ((content_features(map.getNode(pp).getContent()).climbable ||
-                               content_features(map.getNode(pp2).getContent()).climbable) && !free_move);
+               is_climbing = ((nodemgr->get(map.getNode(pp).getContent()).climbable ||
+               nodemgr->get(map.getNode(pp2).getContent()).climbable) && !free_move);
        }
        catch(InvalidPositionException &e)
        {
-               is_climbing = false;
+               is_climbing = false;
        }
 
        /*
@@ -553,7 +577,7 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
                bool is_unloaded = false;
                try{
                        // Player collides into walkable nodes
-                       if(content_walkable(map.getNode(v3s16(x,y,z)).getContent()) == false)
+                       if(nodemgr->get(map.getNode(v3s16(x,y,z))).walkable == false)
                                continue;
                }
                catch(InvalidPositionException &e)
@@ -719,10 +743,10 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
 
                        try{
                                // The node to be sneaked on has to be walkable
-                               if(content_walkable(map.getNode(p).getContent()) == false)
+                               if(nodemgr->get(map.getNode(p)).walkable == false)
                                        continue;
                                // And the node above it has to be nonwalkable
-                               if(content_walkable(map.getNode(p+v3s16(0,1,0)).getContent()) == true)
+                               if(nodemgr->get(map.getNode(p+v3s16(0,1,0))).walkable == true)
                                        continue;
                        }
                        catch(InvalidPositionException &e)
index d6147b2082bf108deafe7fa824d6e441825e9f59..ecde59ce1931b6c5cd554536da070c62b198dd50 100644 (file)
@@ -30,13 +30,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 
 class Map;
+class IGameDef;
 
 class Player
 {
 public:
 
-
-       Player();
+       Player(IGameDef *gamedef);
        virtual ~Player();
 
        void resetInventory();
@@ -141,7 +141,7 @@ public:
                deSerialize stops reading exactly at the right point.
        */
        void serialize(std::ostream &os);
-       void deSerialize(std::istream &is, IGameDef *gamedef);
+       void deSerialize(std::istream &is);
 
        bool touching_ground;
        // This oscillates so that the player jumps a bit above the surface
@@ -164,6 +164,8 @@ public:
        u16 peer_id;
 
 protected:
+       IGameDef *m_gamedef;
+
        char m_name[PLAYERNAME_SIZE];
        u16 m_selected_item;
        f32 m_pitch;
@@ -185,26 +187,15 @@ public:
 class ServerRemotePlayer : public Player, public ServerActiveObject
 {
 public:
-       ServerRemotePlayer(ServerEnvironment *env):
-               ServerActiveObject(env, v3f(0,0,0))
-       {
-       }
+       ServerRemotePlayer(ServerEnvironment *env);
        ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
-                       const char *name_):
-               ServerActiveObject(env, pos_)
-       {
-               setPosition(pos_);
-               peer_id = peer_id_;
-               updateName(name_);
-       }
+                       const char *name_);
+
        virtual ~ServerRemotePlayer()
-       {
-       }
+       {}
 
        virtual bool isLocal() const
-       {
-               return false;
-       }
+       { return false; }
 
        virtual void move(f32 dtime, Map &map, f32 pos_max_d)
        {
@@ -242,6 +233,7 @@ class RemotePlayer : public Player, public scene::ISceneNode
 {
 public:
        RemotePlayer(
+               IGameDef *gamedef,
                scene::ISceneNode* parent=NULL,
                IrrlichtDevice *device=NULL,
                s32 id=0);
@@ -378,7 +370,7 @@ struct PlayerControl
 class LocalPlayer : public Player
 {
 public:
-       LocalPlayer();
+       LocalPlayer(IGameDef *gamedef);
        virtual ~LocalPlayer();
 
        bool isLocal() const
index 40a5e183bbd25195b5827d47dfc6b260f92ed4f6..75fb7cd72f87f33de51f16e1d07e940162e3b7cc 100644 (file)
@@ -41,8 +41,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "log.h"
 #include "script.h"
 #include "scriptapi.h"
-#include "mapnode_contentfeatures.h"
-#include "tool.h"
+#include "nodedef.h"
+#include "tooldef.h"
 #include "content_tool.h" // For content_tool_init
 
 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@@ -959,6 +959,7 @@ Server::Server(
        m_banmanager(mapsavedir+DIR_DELIM+"ipban.txt"),
        m_lua(NULL),
        m_toolmgr(createToolDefManager()),
+       m_nodemgr(createNodeDefManager(NULL)),
        m_thread(this),
        m_emergethread(this),
        m_time_counter(0),
@@ -983,10 +984,15 @@ Server::Server(
 
        JMutexAutoLock envlock(m_env_mutex);
        JMutexAutoLock conlock(m_con_mutex);
+
+       infostream<<"m_nodemgr="<<m_nodemgr<<std::endl;
        
        // Initialize default tool definitions
        content_tool_init(m_toolmgr);
 
+       // Initialize default node definitions
+       content_mapnode_init(NULL, m_nodemgr);
+
        // Initialize scripting
        
        infostream<<"Server: Initializing scripting"<<std::endl;
@@ -1107,6 +1113,7 @@ Server::~Server()
        delete m_env;
 
        delete m_toolmgr;
+       delete m_nodemgr;
        
        // Deinitialize scripting
        infostream<<"Server: Deinitializing scripting"<<std::endl;
@@ -2481,14 +2488,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                        {
                                MapNode n = m_env->getMap().getNode(p_under);
                                // Get mineral
-                               mineral = n.getMineral();
+                               mineral = n.getMineral(m_nodemgr);
                                // Get material at position
                                material = n.getContent();
                                // If not yet cancelled
                                if(cannot_remove_node == false)
                                {
                                        // If it's not diggable, do nothing
-                                       if(content_diggable(material) == false)
+                                       if(m_nodemgr->get(material).diggable == false)
                                        {
                                                infostream<<"Server: Not finishing digging: "
                                                                <<"Node not diggable"
@@ -2584,7 +2591,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                                ToolDiggingProperties tp =
                                                                m_toolmgr->getDiggingProperties(toolname);
                                                DiggingProperties prop =
-                                                               getDiggingProperties(material, &tp);
+                                                               getDiggingProperties(material, &tp, m_nodemgr);
 
                                                if(prop.diggable == false)
                                                {
@@ -2614,7 +2621,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                // If not mineral
                                if(item == NULL)
                                {
-                                       std::string &dug_s = content_features(material).dug_item;
+                                       const std::string &dug_s = m_nodemgr->get(material).dug_item;
                                        if(dug_s != "")
                                        {
                                                std::istringstream is(dug_s, std::ios::binary);
@@ -2640,20 +2647,20 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                // If not mineral
                                if(item == NULL)
                                {
-                                       std::string &extra_dug_s = content_features(material).extra_dug_item;
-                                       s32 extra_rarity = content_features(material).extra_dug_item_rarity;
+                                       const std::string &extra_dug_s = m_nodemgr->get(material).extra_dug_item;
+                                       s32 extra_rarity = m_nodemgr->get(material).extra_dug_item_rarity;
                                        if(extra_dug_s != "" && extra_rarity != 0
                                           && myrand() % extra_rarity == 0)
                                        {
-                                               std::istringstream is(extra_dug_s, std::ios::binary);
+                                               std::istringstream is(extra_dug_s, std::ios::binary);
                                                item = InventoryItem::deSerialize(is, this);
                                        }
                                }
                        
                                if(item != NULL)
                                {
-                                       // Add a item to inventory
-                                       player->inventory.addItem("main", item);
+                                       // Add a item to inventory
+                                       player->inventory.addItem("main", item);
 
                                        // Send inventory
                                        UpdateCrafting(player->peer_id);
@@ -2717,7 +2724,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                                        <<" because privileges are "<<getPlayerPrivs(player)
                                                        <<std::endl;
 
-                                       if(content_features(n2).buildable_to == false
+                                       if(m_nodemgr->get(n2).buildable_to == false
                                                || no_enough_privs)
                                        {
                                                // Client probably has wrong data.
@@ -2755,11 +2762,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                                <<" at "<<PP(p_under)<<std::endl;
                        
                                // Calculate direction for wall mounted stuff
-                               if(content_features(n).wall_mounted)
+                               if(m_nodemgr->get(n).wall_mounted)
                                        n.param2 = packDir(p_under - p_over);
 
                                // Calculate the direction for furnaces and chests and stuff
-                               if(content_features(n).param_type == CPT_FACEDIR_SIMPLE)
+                               if(m_nodemgr->get(n).param_type == CPT_FACEDIR_SIMPLE)
                                {
                                        v3f playerpos = player->getPosition();
                                        v3f blockpos = intToFloat(p_over, BS) - playerpos;
@@ -4192,6 +4199,21 @@ void Server::notifyPlayers(const std::wstring msg)
        BroadcastChatMessage(msg);
 }
 
+// IGameDef interface
+// Under envlock
+IToolDefManager* Server::getToolDefManager()
+{
+       return m_toolmgr;
+}
+INodeDefManager* Server::getNodeDefManager()
+{
+       return m_nodemgr;
+}
+ITextureSource* Server::getTextureSource()
+{
+       return NULL;
+}
+
 v3f findSpawnPos(ServerMap &map)
 {
        //return v3f(50,50,50)*BS;
index 2d0aa8183d29b23280352d086aff59275f43ce3a..e1a5838260815cd9c1d782df870f660f1c5e7e1e 100644 (file)
@@ -32,7 +32,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "gamedef.h"
 struct LuaState;
 typedef struct lua_State lua_State;
-class IToolDefManager;
+class IWritableToolDefManager;
+class IWritableNodeDefManager;
 
 /*
        Some random functions
@@ -486,10 +487,9 @@ public:
        
        // IGameDef interface
        // Under envlock
-       virtual IToolDefManager* getToolDefManager()
-               { return m_toolmgr; }
-       virtual INodeDefManager* getNodeDefManager()
-               { assert(0); return NULL; } // TODO
+       virtual IToolDefManager* getToolDefManager();
+       virtual INodeDefManager* getNodeDefManager();
+       virtual ITextureSource* getTextureSource();
 
 private:
 
@@ -616,7 +616,10 @@ private:
        lua_State *m_lua;
 
        // Tool definition manager
-       IToolDefManager *m_toolmgr;
+       IWritableToolDefManager *m_toolmgr;
+       
+       // Node definition manager
+       IWritableNodeDefManager *m_nodemgr;
        
        /*
                Threads
index deae90bbaa3d7daace756811e48807ff56ca5277..64853604b1a8ec64c11de1411005e66dec95a43f 100644 (file)
@@ -74,7 +74,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "settings.h"
 #include "profiler.h"
 #include "log.h"
-#include "mapnode_contentfeatures.h" // For init_contentfeatures
+#include "nodedef.h" // For init_contentfeatures
 #include "content_mapnode.h" // For content_mapnode_init
 
 /*
@@ -302,11 +302,6 @@ int main(int argc, char *argv[])
 
        // Initialize stuff
        
-       // Initialize content feature table without textures
-       init_contentfeatures(NULL);
-       // Initialize mapnode content without textures
-       content_mapnode_init(NULL);
-
        init_mineral();
 
        /*
index 37412d179e5f0a111723d0b11136eb2dbf11f365..e1242ccb39be9394e0c673eee4b89579b837d406 100644 (file)
@@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <sstream>
 #include "porting.h"
 #include "content_mapnode.h"
+#include "nodedef.h"
 #include "mapsector.h"
 #include "settings.h"
 #include "log.h"
@@ -216,26 +217,26 @@ struct TestCompress
 
 struct TestMapNode
 {
-       void Run()
+       void Run(INodeDefManager *nodedef)
        {
                MapNode n;
 
                // Default values
                assert(n.getContent() == CONTENT_AIR);
-               assert(n.getLight(LIGHTBANK_DAY) == 0);
-               assert(n.getLight(LIGHTBANK_NIGHT) == 0);
+               assert(n.getLight(LIGHTBANK_DAY, nodedef) == 0);
+               assert(n.getLight(LIGHTBANK_NIGHT, nodedef) == 0);
                
                // Transparency
                n.setContent(CONTENT_AIR);
-               assert(n.light_propagates() == true);
+               assert(nodedef->get(n).light_propagates == true);
                n.setContent(CONTENT_STONE);
-               assert(n.light_propagates() == false);
+               assert(nodedef->get(n).light_propagates == false);
        }
 };
 
 struct TestVoxelManipulator
 {
-       void Run()
+       void Run(INodeDefManager *nodedef)
        {
                /*
                        VoxelArea
@@ -278,13 +279,13 @@ struct TestVoxelManipulator
                
                VoxelManipulator v;
 
-               v.print(infostream);
+               v.print(infostream, nodedef);
 
                infostream<<"*** Setting (-1,0,-1)=2 ***"<<std::endl;
                
                v.setNodeNoRef(v3s16(-1,0,-1), MapNode(2));
 
-               v.print(infostream);
+               v.print(infostream, nodedef);
 
                assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2);
 
@@ -292,85 +293,16 @@ struct TestVoxelManipulator
 
                EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,0,-1)));
 
-               v.print(infostream);
+               v.print(infostream, nodedef);
 
                infostream<<"*** Adding area ***"<<std::endl;
 
                v.addArea(a);
                
-               v.print(infostream);
+               v.print(infostream, nodedef);
 
                assert(v.getNode(v3s16(-1,0,-1)).getContent() == 2);
                EXCEPTION_CHECK(InvalidPositionException, v.getNode(v3s16(0,1,1)));
-
-#if 0
-               /*
-                       Water stuff
-               */
-
-               v.clear();
-
-               const char *content =
-                       "#...######  "
-                       "#...##..##  "
-                       "#........ .."
-                       "############"
-
-                       "#...######  "
-                       "#...##..##  "
-                       "#........#  "
-                       "############"
-               ;
-
-               v3s16 size(12, 4, 2);
-               VoxelArea area(v3s16(0,0,0), size-v3s16(1,1,1));
-               
-               const char *p = content;
-               for(s16 z=0; z<size.Z; z++)
-               for(s16 y=size.Y-1; y>=0; y--)
-               for(s16 x=0; x<size.X; x++)
-               {
-                       MapNode n;
-                       //n.pressure = size.Y - y;
-                       if(*p == '#')
-                               n.setContent(CONTENT_STONE);
-                       else if(*p == '.')
-                               n.setContent(CONTENT_WATER);
-                       else if(*p == ' ')
-                               n.setContent(CONTENT_AIR);
-                       else
-                               assert(0);
-                       v.setNode(v3s16(x,y,z), n);
-                       p++;
-               }
-
-               v.print(infostream, VOXELPRINT_WATERPRESSURE);
-               
-               core::map<v3s16, u8> active_nodes;
-               v.updateAreaWaterPressure(area, active_nodes);
-
-               v.print(infostream, VOXELPRINT_WATERPRESSURE);
-               
-               //s16 highest_y = -32768;
-               /*
-                       NOTE: These are commented out because this behaviour is changed
-                             all the time
-               */
-               //assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == -1);
-               //assert(highest_y == 3);
-               /*assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == 3);
-               //assert(highest_y == 3);*/
-               
-               active_nodes.clear();
-               active_nodes[v3s16(9,1,0)] = 1;
-               //v.flowWater(active_nodes, 0, true, 1000);
-               v.flowWater(active_nodes, 0, false, 1000);
-               
-               infostream<<"Final result of flowWater:"<<std::endl;
-               v.print(infostream, VOXELPRINT_WATERPRESSURE);
-#endif
-               
-               //assert(0);
        }
 };
 
@@ -1143,15 +1075,27 @@ struct TestConnection
        x.Run();\
 }
 
+#define TESTPARAMS(X, ...)\
+{\
+       X x;\
+       infostream<<"Running " #X <<std::endl;\
+       x.Run(__VA_ARGS__);\
+}
+
 void run_tests()
 {
        DSTACK(__FUNCTION_NAME);
+       
+       // Create node definitions
+       IWritableNodeDefManager *nodedef = createNodeDefManager(NULL);
+       content_mapnode_init(NULL, nodedef);
+
        infostream<<"run_tests() started"<<std::endl;
        TEST(TestUtilities);
        TEST(TestSettings);
        TEST(TestCompress);
-       TEST(TestMapNode);
-       TEST(TestVoxelManipulator);
+       TESTPARAMS(TestMapNode, nodedef);
+       TESTPARAMS(TestVoxelManipulator, nodedef);
        //TEST(TestMapBlock);
        //TEST(TestMapSector);
        if(INTERNET_SIMULATOR == false){
index 32de8cda23cbd6dc079390b2da48c23610972337..c8fffffa7ad44fca8a8d16669efd0d0b50e9667d 100644 (file)
@@ -27,7 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "log.h"
 #include "mapnode.h" // For texture atlas making
 #include "mineral.h" // For texture atlas making
-#include "mapnode_contentfeatures.h" // For texture atlas making
+#include "nodedef.h" // For texture atlas making
+#include "gamedef.h"
 
 /*
        A cache from texture name to texture path
@@ -148,6 +149,142 @@ std::string getTexturePath(const std::string &filename)
        TextureSource
 */
 
+class TextureSource : public IWritableTextureSource
+{
+public:
+       TextureSource(IrrlichtDevice *device);
+       ~TextureSource();
+
+       /*
+               Example case:
+               Now, assume a texture with the id 1 exists, and has the name
+               "stone.png^mineral1".
+               Then a random thread calls getTextureId for a texture called
+               "stone.png^mineral1^crack0".
+               ...Now, WTF should happen? Well:
+               - getTextureId strips off stuff recursively from the end until
+                 the remaining part is found, or nothing is left when
+                 something is stripped out
+
+               But it is slow to search for textures by names and modify them
+               like that?
+               - ContentFeatures is made to contain ids for the basic plain
+                 textures
+               - Crack textures can be slow by themselves, but the framework
+                 must be fast.
+
+               Example case #2:
+               - Assume a texture with the id 1 exists, and has the name
+                 "stone.png^mineral1" and is specified as a part of some atlas.
+               - Now MapBlock::getNodeTile() stumbles upon a node which uses
+                 texture id 1, and finds out that NODEMOD_CRACK must be applied
+                 with progression=0
+               - It finds out the name of the texture with getTextureName(1),
+                 appends "^crack0" to it and gets a new texture id with
+                 getTextureId("stone.png^mineral1^crack0")
+
+       */
+       
+       /*
+               Gets a texture id from cache or
+               - if main thread, from getTextureIdDirect
+               - if other thread, adds to request queue and waits for main thread
+       */
+       u32 getTextureId(const std::string &name);
+       
+       /*
+               Example names:
+               "stone.png"
+               "stone.png^crack2"
+               "stone.png^blit:mineral_coal.png"
+               "stone.png^blit:mineral_coal.png^crack1"
+
+               - If texture specified by name is found from cache, return the
+                 cached id.
+               - Otherwise generate the texture, add to cache and return id.
+                 Recursion is used to find out the largest found part of the
+                 texture and continue based on it.
+
+               The id 0 points to a NULL texture. It is returned in case of error.
+       */
+       u32 getTextureIdDirect(const std::string &name);
+
+       /*
+               Finds out the name of a cached texture.
+       */
+       std::string getTextureName(u32 id);
+
+       /*
+               If texture specified by the name pointed by the id doesn't
+               exist, create it, then return the cached texture.
+
+               Can be called from any thread. If called from some other thread
+               and not found in cache, the call is queued to the main thread
+               for processing.
+       */
+       AtlasPointer getTexture(u32 id);
+       
+       AtlasPointer getTexture(const std::string &name)
+       {
+               return getTexture(getTextureId(name));
+       }
+       
+       // Gets a separate texture
+       video::ITexture* getTextureRaw(const std::string &name)
+       {
+               AtlasPointer ap = getTexture(name);
+               return ap.atlas;
+       }
+
+       /*
+               Update new texture pointer and texture coordinates to an
+               AtlasPointer based on it's texture id
+       */
+       void updateAP(AtlasPointer &ap);
+
+       /*
+               Build the main texture atlas which contains most of the
+               textures.
+               
+               This is called by the constructor.
+       */
+       void buildMainAtlas(class IGameDef *gamedef);
+       
+       /*
+               Processes queued texture requests from other threads.
+
+               Shall be called from the main thread.
+       */
+       void processQueue();
+       
+private:
+       
+       // The id of the thread that is allowed to use irrlicht directly
+       threadid_t m_main_thread;
+       // The irrlicht device
+       IrrlichtDevice *m_device;
+       
+       // A texture id is index in this array.
+       // The first position contains a NULL texture.
+       core::array<SourceAtlasPointer> m_atlaspointer_cache;
+       // Maps a texture name to an index in the former.
+       core::map<std::string, u32> m_name_to_id;
+       // The two former containers are behind this mutex
+       JMutex m_atlaspointer_cache_mutex;
+       
+       // Main texture atlas. This is filled at startup and is then not touched.
+       video::IImage *m_main_atlas_image;
+       video::ITexture *m_main_atlas_texture;
+
+       // Queued texture fetches (to be processed by the main thread)
+       RequestQueue<std::string, u32, u8, u8> m_get_texture_queue;
+};
+
+IWritableTextureSource* createTextureSource(IrrlichtDevice *device)
+{
+       return new TextureSource(device);
+}
+
 TextureSource::TextureSource(IrrlichtDevice *device):
                m_device(device),
                m_main_atlas_image(NULL),
@@ -162,12 +299,6 @@ TextureSource::TextureSource(IrrlichtDevice *device):
        // Add a NULL AtlasPointer as the first index, named ""
        m_atlaspointer_cache.push_back(SourceAtlasPointer(""));
        m_name_to_id[""] = 0;
-
-       // Build main texture atlas
-       if(g_settings->getBool("enable_texture_atlas"))
-               buildMainAtlas();
-       else
-               infostream<<"Not building texture atlas."<<std::endl;
 }
 
 TextureSource::~TextureSource()
@@ -487,8 +618,17 @@ AtlasPointer TextureSource::getTexture(u32 id)
        return m_atlaspointer_cache[id].a;
 }
 
-void TextureSource::buildMainAtlas() 
+void TextureSource::updateAP(AtlasPointer &ap)
 {
+       AtlasPointer ap2 = getTexture(ap.id);
+       ap = ap2;
+}
+
+void TextureSource::buildMainAtlas(class IGameDef *gamedef) 
+{
+       assert(gamedef->tsrc() == this);
+       INodeDefManager *ndef = gamedef->ndef();
+
        infostream<<"TextureSource::buildMainAtlas()"<<std::endl;
 
        //return; // Disable (for testing)
@@ -521,15 +661,15 @@ void TextureSource::buildMainAtlas()
        {
                if(j == CONTENT_IGNORE || j == CONTENT_AIR)
                        continue;
-               ContentFeatures *f = &content_features(j);
-               for(core::map<std::string, bool>::Iterator
-                               i = f->used_texturenames.getIterator();
-                               i.atEnd() == false; i++)
+               const ContentFeatures &f = ndef->get(j);
+               for(std::set<std::string>::const_iterator
+                               i = f.used_texturenames.begin();
+                               i != f.used_texturenames.end(); i++)
                {
-                       std::string name = i.getNode()->getKey();
+                       std::string name = *i;
                        sourcelist[name] = true;
 
-                       if(f->often_contains_mineral){
+                       if(f.often_contains_mineral){
                                for(int k=1; k<MINERAL_COUNT; k++){
                                        std::string mineraltexture = mineral_block_texture(k);
                                        std::string fulltexture = name + "^" + mineraltexture;
@@ -658,8 +798,18 @@ void TextureSource::buildMainAtlas()
                        Add texture to caches
                */
                
-               // Get next id
+               bool reuse_old_id = false;
                u32 id = m_atlaspointer_cache.size();
+               // Check old id without fetching a texture
+               core::map<std::string, u32>::Node *n;
+               n = m_name_to_id.find(name);
+               // If it exists, we will replace the old definition
+               if(n){
+                       id = n->getValue();
+                       reuse_old_id = true;
+               }
+               infostream<<"TextureSource::buildMainAtlas(): "
+                               <<"Replacing old AtlasPointer"<<std::endl;
 
                // Create AtlasPointer
                AtlasPointer ap(id);
@@ -672,8 +822,11 @@ void TextureSource::buildMainAtlas()
 
                // Create SourceAtlasPointer and add to containers
                SourceAtlasPointer nap(name, ap, atlas_img, pos_in_atlas, dim);
-               m_atlaspointer_cache.push_back(nap);
-               m_name_to_id.insert(name, id);
+               if(reuse_old_id)
+                       m_atlaspointer_cache[id] = nap;
+               else
+                       m_atlaspointer_cache.push_back(nap);
+               m_name_to_id[name] = id;
                        
                // Increment position
                pos_in_atlas.Y += dim.Height + padding * 2;
index da23615c3e32d5eaf212affdf19d414b3cf4d43b..ac4e790b43e86523e08f3589ae1eb9d412206241 100644 (file)
@@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "utility.h"
 #include <string>
 
+class IGameDef;
+
 /*
        tile.{h,cpp}: Texture handling stuff.
 */
@@ -120,8 +122,9 @@ struct SourceAtlasPointer
 };
 
 /*
-       Implementation (to be used as a no-op on the server)
+       TextureSource creates and caches textures.
 */
+
 class ITextureSource
 {
 public:
@@ -137,133 +140,27 @@ public:
                {return NULL;}
 };
 
-/*
-       Creates and caches textures.
-*/
-class TextureSource : public ITextureSource
+class IWritableTextureSource : public ITextureSource
 {
 public:
-       TextureSource(IrrlichtDevice *device);
-       ~TextureSource();
-
-       /*
-               Processes queued texture requests from other threads.
-
-               Shall be called from the main thread.
-       */
-       void processQueue();
-       
-       /*
-               Example case:
-               Now, assume a texture with the id 1 exists, and has the name
-               "stone.png^mineral1".
-               Then a random thread calls getTextureId for a texture called
-               "stone.png^mineral1^crack0".
-               ...Now, WTF should happen? Well:
-               - getTextureId strips off stuff recursively from the end until
-                 the remaining part is found, or nothing is left when
-                 something is stripped out
-
-               But it is slow to search for textures by names and modify them
-               like that?
-               - ContentFeatures is made to contain ids for the basic plain
-                 textures
-               - Crack textures can be slow by themselves, but the framework
-                 must be fast.
-
-               Example case #2:
-               - Assume a texture with the id 1 exists, and has the name
-                 "stone.png^mineral1" and is specified as a part of some atlas.
-               - Now MapBlock::getNodeTile() stumbles upon a node which uses
-                 texture id 1, and finds out that NODEMOD_CRACK must be applied
-                 with progression=0
-               - It finds out the name of the texture with getTextureName(1),
-                 appends "^crack0" to it and gets a new texture id with
-                 getTextureId("stone.png^mineral1^crack0")
-
-       */
-       
-       /*
-               Gets a texture id from cache or
-               - if main thread, from getTextureIdDirect
-               - if other thread, adds to request queue and waits for main thread
-       */
-       u32 getTextureId(const std::string &name);
-       
-       /*
-               Example names:
-               "stone.png"
-               "stone.png^crack2"
-               "stone.png^blit:mineral_coal.png"
-               "stone.png^blit:mineral_coal.png^crack1"
-
-               - If texture specified by name is found from cache, return the
-                 cached id.
-               - Otherwise generate the texture, add to cache and return id.
-                 Recursion is used to find out the largest found part of the
-                 texture and continue based on it.
-
-               The id 0 points to a NULL texture. It is returned in case of error.
-       */
-       u32 getTextureIdDirect(const std::string &name);
-
-       /*
-               Finds out the name of a cached texture.
-       */
-       std::string getTextureName(u32 id);
-
-       /*
-               If texture specified by the name pointed by the id doesn't
-               exist, create it, then return the cached texture.
-
-               Can be called from any thread. If called from some other thread
-               and not found in cache, the call is queued to the main thread
-               for processing.
-       */
-       AtlasPointer getTexture(u32 id);
-       
-       AtlasPointer getTexture(const std::string &name)
-       {
-               return getTexture(getTextureId(name));
-       }
-       
-       // Gets a separate texture
-       video::ITexture* getTextureRaw(const std::string &name)
-       {
-               AtlasPointer ap = getTexture(name);
-               return ap.atlas;
-       }
-
-private:
-       /*
-               Build the main texture atlas which contains most of the
-               textures.
-               
-               This is called by the constructor.
-       */
-       void buildMainAtlas();
-       
-       // The id of the thread that is allowed to use irrlicht directly
-       threadid_t m_main_thread;
-       // The irrlicht device
-       IrrlichtDevice *m_device;
-       
-       // A texture id is index in this array.
-       // The first position contains a NULL texture.
-       core::array<SourceAtlasPointer> m_atlaspointer_cache;
-       // Maps a texture name to an index in the former.
-       core::map<std::string, u32> m_name_to_id;
-       // The two former containers are behind this mutex
-       JMutex m_atlaspointer_cache_mutex;
-       
-       // Main texture atlas. This is filled at startup and is then not touched.
-       video::IImage *m_main_atlas_image;
-       video::ITexture *m_main_atlas_texture;
+       IWritableTextureSource(){}
+       virtual ~IWritableTextureSource(){}
+       virtual u32 getTextureId(const std::string &name){return 0;}
+       virtual u32 getTextureIdDirect(const std::string &name){return 0;}
+       virtual std::string getTextureName(u32 id){return "";}
+       virtual AtlasPointer getTexture(u32 id){return AtlasPointer(0);}
+       virtual AtlasPointer getTexture(const std::string &name)
+               {return AtlasPointer(0);}
+       virtual video::ITexture* getTextureRaw(const std::string &name)
+               {return NULL;}
 
-       // Queued texture fetches (to be processed by the main thread)
-       RequestQueue<std::string, u32, u8, u8> m_get_texture_queue;
+       virtual void updateAP(AtlasPointer &ap)=0;
+       virtual void buildMainAtlas(class IGameDef *gamedef)=0;
+       virtual void processQueue()=0;
 };
 
+IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
+
 enum MaterialType{
        MATERIAL_ALPHA_NONE,
        MATERIAL_ALPHA_VERTEX,
diff --git a/src/tool.cpp b/src/tool.cpp
deleted file mode 100644 (file)
index d455562..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-Minetest-c55
-Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "tool.h"
-#include "irrlichttypes.h"
-#include "log.h"
-#include <ostream>
-
-class CToolDefManager: public IToolDefManager
-{
-public:
-       virtual ~CToolDefManager()
-       {
-               for(core::map<std::string, ToolDefinition*>::Iterator
-                               i = m_tool_definitions.getIterator();
-                               i.atEnd() == false; i++){
-                       delete i.getNode()->getValue();
-               }
-       }
-       virtual bool registerTool(std::string toolname, const ToolDefinition &def)
-       {
-               infostream<<"registerTool: registering tool \""<<toolname<<"\""<<std::endl;
-               core::map<std::string, ToolDefinition*>::Node *n;
-               n = m_tool_definitions.find(toolname);
-               if(n != NULL){
-                       errorstream<<"registerTool: registering tool \""<<toolname
-                                       <<"\" failed: name is already registered"<<std::endl;
-                       return false;
-               }
-               m_tool_definitions[toolname] = new ToolDefinition(def);
-               return true;
-       }
-       virtual ToolDefinition* getToolDefinition(const std::string &toolname)
-       {
-               core::map<std::string, ToolDefinition*>::Node *n;
-               n = m_tool_definitions.find(toolname);
-               if(n == NULL)
-                       return NULL;
-               return n->getValue();
-       }
-       virtual std::string getImagename(const std::string &toolname)
-       {
-               ToolDefinition *def = getToolDefinition(toolname);
-               if(def == NULL)
-                       return "";
-               return def->imagename;
-       }
-       virtual ToolDiggingProperties getDiggingProperties(
-                       const std::string &toolname)
-       {
-               ToolDefinition *def = getToolDefinition(toolname);
-               // If tool does not exist, just return an impossible
-               if(def == NULL){
-                       // If tool does not exist, try empty name
-                       ToolDefinition *def = getToolDefinition("");
-                       if(def == NULL) // If that doesn't exist either, return default
-                               return ToolDiggingProperties();
-                       return def->properties;
-               }
-               return def->properties;
-       }
-private:
-       // Key is name
-       core::map<std::string, ToolDefinition*> m_tool_definitions;
-};
-
-IToolDefManager* createToolDefManager()
-{
-       return new CToolDefManager();
-}
-
diff --git a/src/tool.h b/src/tool.h
deleted file mode 100644 (file)
index a2a94f7..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-Minetest-c55
-Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef TOOL_HEADER
-#define TOOL_HEADER
-
-#include <string>
-
-struct ToolDiggingProperties
-{
-       // time = basetime + sum(feature here * feature in MaterialProperties)
-       float basetime;
-       float dt_weight;
-       float dt_crackiness;
-       float dt_crumbliness;
-       float dt_cuttability;
-       float basedurability;
-       float dd_weight;
-       float dd_crackiness;
-       float dd_crumbliness;
-       float dd_cuttability;
-
-       ToolDiggingProperties(float a=0.75, float b=0, float c=0, float d=0, float e=0,
-                       float f=50, float g=0, float h=0, float i=0, float j=0):
-               basetime(a),
-               dt_weight(b),
-               dt_crackiness(c),
-               dt_crumbliness(d),
-               dt_cuttability(e),
-               basedurability(f),
-               dd_weight(g),
-               dd_crackiness(h),
-               dd_crumbliness(i),
-               dd_cuttability(j)
-       {}
-};
-
-struct ToolDefinition
-{
-       std::string imagename;
-       ToolDiggingProperties properties;
-
-       ToolDefinition(){}
-       ToolDefinition(const std::string &imagename_,
-                       ToolDiggingProperties properties_):
-               imagename(imagename_),
-               properties(properties_)
-       {}
-};
-
-class IToolDefManager
-{
-public:
-       IToolDefManager(){}
-       virtual ~IToolDefManager(){}
-       virtual bool registerTool(std::string toolname, const ToolDefinition &def)=0;
-       virtual ToolDefinition* getToolDefinition(const std::string &toolname)=0;
-       virtual std::string getImagename(const std::string &toolname)=0;
-       virtual ToolDiggingProperties getDiggingProperties(
-                       const std::string &toolname)=0;
-};
-
-IToolDefManager* createToolDefManager();
-
-#endif
-
diff --git a/src/tooldef.cpp b/src/tooldef.cpp
new file mode 100644 (file)
index 0000000..f35cf2b
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+Minetest-c55
+Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "tooldef.h"
+#include "irrlichttypes.h"
+#include "log.h"
+#include <ostream>
+
+class CToolDefManager: public IWritableToolDefManager
+{
+public:
+       virtual ~CToolDefManager()
+       {
+               for(core::map<std::string, ToolDefinition*>::Iterator
+                               i = m_tool_definitions.getIterator();
+                               i.atEnd() == false; i++){
+                       delete i.getNode()->getValue();
+               }
+       }
+       virtual const ToolDefinition* getToolDefinition(const std::string &toolname) const
+       {
+               core::map<std::string, ToolDefinition*>::Node *n;
+               n = m_tool_definitions.find(toolname);
+               if(n == NULL)
+                       return NULL;
+               return n->getValue();
+       }
+       virtual std::string getImagename(const std::string &toolname) const
+       {
+               const ToolDefinition *def = getToolDefinition(toolname);
+               if(def == NULL)
+                       return "";
+               return def->imagename;
+       }
+       virtual ToolDiggingProperties getDiggingProperties(
+                       const std::string &toolname) const
+       {
+               const ToolDefinition *def = getToolDefinition(toolname);
+               // If tool does not exist, just return an impossible
+               if(def == NULL){
+                       // If tool does not exist, try empty name
+                       const ToolDefinition *def = getToolDefinition("");
+                       if(def == NULL) // If that doesn't exist either, return default
+                               return ToolDiggingProperties();
+                       return def->properties;
+               }
+               return def->properties;
+       }
+       virtual bool registerTool(std::string toolname, const ToolDefinition &def)
+       {
+               infostream<<"registerTool: registering tool \""<<toolname<<"\""<<std::endl;
+               core::map<std::string, ToolDefinition*>::Node *n;
+               n = m_tool_definitions.find(toolname);
+               if(n != NULL){
+                       errorstream<<"registerTool: registering tool \""<<toolname
+                                       <<"\" failed: name is already registered"<<std::endl;
+                       return false;
+               }
+               m_tool_definitions[toolname] = new ToolDefinition(def);
+               return true;
+       }
+private:
+       // Key is name
+       core::map<std::string, ToolDefinition*> m_tool_definitions;
+};
+
+IWritableToolDefManager* createToolDefManager()
+{
+       return new CToolDefManager();
+}
+
diff --git a/src/tooldef.h b/src/tooldef.h
new file mode 100644 (file)
index 0000000..8aa6abe
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+Minetest-c55
+Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef TOOLDEF_HEADER
+#define TOOLDEF_HEADER
+
+#include <string>
+
+/*
+       TODO: Rename to tooldef.h
+*/
+
+struct ToolDiggingProperties
+{
+       // time = basetime + sum(feature here * feature in MaterialProperties)
+       float basetime;
+       float dt_weight;
+       float dt_crackiness;
+       float dt_crumbliness;
+       float dt_cuttability;
+       float basedurability;
+       float dd_weight;
+       float dd_crackiness;
+       float dd_crumbliness;
+       float dd_cuttability;
+
+       ToolDiggingProperties(float a=0.75, float b=0, float c=0, float d=0, float e=0,
+                       float f=50, float g=0, float h=0, float i=0, float j=0):
+               basetime(a),
+               dt_weight(b),
+               dt_crackiness(c),
+               dt_crumbliness(d),
+               dt_cuttability(e),
+               basedurability(f),
+               dd_weight(g),
+               dd_crackiness(h),
+               dd_crumbliness(i),
+               dd_cuttability(j)
+       {}
+};
+
+struct ToolDefinition
+{
+       std::string imagename;
+       ToolDiggingProperties properties;
+
+       ToolDefinition(){}
+       ToolDefinition(const std::string &imagename_,
+                       ToolDiggingProperties properties_):
+               imagename(imagename_),
+               properties(properties_)
+       {}
+};
+
+class IToolDefManager
+{
+public:
+       IToolDefManager(){}
+       virtual ~IToolDefManager(){}
+       virtual const ToolDefinition* getToolDefinition(const std::string &toolname) const=0;
+       virtual std::string getImagename(const std::string &toolname) const =0;
+       virtual ToolDiggingProperties getDiggingProperties(
+                       const std::string &toolname) const =0;
+};
+
+class IWritableToolDefManager : public IToolDefManager
+{
+public:
+       IWritableToolDefManager(){}
+       virtual ~IWritableToolDefManager(){}
+       virtual const ToolDefinition* getToolDefinition(const std::string &toolname) const=0;
+       virtual std::string getImagename(const std::string &toolname) const =0;
+       virtual ToolDiggingProperties getDiggingProperties(
+                       const std::string &toolname) const =0;
+                       
+       virtual bool registerTool(std::string toolname, const ToolDefinition &def)=0;
+};
+
+IWritableToolDefManager* createToolDefManager();
+
+#endif
+
index 616a197e3abfdd79afc77ac2417201d36f596da8..6324312440c21ff8e46638bd9828828d70017a4c 100644 (file)
@@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "map.h"
 #include "utility.h" // For TimeTaker
 #include "gettime.h"
-#include "content_mapnode.h"
+#include "nodedef.h"
 
 /*
        Debug stuff
@@ -63,7 +63,8 @@ void VoxelManipulator::clear()
        m_flags = NULL;
 }
 
-void VoxelManipulator::print(std::ostream &o, VoxelPrintMode mode)
+void VoxelManipulator::print(std::ostream &o, INodeDefManager *nodemgr,
+               VoxelPrintMode mode)
 {
        v3s16 em = m_area.getExtent();
        v3s16 of = m_area.MinEdge;
@@ -102,7 +103,7 @@ void VoxelManipulator::print(std::ostream &o, VoxelPrintMode mode)
                                        }
                                        else if(mode == VOXELPRINT_WATERPRESSURE)
                                        {
-                                               if(m == CONTENT_WATER)
+                                               if(nodemgr->get(m).isLiquid())
                                                {
                                                        c = 'w';
                                                        if(pr <= 9)
@@ -279,7 +280,7 @@ void VoxelManipulator::clearFlag(u8 flags)
 }
 
 void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
-               core::map<v3s16, bool> & light_sources)
+               core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr)
 {
        v3s16 dirs[6] = {
                v3s16(0,0,1), // back
@@ -309,21 +310,21 @@ void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
                        If the neighbor is dimmer than what was specified
                        as oldlight (the light of the previous node)
                */
-               if(n2.getLight(bank) < oldlight)
+               if(n2.getLight(bank, nodemgr) < oldlight)
                {
                        /*
                                And the neighbor is transparent and it has some light
                        */
-                       if(n2.light_propagates() && n2.getLight(bank) != 0)
+                       if(nodemgr->get(n2).light_propagates && n2.getLight(bank, nodemgr) != 0)
                        {
                                /*
                                        Set light to 0 and add to queue
                                */
 
-                               u8 current_light = n2.getLight(bank);
-                               n2.setLight(bank, 0);
+                               u8 current_light = n2.getLight(bank, nodemgr);
+                               n2.setLight(bank, 0, nodemgr);
                                
-                               unspreadLight(bank, n2pos, current_light, light_sources);
+                               unspreadLight(bank, n2pos, current_light, light_sources, nodemgr);
                                
                                /*
                                        Remove from light_sources if it is there
@@ -362,7 +363,7 @@ void VoxelManipulator::unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
 */
 void VoxelManipulator::unspreadLight(enum LightBank bank,
                core::map<v3s16, u8> & from_nodes,
-               core::map<v3s16, bool> & light_sources)
+               core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr)
 {
        if(from_nodes.size() == 0)
                return;
@@ -378,7 +379,7 @@ void VoxelManipulator::unspreadLight(enum LightBank bank,
                
                u8 oldlight = j.getNode()->getValue();
 
-               unspreadLight(bank, pos, oldlight, light_sources);
+               unspreadLight(bank, pos, oldlight, light_sources, nodemgr);
        }
 }
 #endif
@@ -448,18 +449,18 @@ void VoxelManipulator::unspreadLight(enum LightBank bank,
                                If the neighbor is dimmer than what was specified
                                as oldlight (the light of the previous node)
                        */
-                       if(n2.getLight(bank) < oldlight)
+                       if(n2.getLight(bank, nodemgr) < oldlight)
                        {
                                /*
                                        And the neighbor is transparent and it has some light
                                */
-                               if(n2.light_propagates() && n2.getLight(bank) != 0)
+                               if(nodemgr->get(n2).light_propagates && n2.getLight(bank, nodemgr) != 0)
                                {
                                        /*
                                                Set light to 0 and add to queue
                                        */
 
-                                       u8 current_light = n2.getLight(bank);
+                                       u8 current_light = n2.getLight(bank, nodemgr);
                                        n2.setLight(bank, 0);
 
                                        unlighted_nodes.insert(n2pos, current_light);
@@ -491,7 +492,8 @@ void VoxelManipulator::unspreadLight(enum LightBank bank,
 }
 #endif
 
-void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p)
+void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p,
+               INodeDefManager *nodemgr)
 {
        const v3s16 dirs[6] = {
                v3s16(0,0,1), // back
@@ -511,7 +513,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p)
 
        MapNode &n = m_data[i];
 
-       u8 oldlight = n.getLight(bank);
+       u8 oldlight = n.getLight(bank, nodemgr);
        u8 newlight = diminish_light(oldlight);
 
        // Loop through 6 neighbors
@@ -531,20 +533,20 @@ void VoxelManipulator::spreadLight(enum LightBank bank, v3s16 p)
                        If the neighbor is brighter than the current node,
                        add to list (it will light up this node on its turn)
                */
-               if(n2.getLight(bank) > undiminish_light(oldlight))
+               if(n2.getLight(bank, nodemgr) > undiminish_light(oldlight))
                {
-                       spreadLight(bank, n2pos);
+                       spreadLight(bank, n2pos, nodemgr);
                }
                /*
                        If the neighbor is dimmer than how much light this node
                        would spread on it, add to list
                */
-               if(n2.getLight(bank) < newlight)
+               if(n2.getLight(bank, nodemgr) < newlight)
                {
-                       if(n2.light_propagates())
+                       if(nodemgr->get(n2).light_propagates)
                        {
-                               n2.setLight(bank, newlight);
-                               spreadLight(bank, n2pos);
+                               n2.setLight(bank, newlight, nodemgr);
+                               spreadLight(bank, n2pos, nodemgr);
                        }
                }
        }
@@ -583,7 +585,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
        goes on recursively.
 */
 void VoxelManipulator::spreadLight(enum LightBank bank,
-               core::map<v3s16, bool> & from_nodes)
+               core::map<v3s16, bool> & from_nodes, INodeDefManager *nodemgr)
 {
        const v3s16 dirs[6] = {
                v3s16(0,0,1), // back
@@ -614,7 +616,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
 
                MapNode &n = m_data[i];
 
-               u8 oldlight = n.getLight(bank);
+               u8 oldlight = n.getLight(bank, nodemgr);
                u8 newlight = diminish_light(oldlight);
 
                // Loop through 6 neighbors
@@ -636,7 +638,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
                                        If the neighbor is brighter than the current node,
                                        add to list (it will light up this node on its turn)
                                */
-                               if(n2.getLight(bank) > undiminish_light(oldlight))
+                               if(n2.getLight(bank, nodemgr) > undiminish_light(oldlight))
                                {
                                        lighted_nodes.insert(n2pos, true);
                                }
@@ -644,11 +646,11 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
                                        If the neighbor is dimmer than how much light this node
                                        would spread on it, add to list
                                */
-                               if(n2.getLight(bank) < newlight)
+                               if(n2.getLight(bank, nodemgr) < newlight)
                                {
-                                       if(n2.light_propagates())
+                                       if(nodemgr->get(n2).light_propagates)
                                        {
-                                               n2.setLight(bank, newlight);
+                                               n2.setLight(bank, newlight, nodemgr);
                                                lighted_nodes.insert(n2pos, true);
                                        }
                                }
@@ -666,7 +668,7 @@ void VoxelManipulator::spreadLight(enum LightBank bank,
                        <<std::endl;*/
        
        if(lighted_nodes.size() > 0)
-               spreadLight(bank, lighted_nodes);
+               spreadLight(bank, lighted_nodes, nodemgr);
 }
 #endif
 
index 51df18299af620401c58f09e6a466ef32c278e99..46864e06e83a81318648d60c709588d3fdc7038f 100644 (file)
@@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "debug.h"
 #include "mapnode.h"
 
+class INodeDefManager;
+
 // For VC++
 #undef min
 #undef max
@@ -475,7 +477,8 @@ public:
 
        virtual void clear();
 
-       void print(std::ostream &o, VoxelPrintMode mode=VOXELPRINT_MATERIAL);
+       void print(std::ostream &o, INodeDefManager *nodemgr,
+                       VoxelPrintMode mode=VOXELPRINT_MATERIAL);
        
        void addArea(VoxelArea area);
 
@@ -497,14 +500,14 @@ public:
        void clearFlag(u8 flag);
        
        void unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight,
-                       core::map<v3s16, bool> & light_sources);
+                       core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr);
        void unspreadLight(enum LightBank bank,
                        core::map<v3s16, u8> & from_nodes,
-                       core::map<v3s16, bool> & light_sources);
+                       core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr);
        
-       void spreadLight(enum LightBank bank, v3s16 p);
+       void spreadLight(enum LightBank bank, v3s16 p, INodeDefManager *nodemgr);
        void spreadLight(enum LightBank bank,
-                       core::map<v3s16, bool> & from_nodes);
+                       core::map<v3s16, bool> & from_nodes, INodeDefManager *nodemgr);
        
        /*
                Virtual functions