From ea6740e9002839f79053cf9d8cd78eb3fcae1b47 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 5 Feb 2011 14:55:16 +0200 Subject: mapgen stuff --- src/map.cpp | 858 +++++++++++------------------------------------------------- 1 file changed, 150 insertions(+), 708 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 117435565..e748b1433 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -36,8 +36,7 @@ Map::Map(std::ostream &dout): m_dout(dout), m_camera_position(0,0,0), m_camera_direction(0,0,1), - m_sector_cache(NULL), - m_hwrapper(this) + m_sector_cache(NULL) { m_sector_mutex.Init(); m_camera_mutex.Init(); @@ -1730,15 +1729,14 @@ void Map::transformLiquids(core::map & modified_blocks) ServerMap */ -ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp): +ServerMap::ServerMap(std::string savedir): Map(dout_server), - m_heightmap(NULL), m_seed(0) { //m_chunksize = 64; - //m_chunksize = 16; - m_chunksize = 8; + //m_chunksize = 16; // Too slow + m_chunksize = 8; // Fine. Takes a few seconds. //m_chunksize = 4; //m_chunksize = 2; @@ -1753,184 +1751,6 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp): */ { - dstream<<"Generating map point attribute lists"<addPoint(p, Attribute(plants_amount));*/ - - float plants_amount = 0; - if(myrand()%4 == 0) - { - plants_amount = 1.5; - } - else if(myrand()%4 == 0) - { - plants_amount = 0.5; - } - else if(myrand()%2 == 0) - { - plants_amount = 0.03; - } - else - { - plants_amount = 0.0; - } - - - list_plants_amount->addPoint(p, Attribute(plants_amount)); - } - - for(u32 i=0; i<500; i++) - { - /*u32 lim = MAP_GENERATION_LIMIT; - if(i < 400) - lim = 2000;*/ - - u32 lim = 500 + MAP_GENERATION_LIMIT * i / 500; - - v3s16 p( - -lim + myrand()%(lim*2), - 0, - -lim + myrand()%(lim*2) - ); - - float caves_amount = 0; - if(myrand()%5 == 0) - { - caves_amount = 1.0; - } - else if(myrand()%3 == 0) - { - caves_amount = 0.3; - } - else - { - caves_amount = 0.05; - } - - list_caves_amount->addPoint(p, Attribute(caves_amount)); - } - - for(u32 i=0; i<500; i++) - { - /*u32 lim = MAP_GENERATION_LIMIT; - if(i < 400) - lim = 2000;*/ - - u32 lim = 500 + MAP_GENERATION_LIMIT * i / 500; - - v3s16 p( - -lim + (myrand()%(lim*2)), - 0, - -lim + (myrand()%(lim*2)) - ); - - /*s32 bh_i = (myrand()%200) - 50; - float baseheight = (float)bh_i; - - float m = 100.; - float e = 3.; - float randmax = (float)(myrand()%(int)(10.*pow(m, 1./e)))/10.; - randmax = pow(randmax, e); - - //float randmax = (float)(myrand()%60); - float randfactor = (float)(myrand()%450) / 1000.0 + 0.4;*/ - - float baseheight = 0; - float randmax = 0; - float randfactor = 0; - - /*if(myrand()%5 == 0) - { - baseheight = 100; - randmax = 50; - randfactor = 0.63; - } - else if(myrand()%6 == 0) - { - baseheight = 200; - randmax = 100; - randfactor = 0.66; - } - else if(myrand()%4 == 0) - { - baseheight = -3; - randmax = 30; - randfactor = 0.7; - } - else if(myrand()%3 == 0) - { - baseheight = 0; - randmax = 30; - randfactor = 0.63; - } - else - { - baseheight = -3; - randmax = 20; - randfactor = 0.5; - }*/ - - if(myrand()%3 < 2) - { - baseheight = 10; - randmax = 30; - randfactor = 0.7; - } - else - { - baseheight = 0; - randmax = 15; - randfactor = 0.63; - } - - list_baseheight->addPoint(p, Attribute(baseheight)); - list_randmax->addPoint(p, Attribute(randmax)); - list_randfactor->addPoint(p, Attribute(randfactor)); - } -#endif - - // Add only one entry - list_baseheight->addPoint(v3s16(0,0,0), Attribute(-4)); - list_randmax->addPoint(v3s16(0,0,0), Attribute(22)); - //list_randmax->addPoint(v3s16(0,0,0), Attribute(0)); - list_randfactor->addPoint(v3s16(0,0,0), Attribute(0.45)); - - // Easy spawn point - /*list_baseheight->addPoint(v3s16(0,0,0), Attribute(0)); - list_randmax->addPoint(v3s16(0,0,0), Attribute(10)); - list_randfactor->addPoint(v3s16(0,0,0), Attribute(0.65));*/ } /* @@ -1986,15 +1806,6 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp): dstream< 0.2) + seed-359, 6, 0.65); + if(a > 0.0) + //if(1) { - return 35. + 10. * noise2d_perlin( + return WATER_LEVEL + 55. * noise2d_perlin( 0.5+(float)p.X/500., 0.5+(float)p.Y/500., - seed+85039, 6, 0.55); + seed+85039, 6, 0.69); } else return -100000; @@ -2202,6 +2011,8 @@ double highlands_level_2d(u64 seed, v2s16 p) MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos, core::map &changed_blocks) { + DSTACK(__FUNCTION_NAME); + /* Don't generate if already fully generated */ @@ -2226,11 +2037,13 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos, s16 max_spread_amount_sectors = 2; assert(max_spread_amount_sectors <= m_chunksize); s16 max_spread_amount = max_spread_amount_sectors * MAP_BLOCKSIZE; + // Minimum amount of space left on sides for mud to fall in - s16 min_mud_fall_space = 2; + //s16 min_mud_fall_space = 2; + // Maximum diameter of stone obstacles in X and Z - s16 stone_obstacle_max_size = (max_spread_amount-min_mud_fall_space)*2; - assert(stone_obstacle_max_size/2 <= max_spread_amount-min_mud_fall_space); + /*s16 stone_obstacle_max_size = (max_spread_amount-min_mud_fall_space)*2; + assert(stone_obstacle_max_size/2 <= max_spread_amount-min_mud_fall_space);*/ s16 y_blocks_min = -4; s16 y_blocks_max = 3; @@ -2326,6 +2139,10 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos, TimeTaker timer_generate("generateChunkRaw() generate"); + // Maximum height of the stone surface and obstacles. + // This is used to disable dungeon generation from going too high. + s16 stone_surface_max_y = 0; + /* Generate general ground level to full area */ @@ -2364,6 +2181,10 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos, // 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 @@ -2386,12 +2207,13 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos, /* Randomize some parameters */ - - u32 stone_obstacle_amount = 0; - if(myrand() % 2 == 0) - stone_obstacle_amount = myrand_range(0, myrand_range(20, 150)); - else - stone_obstacle_amount = myrand_range(0, myrand_range(20, 50)); + + //TODO + s32 stone_obstacle_count = 0; + /*s32 stone_obstacle_count = (1.0+noise2d(m_seed+90443, sectorpos_base.X, + sectorpos_base.Y))/2.0 * stone_obstacle_amount/3;*/ + + s16 stone_obstacle_max_height = 0; //u32 stone_obstacle_amount = // myrand_range(0, myrand_range(20, myrand_range(80,150))); @@ -2403,11 +2225,6 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos, for(u32 i_age=0; i_age<2; i_age++) { // Aging loop - // This is set during the next operation. - // Maximum height of the stone surface and obstacles. - // This is used to disable dungeon generation from going too high. - s16 stone_surface_max_y = 0; - { // 8ms @cs=8 //TimeTaker timer1("stone obstacles"); @@ -2416,38 +2233,28 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos, Add some random stone obstacles */ - for(u32 ri=0; rid)) continue; + /*// Check that under that is air (need a drop of 2) + vmanip.m_area.add_y(em, i2, -1); + if(vmanip.m_area.contains(i2) == false) + continue; + n2 = &vmanip.m_data[i2]; + if(content_walkable(n2->d)) + continue;*/ // Loop further down until not air do{ vmanip.m_area.add_y(em, i2, -1); @@ -3196,7 +3005,9 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos, { MapNode *n = &vmanip.m_data[i]; if(n->d == CONTENT_MUD || n->d == CONTENT_GRASS) + { n->d = CONTENT_SAND; + } else { not_sand_counter++; @@ -3213,10 +3024,10 @@ MapChunk* ServerMap::generateChunkRaw(v2s16 chunkpos, }//timer1 { // 1ms @cs=8 - //TimeTaker timer1("plant trees"); + //TimeTaker timer1("generate trees"); /* - Plant some trees + Generate some trees */ { // Divide area into parts @@ -3616,14 +3427,6 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d) return sector; } - /* - If there is no master heightmap, throw. - */ - if(m_heightmap == NULL) - { - throw InvalidPositionException("createSector(): no heightmap"); - } - /* Do not create over-limit */ @@ -3637,63 +3440,11 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d) Generate blank sector */ - // Number of heightmaps in sector in each direction - u16 hm_split = SECTOR_HEIGHTMAP_SPLIT; - - // Heightmap side width - s16 hm_d = MAP_BLOCKSIZE / hm_split; - - sector = new ServerMapSector(this, p2d, hm_split); + sector = new ServerMapSector(this, p2d); // Sector position on map in nodes v2s16 nodepos2d = p2d * MAP_BLOCKSIZE; - /*dstream<<"Generating sector ("<getGroundHeight(mhm_p+v2s16(0,0)*hm_split), - m_heightmap->getGroundHeight(mhm_p+v2s16(1,0)*hm_split), - m_heightmap->getGroundHeight(mhm_p+v2s16(1,1)*hm_split), - m_heightmap->getGroundHeight(mhm_p+v2s16(0,1)*hm_split), - };*/ - - // Loop through sub-heightmaps - for(s16 y=0; ygetGroundHeight(mhm_p+v2s16(0,0)), - m_heightmap->getGroundHeight(mhm_p+v2s16(1,0)), - m_heightmap->getGroundHeight(mhm_p+v2s16(1,1)), - m_heightmap->getGroundHeight(mhm_p+v2s16(0,1)), - }; - - /*dstream<<"p_in_sector=("<setHeightmap(p_in_sector, hm); - - //hm->generateContinued(1.0, 0.5, corners); - hm->generateContinued(0.5, 0.5, corners); - - //hm->print(); - } - - // Add dummy objects - core::map *objects = new core::map; - sector->setObjects(objects); - /* Insert to container */ @@ -3812,56 +3563,25 @@ MapBlock * ServerMap::generateBlock( block->unDummify(); } - /*u8 water_material = CONTENT_WATER; - if(g_settings.getBool("endless_water")) - water_material = CONTENT_WATERSOURCE;*/ u8 water_material = CONTENT_WATERSOURCE; s32 lowest_ground_y = 32767; s32 highest_ground_y = -32768; - // DEBUG - //sector->printHeightmaps(); - for(s16 z0=0; z0 highest_ground_y) highest_ground_y = surface_y; - s32 surface_depth = 0; - - float slope = sector->getSlope(v2s16(x0,z0)).getLength(); + s32 surface_depth = 2; - //float min_slope = 0.45; - //float max_slope = 0.85; - float min_slope = 0.60; - float max_slope = 1.20; - float min_slope_depth = 5.0; - float max_slope_depth = 0; - - if(slope < min_slope) - surface_depth = min_slope_depth; - else if(slope > max_slope) - surface_depth = max_slope_depth; - else - surface_depth = (1.-(slope-min_slope)/max_slope) * min_slope_depth; - for(s16 y0=0; y0insertBlock(block); - /* - Sector object stuff - */ - - // An y-wise container of changed blocks - core::map changed_blocks_sector; - - /* - Check if any sector's objects can be placed now. - If so, place them. - */ - core::map *objects = sector->getObjects(); - core::list objects_to_remove; - for(core::map::Iterator i = objects->getIterator(); - i.atEnd() == false; i++) - { - v3s16 p = i.getNode()->getKey(); - v2s16 p2d(p.X,p.Z); - u8 d = i.getNode()->getValue(); - - // Ground level point (user for stuff that is on ground) - v3s16 gp = p; - bool ground_found = true; - - // Search real ground level - try{ - for(;;) - { - MapNode n = sector->getNode(gp); - - // If not air, go one up and continue to placing the tree - if(n.d != CONTENT_AIR) - { - gp += v3s16(0,1,0); - break; - } - - // If air, go one down - gp += v3s16(0,-1,0); - } - }catch(InvalidPositionException &e) - { - // Ground not found. - ground_found = false; - // This is most close to ground - gp += v3s16(0,1,0); - } - - try - { - - if(d == SECTOR_OBJECT_TEST) - { - if(sector->isValidArea(p + v3s16(0,0,0), - p + v3s16(0,0,0), &changed_blocks_sector)) - { - MapNode n; - n.d = CONTENT_TORCH; - sector->setNode(p, n); - objects_to_remove.push_back(p); - } - } - else if(d == SECTOR_OBJECT_TREE_1) - { - if(ground_found == false) - continue; - - v3s16 p_min = gp + v3s16(-1,0,-1); - v3s16 p_max = gp + v3s16(1,5,1); - if(sector->isValidArea(p_min, p_max, - &changed_blocks_sector)) - { - MapNode n; - n.d = CONTENT_TREE; - sector->setNode(gp+v3s16(0,0,0), n); - sector->setNode(gp+v3s16(0,1,0), n); - sector->setNode(gp+v3s16(0,2,0), n); - sector->setNode(gp+v3s16(0,3,0), n); - - n.d = CONTENT_LEAVES; - - if(myrand()%4!=0) sector->setNode(gp+v3s16(0,5,0), n); - - if(myrand()%3!=0) sector->setNode(gp+v3s16(-1,5,0), n); - if(myrand()%3!=0) sector->setNode(gp+v3s16(1,5,0), n); - if(myrand()%3!=0) sector->setNode(gp+v3s16(0,5,-1), n); - if(myrand()%3!=0) sector->setNode(gp+v3s16(0,5,1), n); - /*if(myrand()%3!=0) sector->setNode(gp+v3s16(1,5,1), n); - if(myrand()%3!=0) sector->setNode(gp+v3s16(-1,5,1), n); - if(myrand()%3!=0) sector->setNode(gp+v3s16(-1,5,-1), n); - if(myrand()%3!=0) sector->setNode(gp+v3s16(1,5,-1), n);*/ - - sector->setNode(gp+v3s16(0,4,0), n); - - sector->setNode(gp+v3s16(-1,4,0), n); - sector->setNode(gp+v3s16(1,4,0), n); - sector->setNode(gp+v3s16(0,4,-1), n); - sector->setNode(gp+v3s16(0,4,1), n); - sector->setNode(gp+v3s16(1,4,1), n); - sector->setNode(gp+v3s16(-1,4,1), n); - sector->setNode(gp+v3s16(-1,4,-1), n); - sector->setNode(gp+v3s16(1,4,-1), n); - - sector->setNode(gp+v3s16(-1,3,0), n); - sector->setNode(gp+v3s16(1,3,0), n); - sector->setNode(gp+v3s16(0,3,-1), n); - sector->setNode(gp+v3s16(0,3,1), n); - sector->setNode(gp+v3s16(1,3,1), n); - sector->setNode(gp+v3s16(-1,3,1), n); - sector->setNode(gp+v3s16(-1,3,-1), n); - sector->setNode(gp+v3s16(1,3,-1), n); - - if(myrand()%3!=0) sector->setNode(gp+v3s16(-1,2,0), n); - if(myrand()%3!=0) sector->setNode(gp+v3s16(1,2,0), n); - if(myrand()%3!=0) sector->setNode(gp+v3s16(0,2,-1), n); - if(myrand()%3!=0) sector->setNode(gp+v3s16(0,2,1), n); - /*if(myrand()%3!=0) sector->setNode(gp+v3s16(1,2,1), n); - if(myrand()%3!=0) sector->setNode(gp+v3s16(-1,2,1), n); - if(myrand()%3!=0) sector->setNode(gp+v3s16(-1,2,-1), n); - if(myrand()%3!=0) sector->setNode(gp+v3s16(1,2,-1), n);*/ - - // Objects are identified by wanted position - objects_to_remove.push_back(p); - - // Lighting has to be recalculated for this one. - sector->getBlocksInArea(p_min, p_max, - lighting_invalidated_blocks); - } - } - else if(d == SECTOR_OBJECT_BUSH_1) - { - if(ground_found == false) - continue; - - if(sector->isValidArea(gp + v3s16(0,0,0), - gp + v3s16(0,0,0), &changed_blocks_sector)) - { - MapNode n; - n.d = CONTENT_LEAVES; - sector->setNode(gp+v3s16(0,0,0), n); - - // Objects are identified by wanted position - objects_to_remove.push_back(p); - } - } - else if(d == SECTOR_OBJECT_RAVINE) - { - s16 maxdepth = -20; - v3s16 p_min = p + v3s16(-6,maxdepth,-6); - v3s16 p_max = p + v3s16(6,6,6); - if(sector->isValidArea(p_min, p_max, - &changed_blocks_sector)) - { - MapNode n; - n.d = CONTENT_STONE; - MapNode n2; - n2.d = CONTENT_AIR; - s16 depth = maxdepth + (myrand()%10); - s16 z = 0; - s16 minz = -6 - (-2); - s16 maxz = 6 -1; - for(s16 x=-6; x<=6; x++) - { - z += -1 + (myrand()%3); - if(z < minz) - z = minz; - if(z > maxz) - z = maxz; - for(s16 y=depth+(myrand()%2); y<=6; y++) - { - /*std::cout<<"("<getNode(p2).d)) - if(content_features(sector->getNode(p2).d).walkable) - sector->setNode(p2, n); - } - { - v3s16 p2 = p + v3s16(x,y,z-1); - if(content_features(sector->getNode(p2).d).walkable) - sector->setNode(p2, n2); - } - { - v3s16 p2 = p + v3s16(x,y,z+0); - if(content_features(sector->getNode(p2).d).walkable) - sector->setNode(p2, n2); - } - { - v3s16 p2 = p + v3s16(x,y,z+1); - if(content_features(sector->getNode(p2).d).walkable) - sector->setNode(p2, n); - } - - //if(sector->getNode(p+v3s16(x,y,z+1)).solidness()==2) - //if(p.Y+y <= sector->getGroundHeight(p2d+v2s16(x,z-2))+0.5) - } - } - - objects_to_remove.push_back(p); - - // Lighting has to be recalculated for this one. - sector->getBlocksInArea(p_min, p_max, - lighting_invalidated_blocks); - } - } - else - { - dstream<<"ServerMap::generateBlock(): " - "Invalid heightmap object" - <getPos().X<<"," - <getPos().Y<<"," - <getPos().Z<<")" - <getPos().X<<"," + <getPos().Y<<"," + <getPos().Z<<")" + < list2 = fs::GetDirListing + (m_savedir+"/sectors/"+i->name); + std::vector::iterator i2; + for(i2=list2.begin(); i2!=list2.end(); i2++) { - std::vector list2 = fs::GetDirListing - (m_savedir+"/sectors/"+i->name); - std::vector::iterator i2; - for(i2=list2.begin(); i2!=list2.end(); i2++) + // We want files + if(i2->dir) + continue; + try{ + loadBlock(i->name, i2->name, sector); + } + catch(InvalidFilenameException &e) { - // We want files - if(i2->dir) - continue; - try{ - loadBlock(i->name, i2->name, sector); - } - catch(InvalidFilenameException &e) - { - // This catches unknown crap in directory - } + // This catches unknown crap in directory } } } @@ -5019,46 +4480,30 @@ void ServerMap::loadAll() void ServerMap::saveMasterHeightmap() { DSTACK(__FUNCTION_NAME); + + dstream<<"DEPRECATED: "<<__FUNCTION_NAME< hmdata = m_heightmap->serialize(version); - /* - [0] u8 serialization version - [1] X master heightmap - */ - u32 fullsize = 1 + hmdata.getSize(); - SharedBuffer data(fullsize); - - data[0] = version; - memcpy(&data[1], *hmdata, hmdata.getSize()); - - o.write((const char*)*data, fullsize); -#endif - - m_heightmap->serialize(o, version); + //u8 version = SER_FMT_VER_HIGHEST; } void ServerMap::loadMasterHeightmap() { DSTACK(__FUNCTION_NAME); - std::string fullpath = m_savedir + "/master_heightmap"; + + dstream<<"DEPRECATED: "<<__FUNCTION_NAME<differs_from_disk = false; @@ -5128,23 +4573,20 @@ bool ServerMap::loadSectorFull(v2s16 p2d) return false; } - if(ENABLE_BLOCK_LOADING) + std::vector list2 = fs::GetDirListing + (m_savedir+"/sectors/"+sectorsubdir); + std::vector::iterator i2; + for(i2=list2.begin(); i2!=list2.end(); i2++) { - std::vector list2 = fs::GetDirListing - (m_savedir+"/sectors/"+sectorsubdir); - std::vector::iterator i2; - for(i2=list2.begin(); i2!=list2.end(); i2++) + // We want files + if(i2->dir) + continue; + try{ + loadBlock(sectorsubdir, i2->name, sector); + } + catch(InvalidFilenameException &e) { - // We want files - if(i2->dir) - continue; - try{ - loadBlock(sectorsubdir, i2->name, sector); - } - catch(InvalidFilenameException &e) - { - // This catches unknown crap in directory - } + // This catches unknown crap in directory } } return true; @@ -5302,7 +4744,8 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto // Gets from master heightmap void ServerMap::getSectorCorners(v2s16 p2d, s16 *corners) { - assert(m_heightmap != NULL); + dstream<<"DEPRECATED: "<<__FUNCTION_NAME<getGroundHeight + /*corners[0] = m_heightmap->getGroundHeight ((p2d+v2s16(0,0))*SECTOR_HEIGHTMAP_SPLIT); corners[1] = m_heightmap->getGroundHeight ((p2d+v2s16(1,0))*SECTOR_HEIGHTMAP_SPLIT); corners[2] = m_heightmap->getGroundHeight ((p2d+v2s16(1,1))*SECTOR_HEIGHTMAP_SPLIT); corners[3] = m_heightmap->getGroundHeight - ((p2d+v2s16(0,1))*SECTOR_HEIGHTMAP_SPLIT); + ((p2d+v2s16(0,1))*SECTOR_HEIGHTMAP_SPLIT);*/ } void ServerMap::PrintInfo(std::ostream &out) @@ -5341,10 +4784,9 @@ ClientMap::ClientMap( Map(dout_client), scene::ISceneNode(parent, mgr, id), m_client(client), - mesh(NULL), m_control(control) { - mesh_mutex.Init(); + //mesh_mutex.Init(); /*m_box = core::aabbox3d(0,0,0, map->getW()*BS, map->getH()*BS, map->getD()*BS);*/ @@ -5360,13 +4802,13 @@ ClientMap::ClientMap( ClientMap::~ClientMap() { - JMutexAutoLock lock(mesh_mutex); + /*JMutexAutoLock lock(mesh_mutex); if(mesh != NULL) { mesh->drop(); mesh = NULL; - } + }*/ } MapSector * ClientMap::emergeSector(v2s16 p2d) -- cgit v1.2.3