fine-tuning of map generator and server and stuff.
authorPerttu Ahola <celeron55@gmail.com>
Mon, 17 Jan 2011 00:40:53 +0000 (02:40 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Mon, 17 Jan 2011 00:40:53 +0000 (02:40 +0200)
src/defaultsettings.cpp
src/main.cpp
src/map.cpp
src/map.h
src/materials.cpp
src/player.cpp
src/server.cpp
src/server.h
src/test.cpp
src/utility.cpp
src/utility.h

index dd4a7b2ef8be407f40f72eabebac40db09c7a608..d3e193f9ea70e5fc6dad3db74250b14b1b82fde6 100644 (file)
@@ -61,10 +61,11 @@ void set_default_settings()
        g_settings.setDefault("active_object_range", "2");
        g_settings.setDefault("max_simultaneous_block_sends_per_client", "1");
        g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");
+       g_settings.setDefault("water_moves", "true");
        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", "5");
+       g_settings.setDefault("max_block_send_distance", "6");
+       g_settings.setDefault("max_block_generate_distance", "6");
        g_settings.setDefault("time_send_interval", "20");
        g_settings.setDefault("time_speed", "96");
        g_settings.setDefault("server_unload_unused_sectors_timeout", "60");
index f36f17a1de9337115112eb9692bae9318c2a88dc..51d94aba4a1155a080d7ce4c710b77e17c59bd0b 100644 (file)
@@ -168,6 +168,8 @@ TODO: Check what goes wrong with caching map to disk (Kray)
 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
+TODO: Generate map from the area the client is looking at\r
+\r
 Objects:\r
 \r
 TODO: Better handling of objects and mobs\r
@@ -1409,10 +1411,11 @@ int main(int argc, char *argv[])
        video::E_DRIVER_TYPE driverType;\r
 \r
 #ifdef _WIN32\r
-       //driverType = video::EDT_DIRECT3D9; // Doesn't seem to work\r
+       //driverType = video::EDT_DIRECT3D9;\r
        driverType = video::EDT_OPENGL;\r
 #else\r
        driverType = video::EDT_OPENGL;\r
+       //driverType = video::EDT_BURNINGSVIDEO;\r
 #endif\r
 \r
        // create device and exit if creation failed\r
index c290f69e9a2c476b2ca2a6c5acd701183763bd04..d15ac0a7b79402c55d7d6c993c09fffc8e525d80 100644 (file)
@@ -1317,17 +1317,26 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
        */
        
        {
+               dstream<<"Generating map point attribute lists"<<std::endl;
+               
                PointAttributeList *list_baseheight = m_padb.getList("hm_baseheight");
                PointAttributeList *list_randmax = m_padb.getList("hm_randmax");
                PointAttributeList *list_randfactor = m_padb.getList("hm_randfactor");
                PointAttributeList *list_plants_amount = m_padb.getList("plants_amount");
                PointAttributeList *list_caves_amount = m_padb.getList("caves_amount");
+
+               /*
+                       NOTE: BEWARE: Too big amount of these will make map generation
+                       slow. Especially those that are read by every block emerge.
+               */
                
-               for(u32 i=0; i<3000; i++)
+               for(u32 i=0; i<15000; i++)
                {
-                       u32 lim = MAP_GENERATION_LIMIT;
-                       if(i < 200)
-                               lim = 1000;
+                       /*u32 lim = MAP_GENERATION_LIMIT;
+                       if(i < 400)
+                               lim = 2000;*/
+
+                       u32 lim = 1000 + MAP_GENERATION_LIMIT * i / 15000;
 
                        v3s16 p(
                                -lim + myrand()%(lim*2),
@@ -1356,6 +1365,24 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
                                plants_amount = 0.0;
                        }
 
+
+                       list_plants_amount->addPoint(p, Attribute(plants_amount));
+               }
+
+               for(u32 i=0; i<1000; i++)
+               {
+                       /*u32 lim = MAP_GENERATION_LIMIT;
+                       if(i < 400)
+                               lim = 2000;*/
+
+                       u32 lim = 500 + MAP_GENERATION_LIMIT * i / 1000;
+
+                       v3s16 p(
+                               -lim + myrand()%(lim*2),
+                               0,
+                               -lim + myrand()%(lim*2)
+                       );
+
                        float caves_amount = 0;
                        if(myrand()%5 == 0)
                        {
@@ -1370,20 +1397,21 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
                                caves_amount = 0.05;
                        }
 
-                       list_plants_amount->addPoint(p, Attribute(plants_amount));
                        list_caves_amount->addPoint(p, Attribute(caves_amount));
                }
-#if 1
-               for(u32 i=0; i<3000; i++)
+               
+               for(u32 i=0; i<5000; i++)
                {
-                       u32 lim = MAP_GENERATION_LIMIT;
-                       if(i < 100)
-                               lim = 1000;
+                       /*u32 lim = MAP_GENERATION_LIMIT;
+                       if(i < 400)
+                               lim = 2000;*/
+
+                       u32 lim = 1000 + MAP_GENERATION_LIMIT * i / 5000;
 
                        v3s16 p(
-                               -lim + myrand()%(lim*2),
+                               -lim + (myrand()%(lim*2)),
                                0,
-                               -lim + myrand()%(lim*2)
+                               -lim + (myrand()%(lim*2))
                        );
                        
                        /*s32 bh_i = (myrand()%200) - 50;
@@ -1404,13 +1432,13 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
                        if(myrand()%4 == 0)
                        {
                                baseheight = 100;
-                               randmax = 100;
+                               randmax = 50;
                                randfactor = 0.63;
                        }
-                       else if(myrand()%5 == 0)
+                       else if(myrand()%6 == 0)
                        {
                                baseheight = 200;
-                               randmax = 200;
+                               randmax = 100;
                                randfactor = 0.66;
                        }
                        else if(myrand()%4 == 0)
@@ -1423,7 +1451,7 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
                        {
                                baseheight = 0;
                                randmax = 30;
-                               randfactor = 0.60;
+                               randfactor = 0.63;
                        }
                        else
                        {
@@ -1436,68 +1464,16 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
                        list_randmax->addPoint(p, Attribute(randmax));
                        list_randfactor->addPoint(p, Attribute(randfactor));
                }
-#endif
 
                /*list_baseheight->addPoint(v3s16(0,0,0), Attribute(5));
                list_randmax->addPoint(v3s16(0,0,0), Attribute(20));
                list_randfactor->addPoint(v3s16(0,0,0), Attribute(0.6));*/
-       }
-
-#if 0
-       {
-               PointAttributeList *palist = m_padb.getList("hm_baseheight");
-
-               {
-                       v3s16 p(0,0,0);
-                       Attribute attr;
-                       attr.set("5");
-                       palist->addPoint(p, attr);
-               }
 
-               /*{
-                       v3s16 p(-50,-50,0);
-                       Attribute attr;
-                       attr.set("-10");
-                       palist->addPoint(p, attr);
-               }
-               
-               {
-                       v3s16 p(50,0,50);
-                       Attribute attr;
-                       attr.set("200");
-                       palist->addPoint(p, attr);
-               }*/
+               // 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));*/
        }
-#endif
-#if 0
-       {
-               PointAttributeList *palist = m_padb.getList("plants_amount");
-       
-               // Back
-               {
-                       v3s16 p(0,0,-100);
-                       Attribute attr;
-                       attr.set("0");
-                       palist->addPoint(p, attr);
-               }
-               
-               // Front right
-               {
-                       v3s16 p(100,0,100);
-                       Attribute attr;
-                       attr.set("2.0");
-                       palist->addPoint(p, attr);
-               }
-               
-               // Front left
-               {
-                       v3s16 p(-100,0,100);
-                       Attribute attr;
-                       attr.set("0.2");
-                       palist->addPoint(p, attr);
-               }
-       }
-#endif
 
        /*
                Try to load map; if not found, create a new one.
@@ -1704,6 +1680,8 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
                Get local attributes
        */
        
+       //dstream<<"emergeSector(): Reading point attribute lists"<<std::endl;
+       
        // Get plant amount from attributes
        PointAttributeList *palist = m_padb.getList("plants_amount");
        assert(palist);
@@ -1712,6 +1690,8 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
        float local_plants_amount =
                        palist->getInterpolatedFloat(nodepos2d);
 
+       //dstream<<"emergeSector(): done."<<std::endl;
+
        /*
                Generate sector heightmap
        */
@@ -1810,7 +1790,7 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
        /*
                Add ravine (randomly)
        */
-       if(m_params.ravines_amount != 0)
+       if(m_params.ravines_amount > 0.001)
        {
                if(myrand()%(s32)(200.0 / m_params.ravines_amount) == 0)
                {
@@ -2061,13 +2041,32 @@ MapBlock * ServerMap::emergeBlock(
 
        bool some_part_underground = block_y * MAP_BLOCKSIZE <= highest_ground_y;
 
+       bool mostly_underwater_surface = false;
+       if(highest_ground_y < WATER_LEVEL
+                       && some_part_underground && !completely_underground)
+               mostly_underwater_surface = true;
+
        /*
                Get local attributes
        */
+
+       //dstream<<"emergeBlock(): Getting local attributes"<<std::endl;
+
+       float caves_amount = 0;
        
-       v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
-       PointAttributeList *list_caves_amount = m_padb.getList("caves_amount");
-       float caves_amount = list_caves_amount->getInterpolatedFloat(nodepos2d);
+       {
+               /*
+                       NOTE: BEWARE: Too big amount of attribute points slows verything
+                       down by a lot.
+                       1 interpolation from 5000 points takes 2-3ms.
+               */
+               //TimeTaker timer("emergeBlock() local attribute retrieval");
+               v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
+               PointAttributeList *list_caves_amount = m_padb.getList("caves_amount");
+               caves_amount = list_caves_amount->getInterpolatedFloat(nodepos2d);
+       }
+
+       //dstream<<"emergeBlock(): Done"<<std::endl;
 
        /*
                Generate dungeons
@@ -2082,6 +2081,7 @@ MapBlock * ServerMap::emergeBlock(
        }
        
        // Fill table
+#if 1
        {
                /*
                        Initialize orp and ors. Try to find if some neighboring
@@ -2207,21 +2207,34 @@ MapBlock * ServerMap::emergeBlock(
 continue_generating:
                
                /*
-                       Don't always generate dungeon
+                       Choose whether to actually generate dungeon
                */
                bool do_generate_dungeons = true;
                // Don't generate if no part is underground
                if(!some_part_underground)
+               {
                        do_generate_dungeons = false;
-               // If block is partly underground, caves are generated.
+               }
+               // Don't generate if mostly underwater surface
+               else if(mostly_underwater_surface)
+               {
+                       do_generate_dungeons = false;
+               }
+               // Partly underground = cave
                else if(!completely_underground)
-                       do_generate_dungeons = (rand() % 100 <= (u32)(caves_amount*100));
-               // Always continue if found existing dungeons underground
+               {
+                       do_generate_dungeons = (rand() % 100 <= (s32)(caves_amount*100));
+               }
+               // Found existing dungeon underground
                else if(found_existing && completely_underground)
-                       do_generate_dungeons = true;
-               // If underground and no dungeons found
+               {
+                       do_generate_dungeons = (rand() % 100 <= (s32)(caves_amount*100));
+               }
+               // Underground and no dungeons found
                else
-                       do_generate_dungeons = (rand() % 2 == 0);
+               {
+                       do_generate_dungeons = (rand() % 300 <= (s32)(caves_amount*100));
+               }
 
                if(do_generate_dungeons)
                {
@@ -2271,10 +2284,11 @@ continue_generating:
                        }
                }
        }
+#endif
 
        // Set to true if has caves.
        // Set when some non-air is changed to air when making caves.
-       bool has_caves = false;
+       bool has_dungeons = false;
 
        /*
                Apply temporary cave data to block
@@ -2296,7 +2310,7 @@ continue_generating:
                                if(is_ground_content(n.d))
                                {
                                        // Has now caves
-                                       has_caves = true;
+                                       has_dungeons = true;
                                        // Set air to node
                                        n.d = CONTENT_AIR;
                                }
@@ -2316,7 +2330,7 @@ continue_generating:
                Force lighting update if some part of block is partly
                underground and has caves.
        */
-       /*if(some_part_underground && !completely_underground && has_caves)
+       /*if(some_part_underground && !completely_underground && has_dungeons)
        {
                //dstream<<"Half-ground caves"<<std::endl;
                lighting_invalidated_blocks[block->getPos()] = block;
@@ -2336,9 +2350,9 @@ continue_generating:
                /*
                        Add meseblocks
                */
-               for(s16 i=0; i< underground_level/4 + 1; i++)
+               for(s16 i=0; i<underground_level/4 + 1; i++)
                {
-                       if(myrand()%10 == 0)
+                       if(myrand()%50 == 0)
                        {
                                v3s16 cp(
                                        (myrand()%(MAP_BLOCKSIZE-2))+1,
@@ -2697,7 +2711,27 @@ continue_generating:
 
                changed_blocks.insert(block->getPos(), block);
        }
-       
+
+       /*
+               Debug information
+       */
+       if(0)
+       {
+               dstream
+               <<"lighting_invalidated_blocks.size()"
+               <<", has_dungeons"
+               <<", completely_ug"
+               <<", some_part_ug"
+               <<"  "<<lighting_invalidated_blocks.size()
+               <<", "<<has_dungeons
+               <<", "<<completely_underground
+               <<", "<<some_part_underground
+               <<std::endl;
+       }
+
+       /*
+               Debug mode operation
+       */
        if(HAXMODE)
        {
                // Don't calculate lighting at all
@@ -3412,6 +3446,17 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                                if not seen on display
                        */
                        
+                       float range = 100000 * BS;
+                       if(m_control.range_all == false)
+                               range = m_control.wanted_range * BS;
+
+                       if(isBlockInSight(block->getPos(), camera_position,
+                                       camera_direction, range) == false)
+                       {
+                               continue;
+                       }
+
+#if 0                  
                        v3s16 blockpos_nodes = block->getPosRelative();
                        
                        // Block center position
@@ -3434,8 +3479,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                        {
                                // If block is far away, don't draw it
                                if(d > m_control.wanted_range * BS)
-                               // This is nicer when fog is used
-                               //if((dforward+d)/2 > m_control.wanted_range * BS)
                                        continue;
                        }
                        
@@ -3460,7 +3503,23 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                                if(cosangle < cos(FOV_ANGLE/2. * 4./3.))
                                        continue;
                        }
+#endif                 
+
+                       v3s16 blockpos_nodes = block->getPosRelative();
                        
+                       // Block center position
+                       v3f blockpos(
+                                       ((float)blockpos_nodes.X + MAP_BLOCKSIZE/2) * BS,
+                                       ((float)blockpos_nodes.Y + MAP_BLOCKSIZE/2) * BS,
+                                       ((float)blockpos_nodes.Z + MAP_BLOCKSIZE/2) * BS
+                       );
+
+                       // Block position relative to camera
+                       v3f blockpos_relative = blockpos - camera_position;
+
+                       // Total distance
+                       f32 d = blockpos_relative.getLength();
+
                        /*
                                Draw the faces of the block
                        */
index 3385d7c68a99d18d66ea129ef5a054c805d97f66..d858a99070161ba83be825ea7ffb0b8866fe739a 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -206,7 +206,7 @@ public:
                their differing fetch methods.
        */
        virtual MapSector * emergeSector(v2s16 p) = 0;
-       
+
        // Returns InvalidPositionException if not found
        MapBlock * getBlockNoCreate(v3s16 p);
        // Returns NULL if not found
index 1c177e9a3189c0e7f7e04eb52d45852b7668045b..bc39619fcf0abed0f21ae14953d418d6ffa2b49d 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, 1.5*toughness, 65535./20.*toughness));
+                       DiggingProperties(true, 1.5*toughness, 65535./30.*toughness));
        g_material_properties[material].setDiggingProperties("STPick",
-                       DiggingProperties(true, 0.7*toughness, 65535./60.*toughness));
+                       DiggingProperties(true, 0.7*toughness, 65535./100.*toughness));
 
        /*g_material_properties[material].setDiggingProperties("MesePick",
                        DiggingProperties(true, 0.0*toughness, 65535./20.*toughness));*/
index 3c06283a03a4afaab0e37d19d4f83ce9b06675cb..72e44f0e06b5c235af1f031be4e3c14bc0709f6f 100644 (file)
@@ -46,6 +46,20 @@ Player::~Player()
 // Y direction is ignored
 void Player::accelerate(v3f target_speed, f32 max_increase)
 {
+       v3f d_wanted = target_speed - m_speed;
+       d_wanted.Y = 0;
+       f32 dl_wanted = d_wanted.getLength();
+       f32 dl = dl_wanted;
+       if(dl > max_increase)
+               dl = max_increase;
+       
+       v3f d = d_wanted.normalize() * dl;
+
+       m_speed.X += d.X;
+       m_speed.Z += d.Z;
+       //m_speed += d;
+
+#if 0 // old code
        if(m_speed.X < target_speed.X - max_increase)
                m_speed.X += max_increase;
        else if(m_speed.X > target_speed.X + max_increase)
@@ -63,6 +77,7 @@ void Player::accelerate(v3f target_speed, f32 max_increase)
                m_speed.Z = target_speed.Z;
        else if(m_speed.Z > target_speed.Z)
                m_speed.Z = target_speed.Z;
+#endif
 }
 
 /*
@@ -209,7 +224,7 @@ void LocalPlayer::move(f32 dtime, Map &map)
        position += m_speed * dtime;
 
        // Skip collision detection if player is non-local
-       if(isLocal() == false)
+       if(isLocal() == false || HAXMODE)
        {
                setPosition(position);
                return;
@@ -286,10 +301,6 @@ void LocalPlayer::move(f32 dtime, Map &map)
                                {
                                        // Doing nothing here will block the player from
                                        // walking over map borders
-
-                                       // Go over borders in debug mode
-                                       if(HAXMODE)
-                                               continue;
                                }
 
                                core::aabbox3d<f32> nodebox = Map::getNodeBox(
index da643339bb5f4d61da7820bef6d425d4c329a4bc..3b3dfb657b6944e80e0510188504d651582d25a6 100644 (file)
@@ -328,6 +328,13 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
        v3s16 center_nodepos = floatToInt(playerpos);
 
        v3s16 center = getNodeBlockPos(center_nodepos);
+       
+       // Camera position and direction
+       v3f camera_pos =
+                       playerpos + v3f(0, BS+BS/2, 0);
+       v3f camera_dir = v3f(0,0,1);
+       camera_dir.rotateYZBy(player->getPitch());
+       camera_dir.rotateXZBy(player->getYaw());
 
        /*
                Get the starting value of the block finder radius.
@@ -496,6 +503,15 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                                if(abs(p.Y - center.Y) > d_max_gen - d_max_gen / 3)
                                        generate = false;
                        }
+
+                       /*
+                               Don't draw if not in sight
+                       */
+
+                       if(isBlockInSight(p, camera_pos, camera_dir, 10000*BS) == false)
+                       {
+                               continue;
+                       }
                        
                        /*
                                Don't send already sent blocks
@@ -511,6 +527,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                        {
                                /*
                                        Ignore block if it is not at ground surface
+                                       but don't ignore water surface blocks
                                */
                                v2s16 p2d(p.X*MAP_BLOCKSIZE + MAP_BLOCKSIZE/2,
                                                p.Z*MAP_BLOCKSIZE + MAP_BLOCKSIZE/2);
@@ -519,7 +536,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                                if(y > GROUNDHEIGHT_VALID_MINVALUE)
                                {
                                        f32 by = p.Y*MAP_BLOCKSIZE + MAP_BLOCKSIZE/2;
-                                       if(fabs(by - y) > MAP_BLOCKSIZE + MAP_BLOCKSIZE/3)
+                                       if(fabs(by - y) > MAP_BLOCKSIZE + MAP_BLOCKSIZE/3
+                                                       && fabs(by - WATER_LEVEL) >= MAP_BLOCKSIZE)
                                                continue;
                                }
                        }
