X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fmap.cpp;h=cd2ba9154eadac0202782697b47cf2ff5052ce92;hb=d4d49ee8f4d425e7a4136d65f519728869680951;hp=ff823af94aaf05bf24da6d4650f17f515407134f;hpb=32360321018b83cb7b2c2018f6f477c70b9f633b;p=dragonfireclient.git diff --git a/src/map.cpp b/src/map.cpp index ff823af94..cd2ba9154 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1,6 +1,6 @@ /* Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola +Copyright (C) 2010-2011 celeron55, Perttu Ahola 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::Iterator si; @@ -1397,7 +1397,7 @@ void Map::deleteSectors(core::list &list, bool only_blocks) u32 Map::deleteUnusedSectors(float timeout, bool only_blocks, core::list *deleted_blocks) { - JMutexAutoLock lock(m_sector_mutex); + //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out core::list sector_deletion_queue; core::map::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<>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; xsectorpos_bigbase_size*MAP_BLOCKSIZE; x++) + for(s16 z=0; zsectorpos_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; xsectorpos_bigbase_size*MAP_BLOCKSIZE; x++) for(s16 z=0; zsectorpos_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_agesectorpos_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 &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; z0setNode(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 &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,13 +4868,16 @@ 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; } -void ServerMap::createDir(std::string path) +void ServerMap::createDirs(std::string path) { - if(fs::CreateDir(path) == false) + if(fs::CreateAllDirs(path) == false) { m_dout<::Iterator i = m_sectors.getIterator(); for(; i.atEnd() == false; i++) @@ -4853,7 +5040,7 @@ void ServerMap::loadAll() dstream<serialize(os, version); } + + setChunksNonModified(); } void ServerMap::loadChunkMeta() @@ -5100,10 +5290,8 @@ void ServerMap::saveSectorMeta(ServerMapSector *sector) u8 version = SER_FMT_VER_HIGHEST; // Get destination v2s16 pos = sector->getPos(); - createDir(m_savedir); - createDir(m_savedir+"/sectors"); std::string dir = getSectorDir(pos); - createDir(dir); + createDirs(dir); std::string fullpath = dir + "/meta"; std::ofstream o(fullpath.c_str(), std::ios_base::binary); @@ -5115,36 +5303,40 @@ void ServerMap::saveSectorMeta(ServerMapSector *sector) sector->differs_from_disk = false; } -MapSector* ServerMap::loadSectorMeta(std::string dirname) +MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load) { DSTACK(__FUNCTION_NAME); // Get destination - v2s16 p2d = getSectorPos(dirname); - std::string dir = m_savedir + "/sectors/" + dirname; + v2s16 p2d = getSectorPos(sectordir); ServerMapSector *sector = NULL; - - std::string fullpath = dir + "/meta"; + + std::string fullpath = sectordir + "/meta"; std::ifstream is(fullpath.c_str(), std::ios_base::binary); if(is.good() == false) { // If the directory exists anyway, it probably is in some old // format. Just go ahead and create the sector. - if(fs::PathExists(dir)) + if(fs::PathExists(sectordir)) { dstream<<"ServerMap::loadSectorMeta(): Sector metafile " <differs_from_disk = false; @@ -5155,14 +5347,31 @@ MapSector* ServerMap::loadSectorMeta(std::string dirname) bool ServerMap::loadSectorFull(v2s16 p2d) { DSTACK(__FUNCTION_NAME); - std::string sectorsubdir = getSectorSubDir(p2d); MapSector *sector = NULL; - JMutexAutoLock lock(m_sector_mutex); + // The directory layout we're going to load from. + // 1 - original sectors/xxxxzzzz/ + // 2 - new sectors2/xxx/zzz/ + // If we load from anything but the latest structure, we will + // immediately save to the new one, and remove the old. + int loadlayout = 1; + std::string sectordir1 = getSectorDir(p2d, 1); + std::string sectordir; + if(fs::PathExists(sectordir1)) + { + sectordir = sectordir1; + } + else + { + loadlayout = 2; + sectordir = getSectorDir(p2d, 2); + } + + //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out try{ - sector = loadSectorMeta(sectorsubdir); + sector = loadSectorMeta(sectordir, loadlayout != 2); } catch(InvalidFilenameException &e) { @@ -5181,7 +5390,7 @@ bool ServerMap::loadSectorFull(v2s16 p2d) Load blocks */ std::vector list2 = fs::GetDirListing - (m_savedir+"/sectors/"+sectorsubdir); + (sectordir); std::vector::iterator i2; for(i2=list2.begin(); i2!=list2.end(); i2++) { @@ -5189,16 +5398,25 @@ bool ServerMap::loadSectorFull(v2s16 p2d) if(i2->dir) continue; try{ - loadBlock(sectorsubdir, i2->name, sector); + loadBlock(sectordir, i2->name, sector, loadlayout != 2); } catch(InvalidFilenameException &e) { // This catches unknown crap in directory } } + + if(loadlayout != 2) + { + dstream<<"Sector converted to new layout - deleting "<< + sectordir1<getPos(); v2s16 p2d(p3d.X, p3d.Z); - createDir(m_savedir); - createDir(m_savedir+"/sectors"); std::string dir = getSectorDir(p2d); - createDir(dir); + createDirs(dir); - // Block file is map/sectors/xxxxxxxx/xxxx char cc[5]; snprintf(cc, 5, "%.4x", (unsigned int)p3d.Y&0xffff); std::string fullpath = dir + "/" + cc; @@ -5259,12 +5474,11 @@ void ServerMap::saveBlock(MapBlock *block) block->resetChangedFlag(); } -void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSector *sector) +void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSector *sector, bool save_after_load) { DSTACK(__FUNCTION_NAME); - // Block file is map/sectors/xxxxxxxx/xxxx - std::string fullpath = m_savedir+"/sectors/"+sectordir+"/"+blockfile; + std::string fullpath = sectordir+"/"+blockfile; try{ std::ifstream is(fullpath.c_str(), std::ios_base::binary); @@ -5328,7 +5542,7 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto */ // Save old format blocks in new format - if(version < SER_FMT_VER_HIGHEST) + if(version < SER_FMT_VER_HIGHEST || save_after_load) { saveBlock(block); } @@ -5406,7 +5620,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); } @@ -5418,7 +5632,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::Node *n = m_sectors.find(p2d); @@ -5431,7 +5645,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); } } @@ -6029,7 +6243,8 @@ void MapVoxelManipulator::blitBack } ManualMapVoxelManipulator::ManualMapVoxelManipulator(Map *map): - MapVoxelManipulator(map) + MapVoxelManipulator(map), + m_create_area(false) { }