better support for old maps

This commit is contained in:
Perttu Ahola 2011-04-10 22:50:31 +03:00
parent 3d25fe42f3
commit b0b5c43254
6 changed files with 145 additions and 50 deletions

@ -1801,7 +1801,6 @@ ServerMap::ServerMap(std::string savedir):
//m_chunksize = 4; //m_chunksize = 4;
//m_chunksize = 2; //m_chunksize = 2;
// TODO: Save to and load from a file
m_seed = (((u64)(myrand()%0xffff)<<0) m_seed = (((u64)(myrand()%0xffff)<<0)
+ ((u64)(myrand()%0xffff)<<16) + ((u64)(myrand()%0xffff)<<16)
+ ((u64)(myrand()%0xffff)<<32) + ((u64)(myrand()%0xffff)<<32)
@ -1838,8 +1837,16 @@ ServerMap::ServerMap(std::string savedir):
// Load map metadata (seed, chunksize) // Load map metadata (seed, chunksize)
loadMapMeta(); loadMapMeta();
// Load chunk metadata try{
loadChunkMeta(); // 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 /*// Load sector (0,0) and throw and exception on fail
if(loadSectorFull(v2s16(0,0)) == false) if(loadSectorFull(v2s16(0,0)) == false)
@ -2173,6 +2180,9 @@ void addRandomObjects(MapBlock *block)
void makeChunk(ChunkMakeData *data) void makeChunk(ChunkMakeData *data)
{ {
if(data->no_op)
return;
s16 y_nodes_min = data->y_blocks_min * MAP_BLOCKSIZE; s16 y_nodes_min = data->y_blocks_min * MAP_BLOCKSIZE;
s16 y_nodes_max = data->y_blocks_max * MAP_BLOCKSIZE + MAP_BLOCKSIZE - 1; 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; 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 // Add to transforming liquid queue (in case it'd
// start flowing) // start flowing)
/*v3s16 p = v3s16(p2d.X, y, p2d.Y); v3s16 p = v3s16(p2d.X, y, p2d.Y);
m_transforming_liquid.push_back(p);*/ data->transforming_liquid.push_back(p);
} }
// Next one // Next one
@ -3419,6 +3429,14 @@ void makeChunk(ChunkMakeData *data)
void ServerMap::initChunkMake(ChunkMakeData &data, v2s16 chunkpos) 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. // The distance how far into the neighbors the generator is allowed to go.
s16 max_spread_amount_sectors = 2; s16 max_spread_amount_sectors = 2;
assert(max_spread_amount_sectors <= m_chunksize); 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 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 x=0; x<sectorpos_bigbase_size; x++)
for(s16 z=0; z<sectorpos_bigbase_size; z++) for(s16 z=0; z<sectorpos_bigbase_size; z++)
@ -3503,7 +3521,7 @@ void ServerMap::initChunkMake(ChunkMakeData &data, v2s16 chunkpos)
data.vmanip.setMap(this); data.vmanip.setMap(this);
// Add the area // Add the area
{ {
TimeTaker timer("generateChunkRaw() initialEmerge"); TimeTaker timer("initChunkMake() initialEmerge");
data.vmanip.initialEmerge(bigarea_blocks_min, bigarea_blocks_max); 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, MapChunk* ServerMap::finishChunkMake(ChunkMakeData &data,
core::map<v3s16, MapBlock*> &changed_blocks) core::map<v3s16, MapBlock*> &changed_blocks)
{ {
if(data.no_op)
return NULL;
/* /*
Blit generated stuff to map 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 Add random objects to blocks
*/ */
@ -3590,6 +3620,7 @@ MapChunk* ServerMap::finishChunkMake(ChunkMakeData &data,
return chunk; return chunk;
} }
#if 0
// NOTE: Deprecated // NOTE: Deprecated
MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos, MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos,
core::map<v3s16, MapBlock*> &changed_blocks, core::map<v3s16, MapBlock*> &changed_blocks,
@ -3661,6 +3692,7 @@ MapChunk* ServerMap::generateChunk(v2s16 chunkpos1,
MapChunk *chunk = getChunk(chunkpos1); MapChunk *chunk = getChunk(chunkpos1);
return chunk; return chunk;
} }
#endif
ServerMapSector * ServerMap::createSector(v2s16 p2d) ServerMapSector * ServerMap::createSector(v2s16 p2d)
{ {
@ -3715,6 +3747,7 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d)
return sector; return sector;
} }
#if 0
MapSector * ServerMap::emergeSector(v2s16 p2d, MapSector * ServerMap::emergeSector(v2s16 p2d,
core::map<v3s16, MapBlock*> &changed_blocks) core::map<v3s16, MapBlock*> &changed_blocks)
{ {
@ -3801,6 +3834,7 @@ MapSector * ServerMap::emergeSector(v2s16 p2d,
*/ */
//return generateSector(); //return generateSector();
} }
#endif
/* /*
NOTE: This is not used for main map generation, only for blocks NOTE: This is not used for main map generation, only for blocks
@ -3818,6 +3852,14 @@ MapBlock * ServerMap::generateBlock(
__FUNCTION_NAME, __FUNCTION_NAME,
p.X, p.Y, p.Z); 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(): " /*dstream<<"generateBlock(): "
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<")" <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
<<std::endl;*/ <<std::endl;*/
@ -3869,6 +3911,9 @@ MapBlock * ServerMap::generateBlock(
s16 surface_y = base_rock_level_2d(m_seed, p2d_nodes+v2s16(x0,z0)) s16 surface_y = base_rock_level_2d(m_seed, p2d_nodes+v2s16(x0,z0))
+ AVERAGE_MUD_AMOUNT; + AVERAGE_MUD_AMOUNT;
// If chunks are disabled
if(m_chunksize == 0)
surface_y = WATER_LEVEL + 1;
if(surface_y < lowest_ground_y) if(surface_y < lowest_ground_y)
lowest_ground_y = surface_y; lowest_ground_y = surface_y;
@ -4735,7 +4780,12 @@ void ServerMap::save(bool only_changed)
<<std::endl; <<std::endl;
saveMapMeta(); saveMapMeta();
saveChunkMeta();
// Disable saving chunk metadata file if chunks are disabled
if(m_chunksize != 0)
{
saveChunkMeta();
}
u32 sector_meta_count = 0; u32 sector_meta_count = 0;
u32 block_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() void ServerMap::loadAll()
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
@ -4849,6 +4901,7 @@ void ServerMap::loadAll()
} }
dstream<<DTIME<<"ServerMap: Map loaded."<<std::endl; dstream<<DTIME<<"ServerMap: Map loaded."<<std::endl;
} }
#endif
#if 0 #if 0
void ServerMap::saveMasterHeightmap() void ServerMap::saveMasterHeightmap()
@ -4953,6 +5006,9 @@ void ServerMap::saveChunkMeta()
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
// This should not be called if chunks are disabled.
assert(m_chunksize != 0);
u32 count = m_chunks.size(); u32 count = m_chunks.size();
dstream<<"INFO: ServerMap::saveChunkMeta(): Saving metadata of " dstream<<"INFO: ServerMap::saveChunkMeta(): Saving metadata of "

