]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/map.cpp
(hopefully) fixed stoi/stof compile problems on vc2010
[dragonfireclient.git] / src / map.cpp
index 82317aec5a02281b7691206598dbf4c091c4eba8..63f01ddee0de773018e2d02481467b4eb0874a97 100644 (file)
@@ -1,6 +1,6 @@
 /*
 Minetest-c55
-Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+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
@@ -37,8 +37,8 @@ Map::Map(std::ostream &dout):
        m_dout(dout),
        m_sector_cache(NULL)
 {
-       m_sector_mutex.Init();
-       assert(m_sector_mutex.IsInitialized());
+       /*m_sector_mutex.Init();
+       assert(m_sector_mutex.IsInitialized());*/
 }
 
 Map::~Map()
@@ -104,7 +104,7 @@ MapSector * Map::getSectorNoGenerateNoExNoLock(v2s16 p)
 
 MapSector * Map::getSectorNoGenerateNoEx(v2s16 p)
 {
-       JMutexAutoLock lock(m_sector_mutex);
+       //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
 
        return getSectorNoGenerateNoExNoLock(p);
 }
@@ -1347,7 +1347,7 @@ bool Map::dayNightDiffed(v3s16 blockpos)
 */
 void Map::timerUpdate(float dtime)
 {
-       JMutexAutoLock lock(m_sector_mutex);
+       //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
 
        core::map<v2s16, MapSector*>::Iterator si;
 
@@ -1397,7 +1397,7 @@ void Map::deleteSectors(core::list<v2s16> &list, bool only_blocks)
 u32 Map::deleteUnusedSectors(float timeout, bool only_blocks,
                core::list<v3s16> *deleted_blocks)
 {
-       JMutexAutoLock lock(m_sector_mutex);
+       //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
 
        core::list<v2s16> sector_deletion_queue;
        core::map<v2s16, MapSector*>::Iterator i = m_sectors.getIterator();
@@ -1792,8 +1792,10 @@ void Map::nodeMetadataStep(float dtime,
 
 ServerMap::ServerMap(std::string savedir):
        Map(dout_server),
-       m_seed(0)
+       m_seed(0),
+       m_map_metadata_changed(true)
 {
+       dstream<<__FUNCTION_NAME<<std::endl;
        
        //m_chunksize = 64;
        //m_chunksize = 16; // Too slow
@@ -1891,6 +1893,8 @@ ServerMap::ServerMap(std::string savedir):
 
 ServerMap::~ServerMap()
 {
+       dstream<<__FUNCTION_NAME<<std::endl;
+       
        try
        {
                if(m_map_saving_enabled)
@@ -2064,7 +2068,7 @@ double base_rock_level_2d(u64 seed, v2s16 p)
 {
        // The base ground level
        double base = (double)WATER_LEVEL - (double)AVERAGE_MUD_AMOUNT
-                       + 25. * noise2d_perlin(
+                       + 20. * noise2d_perlin(
                        0.5+(float)p.X/500., 0.5+(float)p.Y/500.,
                        (seed>>32)+654879876, 6, 0.6);
        
@@ -2076,7 +2080,7 @@ double base_rock_level_2d(u64 seed, v2s16 p)
                base = base2;*/
 #if 1
        // Higher ground level
-       double higher = (double)WATER_LEVEL + 25. + 45. * noise2d_perlin(
+       double higher = (double)WATER_LEVEL + 25. + 35. * noise2d_perlin(
                        0.5+(float)p.X/250., 0.5+(float)p.Y/250.,
                        seed+85039, 5, 0.69);
        //higher = 30; // For debugging
@@ -2117,6 +2121,13 @@ double base_rock_level_2d(u64 seed, v2s16 p)
        return h;
 }
 
+double get_mud_add_amount(u64 seed, v2s16 p)
+{
+       return ((float)AVERAGE_MUD_AMOUNT + 3.0 * noise2d_perlin(
+                       0.5+(float)p.X/200, 0.5+(float)p.Y/200,
+                       seed+91013, 3, 0.55));
+}
+
 /*
        Adds random objects to block, depending on the content of the block
 */
@@ -2163,6 +2174,18 @@ void addRandomObjects(MapBlock *block)
                                                        block->m_static_objects.insert(0, s_obj);
                                                        delete obj;
                                                }
+                                               if(myrand() % 300 == 0)
+                                               {
+                                                       v3f pos_f = intToFloat(p+block->getPosRelative(), BS);
+                                                       pos_f.Y -= BS*0.4;
+                                                       ServerActiveObject *obj = new Oerkki1SAO(NULL,0,pos_f);
+                                                       std::string data = obj->getStaticData();
+                                                       StaticObject s_obj(obj->getType(),
+                                                                       obj->getBasePosition(), data);
+                                                       // Add one
+                                                       block->m_static_objects.insert(0, s_obj);
+                                                       delete obj;
+                                               }
                                        }
                                }
                        }
@@ -2215,11 +2238,99 @@ void makeChunk(ChunkMakeData *data)
        /*
                Generate general ground level to full area
        */
-       
        {
        // 22ms @cs=8
-       //TimeTaker timer1("ground level");
+       TimeTaker timer1("Generating ground level");
+
+#if 0
+       NoiseBuffer noisebuf1;
+       //NoiseBuffer noisebuf2;
+       {
+               v3f minpos_f(
+                       data->sectorpos_bigbase.X*MAP_BLOCKSIZE,
+                       y_nodes_min,
+                       data->sectorpos_bigbase.Y*MAP_BLOCKSIZE
+               );
+               v3f maxpos_f = minpos_f + v3f(
+                       data->sectorpos_bigbase_size*MAP_BLOCKSIZE,
+                       y_nodes_max-y_nodes_min,
+                       data->sectorpos_bigbase_size*MAP_BLOCKSIZE
+               );
+               v3f samplelength_f = v3f(4.0, 4.0, 4.0);
+
+               TimeTaker timer("noisebuf.create");
+               
+               noisebuf1.create(data->seed+25104, 6, 0.60, 200.0,
+                               minpos_f.X, minpos_f.Y, minpos_f.Z,
+                               maxpos_f.X, maxpos_f.Y, maxpos_f.Z,
+                               samplelength_f.X, samplelength_f.Y, samplelength_f.Z);
+               /*noisebuf1.create(data->seed+25104, 3, 0.60, 25.0,
+                               minpos_f.X, minpos_f.Y, minpos_f.Z,
+                               maxpos_f.X, maxpos_f.Y, maxpos_f.Z,
+                               samplelength_f.X, samplelength_f.Y, samplelength_f.Z);
+               noisebuf2.create(data->seed+25105, 4, 0.50, 200.0,
+                               minpos_f.X, minpos_f.Y, minpos_f.Z,
+                               maxpos_f.X, maxpos_f.Y, maxpos_f.Z,
+                               samplelength_f.X, samplelength_f.Y, samplelength_f.Z);*/
+       }
 
+       for(s16 x=0; x<data->sectorpos_bigbase_size*MAP_BLOCKSIZE; x++)
+       for(s16 z=0; z<data->sectorpos_bigbase_size*MAP_BLOCKSIZE; z++)
+       {
+               // Node position
+               v2s16 p2d = data->sectorpos_bigbase*MAP_BLOCKSIZE + v2s16(x,z);
+               
+               // Ground height at this point
+               float surface_y_f = 0.0;
+
+               // Use perlin noise for ground height
+               surface_y_f = base_rock_level_2d(data->seed, p2d);
+               //surface_y_f = base_rock_level_2d(data->seed, p2d);
+               
+               // Convert to integer
+               s16 surface_y = (s16)surface_y_f;
+               
+               // Log it
+               if(surface_y > stone_surface_max_y)
+                       stone_surface_max_y = surface_y;
+
+               /*
+                       Fill ground with stone
+               */
+               {
+                       // Use fast index incrementing
+                       v3s16 em = data->vmanip.m_area.getExtent();
+                       u32 i = data->vmanip.m_area.index(v3s16(p2d.X, y_nodes_min, p2d.Y));
+                       for(s16 y=y_nodes_min; y<=y_nodes_max; y++)
+                       {
+                               // Skip if already generated.
+                               // This is done here because there might be a cave at
+                               // any point in ground, which could look like it
+                               // wasn't generated.
+                               if(data->vmanip.m_data[i].d != CONTENT_AIR)
+                                       break;
+
+                               /*s16 noiseval = 50.0 * noise3d_perlin(
+                                               0.5+(float)p2d.X/100.0,
+                                               0.5+(float)y/100.0,
+                                               0.5+(float)p2d.Y/100.0,
+                                               data->seed+123, 5, 0.5);*/
+                               double noiseval = 64.0 * noisebuf1.get(p2d.X, y, p2d.Y);
+                               /*double noiseval = 30.0 * noisebuf1.get(p2d.X, y, p2d.Y);
+                               noiseval *= MYMAX(0, -0.2 + noisebuf2.get(p2d.X, y, p2d.Y));*/
+                               
+                               //if(y < surface_y + noiseval)
+                               if(noiseval > 0)
+                               //if(noiseval > y)
+                                       data->vmanip.m_data[i].d = CONTENT_STONE;
+
+                               data->vmanip.m_area.add_y(em, i, 1);
+                       }
+               }
+       }
+#endif
+       
+#if 1
        for(s16 x=0; x<data->sectorpos_bigbase_size*MAP_BLOCKSIZE; x++)
        for(s16 z=0; z<data->sectorpos_bigbase_size*MAP_BLOCKSIZE; z++)
        {
@@ -2277,6 +2388,7 @@ void makeChunk(ChunkMakeData *data)
                        }
                }
        }
+#endif
        
        }//timer1
 
@@ -2297,13 +2409,14 @@ void makeChunk(ChunkMakeData *data)
        /*
                Loop this part, it will make stuff look older and newer nicely
        */
-       //for(u32 i_age=0; i_age<1; i_age++)
-       for(u32 i_age=0; i_age<2; i_age++)
+       const u32 age_loops = 2;
+       for(u32 i_age=0; i_age<age_loops; i_age++)
        { // Aging loop
        /******************************
                BEGINNING OF AGING LOOP
        ******************************/
 
+#if 1
        {
        // 24ms @cs=8
        //TimeTaker timer1("caves");
@@ -2542,6 +2655,9 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
+
+#if 1
        {
        // 46ms @cs=8
        //TimeTaker timer1("ore veins");
@@ -2675,9 +2791,12 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
+
+#if 1
        {
        // 15ms @cs=8
-       //TimeTaker timer1("add mud");
+       TimeTaker timer1("add mud");
 
        /*
                Add mud to the central chunk
@@ -2690,9 +2809,7 @@ void makeChunk(ChunkMakeData *data)
                v2s16 p2d = data->sectorpos_base*MAP_BLOCKSIZE + v2s16(x,z);
                
                // Randomize mud amount
-               s16 mud_add_amount = (s16)(2.5 + 2.0 * noise2d_perlin(
-                               0.5+(float)p2d.X/200, 0.5+(float)p2d.Y/200,
-                               data->seed+1, 3, 0.55));
+               s16 mud_add_amount = get_mud_add_amount(data->seed, p2d) / 2.0;
 
                // Find ground level
                s16 surface_y = find_ground_level_clever(data->vmanip, p2d);
@@ -2706,7 +2823,8 @@ void makeChunk(ChunkMakeData *data)
                        u32 i = data->vmanip.m_area.index(v3s16(p2d.X, surface_y, p2d.Y));
                        MapNode *n = &data->vmanip.m_data[i];
                        if(n->d == CONTENT_GRASS)
-                               n->d = CONTENT_MUD;
+                               *n = MapNode(CONTENT_MUD);
+                               //n->d = CONTENT_MUD;
                }
 
                /*
@@ -2723,7 +2841,8 @@ void makeChunk(ChunkMakeData *data)
                                        break;
                                        
                                MapNode &n = data->vmanip.m_data[i];
-                               n.d = CONTENT_MUD;
+                               n = MapNode(CONTENT_MUD);
+                               //n.d = CONTENT_MUD;
                                mudcount++;
 
                                data->vmanip.m_area.add_y(em, i, 1);
@@ -2733,6 +2852,9 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
+
+#if 1
        {
        // 340ms @cs=8
        TimeTaker timer1("flow mud");
@@ -2887,9 +3009,12 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
+
+#if 1
        {
        // 50ms @cs=8
-       //TimeTaker timer1("add water");
+       TimeTaker timer1("add water");
 
        /*
                Add water to the central chunk (and a bit more)
@@ -2962,12 +3087,14 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
        
        } // Aging loop
        /***********************
                END OF AGING LOOP
        ************************/
 
+#if 1
        {
        //TimeTaker timer1("convert mud to sand");
 
@@ -3032,6 +3159,9 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
+
+#if 1
        {
        // 1ms @cs=8
        //TimeTaker timer1("generate trees");
@@ -3110,7 +3240,9 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
 
+#if 1
        {
        // 19ms @cs=8
        //TimeTaker timer1("grow grass");
@@ -3164,6 +3296,7 @@ void makeChunk(ChunkMakeData *data)
        }
 
        }//timer1
+#endif
 
        /*
                Initial lighting (sunlight)
@@ -3175,6 +3308,7 @@ void makeChunk(ChunkMakeData *data)
        // 750ms @cs=8, can't optimize more
        TimeTaker timer1("initial lighting");
 
+       // NOTE: This is no used... umm... for some reason!
 #if 0
        /*
                Go through the edges and add all nodes that have light to light_sources
@@ -3696,7 +3830,7 @@ MapChunk* ServerMap::generateChunk(v2s16 chunkpos1,
 
 ServerMapSector * ServerMap::createSector(v2s16 p2d)
 {
-       DSTACK("%s: p2d=(%d,%d)",
+       DSTACKF("%s: p2d=(%d,%d)",
                        __FUNCTION_NAME,
                        p2d.X, p2d.Y);
        
@@ -3848,7 +3982,7 @@ MapBlock * ServerMap::generateBlock(
                core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
 )
 {
-       DSTACK("%s: p=(%d,%d,%d)",
+       DSTACKF("%s: p=(%d,%d,%d)",
                        __FUNCTION_NAME,
                        p.X, p.Y, p.Z);
 
@@ -3897,6 +4031,25 @@ MapBlock * ServerMap::generateBlock(
                block->unDummify();
        }
        
+#if 0
+       /*
+               Generate a completely empty block
+       */
+       for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
+       for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
+       {
+               for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
+               {
+                       MapNode n;
+                       n.d = CONTENT_AIR;
+                       block->setNode(v3s16(x0,y0,z0), n);
+               }
+       }
+#else
+       /*
+               Generate a proper block
+       */
+       
        u8 water_material = CONTENT_WATERSOURCE;
        
        s32 lowest_ground_y = 32767;
@@ -3909,8 +4062,10 @@ MapBlock * ServerMap::generateBlock(
 
                //s16 surface_y = 0;
 
+               s16 mud_add_amount = get_mud_add_amount(m_seed, p2d_nodes+v2s16(x0,z0));
+
                s16 surface_y = base_rock_level_2d(m_seed, p2d_nodes+v2s16(x0,z0))
-                               + AVERAGE_MUD_AMOUNT;
+                               + mud_add_amount;
                // If chunks are disabled
                if(m_chunksize == 0)
                        surface_y = WATER_LEVEL + 1;
@@ -4431,6 +4586,8 @@ MapBlock * ServerMap::generateBlock(
                        }
                }
        }
+
+#endif // end of proper block generation
        
        /*
                Add block to sector.
@@ -4461,7 +4618,7 @@ MapBlock * ServerMap::generateBlock(
 
 MapBlock * ServerMap::createBlock(v3s16 p)
 {
-       DSTACK("%s: p=(%d,%d,%d)",
+       DSTACKF("%s: p=(%d,%d,%d)",
                        __FUNCTION_NAME, p.X, p.Y, p.Z);
        
        /*
@@ -4525,7 +4682,7 @@ MapBlock * ServerMap::emergeBlock(
                core::map<v3s16, MapBlock*> &lighting_invalidated_blocks
 )
 {
-       DSTACK("%s: p=(%d,%d,%d), only_from_disk=%d",
+       DSTACKF("%s: p=(%d,%d,%d), only_from_disk=%d",
                        __FUNCTION_NAME,
                        p.X, p.Y, p.Z, only_from_disk);
        
@@ -4711,7 +4868,10 @@ s16 ServerMap::findGroundLevel(v2s16 p2d)
        /*
                Plan B: Get from map generator perlin noise function
        */
-       double level = base_rock_level_2d(m_seed, p2d);
+       // This won't work if proper generation is disabled
+       if(m_chunksize == 0)
+               return WATER_LEVEL+2;
+       double level = base_rock_level_2d(m_seed, p2d) + AVERAGE_MUD_AMOUNT;
        return (s16)level;
 }
 
@@ -4779,19 +4939,23 @@ void ServerMap::save(bool only_changed)
                dstream<<DTIME<<"ServerMap: Saving whole map, this can take time."
                                <<std::endl;
        
-       saveMapMeta();
+       if(only_changed == false || m_map_metadata_changed)
+       {
+               saveMapMeta();
+       }
 
-       // Disable saving chunk metadata file if chunks are disabled
+       // Disable saving chunk metadata if chunks are disabled
        if(m_chunksize != 0)
        {
-               saveChunkMeta();
+               if(only_changed == false || anyChunkModified())
+                       saveChunkMeta();
        }
        
        u32 sector_meta_count = 0;
        u32 block_count = 0;
        
        { //sectorlock
-       JMutexAutoLock lock(m_sector_mutex);
+       //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
        
        core::map<v2s16, MapSector*>::Iterator i = m_sectors.getIterator();
        for(; i.atEnd() == false; i++)
@@ -4853,7 +5017,7 @@ void ServerMap::loadAll()
 
        dstream<<DTIME<<"There are "<<list.size()<<" sectors."<<std::endl;
        
-       JMutexAutoLock lock(m_sector_mutex);
+       //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
        
        s32 counter = 0;
        s32 printed_counter = -100000;
@@ -4961,6 +5125,7 @@ void ServerMap::saveMapMeta()
 
        os<<"[end_of_params]\n";
        
+       m_map_metadata_changed = false;
 }
 
 void ServerMap::loadMapMeta()
@@ -5048,6 +5213,8 @@ void ServerMap::saveChunkMeta()
                // Write chunk data
                chunk->serialize(os, version);
        }
+
+       setChunksNonModified();
 }
 
 void ServerMap::loadChunkMeta()
@@ -5160,7 +5327,7 @@ bool ServerMap::loadSectorFull(v2s16 p2d)
 
        MapSector *sector = NULL;
 
-       JMutexAutoLock lock(m_sector_mutex);
+       //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
 
        try{
                sector = loadSectorMeta(sectorsubdir);
@@ -5407,7 +5574,7 @@ MapSector * ClientMap::emergeSector(v2s16 p2d)
        ClientMapSector *sector = new ClientMapSector(this, p2d);
        
        {
-               JMutexAutoLock lock(m_sector_mutex);
+               //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
                m_sectors.insert(p2d, sector);
        }
        
@@ -5419,7 +5586,7 @@ void ClientMap::deSerializeSector(v2s16 p2d, std::istream &is)
        DSTACK(__FUNCTION_NAME);
        ClientMapSector *sector = NULL;
 
-       JMutexAutoLock lock(m_sector_mutex);
+       //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
        
        core::map<v2s16, MapSector*>::Node *n = m_sectors.find(p2d);
 
@@ -5432,7 +5599,7 @@ void ClientMap::deSerializeSector(v2s16 p2d, std::istream &is)
        {
                sector = new ClientMapSector(this, p2d);
                {
-                       JMutexAutoLock lock(m_sector_mutex);
+                       //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
                        m_sectors.insert(p2d, sector);
                }
        }