From b0b5c432542ea5f9292f428bb59e2670c0d7c53d Mon Sep 17 00:00:00 2001
From: Perttu Ahola <celeron55@gmail.com>
Date: Sun, 10 Apr 2011 22:50:31 +0300
Subject: [PATCH] better support for old maps

---
 src/map.cpp          | 72 +++++++++++++++++++++++++++++++++++++++-----
 src/map.h            | 32 ++++++++++++++------
 src/server.cpp       | 12 +++++++-
 src/serverobject.cpp | 15 +++++++++
 src/serverobject.h   | 35 ++-------------------
 src/utility.h        | 29 ++++++++++++++++++
 6 files changed, 145 insertions(+), 50 deletions(-)

diff --git a/src/map.cpp b/src/map.cpp
index c258d157b..7fe58dc11 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -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();
 
diff --git a/src/map.h b/src/map.h
index e2cd432be..cb48cb32b 100644
--- a/src/map.h
+++ b/src/map.h
@@ -341,6 +341,8 @@ class ServerMap : public Map
 	// 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 @@ class ServerMap : public Map
 	// 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 @@ class ServerMap : public Map
 	*/
 	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 @@ class ServerMap : public Map
 		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 @@ class ServerMap : public Map
 
 		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 @@ class ServerMap : public Map
 		- 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 @@ class ServerMap : public Map
 	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 @@ class ServerMap : public Map
 	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 @@ class ManualMapVoxelManipulator : public MapVoxelManipulator
 
 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)
 	{}
 };
diff --git a/src/server.cpp b/src/server.cpp
index 63d8e31db..925b2e0d7 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -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;
 				}
 			}
 
diff --git a/src/serverobject.cpp b/src/serverobject.cpp
index a58ca524d..b6015a477 100644
--- a/src/serverobject.cpp
+++ b/src/serverobject.cpp
@@ -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)
 	{
diff --git a/src/serverobject.h b/src/serverobject.h
index 76f7d01d6..2889d0c39 100644
--- a/src/serverobject.h
+++ b/src/serverobject.h
@@ -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 @@ class ItemSAO : public ServerActiveObject
 	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 @@ class RatSAO : public ServerActiveObject
 	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;
diff --git a/src/utility.h b/src/utility.h
index f2f3018df..19946354c 100644
--- a/src/utility.h
+++ b/src/utility.h
@@ -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
 
-- 
GitLab