@@ -839,8 +857,11 @@ void RemoteClient::GotBlock(v3s16 p)
        if(m_blocks_sending.find(p) != NULL)
                m_blocks_sending.remove(p);
        else
-               dstream<<"RemoteClient::GotBlock(): Didn't find in"
-                               " m_blocks_sending"<<std::endl;
+       {
+               /*dstream<<"RemoteClient::GotBlock(): Didn't find in"
+                               " m_blocks_sending"<<std::endl;*/
+               m_excess_gotblocks++;
+       }
        m_blocks_sent.insert(p, true);
 }
 
@@ -1118,6 +1139,7 @@ void Server::AsyncRunStep()
        /*
                Flow water
        */
+       if(g_settings.getBool("water_moves") == true)
        {
                float interval;
                
@@ -3040,12 +3062,12 @@ Player *Server::emergePlayer(const char *name, const char *password)
                v2s16 nodepos;
                f32 groundheight = 0;
                // Try to find a good place a few times
-               for(s32 i=0; i<100; i++)
+               for(s32 i=0; i<500; i++)
                {
-                       s32 range = 1 + i*4;
+                       s32 range = 1 + i;
                        // We're going to try to throw the player to this position
-                       nodepos = v2s16(-range/2 + (myrand()%range),
-                                       -range/2 + (myrand()%range));
+                       nodepos = v2s16(-range + (myrand()%(range*2)),
+                                       -range + (myrand()%(range*2)));
                        v2s16 sectorpos = getNodeSectorPos(nodepos);
                        // Get sector
                        m_env.getMap().emergeSector(sectorpos);
@@ -3055,23 +3077,38 @@ Player *Server::emergePlayer(const char *name, const char *password)
                        assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE);
                        // Don't go underwater
                        if(groundheight < WATER_LEVEL)
+                       {
+                               //dstream<<"-> Underwater"<<std::endl;
                                continue;
+                       }
+#if 0 // Doesn't work, generating blocks is a bit too complicated for doing here
+                       // Get block at point
+                       v3s16 nodepos3d;
+                       nodepos3d = v3s16(nodepos.X, groundheight+1, nodepos.Y);
+                       v3s16 blockpos = getNodeBlockPos(nodepos3d);
+                       ((ServerMap*)(&m_env.getMap()))->emergeBlock(blockpos);
                        // Don't go inside ground
                        try{
-                               v3s16 footpos(nodepos.X, groundheight+1, nodepos.Y);
-                               v3s16 headpos(nodepos.X, groundheight+2, nodepos.Y);
+                               /*v3s16 footpos(nodepos.X, groundheight+1, nodepos.Y);
+                               v3s16 headpos(nodepos.X, groundheight+2, nodepos.Y);*/
+                               v3s16 footpos = nodepos3d + v3s16(0,0,0);
+                               v3s16 headpos = nodepos3d + v3s16(0,1,0);
                                if(m_env.getMap().getNode(footpos).d != CONTENT_AIR
                                        || m_env.getMap().getNode(headpos).d != CONTENT_AIR)
                                {
+                                       dstream<<"-> Inside ground"<<std::endl;
                                        // In ground
                                        continue;
                                }
                        }catch(InvalidPositionException &e)
                        {
+                               dstream<<"-> Invalid position"<<std::endl;
                                // Ignore invalid position
                                continue;
                        }
+#endif
                        // Found a good place
+                       dstream<<"Searched through "<<i<<" places."<<std::endl;
                        break;
                }
 #endif
