better support for old maps
authorPerttu Ahola <celeron55@gmail.com>
Sun, 10 Apr 2011 19:50:31 +0000 (22:50 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 10 Apr 2011 19:50:31 +0000 (22:50 +0300)
src/map.cpp
src/map.h
src/server.cpp
src/serverobject.cpp
src/serverobject.h
src/utility.h

index c258d157b79ba3115e6eb6e403cc83fdcf589f78..7fe58dc115f9b240bcd9e780343f5194faa6c76b 100644 (file)
@@ -1801,7 +1801,6 @@ ServerMap::ServerMap(std::string savedir):
        //m_chunksize = 4;
        //m_chunksize = 2;
        
-       // TODO: Save to and load from a file
        m_seed = (((u64)(myrand()%0xffff)<<0)
                        + ((u64)(myrand()%0xffff)<<16)
                        + ((u64)(myrand()%0xffff)<<32)
@@ -1838,8 +1837,16 @@ ServerMap::ServerMap(std::string savedir):
                                // Load map metadata (seed, chunksize)
                                loadMapMeta();
                                
-                               // Load chunk metadata
-                               loadChunkMeta();
+                               try{
+                                       // Load chunk metadata
+                                       loadChunkMeta();
+                               }
+                               catch(FileNotGoodException &e){
+                                       dstream<<DTIME<<"WARNING: Server: Could not load "
+                                                       <<"chunk metafile. Disabling chunk-based "
+                                                       <<"generation."<<std::endl;
+                                       m_chunksize = 0;
+                               }
                        
                                /*// Load sector (0,0) and throw and exception on fail
                                if(loadSectorFull(v2s16(0,0)) == false)
@@ -2173,6 +2180,9 @@ void addRandomObjects(MapBlock *block)
 
 void makeChunk(ChunkMakeData *data)
 {
+       if(data->no_op)
+               return;
+       
        s16 y_nodes_min = data->y_blocks_min * MAP_BLOCKSIZE;
        s16 y_nodes_max = data->y_blocks_max * MAP_BLOCKSIZE + MAP_BLOCKSIZE - 1;
        s16 h_blocks = data->y_blocks_max - data->y_blocks_min + 1;
@@ -2938,8 +2948,8 @@ void makeChunk(ChunkMakeData *data)
 
                                        // Add to transforming liquid queue (in case it'd
                                        // start flowing)
-                                       /*v3s16 p = v3s16(p2d.X, y, p2d.Y);
-                                       m_transforming_liquid.push_back(p);*/
+                                       v3s16 p = v3s16(p2d.X, y, p2d.Y);
+                                       data->transforming_liquid.push_back(p);
                                }
                                
                                // Next one
@@ -3419,6 +3429,14 @@ void makeChunk(ChunkMakeData *data)
 
 void ServerMap::initChunkMake(ChunkMakeData &data, v2s16 chunkpos)
 {
+       if(m_chunksize == 0)
+       {
+               data.no_op = true;
+               return;
+       }
+
+       data.no_op = false;
+
        // The distance how far into the neighbors the generator is allowed to go.
        s16 max_spread_amount_sectors = 2;
        assert(max_spread_amount_sectors <= m_chunksize);
@@ -3449,7 +3467,7 @@ void ServerMap::initChunkMake(ChunkMakeData &data, v2s16 chunkpos)
                Create the whole area of this and the neighboring chunks
        */
        {
-               TimeTaker timer("generateChunkRaw() create area");
+               TimeTaker timer("initChunkMake() create area");
                
                for(s16 x=0; x<sectorpos_bigbase_size; x++)
                for(s16 z=0; z<sectorpos_bigbase_size; z++)
@@ -3503,7 +3521,7 @@ void ServerMap::initChunkMake(ChunkMakeData &data, v2s16 chunkpos)
        data.vmanip.setMap(this);
        // Add the area
        {
-               TimeTaker timer("generateChunkRaw() initialEmerge");
+               TimeTaker timer("initChunkMake() initialEmerge");
                data.vmanip.initialEmerge(bigarea_blocks_min, bigarea_blocks_max);
        }
        
@@ -3512,6 +3530,9 @@ void ServerMap::initChunkMake(ChunkMakeData &data, v2s16 chunkpos)
 MapChunk* ServerMap::finishChunkMake(ChunkMakeData &data,
                core::map<v3s16, MapBlock*> &changed_blocks)
 {
+       if(data.no_op)
+               return NULL;
+       
        /*
                Blit generated stuff to map
        */
@@ -3533,6 +3554,15 @@ MapChunk* ServerMap::finishChunkMake(ChunkMakeData &data,
                }
        }
 
+       /*
+               Copy transforming liquid information
+       */
+       while(data.transforming_liquid.size() > 0)
+       {
+               v3s16 p = data.transforming_liquid.pop_front();
+               m_transforming_liquid.push_back(p);
+       }
+
        /*
                Add random objects to blocks
        */
@@ -3590,6 +3620,7 @@ MapChunk* ServerMap::finishChunkMake(ChunkMakeData &data,
        return chunk;
 }
 
+#if 0
 // NOTE: Deprecated
 MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
                core::map<v3s16, MapBlock*> &changed_blocks,
@@ -3661,6 +3692,7 @@ MapChunk* ServerMap::generateChunk(v2s16 chunkpos1,
        MapChunk *chunk = getChunk(chunkpos1);
        return chunk;
 }
+#endif
 
 ServerMapSector * ServerMap::createSector(v2s16 p2d)
 {
@@ -3715,6 +3747,7 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d)
        return sector;
 }
 
+#if 0
 MapSector * ServerMap::emergeSector(v2s16 p2d,
                core::map<v3s16, MapBlock*> &changed_blocks)
 {
@@ -3801,6 +3834,7 @@ MapSector * ServerMap::emergeSector(v2s16 p2d,
        */
        //return generateSector();
 }
+#endif
 
 /*
        NOTE: This is not used for main map generation, only for blocks
@@ -3817,6 +3851,14 @@ MapBlock * ServerMap::generateBlock(
        DSTACK("%s: p=(%d,%d,%d)",
                        __FUNCTION_NAME,
                        p.X, p.Y, p.Z);
+
+       // If chunks are disabled
+       /*if(m_chunksize == 0)
+       {
+               dstream<<"ServerMap::generateBlock(): Chunks disabled -> "
+                               <<"not generating."<<std::endl;
+               return NULL;
+       }*/
        
        /*dstream<<"generateBlock(): "
                        <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
@@ -3869,6 +3911,9 @@ MapBlock * ServerMap::generateBlock(
 
                s16 surface_y = base_rock_level_2d(m_seed, p2d_nodes+v2s16(x0,z0))
                                + AVERAGE_MUD_AMOUNT;
+               // If chunks are disabled
+               if(m_chunksize == 0)
+                       surface_y = WATER_LEVEL + 1;
 
                if(surface_y < lowest_ground_y)
                        lowest_ground_y = surface_y;
@@ -4735,7 +4780,12 @@ void ServerMap::save(bool only_changed)
                                <<std::endl;
        
        saveMapMeta();
-       saveChunkMeta();
+
+       // Disable saving chunk metadata file if chunks are disabled
+       if(m_chunksize != 0)
+       {
+               saveChunkMeta();
+       }
        
        u32 sector_meta_count = 0;
        u32 block_count = 0;
@@ -4789,6 +4839,8 @@ void ServerMap::save(bool only_changed)
        }
 }
 
+#if 0
+// NOTE: Doing this is insane. Deprecated and probably broken.
 void ServerMap::loadAll()
 {
        DSTACK(__FUNCTION_NAME);
@@ -4849,6 +4901,7 @@ void ServerMap::loadAll()
        }
        dstream<<DTIME<<"ServerMap: Map loaded."<<std::endl;
 }
+#endif
 
 #if 0
 void ServerMap::saveMasterHeightmap()
@@ -4952,6 +5005,9 @@ void ServerMap::loadMapMeta()
 void ServerMap::saveChunkMeta()
 {
        DSTACK(__FUNCTION_NAME);
+
+       // This should not be called if chunks are disabled.
+       assert(m_chunksize != 0);
        
        u32 count = m_chunks.size();
 
index e2cd432be381f9a604af70f9f2ab4549d077d25e..cb48cb32b65184616cb13d69f44c1975976dfdb7 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -341,6 +341,8 @@ public:
        // Returns the position of the chunk where the sector is in
        v2s16 sector_to_chunk(v2s16 sectorpos)
        {
+               if(m_chunksize == 0)
+                       return v2s16(0,0);
                sectorpos.X += m_chunksize / 2;
                sectorpos.Y += m_chunksize / 2;
                v2s16 chunkpos = getContainerPos(sectorpos, m_chunksize);
@@ -350,6 +352,8 @@ public:
        // Returns the position of the (0,0) sector of the chunk
        v2s16 chunk_to_sector(v2s16 chunkpos)
        {
+               if(m_chunksize == 0)
+                       return v2s16(0,0);
                v2s16 sectorpos(
                        chunkpos.X * m_chunksize,
                        chunkpos.Y * m_chunksize
@@ -378,6 +382,9 @@ public:
        */
        bool chunkNonVolatile(v2s16 chunkpos)
        {
+               if(m_chunksize == 0)
+                       return true;
+               
                /*for(s16 x=-1; x<=1; x++)
                for(s16 y=-1; y<=1; y++)*/
                s16 x=0;
@@ -393,6 +400,9 @@ public:
                return true;
        }
 
+       /*
+               Chunks are generated by using these and makeChunk().
+       */
        void initChunkMake(ChunkMakeData &data, v2s16 chunkpos);
        MapChunk* finishChunkMake(ChunkMakeData &data,
                        core::map<v3s16, MapBlock*> &changed_blocks);
@@ -402,16 +412,16 @@ public:
 
                All chunks touching this one can be altered also.
        */
-       MapChunk* generateChunkRaw(v2s16 chunkpos,
+       /*MapChunk* generateChunkRaw(v2s16 chunkpos,
                        core::map<v3s16, MapBlock*> &changed_blocks,
-                       bool force=false);
+                       bool force=false);*/
        
        /*
                Generate a chunk and its neighbors so that it won't be touched
                anymore.
        */
-       MapChunk* generateChunk(v2s16 chunkpos,
-                       core::map<v3s16, MapBlock*> &changed_blocks);
+       /*MapChunk* generateChunk(v2s16 chunkpos,
+                       core::map<v3s16, MapBlock*> &changed_blocks);*/
        
        /*
                Generate a sector.
@@ -434,14 +444,14 @@ public:
                - Check disk (loads blocks also)
                - Generate chunk
        */
-       MapSector * emergeSector(v2s16 p,
-                       core::map<v3s16, MapBlock*> &changed_blocks);
+       /*MapSector * emergeSector(v2s16 p,
+                       core::map<v3s16, MapBlock*> &changed_blocks);*/
        
-       MapSector * emergeSector(v2s16 p)
+       /*MapSector * emergeSector(v2s16 p)
        {
                core::map<v3s16, MapBlock*> changed_blocks;
                return emergeSector(p, changed_blocks);
-       }
+       }*/
 
        MapBlock * generateBlock(
                        v3s16 p,
@@ -516,7 +526,7 @@ public:
        v3s16 getBlockPos(std::string sectordir, std::string blockfile);
 
        void save(bool only_changed);
-       void loadAll();
+       //void loadAll();
        
        // Saves map seed and possibly other stuff
        void saveMapMeta();
@@ -557,6 +567,7 @@ private:
        bool m_map_saving_enabled;
 
        // Chunk size in MapSectors
+       // If 0, chunks are disabled.
        s16 m_chunksize;
        // Chunks
        core::map<v2s16, MapChunk*> m_chunks;
@@ -754,6 +765,7 @@ protected:
 
 struct ChunkMakeData
 {
+       bool no_op;
        ManualMapVoxelManipulator vmanip;
        u64 seed;
        v2s16 chunkpos;
@@ -764,8 +776,10 @@ struct ChunkMakeData
        v2s16 sectorpos_bigbase;
        s16 sectorpos_bigbase_size;
        s16 max_spread_amount;
+       UniqueQueue<v3s16> transforming_liquid;
 
        ChunkMakeData():
+               no_op(false),
                vmanip(NULL)
        {}
 };
index 63d8e31db786c809e14bc5323217f4ef93edbcd8..925b2e0d76c430a1086f74159eb54a2587608b3a 100644 (file)
@@ -201,10 +201,20 @@ void * EmergeThread::Thread()
                                }
                                else
                                {
+                                       // Get, load or create sector
                                        ServerMapSector *sector =
-                                                       (ServerMapSector*)map.getSectorNoGenerateNoEx(p2d);
+                                                       (ServerMapSector*)map.createSector(p2d);
+                                       // Generate block
                                        block = map.generateBlock(p, block, sector, changed_blocks,
                                                        lighting_invalidated_blocks);
+                                       if(block == NULL)
+                                               got_block = false;
+                               }
+                       }
+                       else
+                       {
+                               if(block->getLightingExpired()){
+                                       lighting_invalidated_blocks[block->getPos()] = block;
                                }
                        }
 
index a58ca524db538bde457877b1367422960ec92e74..b6015a4775d5cb692cb78f7618f72595e6d30415 100644 (file)
@@ -170,6 +170,12 @@ void ItemSAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
                bool send_recommended)
 {
        assert(m_env);
+
+       const float interval = 0.2;
+       if(m_move_interval.step(dtime, interval))
+               return;
+       dtime = interval;
+       
        core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.);
        collisionMoveResult moveresult;
        // Apply gravity
@@ -270,6 +276,7 @@ RatSAO proto_RatSAO(NULL, 0, v3f(0,0,0));
 
 RatSAO::RatSAO(ServerEnvironment *env, u16 id, v3f pos):
        ServerActiveObject(env, id, pos),
+       m_is_active(false),
        m_speed_f(0,0,0)
 {
        //dstream<<"Server: RatSAO created"<<std::endl;
@@ -303,6 +310,12 @@ void RatSAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
 {
        assert(m_env);
 
+       if(m_is_active == false)
+       {
+               if(m_inactive_interval.step(dtime, 0.5))
+                       return;
+       }
+
        /*
                The AI
        */
@@ -336,6 +349,8 @@ void RatSAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
                        break;
                }
        }
+
+       m_is_active = player_is_close;
        
        if(player_is_close == false)
        {
index 76f7d01d678b8159b783eacc93f31b224210e049..2889d0c3940e6668fcb809070736f28382698c0a 100644 (file)
@@ -40,38 +40,6 @@ Some planning
 
 */
 
-#if 0
-class IntervalLimiter
-{
-public:
-       IntervalLimiter():
-               m_accumulator(0)
-       {
-       }
-       /*
-               dtime: time from last call to this method
-               wanted_interval: interval wanted
-               return value:
-                       true: action should be skipped
-                       false: action should be done and dtime has been set
-       */
-       bool step(float &dtime, float wanted_interval)
-       {
-               accumulator += dtime;
-               if(accumulator < wanted_interval)
-               {
-                       dtime = 0;
-                       return true;
-               }
-               accumulator -= wanted-interval;
-               dtime = wanted_interval;
-               return false;
-       }
-protected:
-       float m_accumulator;
-};
-#endif
-
 class ServerEnvironment;
 class InventoryItem;
 
@@ -204,6 +172,7 @@ private:
        std::string m_inventorystring;
        v3f m_speed_f;
        v3f m_last_sent_position;
+       IntervalLimiter m_move_interval;
 };
 
 class RatSAO : public ServerActiveObject
@@ -220,6 +189,8 @@ public:
        std::string getStaticData();
        InventoryItem* createPickedUpItem();
 private:
+       bool m_is_active;
+       IntervalLimiter m_inactive_interval;
        v3f m_speed_f;
        v3f m_oldpos;
        v3f m_last_sent_position;
index f2f3018dfd28a05d888838ee32e30ce3a9f9319d..19946354c1eb6fcb280dde7cd12776e310832bf5 100644 (file)
@@ -2015,6 +2015,35 @@ inline core::aabbox3d<f32> getNodeBox(v3s16 p, float d)
        );
 }
        
+class IntervalLimiter
+{
+public:
+       IntervalLimiter():
+               m_accumulator(0)
+       {
+       }
+       /*
+               dtime: time from last call to this method
+               wanted_interval: interval wanted
+               return value:
+                       true: action should be skipped
+                       false: action should be done
+       */
+       bool step(float dtime, float wanted_interval)
+       {
+               m_accumulator += dtime;
+               if(m_accumulator < wanted_interval)
+               {
+                       dtime = 0;
+                       return true;
+               }
+               m_accumulator -= wanted_interval;
+               return false;
+       }
+protected:
+       float m_accumulator;
+};
+
 
 #endif