@ -341,6 +341,8 @@ public:
// Returns the position of the chunk where the sector is in // Returns the position of the chunk where the sector is in
v2s16 sector_to_chunk(v2s16 sectorpos) v2s16 sector_to_chunk(v2s16 sectorpos)
{ {
if(m_chunksize == 0)
return v2s16(0,0);
sectorpos.X += m_chunksize / 2; sectorpos.X += m_chunksize / 2;
sectorpos.Y += m_chunksize / 2; sectorpos.Y += m_chunksize / 2;
v2s16 chunkpos = getContainerPos(sectorpos, m_chunksize); v2s16 chunkpos = getContainerPos(sectorpos, m_chunksize);
@ -350,6 +352,8 @@ public:
// Returns the position of the (0,0) sector of the chunk // Returns the position of the (0,0) sector of the chunk
v2s16 chunk_to_sector(v2s16 chunkpos) v2s16 chunk_to_sector(v2s16 chunkpos)
{ {
if(m_chunksize == 0)
return v2s16(0,0);
v2s16 sectorpos( v2s16 sectorpos(
chunkpos.X * m_chunksize, chunkpos.X * m_chunksize,
chunkpos.Y * m_chunksize chunkpos.Y * m_chunksize
@ -378,6 +382,9 @@ public:
*/ */
bool chunkNonVolatile(v2s16 chunkpos) bool chunkNonVolatile(v2s16 chunkpos)
{ {
if(m_chunksize == 0)
return true;
/*for(s16 x=-1; x<=1; x++) /*for(s16 x=-1; x<=1; x++)
for(s16 y=-1; y<=1; y++)*/ for(s16 y=-1; y<=1; y++)*/
s16 x=0; s16 x=0;
@ -393,6 +400,9 @@ public:
return true; return true;
} }
/*
Chunks are generated by using these and makeChunk().
*/
void initChunkMake(ChunkMakeData &data, v2s16 chunkpos); void initChunkMake(ChunkMakeData &data, v2s16 chunkpos);
MapChunk* finishChunkMake(ChunkMakeData &data, MapChunk* finishChunkMake(ChunkMakeData &data,
core::map<v3s16, MapBlock*> &changed_blocks); core::map<v3s16, MapBlock*> &changed_blocks);
@ -402,16 +412,16 @@ public:
All chunks touching this one can be altered also. All chunks touching this one can be altered also.
*/ */
MapChunk* generateChunkRaw(v2s16 chunkpos, /*MapChunk* generateChunkRaw(v2s16 chunkpos,
core::map<v3s16, MapBlock*> &changed_blocks, 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 Generate a chunk and its neighbors so that it won't be touched
anymore. anymore.
*/ */
MapChunk* generateChunk(v2s16 chunkpos, /*MapChunk* generateChunk(v2s16 chunkpos,
core::map<v3s16, MapBlock*> &changed_blocks); core::map<v3s16, MapBlock*> &changed_blocks);*/
/* /*
Generate a sector. Generate a sector.
@ -434,14 +444,14 @@ public:
- Check disk (loads blocks also) - Check disk (loads blocks also)
- Generate chunk - Generate chunk
*/ */
MapSector * emergeSector(v2s16 p, /*MapSector * emergeSector(v2s16 p,
core::map<v3s16, MapBlock*> &changed_blocks); core::map<v3s16, MapBlock*> &changed_blocks);*/
MapSector * emergeSector(v2s16 p) /*MapSector * emergeSector(v2s16 p)
{ {
core::map<v3s16, MapBlock*> changed_blocks; core::map<v3s16, MapBlock*> changed_blocks;
return emergeSector(p, changed_blocks); return emergeSector(p, changed_blocks);
} }*/
MapBlock * generateBlock( MapBlock * generateBlock(
v3s16 p, v3s16 p,
@ -516,7 +526,7 @@ public:
v3s16 getBlockPos(std::string sectordir, std::string blockfile); v3s16 getBlockPos(std::string sectordir, std::string blockfile);
void save(bool only_changed); void save(bool only_changed);
void loadAll(); //void loadAll();
// Saves map seed and possibly other stuff // Saves map seed and possibly other stuff
void saveMapMeta(); void saveMapMeta();
@ -557,6 +567,7 @@ private:
bool m_map_saving_enabled; bool m_map_saving_enabled;
// Chunk size in MapSectors // Chunk size in MapSectors
// If 0, chunks are disabled.
s16 m_chunksize; s16 m_chunksize;
// Chunks // Chunks
core::map<v2s16, MapChunk*> m_chunks; core::map<v2s16, MapChunk*> m_chunks;
@ -754,6 +765,7 @@ protected:
struct ChunkMakeData struct ChunkMakeData
{ {
bool no_op;
ManualMapVoxelManipulator vmanip; ManualMapVoxelManipulator vmanip;
u64 seed; u64 seed;
v2s16 chunkpos; v2s16 chunkpos;
@ -764,8 +776,10 @@ struct ChunkMakeData
v2s16 sectorpos_bigbase; v2s16 sectorpos_bigbase;
s16 sectorpos_bigbase_size; s16 sectorpos_bigbase_size;
s16 max_spread_amount; s16 max_spread_amount;
UniqueQueue<v3s16> transforming_liquid;
ChunkMakeData(): ChunkMakeData():
no_op(false),
vmanip(NULL) vmanip(NULL)
{} {}
}; };

@ -201,10 +201,20 @@ void * EmergeThread::Thread()
} }
else else
{ {
// Get, load or create sector
ServerMapSector *sector = ServerMapSector *sector =
(ServerMapSector*)map.getSectorNoGenerateNoEx(p2d); (ServerMapSector*)map.createSector(p2d);
// Generate block
block = map.generateBlock(p, block, sector, changed_blocks, block = map.generateBlock(p, block, sector, changed_blocks,
lighting_invalidated_blocks); lighting_invalidated_blocks);
if(block == NULL)
got_block = false;
}
}
else
{
if(block->getLightingExpired()){
lighting_invalidated_blocks[block->getPos()] = block;
} }
} }

@ -170,6 +170,12 @@ void ItemSAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
bool send_recommended) bool send_recommended)
{ {
assert(m_env); 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.); core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.);
collisionMoveResult moveresult; collisionMoveResult moveresult;
// Apply gravity // Apply gravity
@ -270,6 +276,7 @@ RatSAO proto_RatSAO(NULL, 0, v3f(0,0,0));
RatSAO::RatSAO(ServerEnvironment *env, u16 id, v3f pos): RatSAO::RatSAO(ServerEnvironment *env, u16 id, v3f pos):
ServerActiveObject(env, id, pos), ServerActiveObject(env, id, pos),
m_is_active(false),
m_speed_f(0,0,0) m_speed_f(0,0,0)
{ {
//dstream<<"Server: RatSAO created"<<std::endl; //dstream<<"Server: RatSAO created"<<std::endl;
@ -303,6 +310,12 @@ void RatSAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
{ {
assert(m_env); assert(m_env);
if(m_is_active == false)
{
if(m_inactive_interval.step(dtime, 0.5))
return;
}
/* /*
The AI The AI
*/ */
@ -337,6 +350,8 @@ void RatSAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
} }
} }
m_is_active = player_is_close;
if(player_is_close == false) if(player_is_close == false)
{ {
m_speed_f.X = 0; m_speed_f.X = 0;

@ -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 ServerEnvironment;
class InventoryItem; class InventoryItem;
@ -204,6 +172,7 @@ private:
std::string m_inventorystring; std::string m_inventorystring;
v3f m_speed_f; v3f m_speed_f;
v3f m_last_sent_position; v3f m_last_sent_position;
IntervalLimiter m_move_interval;
}; };
class RatSAO : public ServerActiveObject class RatSAO : public ServerActiveObject
@ -220,6 +189,8 @@ public:
std::string getStaticData(); std::string getStaticData();
InventoryItem* createPickedUpItem(); InventoryItem* createPickedUpItem();
private: private:
bool m_is_active;
IntervalLimiter m_inactive_interval;
v3f m_speed_f; v3f m_speed_f;
v3f m_oldpos; v3f m_oldpos;
v3f m_last_sent_position; v3f m_last_sent_position;

@ -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 #endif