tweaking around, including mapgen, player speed in water, settings
authorPerttu Ahola <celeron55@gmail.com>
Fri, 14 Jan 2011 23:26:29 +0000 (01:26 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Fri, 14 Jan 2011 23:26:29 +0000 (01:26 +0200)
src/defaultsettings.cpp
src/environment.cpp
src/main.cpp
src/map.cpp
src/mapblock.cpp
src/materials.cpp
src/player.h
src/server.cpp

index 66564bc1f177c8976d12796e008e950c9d86d4f6..e15a5b3a20319fb31ccc76349285f7e1299e31c0 100644 (file)
@@ -40,12 +40,19 @@ void set_default_settings()
 
        // Server stuff
        g_settings.setDefault("creative_mode", "false");
-       g_settings.setDefault("heightmap_blocksize", "32");
+       /*g_settings.setDefault("heightmap_blocksize", "32");
        g_settings.setDefault("height_randmax", "constant 45.0");
        g_settings.setDefault("height_randfactor", "constant 0.6");
        g_settings.setDefault("height_base", "linear 0 0 0");
        g_settings.setDefault("plants_amount", "1.0");
        g_settings.setDefault("ravines_amount", "1.0");
+       g_settings.setDefault("coal_amount", "1.0");*/
+       g_settings.setDefault("heightmap_blocksize", "16");
+       g_settings.setDefault("height_randmax", "linear 0 0 40");
+       g_settings.setDefault("height_randfactor", "linear 0.60 -0.10 0");
+       g_settings.setDefault("height_base", "linear 5 0 0");
+       g_settings.setDefault("plants_amount", "0.2");
+       g_settings.setDefault("ravines_amount", "0");
        g_settings.setDefault("coal_amount", "1.0");
 
        g_settings.setDefault("objectdata_interval", "0.2");
@@ -55,7 +62,7 @@ void set_default_settings()
        g_settings.setDefault("disable_water_climb", "true");
        g_settings.setDefault("endless_water", "true");
        g_settings.setDefault("max_block_send_distance", "5");
-       g_settings.setDefault("max_block_generate_distance", "4");
+       g_settings.setDefault("max_block_generate_distance", "5");
        g_settings.setDefault("time_send_interval", "20");
        g_settings.setDefault("time_speed", "96");
        g_settings.setDefault("server_unload_unused_sectors_timeout", "60");
index 7c236c3556a54324eca746e5980a43c8078df006..c43525c37779d0eca4415ffd73ccef709cf5ec53 100644 (file)
@@ -121,7 +121,7 @@ void Environment::step(float dtime)
                                        f32 max_down = 1.0*BS;
                                        if(speed.Y < -max_down) speed.Y = -max_down;
 
-                                       f32 max = 2.0*BS;
+                                       f32 max = 2.5*BS;
                                        if(speed.getLength() > max)
                                        {
                                                speed = speed / speed.getLength() * max;
index eacf08c757d226482a4a518302964f8744da26a2..f36f17a1de9337115112eb9692bae9318c2a88dc 100644 (file)
@@ -23,20 +23,21 @@ NOTE: Things starting with TODO are sometimes only suggestions.
 \r
 NOTE: VBO cannot be turned on for fast-changing stuff because there\r
       is an apparanet memory leak in irrlicht when using it (not sure)\r
+         - It is not a memory leak but some kind of a buffer.\r
 \r
 NOTE: iostream.imbue(std::locale("C")) is very slow\r
 NOTE: Global locale is now set at initialization\r
 \r
 SUGG: Fix address to be ipv6 compatible\r
 \r
-FIXME: When a new sector is generated, it may change the ground level\r
-       of it's and it's neighbors border that two blocks that are\r
-          above and below each other and that are generated before and\r
-          after the sector heightmap generation (order doesn't matter),\r
-          can have a small gap between each other at the border.\r
-SUGGESTION: Use same technique for sector heightmaps as what we're\r
-            using for UnlimitedHeightmap? (getting all neighbors\r
-                       when generating)\r
+NOTE: When a new sector is generated, it may change the ground level\r
+      of it's and it's neighbors border that two blocks that are\r
+         above and below each other and that are generated before and\r
+         after the sector heightmap generation (order doesn't matter),\r
+         can have a small gap between each other at the border.\r
+SUGG: Use same technique for sector heightmaps as what we're\r
+      using for UnlimitedHeightmap? (getting all neighbors\r
+         when generating)\r
 \r
 SUGG: Transfer more blocks in a single packet\r
 SUGG: A blockdata combiner class, to which blocks are added and at\r
@@ -78,10 +79,6 @@ SUGG: Split MapBlockObject serialization to to-client and to-disk
 SUGG: Implement lighting using VoxelManipulator\r
       - Would it be significantly faster?\r
 \r
-FIXME: Rats somehow go underground sometimes (you can see it in water)\r
-       - Does their position get saved to a border value or something?\r
-          - Does this happen anymore?\r
-\r
 SUGG: MovingObject::move and Player::move are basically the same.\r
       combine them.\r
 \r
@@ -90,6 +87,8 @@ SUGG: Implement a "Fast check queue" (a queue with a map for checking
       - Use it in active block queue in water flowing\r
 \r
 SUGG: Precalculate lighting translation table at runtime (at startup)\r
+      - This is not doable because it is currently hand-made and not\r
+           based on some mathematical function.\r
 \r
 SUGG: A version number to blocks, which increments when the block is\r
       modified (node add/remove, water update, lighting update)\r
@@ -105,51 +104,71 @@ SUGG: Meshes of blocks could be split into 6 meshes facing into
       different directions and then only those drawn that need to be\r
          - Also an 1-dimensional tile map would be nice probably\r
 \r
-TODO: Untie client network operations from framerate\r
-      - Needs some input queues or something\r
-         - Not really necessary?\r
+Networking:\r
+\r
+TODO: Get rid of GotSplitPacketException\r
+\r
+GUI:\r
+\r
+TODO: Add gui option to remove map\r
+\r
+TODO: Startup and configuration menu\r
+\r
+Graphics:\r
+\r
+TODO: Optimize day/night mesh updating somehow\r
+      - create copies of all textures for all lighting values and only\r
+           change texture for material?\r
+         - Umm... the collecting of the faces is the slow part\r
+           -> what about just changing the color values of the existing\r
+                  meshbuffers? It should go quite fast.\r
+\r
+TODO: Draw big amounts of torches better (that is, throw them in the\r
+      same meshbuffer (can the meshcollector class be used?))\r
 \r
 TODO: Combine MapBlock's face caches to so big pieces that VBO\r
       gets used\r
       - That is >500 vertices\r
 \r
-TODO: Startup and configuration menu\r
+TODO: Make fetching sector's blocks more efficient when rendering\r
+      sectors that have very large amounts of blocks (on client)\r
 \r
-TODO: There are some lighting-related todos and fixmes in\r
-      ServerMap::emergeBlock\r
+Configuration:\r
 \r
-TODO: Proper handling of spawning place (try to find something that\r
-      is not in the middle of an ocean (some land to stand on at\r
-         least) and save it in map config.\r
+TODO: Make the video backend selectable\r
+\r
+Client:\r
+\r
+TODO: Untie client network operations from framerate\r
+      - Needs some input queues or something\r
+         - Not really necessary?\r
+\r
+Server:\r
+\r
+TODO: When player dies, throw items on map\r
+\r
+TODO: Make an option to the server to disable building and digging near\r
+      the starting position\r
 \r
 TODO: Players to only be hidden when the client quits.\r
 TODO: - Players to be saved on disk, with inventory\r
 TODO: Players to be saved as text in map/players/<name>\r
 TODO: Player inventory to be saved on disk\r
 \r
-TODO: Make fetching sector's blocks more efficient when rendering\r
-      sectors that have very large amounts of blocks (on client)\r
-\r
-TODO: Make the video backend selectable\r
+TODO: Proper handling of spawning place (try to find something that\r
+      is not in the middle of an ocean (some land to stand on at\r
+         least) and save it in map config.\r
 \r
 TODO: Copy the text of the last picked sign to inventory in creative\r
       mode\r
 \r
-TODO: Get rid of GotSplitPacketException\r
-\r
 TODO: Check what goes wrong with caching map to disk (Kray)\r
       - Nothing?\r
 \r
-Block object server side:\r
-      - A "near blocks" buffer, in which some nearby blocks are stored.\r
-         - For all blocks in the buffer, objects are stepped(). This\r
-           means they are active.\r
-         - TODO: A global active buffer is needed for the server\r
-         - TODO: A timestamp to blocks\r
-      - TODO: All blocks going in and out of the buffer are recorded.\r
-           - TODO: For outgoing blocks, timestamp is written.\r
-           - TODO: For incoming blocks, time difference is calculated and\r
-             objects are stepped according to it.\r
+TODO: When server sees that client is removing an inexistent block or\r
+      adding a block to an existent position, resend the MapBlock.\r
+\r
+Objects:\r
 \r
 TODO: Better handling of objects and mobs\r
       - Scripting?\r
@@ -160,31 +179,31 @@ TODO: Better handling of objects and mobs
                - This is also needed for objects that don't get sent to client\r
                  but are used for triggers etc\r
 \r
-TODO: Draw big amounts of torches better (that is, throw them in the\r
-      same meshbuffer (can the meshcollector class be used?))\r
-\r
-TODO: Make an option to the server to disable building and digging near\r
-      the starting position\r
-\r
 SUGG: Signs could be done in the same way as torches. For this, blocks\r
       need an additional metadata field for the texts\r
          - This is also needed for item container chests\r
 TODO: There has to be some better way to handle static objects than to\r
       send them all the time. This affects signs and item objects.\r
 \r
-TODO: When server sees that client is removing an inexistent block or\r
-      adding a block to an existent position, resend the MapBlock.\r
+Block object server side:\r
+      - A "near blocks" buffer, in which some nearby blocks are stored.\r
+         - For all blocks in the buffer, objects are stepped(). This\r
+           means they are active.\r
+         - TODO: A global active buffer is needed for the server\r
+         - TODO: A timestamp to blocks\r
+      - TODO: All blocks going in and out of the buffer are recorded.\r
+           - TODO: For outgoing blocks, timestamp is written.\r
+           - TODO: For incoming blocks, time difference is calculated and\r
+             objects are stepped according to it.\r
 \r
-TODO: When player dies, throw items on map\r
+Map generator:\r
 \r
-TODO: Use porting::path_userdata for configuration file\r
+TODO: There are some lighting-related todos and fixmes in\r
+      ServerMap::emergeBlock\r
 \r
-TODO: Optimize day/night mesh updating somehow\r
-      - create copies of all textures for all lighting values and only\r
-           change texture for material?\r
-         - Umm... the collecting of the faces is the slow part\r
-           -> what about just changing the color values of the existing\r
-                  meshbuffers? It should go quite fast.\r
+TODO: When generating a block, check that there is no sunlight\r
+      below the block if the bottom of the block doesn't have\r
+         sunlight. If it has, add it to the invalid lighting list.\r
 \r
 TODO: Map generator version 2\r
        - Create surface areas based on central points; a given point's\r
@@ -193,8 +212,6 @@ TODO: Map generator version 2
          - Flat land, mountains, forest, jungle\r
     - Cliffs, arcs\r
 \r
-TODO: Add gui option to remove map\r
-\r
 Doing now:\r
 ======================================================================\r
 \r
index f5e490ad4ccaaa44c833b98d30b6edba1b24a5e9..119b487db59199d75f1f683212ab4f7a705bf501 100644 (file)
@@ -1482,8 +1482,10 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
                sector->setHeightmap(p_in_sector, hm);
 
                //TODO: Make these values configurable
+               
                //hm->generateContinued(0.0, 0.0, corners);
-               hm->generateContinued(0.5, 0.2, corners);
+               hm->generateContinued(0.25, 0.2, corners);
+               //hm->generateContinued(0.5, 0.2, corners);
                //hm->generateContinued(1.0, 0.2, corners);
                //hm->generateContinued(2.0, 0.2, corners);
 
@@ -1712,6 +1714,7 @@ MapBlock * ServerMap::emergeBlock(
        {
                underground_emptiness[i] = 0;
        }
+       
        // Generate dungeons
        {
                /*
@@ -1863,6 +1866,10 @@ continue_generating:
        // DEBUG
        //sector->printHeightmaps();
 
+       // Set to true if has caves.
+       // Set when some non-air is changed to air when making caves.
+       bool has_caves = false;
+
        for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
        for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
        {
@@ -1894,6 +1901,7 @@ continue_generating:
                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)
@@ -1935,101 +1943,85 @@ continue_generating:
                        // Else it's ground or dungeons (air)
                        else
                        {
-                               // Create dungeons
-                               if(underground_emptiness[
-                                               ued*ued*(z0*ued/MAP_BLOCKSIZE)
-                                               +ued*(y0*ued/MAP_BLOCKSIZE)
-                                               +(x0*ued/MAP_BLOCKSIZE)])
+                               // If it's surface_depth under ground, it's stone
+                               if(real_y <= surface_y - surface_depth)
                                {
-                                       n.d = CONTENT_AIR;
+                                       n.d = CONTENT_STONE;
                                }
                                else
                                {
-                                       // If it's surface_depth under ground, it's stone
-                                       if(real_y <= surface_y - surface_depth)
+                                       // It is mud if it is under the first ground
+                                       // level or under water
+                                       if(real_y < WATER_LEVEL || real_y <= surface_y - 1)
                                        {
-                                               n.d = CONTENT_STONE;
+                                               n.d = CONTENT_MUD;
                                        }
                                        else
                                        {
-                                               // It is mud if it is under the first ground
-                                               // level or under water
-                                               if(real_y < WATER_LEVEL || real_y <= surface_y - 1)
-                                               {
-                                                       n.d = CONTENT_MUD;
-                                               }
-                                               else
-                                               {
-                                                       n.d = CONTENT_GRASS;
-                                               }
-
-                                               //n.d = CONTENT_MUD;
-                                               
-                                               /*// If under water level, it's mud
-                                               if(real_y < WATER_LEVEL)
-                                                       n.d = CONTENT_MUD;
-                                               // Only the topmost node is grass
-                                               else if(real_y <= surface_y - 1)
-                                                       n.d = CONTENT_MUD;
-                                               else
-                                                       n.d = CONTENT_GRASS;*/
+                                               n.d = CONTENT_GRASS;
                                        }
+
+                                       //n.d = CONTENT_MUD;
+                                       
+                                       /*// If under water level, it's mud
+                                       if(real_y < WATER_LEVEL)
+                                               n.d = CONTENT_MUD;
+                                       // Only the topmost node is grass
+                                       else if(real_y <= surface_y - 1)
+                                               n.d = CONTENT_MUD;
+                                       else
+                                               n.d = CONTENT_GRASS;*/
                                }
-                       }
-#if 0
-                       else if(real_y <= surface_y - surface_depth)
-                       {
+
                                // Create dungeons
                                if(underground_emptiness[
                                                ued*ued*(z0*ued/MAP_BLOCKSIZE)
                                                +ued*(y0*ued/MAP_BLOCKSIZE)
                                                +(x0*ued/MAP_BLOCKSIZE)])
                                {
+                                       // Has now caves if previous content is air
+                                       if(n.d != CONTENT_AIR)
+                                       {
+                                               has_caves = true;
+                                       }
+
                                        n.d = CONTENT_AIR;
                                }
-                               else
-                               {
-                                       n.d = CONTENT_STONE;
-                               }
                        }
-                       // If node is at or under heightmap y
-                       else if(real_y <= surface_y)
-                       {
-                               // If under water level, it's mud
-                               if(real_y < WATER_LEVEL)
-                                       n.d = CONTENT_MUD;
-                               // Only the topmost node is grass
-                               else if(real_y <= surface_y - 1)
-                                       n.d = CONTENT_MUD;
-                               // Else it's the main material
-                               else
-                                       n.d = material;
-                       }
-#endif
+
                        block->setNode(v3s16(x0,y0,z0), n);
                }
        }
 
        /*
-               Calculate is_underground
+               Calculate completely_underground
        */
-       // Probably underground if the highest part of block is under lowest
-       // ground height
-       bool is_underground = (block_y+1) * MAP_BLOCKSIZE <= lowest_ground_y;
-       block->setIsUnderground(is_underground);
+       // Completely underground if the highest part of block is under lowest
+       // ground height.
+       // This has to be very sure; it's probably one too strict now but
+       // that's just better.
+       bool completely_underground =
+                       block_y * MAP_BLOCKSIZE + MAP_BLOCKSIZE < lowest_ground_y;
+
+       // This isn't used anymore (?) but set it anyway
+       block->setIsUnderground(completely_underground);
+
+       bool some_part_underground = block_y * MAP_BLOCKSIZE <= highest_ground_y;
 
        /*
-               Force lighting update if some part of block is underground
-               This is needed because of caves.
+               Force lighting update if some part of block is partly
+               underground and has caves.
        */
        
-       bool some_part_underground = (block_y+0) * MAP_BLOCKSIZE < highest_ground_y;
-       if(some_part_underground)
-       //if(is_underground)
+       if(some_part_underground && !completely_underground && has_caves)
        {
+               //dstream<<"Half-ground caves"<<std::endl;
                lighting_invalidated_blocks[block->getPos()] = block;
        }
        
+       // DEBUG: Always update lighting
+       //lighting_invalidated_blocks[block->getPos()] = block;
+       
        /*
                Add some minerals
        */
@@ -2041,9 +2033,9 @@ continue_generating:
                /*
                        Add meseblocks
                */
-               for(s16 i=0; i<underground_level*1; i++)
+               for(s16 i=0; i< underground_level/4 + 1; i++)
                {
-                       if(myrand()%2 == 0)
+                       if(myrand()%10 == 0)
                        {
                                v3s16 cp(
                                        (myrand()%(MAP_BLOCKSIZE-2))+1,
@@ -2112,7 +2104,7 @@ continue_generating:
        /*
                Create a few rats in empty blocks underground
        */
-       if(is_underground)
+       if(completely_underground)
        {
                //for(u16 i=0; i<2; i++)
                {
@@ -2157,8 +2149,34 @@ continue_generating:
                v2s16 p2d(p.X,p.Z);
                u8 d = i.getNode()->getValue();
 
-               //v3s16 p = p_sector - v3s16(0, block_y*MAP_BLOCKSIZE, 0);
+               // 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
                {
 
@@ -2175,40 +2193,64 @@ continue_generating:
                }
                else if(d == SECTOR_OBJECT_TREE_1)
                {
-                       v3s16 p_min = p + v3s16(-1,0,-1);
-                       v3s16 p_max = p + v3s16(1,4,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(p+v3s16(0,0,0), n);
-                               sector->setNode(p+v3s16(0,1,0), n);
-                               sector->setNode(p+v3s16(0,2,0), n);
-                               sector->setNode(p+v3s16(0,3,0), n);
+                               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;
 
-                               sector->setNode(p+v3s16(0,4,0), n);
+                               if(rand()%4!=0) sector->setNode(gp+v3s16(0,5,0), n);
+
+                               if(rand()%3!=0) sector->setNode(gp+v3s16(-1,5,0), n);
+                               if(rand()%3!=0) sector->setNode(gp+v3s16(1,5,0), n);
+                               if(rand()%3!=0) sector->setNode(gp+v3s16(0,5,-1), n);
+                               if(rand()%3!=0) sector->setNode(gp+v3s16(0,5,1), n);
+                               /*if(rand()%3!=0) sector->setNode(gp+v3s16(1,5,1), n);
+                               if(rand()%3!=0) sector->setNode(gp+v3s16(-1,5,1), n);
+                               if(rand()%3!=0) sector->setNode(gp+v3s16(-1,5,-1), n);
+                               if(rand()%3!=0) sector->setNode(gp+v3s16(1,5,-1), n);*/
+
+                               sector->setNode(gp+v3s16(0,4,0), n);
                                
-                               sector->setNode(p+v3s16(-1,4,0), n);
-                               sector->setNode(p+v3s16(1,4,0), n);
-                               sector->setNode(p+v3s16(0,4,-1), n);
-                               sector->setNode(p+v3s16(0,4,1), n);
-                               sector->setNode(p+v3s16(1,4,1), n);
-                               sector->setNode(p+v3s16(-1,4,1), n);
-                               sector->setNode(p+v3s16(-1,4,-1), n);
-                               sector->setNode(p+v3s16(1,4,-1), n);
-
-                               sector->setNode(p+v3s16(-1,3,0), n);
-                               sector->setNode(p+v3s16(1,3,0), n);
-                               sector->setNode(p+v3s16(0,3,-1), n);
-                               sector->setNode(p+v3s16(0,3,1), n);
-                               sector->setNode(p+v3s16(1,3,1), n);
-                               sector->setNode(p+v3s16(-1,3,1), n);
-                               sector->setNode(p+v3s16(-1,3,-1), n);
-                               sector->setNode(p+v3s16(1,3,-1), 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(rand()%3!=0) sector->setNode(gp+v3s16(-1,2,0), n);
+                               if(rand()%3!=0) sector->setNode(gp+v3s16(1,2,0), n);
+                               if(rand()%3!=0) sector->setNode(gp+v3s16(0,2,-1), n);
+                               if(rand()%3!=0) sector->setNode(gp+v3s16(0,2,1), n);
+                               /*if(rand()%3!=0) sector->setNode(gp+v3s16(1,2,1), n);
+                               if(rand()%3!=0) sector->setNode(gp+v3s16(-1,2,1), n);
+                               if(rand()%3!=0) sector->setNode(gp+v3s16(-1,2,-1), n);
+                               if(rand()%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.
@@ -2218,13 +2260,17 @@ continue_generating:
                }
                else if(d == SECTOR_OBJECT_BUSH_1)
                {
-                       if(sector->isValidArea(p + v3s16(0,0,0),
-                                       p + v3s16(0,0,0), &changed_blocks_sector))
+                       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(p+v3s16(0,0,0), n);
+                               sector->setNode(gp+v3s16(0,0,0), n);
                                
+                               // Objects are identified by wanted position
                                objects_to_remove.push_back(p);
                        }
                }
index 90ff05bd1468434066d23e51baa06dfe69b73ed6..2d077121c827c13f18bdec9bf288bf85324ded1c 100644 (file)
@@ -876,6 +876,7 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
        {
                for(s16 z=0; z<MAP_BLOCKSIZE; z++)
                {
+#if 1
                        bool no_sunlight = false;
                        bool no_top_block = false;
                        // Check if node above block has sunlight
@@ -901,6 +902,23 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources)
                                // No sunlight here
                                //no_sunlight = true;
                        }
+#endif
+#if 0 // Doesn't work; nothing gets light.
+                       bool no_sunlight = true;
+                       bool no_top_block = false;
+                       // Check if node above block has sunlight
+                       try{
+                               MapNode n = getNodeParent(v3s16(x, MAP_BLOCKSIZE, z));
+                               if(n.getLight(LIGHTBANK_DAY) == LIGHT_SUN)
+                               {
+                                       no_sunlight = false;
+                               }
+                       }
+                       catch(InvalidPositionException &e)
+                       {
+                               no_top_block = true;
+                       }
+#endif
 
                        /*std::cout<<"("<<x<<","<<z<<"): "
                                        <<"no_top_block="<<no_top_block
index dc080ba2304cf130fc0ba4f75020e1de48e43a41..1c177e9a3189c0e7f7e04eb52d45852b7668045b 100644 (file)
@@ -13,9 +13,9 @@ void setStoneLikeDiggingProperties(u8 material, float toughness)
                        DiggingProperties(true, 15.0*toughness, 0));
        
        g_material_properties[material].setDiggingProperties("WPick",
-                       DiggingProperties(true, 2.0*toughness, 65535./20.*toughness));
+                       DiggingProperties(true, 1.5*toughness, 65535./20.*toughness));
        g_material_properties[material].setDiggingProperties("STPick",
-                       DiggingProperties(true, 1.0*toughness, 65535./50.*toughness));
+                       DiggingProperties(true, 0.7*toughness, 65535./60.*toughness));
 
        /*g_material_properties[material].setDiggingProperties("MesePick",
                        DiggingProperties(true, 0.0*toughness, 65535./20.*toughness));*/
@@ -63,7 +63,7 @@ void initializeMaterialProperties()
        for(u16 i=0; i<MATERIAL_PROPERTIES_COUNT; i++)
        {
                g_material_properties[i].setDiggingProperties("MesePick",
-                               DiggingProperties(true, 0.0, 65535./20.));
+                               DiggingProperties(true, 0.0, 65535./1337));
        }
 
        g_material_properties_initialized = true;
index 0b9f014c1274d1a93fdac3bba00055979181f687..fc87a5edd33a750804746bff0dac017b94717814 100644 (file)
@@ -97,6 +97,9 @@ public:
 
        virtual void updateLight(u8 light_at_pos) {};
 
+       virtual bool isClientConnected() { return false; }
+       virtual void setClientConnected(bool) {}
+
        bool touching_ground;
        bool in_water;
        
@@ -115,22 +118,35 @@ protected:
 class ServerRemotePlayer : public Player
 {
 public:
-       ServerRemotePlayer()
+       ServerRemotePlayer(bool client_connected):
+               m_client_connected(client_connected)
        {
        }
        virtual ~ServerRemotePlayer()
        {
        }
 
-       bool isLocal() const
+       virtual bool isLocal() const
        {
                return false;
        }
 
-       void move(f32 dtime, Map &map)
+       virtual void move(f32 dtime, Map &map)
+       {
+       }
+
+       virtual bool isClientConnected()
+       {
+               return m_client_connected;
+       }
+       virtual void setClientConnected(bool client_connected)
        {
+               m_client_connected = client_connected;
        }
 
+       // This 
+       bool m_client_connected;
+
 private:
 };
 
index daf00b8ee9bb5128b651a1c183b57de9781851a0..38c421e4119a708b70f4a84b7c87aee4f7d88d45 100644 (file)
@@ -88,7 +88,7 @@ void * EmergeThread::Thread()
                
                //derr_server<<"EmergeThread::Thread(): running"<<std::endl;
 
-               //TimeTaker timer("block emerge", g_device);
+               //TimeTaker timer("block emerge");
                
                /*
                        Try to emerge it from somewhere.
@@ -135,9 +135,14 @@ void * EmergeThread::Thread()
                
                {//envlock
 
+               //TimeTaker envlockwaittimer("block emerge envlock wait time");
+               
+               // 0-50ms
                JMutexAutoLock envlock(m_server->m_env_mutex);
 
-               //TimeTaker timer("block emerge envlock", g_device);
+               //envlockwaittimer.stop();
+
+               //TimeTaker timer("block emerge (while env locked)");
                        
                try{
                        bool only_from_disk = false;
@@ -209,8 +214,9 @@ void * EmergeThread::Thread()
                        }
                        
                        /*dstream<<"lighting "<<lighting_invalidated_blocks.size()
-                                       <<" blocks"<<std::endl;
-                       TimeTaker timer("** updateLighting", g_device);*/
+                                       <<" blocks"<<std::endl;*/
+                       
+                       //TimeTaker timer("** updateLighting", g_device);
                        
                        // Update lighting without locking the environment mutex,
                        // add modified blocks to changed blocks
@@ -450,8 +456,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
 
                        bool generate = d <= d_max_gen;
                
-                       // Limit the generating area vertically to half
-                       if(abs(p.Y - center.Y) > d_max_gen / 2)
+                       // Limit the generating area vertically to 2/3
+                       if(abs(p.Y - center.Y) > d_max_gen - d_max_gen / 3)
                                generate = false;
                        
                        /*
@@ -2967,7 +2973,7 @@ void Server::handlePeerChange(PeerChange &c)
                        // The player shouldn't already exist
                        assert(player == NULL);
 
-                       player = new ServerRemotePlayer();
+                       player = new ServerRemotePlayer(true);
                        player->peer_id = c.peer_id;
 
                        /*