index 099be9e14df9d17a8e824835204ea854cb57cb3b..3d7d133fc41a89fd7194e82bfefbc70bc309a33b 100644 (file)
@@ -231,7 +231,8 @@ public:
        u8 pending_serialization_version;
 
        RemoteClient():
-               m_time_from_building(9999)
+               m_time_from_building(9999),
+               m_excess_gotblocks(0)
        {
                peer_id = 0;
                serialization_version = SER_FMT_VER_INVALID;
@@ -295,7 +296,9 @@ public:
                                <<", m_blocks_sent.size()="<<m_blocks_sent.size()
                                <<", m_blocks_sending.size()="<<m_blocks_sending.size()
                                <<", m_nearest_unsent_d="<<m_nearest_unsent_d
+                               <<", m_excess_gotblocks="<<m_excess_gotblocks
                                <<std::endl;
+               m_excess_gotblocks = 0;
        }
 
        // Time from last placing or removing blocks
@@ -347,6 +350,15 @@ private:
        */
        core::map<v3s16, float> m_blocks_sending;
        JMutex m_blocks_sending_mutex;
+
+       /*
+               Count of excess GotBlocks().
+               There is an excess amount because the client sometimes
+               gets a block so late that the server sends it again,
+               and the client then sends two GOTBLOCKs.
+               This is resetted by PrintInfo()
+       */
+       u32 m_excess_gotblocks;
 };
 
 /*struct ServerSettings
index d78c62120c0944de9f1b1ac2fecd737c677280c3..1a172e4f5e0f736b8250d57d10dffe5a961f932f 100644 (file)
@@ -748,7 +748,7 @@ struct TestHeightmap
 
                padb.getList("hm_baseheight")->addPoint(v2s16(BS1*2,BS1), Attribute(0));
                padb.getList("hm_randmax")->addPoint(v2s16(BS1*2,BS1), Attribute(30));
-               padb.getList("hm_randfactor")->addPoint(v2s16(BS1*2,BS1), Attribute(0.9));
+               padb.getList("hm_randfactor")->addPoint(v2s16(BS1*2,BS1), Attribute(0.63));
 
                UnlimitedHeightmap hm1(BS1, &padb);
 
index d6ca48153746e2061838ae42f69c77914e0dc1bc..6f16b7658b578f4f6f3d127dfce6ec147040619b 100644 (file)
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "utility.h"
 #include "irrlichtwrapper.h"
 #include "gettime.h"
+#include "mapblock.h"
 
 TimeTaker::TimeTaker(const char *name, u32 *result)
 {
@@ -328,4 +329,58 @@ lopuks sit otetaan a/b
 }
 #endif
 
+/*
+       blockpos: position of block in block coordinates
+       camera_pos: position of camera in nodes
+       camera_dir: an unit vector pointing to camera direction
+       range: viewing range
+*/
+bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range)
+{
+       v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE;
+       
+       // Block center position
+       v3f blockpos(
+                       ((float)blockpos_nodes.X + MAP_BLOCKSIZE/2) * BS,
+                       ((float)blockpos_nodes.Y + MAP_BLOCKSIZE/2) * BS,
+                       ((float)blockpos_nodes.Z + MAP_BLOCKSIZE/2) * BS
+       );
+
+       // Block position relative to camera
+       v3f blockpos_relative = blockpos - camera_pos;
+
+       // Distance in camera direction (+=front, -=back)
+       f32 dforward = blockpos_relative.dotProduct(camera_dir);
+
+       // Total distance
+       f32 d = blockpos_relative.getLength();
+       
+       // If block is far away, it's not in sight
+       if(d > range * BS)
+               return false;
+
+       // Maximum radius of a block
+       f32 block_max_radius = 0.5*1.44*1.44*MAP_BLOCKSIZE*BS;
+       
+       // If block is (nearly) touching the camera, don't
+       // bother validating further (that is, render it anyway)
+       if(d > block_max_radius * 1.5)
+       {
+               // Cosine of the angle between the camera direction
+               // and the block direction (camera_dir is an unit vector)
+               f32 cosangle = dforward / d;
+               
+               // Compensate for the size of the block
+               // (as the block has to be shown even if it's a bit off FOV)
+               // This is an estimate.
+               cosangle += block_max_radius / dforward;
+
+               // If block is not in the field of view, skip it
+               //if(cosangle < cos(FOV_ANGLE/2))
+               if(cosangle < cos(FOV_ANGLE/2. * 4./3.))
+                       return false;
+       }
+
+       return true;
+}
 
index 28cc95ddd7b0eb847ca6f6b5ac3be51daf818373..c4f45ba0f1822232379fe617493cd0980352ccd2 100644 (file)
@@ -1574,5 +1574,12 @@ private:
        core::map<std::string, PointAttributeList*> m_lists;
 };
 
+/*
+       Miscellaneous functions
+*/
+
+bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range);
+
+
 #endif