day/night working client side
authorPerttu Ahola <celeron55@gmail.com>
Sun, 19 Dec 2010 14:51:45 +0000 (16:51 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 19 Dec 2010 14:51:45 +0000 (16:51 +0200)
22 files changed:
minetest.conf.example
src/client.cpp
src/client.h
src/connection.cpp
src/constants.h
src/environment.cpp
src/environment.h
src/light.cpp
src/light.h
src/main.cpp
src/map.cpp
src/map.h
src/mapblock.cpp
src/mapblock.h
src/mapblockobject.cpp
src/mapblockobject.h
src/serialization.h
src/server.cpp
src/server.h
src/tile.cpp
src/utility.h
src/voxel.cpp

index aa38c8c7a7dbd6394d75155994cc3017d219b54b..df0ff1e7c5bfb4f2ae5fc58e451cb23d8a2360f1 100644 (file)
@@ -23,6 +23,8 @@
 #random_input = false
 #client_delete_unused_sectors_timeout = 1200
 
+#enable_fog = true
+
 # Server side stuff
 
 # - The possible generators are:
@@ -51,8 +53,8 @@
 #max_simultaneous_block_sends_per_client = 1
 #max_simultaneous_block_sends_server_total = 4
 
-#max_block_send_distance = 8
-#max_block_generate_distance = 6
+#max_block_send_distance = 5
+#max_block_generate_distance = 4
 
 #disable_water_climb = true
 # Note that this gets applied at map generation time
index 9fc9ebce61442207aaabb4ecf63cdf7e9f333220..b4871ff61baf37b9c82e39ddd52cdc3443b5b1ba 100644 (file)
@@ -47,6 +47,8 @@ void * ClientUpdateThread::Thread()
                {
                        m_client->asyncStep();
 
+                       //m_client->updateSomeExpiredMeshes();
+
                        bool was = m_client->AsyncProcessData();
 
                        if(was == false)
@@ -84,7 +86,15 @@ Client::Client(IrrlichtDevice *device,
        m_inventory_updated(false),
        m_time(0),
        m_time_counter(0.0)
+       //m_daynight_i(0)
+       //m_daynight_ratio(1000)
 {
+       m_packetcounter_timer = 0.0;
+       m_delete_unused_sectors_timer = 0.0;
+       m_connection_reinit_timer = 0.0;
+       m_avg_rtt_timer = 0.0;
+       m_playerpos_send_timer = 0.0;
+
        //m_fetchblock_mutex.Init();
        m_incoming_queue_mutex.Init();
        m_env_mutex.Init();
@@ -154,14 +164,41 @@ void Client::step(float dtime)
                m_time += seconds;
                if(seconds > 0)
                {
-                       dstream<<"m_time="<<m_time<<std::endl;
-                       JMutexAutoLock envlock(m_env_mutex);
+                       //dstream<<"m_time="<<m_time<<std::endl;
+                       /*JMutexAutoLock envlock(m_env_mutex);
                        u32 dr = 500+500*sin((float)((m_time/10)%7)/7.*2.*PI);
-                       if(dr != m_env.getDaylightRatio())
+                       if(dr != m_env.getDayNightRatio())
                        {
                                dstream<<"dr="<<dr<<std::endl;
-                               m_env.setDaylightRatio(dr);
+                               m_env.setDayNightRatio(dr);
                                m_env.expireMeshes();
+                       }*/
+#if 1
+                       s32 d = 4;
+                       s32 t = (m_time/10)%d;
+                       s32 dn = 0;
+                       if(t == d/2-1 || t == d-1)
+                               dn = 1;
+                       else if(t < d/2-1)
+                               dn = 0;
+                       else
+                               dn = 2;
+
+                       u32 dr = 1000;
+                       if(dn == 0)
+                               dr = 1000;
+                       if(dn == 1)
+                               dr = 600;
+                       if(dn == 2)
+                               dr = 300;
+#else
+                       u32 dr = 1000;
+#endif
+                       if(dr != m_env.getDayNightRatio())
+                       {
+                               dstream<<"dr="<<dr<<std::endl;
+                               m_env.setDayNightRatio(dr);
+                               m_env.expireMeshes(true);
                        }
                }
        }
@@ -186,7 +223,7 @@ void Client::step(float dtime)
                Packet counter
        */
        {
-               static float counter = -0.001;
+               float &counter = m_packetcounter_timer;
                counter -= dtime;
                if(counter <= 0.0)
                {
@@ -206,12 +243,13 @@ void Client::step(float dtime)
                              clear caches
                */
                
-               static float counter = -0.001;
+               float &counter = m_delete_unused_sectors_timer;
                counter -= dtime;
                if(counter <= 0.0)
                {
                        // 3 minute interval
-                       counter = 180.0;
+                       //counter = 180.0;
+                       counter = 60.0;
 
                        JMutexAutoLock lock(m_env_mutex);
 
@@ -290,7 +328,7 @@ void Client::step(float dtime)
 
        if(connected == false)
        {
-               static float counter = -0.001;
+               float &counter = m_connection_reinit_timer;
                counter -= dtime;
                if(counter <= 0.0)
                {
@@ -354,12 +392,7 @@ void Client::step(float dtime)
        }
 
        {
-               // Fetch some nearby blocks
-               //fetchBlocks();
-       }
-
-       {
-               static float counter = 0.0;
+               float &counter = m_avg_rtt_timer;
                counter += dtime;
                if(counter >= 10)
                {
@@ -371,8 +404,7 @@ void Client::step(float dtime)
                }
        }
        {
-               // Update at reasonable intervals (0.2s)
-               static float counter = 0.0;
+               float &counter = m_playerpos_send_timer;
                counter += dtime;
                if(counter >= 0.2)
                {
@@ -1121,7 +1153,7 @@ bool Client::AsyncProcessPacket(LazyMeshUpdater &mesh_updater)
                                <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
 
                /*dstream<<DTIME<<"Client: Thread: BLOCKDATA for ("
-                               <<p.X<<","<<p.Y<<","<<p.Z<<"): ";*/
+                               <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/
                
                std::string datastring((char*)&data[8], datasize-8);
                std::istringstream istr(datastring, std::ios_base::binary);
@@ -1780,9 +1812,71 @@ void Client::printDebugInfo(std::ostream &os)
                <<std::endl;
 }
        
-float Client::getDaylightRatio()
+/*s32 Client::getDayNightIndex()
+{
+       assert(m_daynight_i >= 0 && m_daynight_i < DAYNIGHT_CACHE_COUNT);
+       return m_daynight_i;
+}*/
+
+u32 Client::getDayNightRatio()
 {
        JMutexAutoLock envlock(m_env_mutex);
-       return m_env.getDaylightRatio();
+       return m_env.getDayNightRatio();
 }
 
+/*void Client::updateSomeExpiredMeshes()
+{
+       TimeTaker timer("updateSomeExpiredMeshes()", g_device);
+       
+       Player *player;
+       {
+               JMutexAutoLock envlock(m_env_mutex);
+               player = m_env.getLocalPlayer();
+       }
+
+       u32 daynight_ratio = getDayNightRatio();
+
+       v3f playerpos = player->getPosition();
+       v3f playerspeed = player->getSpeed();
+
+       v3s16 center_nodepos = floatToInt(playerpos);
+       v3s16 center = getNodeBlockPos(center_nodepos);
+
+       u32 counter = 0;
+
+       s16 d_max = 5;
+       
+       for(s16 d = 0; d <= d_max; d++)
+       {
+               core::list<v3s16> list;
+               getFacePositions(list, d);
+               
+               core::list<v3s16>::Iterator li;
+               for(li=list.begin(); li!=list.end(); li++)
+               {
+                       v3s16 p = *li + center;
+                       MapBlock *block = NULL;
+                       try
+                       {
+                               //JMutexAutoLock envlock(m_env_mutex);
+                               block = m_env.getMap().getBlockNoCreate(p);
+                       }
+                       catch(InvalidPositionException &e)
+                       {
+                       }
+
+                       if(block == NULL)
+                               continue;
+
+                       if(block->getMeshExpired() == false)
+                               continue;
+
+                       block->updateMesh(daynight_ratio);
+
+                       counter++;
+                       if(counter >= 5)
+                               return;
+               }
+       }
+}*/
+
index 413a936c6b9dac8edf1608f115b70ebdb6785a81..18aa619c62a42a7b0695ceb055f8067ef73714e3 100644 (file)
@@ -36,35 +36,19 @@ public:
 
 class Client;
 
-class ClientUpdateThread : public JThread
+class ClientUpdateThread : public SimpleThread
 {
-       bool run;
-       JMutex run_mutex;
-
        Client *m_client;
 
 public:
 
-       ClientUpdateThread(Client *client) : JThread(), run(true), m_client(client)
+       ClientUpdateThread(Client *client):
+                       SimpleThread(),
+                       m_client(client)
        {
-               run_mutex.Init();
        }
 
        void * Thread();
-
-       bool getRun()
-       {
-               run_mutex.Lock();
-               bool run_cached = run;
-               run_mutex.Unlock();
-               return run_cached;
-       }
-       void setRun(bool a_run)
-       {
-               run_mutex.Lock();
-               run = a_run;
-               run_mutex.Unlock();
-       }
 };
 
 struct IncomingPacket
@@ -98,6 +82,7 @@ struct IncomingPacket
                        if(*m_refcount == 0){
                                if(m_data != NULL)
                                        delete[] m_data;
+                               delete m_refcount;
                        }
                }
        }
@@ -237,7 +222,10 @@ public:
        // Prints a line or two of info
        void printDebugInfo(std::ostream &os);
 
-       float getDaylightRatio();
+       //s32 getDayNightIndex();
+       u32 getDayNightRatio();
+
+       //void updateSomeExpiredMeshes();
        
 private:
        
@@ -252,6 +240,12 @@ private:
        // This sends the player's current name etc to the server
        void sendPlayerInfo();
 
+       float m_packetcounter_timer;
+       float m_delete_unused_sectors_timer;
+       float m_connection_reinit_timer;
+       float m_avg_rtt_timer;
+       float m_playerpos_send_timer;
+
        ClientUpdateThread m_thread;
        
        // NOTE: If connection and environment are both to be locked,
@@ -290,6 +284,10 @@ private:
        // Access these only in main thread.
        u32 m_time;
        float m_time_counter;
+       
+       // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
+       //s32 m_daynight_i;
+       //u32 m_daynight_ratio;
 };
 
 #endif
index 4e26c43e95766d0590725584d73ab491f14678a3..e0a201773da944849f1f4e72a034660353430633 100644 (file)
@@ -445,6 +445,7 @@ Peer::Peer(u16 a_id, Address a_address)
        address = a_address;
        timeout_counter = 0.0;
        //resend_timeout = RESEND_TIMEOUT_MINIMUM;
+       ping_timer = 0.0;
        resend_timeout = 0.5;
        avg_rtt = -1.0;
        has_sent_with_id = false;
index 83a070217f1e547e0ffe5c8f62e2572ca1968384..3c9b50eff2610de4faba9c6451140f60ca2fde27 100644 (file)
@@ -39,32 +39,29 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #define PI 3.14159
 
-#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (60*10)
+//#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (60*10)
+#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (60)
 #define SERVER_MAP_SAVE_INTERVAL (60)
 /*#define SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT (10)
 #define SERVER_MAP_SAVE_INTERVAL (10)*/
 
+// This is the same as in minecraft and everything else
 #define FOV_ANGLE (PI/2.5)
-//#define FOV_ANGLE (PI/2.25)
 
 // The absolute working limit is (2^15 - viewing_range).
 #define MAP_GENERATION_LIMIT (31000)
 
-//#define MAX_SIMULTANEOUS_BLOCK_SENDS 2
-
+// Time after building, during which the following limit
+// is in use
 #define FULL_BLOCK_SEND_ENABLE_MIN_TIME_FROM_BUILDING 2.0
-//#define LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS 1
+// This many blocks are sent when player is building
 #define LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS 0
-
-// Override for the previous one when distance is low
+// Override for the previous one when distance of block
+// is very low
 #define BLOCK_SEND_DISABLE_LIMITS_MAX_D 1
 
-//#define MAX_SIMULTANEOUS_BLOCK_SENDS_SERVER_TOTAL 4
-
 // Viewing range stuff
 
-//#define HEIGHTMAP_RANGE_NODES 300
-
 //#define FREETIME_RATIO 0.2
 #define FREETIME_RATIO 0.15
 
@@ -75,10 +72,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #define SIGN_TEXT_MAX_LENGTH 50
 
-// The distance of how far objects will be sent to client
-//#define ACTIVE_OBJECT_D_BLOCKS 2
-
-// Wether to catch all std::exceptions.
+// Whether to catch all std::exceptions.
 // Assert will be called on such an event.
 #define CATCH_UNHANDLED_EXCEPTIONS 1
 
@@ -88,7 +82,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 #define MAX_OBJECTDATA_SIZE 450
 
-//#define WATER_LEVEL (-5)
 #define WATER_LEVEL (0)
 
 #endif
index d9d8b13aeb046d4754cfe3936dfe6359225d2c7a..bb2d168edd425f60afab9f1de1f70705ea2477df 100644 (file)
@@ -24,7 +24,7 @@ Environment::Environment(Map *map, std::ostream &dout):
                m_dout(dout)
 {
        m_map = map;
-       m_daylight_ratio = 0.2;
+       m_daynight_ratio = 0.2;
 }
 
 Environment::~Environment()
@@ -36,7 +36,9 @@ Environment::~Environment()
                delete (*i);
        }
        
-       delete m_map;
+       // The map is removed by the SceneManager
+       m_map->drop();
+       //delete m_map;
 }
 
 void Environment::step(float dtime)
@@ -153,7 +155,7 @@ void Environment::step(float dtime)
                                        {
                                                v3s16 p_blocks = getNodeBlockPos(bottompos);
                                                MapBlock *b = m_map->getBlockNoCreate(p_blocks);
-                                               b->updateMesh(m_daylight_ratio);
+                                               b->updateMesh(m_daynight_ratio);
                                        }
                                }
                        }
@@ -243,21 +245,21 @@ void Environment::printPlayers(std::ostream &o)
 
 void Environment::updateMeshes(v3s16 blockpos)
 {
-       m_map->updateMeshes(blockpos, m_daylight_ratio);
+       m_map->updateMeshes(blockpos, m_daynight_ratio);
 }
 
-void Environment::expireMeshes()
+void Environment::expireMeshes(bool only_daynight_diffed)
 {
-       m_map->expireMeshes();
+       m_map->expireMeshes(only_daynight_diffed);
 }
 
-void Environment::setDaylightRatio(u32 r)
+void Environment::setDayNightRatio(u32 r)
 {
-       m_daylight_ratio = r;
+       m_daynight_ratio = r;
 }
 
-u32 Environment::getDaylightRatio()
+u32 Environment::getDayNightRatio()
 {
-       return m_daylight_ratio;
+       return m_daynight_ratio;
 }
 
index 6fdf6d33dcbe0abc958ab077c7e41c27a75cd16d..4b18d6b7367ce9ffb63142a354523c3d90e8c337 100644 (file)
@@ -61,16 +61,16 @@ public:
        void printPlayers(std::ostream &o);
 
        void updateMeshes(v3s16 blockpos);
-       void expireMeshes();
-       void setDaylightRatio(u32 r);
-       u32 getDaylightRatio();
+       void expireMeshes(bool only_daynight_diffed);
+       void setDayNightRatio(u32 r);
+       u32 getDayNightRatio();
 
 private:
        Map *m_map;
        core::list<Player*> m_players;
        // Debug output goes here
        std::ostream &m_dout;
-       u32 m_daylight_ratio;
+       u32 m_daynight_ratio;
 };
 
 #endif
index 73ca297c7ca3d997de55c19d8caf7abc9290b946..fec800874b717f20e8017ec63e7012cf089ec7a0 100644 (file)
@@ -19,15 +19,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "light.h"
 
-// LIGHT_MAX is 14, 0-14 is 15 values
-/*u8 light_decode_table[LIGHT_MAX+1] = 
+/*u32 daynight_cache_ratios[DAYNIGHT_CACHE_COUNT] =
+{
+       1000,
+       600,
+       300
+};*/
+
+u8 light_decode_table[LIGHT_MAX+1] = 
 {
 0,
-9,
-12,
+6,
+8,
+11,
 14,
-16,
-20,
+19,
 26,
 34,
 45,
@@ -37,8 +43,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 143,
 191,
 255,
+};
+/*u8 light_decode_table[LIGHT_MAX+1] = 
+{
+0,
+3,
+6,
+10,
+18,
+25,
+35,
+50,
+75,
+95,
+120,
+150,
+185,
+215,
+255,
 };*/
-u8 light_decode_table[LIGHT_MAX+1] = 
+/*u8 light_decode_table[LIGHT_MAX+1] = 
 {
 0,
 5,
@@ -55,7 +79,26 @@ u8 light_decode_table[LIGHT_MAX+1] =
 185,
 215,
 255,
-};
+};*/
+// LIGHT_MAX is 14, 0-14 is 15 values
+/*u8 light_decode_table[LIGHT_MAX+1] = 
+{
+0,
+9,
+12,
+14,
+16,
+20,
+26,
+34,
+45,
+61,
+81,
+108,
+143,
+191,
+255,
+};*/
 
 #if 0
 /*
index 41d6f8bbe9f7b9548c9a9ca3a7b10c30de97b9e6..269948e86bcc2b77ed08e260253651a3963d421b 100644 (file)
@@ -22,6 +22,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "common_irrlicht.h"
 
+/*
+       Day/night cache:
+       Meshes are cached for different day-to-night transition values
+*/
+
+/*#define DAYNIGHT_CACHE_COUNT 3
+// First one is day, last one is night.
+extern u32 daynight_cache_ratios[DAYNIGHT_CACHE_COUNT];*/
+
 /*
        Lower level lighting stuff
 */
index 5d1be0184c174670e3edff4c02b15ffa6178a3e6..6d470f73d8c2708e98c25e51aef5fefc64cd671d 100644 (file)
@@ -176,14 +176,13 @@ TODO: Node cracking animation when digging
       - TODO: A way to generate new textures by combining textures\r
          - TODO: Mesh update to fetch cracked faces from the former\r
 \r
+TODO: Add server unused sector deletion settings to settings\r
+\r
+TODO: TOSERVER_LEAVE\r
+\r
 Doing now:\r
 ======================================================================\r
 \r
-TODO: Add a second lighting value to the MS nibble of param of\r
-      air to tell how bright the air node is when there is no sunlight.\r
-         When day changes to night, these two values can be interpolated.\r
-         - The biggest job is to add support to the lighting routines\r
-\r
 ======================================================================\r
 \r
 */\r
@@ -315,8 +314,7 @@ void set_default_settings()
        g_settings.setDefault("name", "");\r
        g_settings.setDefault("random_input", "false");\r
        g_settings.setDefault("client_delete_unused_sectors_timeout", "1200");\r
-       g_settings.setDefault("max_block_send_distance", "8");\r
-       g_settings.setDefault("max_block_generate_distance", "6");\r
+       g_settings.setDefault("enable_fog", "true");\r
 \r
        // Server stuff\r
        g_settings.setDefault("creative_mode", "false");\r
@@ -332,6 +330,8 @@ void set_default_settings()
        g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");\r
        g_settings.setDefault("disable_water_climb", "true");\r
        g_settings.setDefault("endless_water", "true");\r
+       g_settings.setDefault("max_block_send_distance", "5");\r
+       g_settings.setDefault("max_block_generate_distance", "4");\r
 }\r
 \r
 /*\r
@@ -860,7 +860,8 @@ void updateViewingRange(f32 frametime, Client *client)
        \r
        // Initialize to the target value\r
        static float frametime_avg = 1.0/wanted_fps;\r
-       frametime_avg = frametime_avg * 0.9 + frametime * 0.1;\r
+       //frametime_avg = frametime_avg * 0.9 + frametime * 0.1;\r
+       frametime_avg = frametime_avg * 0.7 + frametime * 0.3;\r
 \r
        static f32 counter = 0;\r
        if(counter > 0){\r
@@ -878,6 +879,11 @@ void updateViewingRange(f32 frametime, Client *client)
 \r
        float fraction = sqrt(frametime_avg / frametime_wanted);\r
 \r
+       /*float fraction = sqrt(frametime_avg / frametime_wanted) / 2.0\r
+                       + frametime_avg / frametime_wanted / 2.0;*/\r
+       \r
+       //float fraction = frametime_avg / frametime_wanted;\r
+\r
        static bool fraction_is_good = false;\r
        \r
        float fraction_good_threshold = 0.1;\r
@@ -1048,9 +1054,9 @@ int main(int argc, char *argv[])
        \r
        /*\r
                Parse command line\r
-               TODO\r
        */\r
        \r
+       // List all allowed options\r
        core::map<std::string, ValueSpec> allowed_options;\r
        allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG));\r
        allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG,\r
@@ -1058,6 +1064,10 @@ int main(int argc, char *argv[])
        allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,\r
                        "Load configuration from specified file"));\r
        allowed_options.insert("port", ValueSpec(VALUETYPE_STRING));\r
+       allowed_options.insert("address", ValueSpec(VALUETYPE_STRING));\r
+       allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG));\r
+       allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG));\r
+       allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG));\r
 \r
        Settings cmd_args;\r
        \r
@@ -1116,14 +1126,6 @@ int main(int argc, char *argv[])
        // Initialize timestamp mutex\r
        g_timestamp_mutex.Init();\r
 \r
-       /*\r
-               Run unit tests\r
-       */\r
-       if(ENABLE_TESTS)\r
-       {\r
-               run_tests();\r
-       }\r
-       \r
        /*\r
                Initialization\r
        */\r
@@ -1168,6 +1170,18 @@ int main(int argc, char *argv[])
        // Initialize random seed\r
        srand(time(0));\r
 \r
+       /*\r
+               Run unit tests\r
+       */\r
+       if((ENABLE_TESTS && cmd_args.getFlag("disable-unittests") == false)\r
+                       || cmd_args.getFlag("enable-unittests") == true)\r
+       {\r
+               run_tests();\r
+       }\r
+       \r
+       /*\r
+               Global range mutex\r
+       */\r
        g_range_mutex.Init();\r
        assert(g_range_mutex.IsInitialized());\r
 \r
@@ -1263,14 +1277,18 @@ int main(int argc, char *argv[])
        bool hosting = false;\r
        char connect_name[100] = "";\r
 \r
-       std::cout<<"Address to connect to [empty = host a game]: ";\r
-       if(g_settings.get("address") != "" && is_yes(g_settings.get("host_game")) == false)\r
+       if(cmd_args.exists("address"))\r
+       {\r
+               snprintf(connect_name, 100, "%s", cmd_args.get("address").c_str());\r
+       }\r
+       else if(g_settings.get("address") != "" && is_yes(g_settings.get("host_game")) == false)\r
        {\r
                std::cout<<g_settings.get("address")<<std::endl;\r
                snprintf(connect_name, 100, "%s", g_settings.get("address").c_str());\r
        }\r
        else\r
        {\r
+               std::cout<<"Address to connect to [empty = host a game]: ";\r
                std::cin.getline(connect_name, 100);\r
        }\r
        \r
@@ -1280,9 +1298,9 @@ int main(int argc, char *argv[])
        }\r
        \r
        if(hosting)\r
-               std::cout<<"-> hosting"<<std::endl;\r
+               std::cout<<"> Hosting game"<<std::endl;\r
        else\r
-               std::cout<<"-> "<<connect_name<<std::endl;\r
+               std::cout<<"> Connecting to "<<connect_name<<std::endl;\r
        \r
        char playername[PLAYERNAME_SIZE] = "";\r
        if(g_settings.get("name") != "")\r
@@ -1393,7 +1411,9 @@ int main(int argc, char *argv[])
        \r
        device->setResizable(true);\r
 \r
-       if(g_settings.getBool("random_input"))\r
+       bool random_input = g_settings.getBool("random_input")\r
+                       || cmd_args.getFlag("random-input");\r
+       if(random_input)\r
                g_input = new RandomInputHandler();\r
        else\r
                g_input = new RealInputHandler(device, &receiver);\r
@@ -1523,14 +1543,14 @@ int main(int argc, char *argv[])
        /*\r
                Create skybox\r
        */\r
-       scene::ISceneNode* skybox;\r
+       /*scene::ISceneNode* skybox;\r
        skybox = smgr->addSkyBoxSceneNode(\r
                driver->getTexture("../data/skybox2.png"),\r
                driver->getTexture("../data/skybox3.png"),\r
                driver->getTexture("../data/skybox1.png"),\r
                driver->getTexture("../data/skybox1.png"),\r
                driver->getTexture("../data/skybox1.png"),\r
-               driver->getTexture("../data/skybox1.png"));\r
+               driver->getTexture("../data/skybox1.png"));*/\r
        \r
        /*\r
                Create the camera node\r
@@ -1553,21 +1573,6 @@ int main(int argc, char *argv[])
        // Just so big a value that everything rendered is visible\r
        camera->setFarValue(100000*BS);\r
 \r
-       /*//f32 range = BS*HEIGHTMAP_RANGE_NODES*0.9;\r
-       f32 range = BS*HEIGHTMAP_RANGE_NODES*0.9;\r
-       \r
-       camera->setFarValue(range);\r
-       \r
-       driver->setFog(\r
-               skycolor,\r
-               video::EFT_FOG_LINEAR,\r
-               range*0.8,\r
-               range,\r
-               0.01,\r
-               false,\r
-               false\r
-               );*/\r
-       \r
        f32 camera_yaw = 0; // "right/left"\r
        f32 camera_pitch = 0; // "up/down"\r
 \r
@@ -1888,9 +1893,11 @@ int main(int argc, char *argv[])
                        Mouse and camera control\r
                */\r
                \r
-               if(device->isWindowActive() && g_game_focused && !pauseMenu.isVisible())\r
+               if((device->isWindowActive() && g_game_focused && !pauseMenu.isVisible())\r
+                               || random_input)\r
                {\r
-                       device->getCursorControl()->setVisible(false);\r
+                       if(!random_input)\r
+                               device->getCursorControl()->setVisible(false);\r
 \r
                        if(first_loop_after_window_activation){\r
                                //std::cout<<"window active, first loop"<<std::endl;\r
@@ -1981,7 +1988,7 @@ int main(int argc, char *argv[])
                                if(selected_object->getTypeId() == MAPBLOCKOBJECT_TYPE_SIGN)\r
                                {\r
                                        dstream<<"Sign object right-clicked"<<std::endl;\r
-\r
+                                       \r
                                        unFocusGame();\r
 \r
                                        input_guitext = guienv->addStaticText(L"",\r
@@ -1992,8 +1999,17 @@ int main(int argc, char *argv[])
 \r
                                        input_guitext->setDrawBackground(true);\r
 \r
-                                       g_text_buffer = L"";\r
-                                       g_text_buffer_accepted = false;\r
+                                       if(random_input)\r
+                                       {\r
+                                               g_text_buffer = L"ASD LOL 8)";\r
+                                               g_text_buffer_accepted = true;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               g_text_buffer = L"";\r
+                                               g_text_buffer_accepted = false;\r
+                                       }\r
+\r
                                        textbuf_dest = new TextDestSign(\r
                                                        selected_object->getBlock()->getPos(),\r
                                                        selected_object->getId(),\r
@@ -2227,20 +2243,54 @@ int main(int argc, char *argv[])
                */\r
 \r
                camera->setAspectRatio((f32)screensize.X / (f32)screensize.Y);\r
+               \r
+               // Background color is choosen based on whether the player is\r
+               // much beyond the initial ground level\r
+               /*video::SColor bgcolor;\r
+               v3s16 p0 = Map::floatToInt(player_position);\r
+               // Does this make short random delays?\r
+               // NOTE: no need for this, sky doesn't show underground with\r
+               // enough range\r
+               bool is_underground = client.isNodeUnderground(p0);\r
+               //bool is_underground = false;\r
+               if(is_underground == false)\r
+                       bgcolor = video::SColor(255,90,140,200);\r
+               else\r
+                       bgcolor = video::SColor(255,0,0,0);*/\r
+                       \r
+               //video::SColor bgcolor = video::SColor(255,90,140,200);\r
+               //video::SColor bgcolor = skycolor;\r
+               \r
+               //s32 daynight_i = client.getDayNightIndex();\r
+               //video::SColor bgcolor = skycolor[daynight_i];\r
 \r
-               /*f32 range = g_viewing_range_nodes * BS;\r
-               if(g_viewing_range_all)\r
-                       range = 100000*BS;\r
+               u32 daynight_ratio = client.getDayNightRatio();\r
+               video::SColor bgcolor = video::SColor(\r
+                               255,\r
+                               skycolor.getRed() * daynight_ratio / 1000,\r
+                               skycolor.getGreen() * daynight_ratio / 1000,\r
+                               skycolor.getBlue() * daynight_ratio / 1000);\r
 \r
-               driver->setFog(\r
-                       skycolor,\r
-                       video::EFT_FOG_LINEAR,\r
-                       range*0.6,\r
-                       range,\r
-                       0.01,\r
-                       false, // pixel fog\r
-                       false // range fog\r
-                       );*/\r
+               /*\r
+                       Fog\r
+               */\r
+               \r
+               if(g_settings.getBool("enable_fog") == true)\r
+               {\r
+                       f32 range = g_viewing_range_nodes * BS;\r
+                       if(g_viewing_range_all)\r
+                               range = 100000*BS;\r
+\r
+                       driver->setFog(\r
+                               bgcolor,\r
+                               video::EFT_FOG_LINEAR,\r
+                               range*0.6,\r
+                               range,\r
+                               0.01,\r
+                               false, // pixel fog\r
+                               false // range fog\r
+                               );\r
+               }\r
 \r
 \r
                /*\r
@@ -2359,29 +2409,11 @@ int main(int argc, char *argv[])
 \r
                TimeTaker drawtimer("Drawing", device);\r
 \r
-               /*\r
-                       Background color is choosen based on whether the player is\r
-                       much beyond the initial ground level\r
-               */\r
-               /*video::SColor bgcolor;\r
-               v3s16 p0 = Map::floatToInt(player_position);\r
-               // Does this make short random delays?\r
-               // NOTE: no need for this, sky doesn't show underground with\r
-               // enough range\r
-               bool is_underground = client.isNodeUnderground(p0);\r
-               //bool is_underground = false;\r
-               if(is_underground == false)\r
-                       bgcolor = video::SColor(255,90,140,200);\r
-               else\r
-                       bgcolor = video::SColor(255,0,0,0);*/\r
-                       \r
-               //video::SColor bgcolor = video::SColor(255,90,140,200);\r
-               video::SColor bgcolor = skycolor;\r
                \r
                {\r
                TimeTaker timer("beginScene", device);\r
-               //driver->beginScene(true, true, bgcolor);\r
-               driver->beginScene(false, true, bgcolor);\r
+               driver->beginScene(true, true, bgcolor);\r
+               //driver->beginScene(false, true, bgcolor);\r
                beginscenetime = timer.stop(true);\r
                }\r
 \r
@@ -2471,6 +2503,8 @@ int main(int argc, char *argv[])
                        device->yield();*/\r
        }\r
 \r
+       delete quick_inventory;\r
+\r
        } // client is deleted at this point\r
        \r
        delete g_input;\r
index 80d41ce8f24454116418dac072d91e31d81ec4cb..671e74edd9dd9c5fd1d6691b6be8f670d38f8293 100644 (file)
@@ -755,7 +755,7 @@ void Map::updateLighting(enum LightBank bank,
        // Yes, add it to light_sources... somehow.
        // It has to be added at somewhere above, in the loop.
        // TODO
-       // NOTE: This actually works quite fine without it
+       // NOTE: This actually works fine without doing so
        //       - Find out why it works
 
        {
@@ -778,6 +778,17 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
 {
        updateLighting(LIGHTBANK_DAY, a_blocks, modified_blocks);
        updateLighting(LIGHTBANK_NIGHT, a_blocks, modified_blocks);
+       
+       /*
+               Update information about whether day and night light differ
+       */
+       for(core::map<v3s16, MapBlock*>::Iterator
+                       i = modified_blocks.getIterator();
+                       i.atEnd() == false; i++)
+       {
+               MapBlock *block = i.getNode()->getValue();
+               block->updateDayNightDiff();
+       }
 }
 
 /*
@@ -901,6 +912,17 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
                */
                spreadLight(bank, light_sources, modified_blocks);
        }
+
+       /*
+               Update information about whether day and night light differ
+       */
+       for(core::map<v3s16, MapBlock*>::Iterator
+                       i = modified_blocks.getIterator();
+                       i.atEnd() == false; i++)
+       {
+               MapBlock *block = i.getNode()->getValue();
+               block->updateDayNightDiff();
+       }
 }
 
 /*
@@ -1027,9 +1049,20 @@ void Map::removeNodeAndUpdate(v3s16 p,
                {
                }
        }
+
+       /*
+               Update information about whether day and night light differ
+       */
+       for(core::map<v3s16, MapBlock*>::Iterator
+                       i = modified_blocks.getIterator();
+                       i.atEnd() == false; i++)
+       {
+               MapBlock *block = i.getNode()->getValue();
+               block->updateDayNightDiff();
+       }
 }
 
-void Map::expireMeshes()
+void Map::expireMeshes(bool only_daynight_diffed)
 {
        TimeTaker timer("expireMeshes()", g_device);
 
@@ -1046,12 +1079,18 @@ void Map::expireMeshes()
                for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++)
                {
                        MapBlock *block = *i;
+
+                       if(only_daynight_diffed && dayNightDiffed(block->getPos()) == false)
+                       {
+                               continue;
+                       }
+                       
                        {
                                JMutexAutoLock lock(block->mesh_mutex);
                                if(block->mesh != NULL)
                                {
-                                       //block->mesh->drop();
-                                       //block->mesh = NULL;
+                                       /*block->mesh->drop();
+                                       block->mesh = NULL;*/
                                        block->setMeshExpired(true);
                                }
                        }
@@ -1059,36 +1098,70 @@ void Map::expireMeshes()
        }
 }
 
-void Map::updateMeshes(v3s16 blockpos, u32 daylight_factor)
+void Map::updateMeshes(v3s16 blockpos, u32 daynight_ratio)
 {
        assert(mapType() == MAPTYPE_CLIENT);
 
        try{
                v3s16 p = blockpos + v3s16(0,0,0);
                MapBlock *b = getBlockNoCreate(p);
-               b->updateMesh(daylight_factor);
+               b->updateMesh(daynight_ratio);
        }
        catch(InvalidPositionException &e){}
        try{
                v3s16 p = blockpos + v3s16(-1,0,0);
                MapBlock *b = getBlockNoCreate(p);
-               b->updateMesh(daylight_factor);
+               b->updateMesh(daynight_ratio);
        }
        catch(InvalidPositionException &e){}
        try{
                v3s16 p = blockpos + v3s16(0,-1,0);
                MapBlock *b = getBlockNoCreate(p);
-               b->updateMesh(daylight_factor);
+               b->updateMesh(daynight_ratio);
        }
        catch(InvalidPositionException &e){}
        try{
                v3s16 p = blockpos + v3s16(0,0,-1);
                MapBlock *b = getBlockNoCreate(p);
-               b->updateMesh(daylight_factor);
+               b->updateMesh(daynight_ratio);
        }
        catch(InvalidPositionException &e){}
 }
 
+bool Map::dayNightDiffed(v3s16 blockpos)
+{
+       try{
+               v3s16 p = blockpos + v3s16(0,0,0);
+               MapBlock *b = getBlockNoCreate(p);
+               if(b->dayNightDiffed())
+                       return true;
+       }
+       catch(InvalidPositionException &e){}
+       try{
+               v3s16 p = blockpos + v3s16(1,0,0);
+               MapBlock *b = getBlockNoCreate(p);
+               if(b->dayNightDiffed())
+                       return true;
+       }
+       catch(InvalidPositionException &e){}
+       try{
+               v3s16 p = blockpos + v3s16(0,1,0);
+               MapBlock *b = getBlockNoCreate(p);
+               if(b->dayNightDiffed())
+                       return true;
+       }
+       catch(InvalidPositionException &e){}
+       try{
+               v3s16 p = blockpos + v3s16(0,0,1);
+               MapBlock *b = getBlockNoCreate(p);
+               if(b->dayNightDiffed())
+                       return true;
+       }
+       catch(InvalidPositionException &e){}
+
+       return false;
+}
+
 /*
        Updates usage timers
 */
@@ -2216,8 +2289,8 @@ void ServerMap::save(bool only_changed)
        }//sectorlock
        
        u32 deleted_count = 0;
-       deleted_count = deleteUnusedSectors
-                       (SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT);
+       deleted_count = deleteUnusedSectors(
+                       SERVERMAP_DELETE_UNUSED_SECTORS_TIMEOUT);
        
        /*
                Only print if something happened or saved whole map
@@ -2719,6 +2792,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
        */
        int time1 = time(0);
 
+       //s32 daynight_i = m_client->getDayNightIndex();
+       u32 daynight_ratio = m_client->getDayNightRatio();
+
        /*
                Collect all blocks that are in the view range
 
@@ -2771,12 +2847,13 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
        //NOTE: The sectors map should be locked but we're not doing it
        // because it'd cause too much delays
 
+       int timecheck_counter = 0;
+
        core::map<v2s16, MapSector*>::Iterator si;
        si = m_sectors.getIterator();
        for(; si.atEnd() == false; si++)
        {
                {
-                       static int timecheck_counter = 0;
                        timecheck_counter++;
                        if(timecheck_counter > 50)
                        {
@@ -2872,7 +2949,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                        /*
                                Draw the faces of the block
                        */
-
+#if 1
                        bool mesh_expired = false;
                        
                        {
@@ -2885,29 +2962,56 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                                if(block->mesh == NULL && mesh_expired == false)
                                        continue;
                        }
+
+                       f32 faraway = BS*50;
+                       //f32 faraway = viewing_range_nodes * BS;
                        
                        /*
                                This has to be done with the mesh_mutex unlocked
                        */
-                       if(mesh_expired && mesh_update_count < 1)
+                       if(mesh_expired && mesh_update_count < 6
+                                       && (d < faraway || mesh_update_count < 3))
+                       //if(mesh_expired && mesh_update_count < 4)
                        {
                                mesh_update_count++;
 
                                // Mesh has been expired: generate new mesh
-                               block->updateMesh(m_client->getDaylightRatio());
-                       }
+                               //block->updateMeshes(daynight_i);
+                               block->updateMesh(daynight_ratio);
 
+                               mesh_expired = false;
+                       }
+                       
+                       /*
+                               Don't draw an expired mesh that is far away
+                       */
+                       /*if(mesh_expired && d >= faraway)
+                       //if(mesh_expired)
                        {
+                               // Instead, delete it
                                JMutexAutoLock lock(block->mesh_mutex);
+                               if(block->mesh)
+                               {
+                                       block->mesh->drop();
+                                       block->mesh = NULL;
+                               }
+                               // And continue to next block
+                               continue;
+                       }*/
+#endif
+                       {
+                               JMutexAutoLock lock(block->mesh_mutex);
+
+                               scene::SMesh *mesh = block->mesh;
 
-                               if(block->mesh == NULL)
+                               if(mesh == NULL)
                                        continue;
 
-                               u32 c = block->mesh->getMeshBufferCount();
+                               u32 c = mesh->getMeshBufferCount();
 
                                for(u32 i=0; i<c; i++)
                                {
-                                       scene::IMeshBuffer *buf = block->mesh->getMeshBuffer(i);
+                                       scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
                                        const video::SMaterial& material = buf->getMaterial();
                                        video::IMaterialRenderer* rnd =
                                                        driver->getMaterialRenderer(material.MaterialType);
index 41eadb080d1725c976572653ac84e2ed51df7472..d04d647e633af9338d005c72d2e2657f56f9cf50 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -224,6 +224,11 @@ public:
                return MAPTYPE_BASE;
        }
 
+       virtual void drop()
+       {
+               delete this;
+       }
+
        void updateCamera(v3f pos, v3f dir)
        {
                JMutexAutoLock lock(m_camera_mutex);
@@ -375,9 +380,14 @@ public:
                Updates the faces of the given block and blocks on the
                leading edge.
        */
-       void updateMeshes(v3s16 blockpos, u32 daylight_factor);
+       void updateMeshes(v3s16 blockpos, u32 daynight_ratio);
 
-       void expireMeshes();
+       void expireMeshes(bool only_daynight_diffed);
+
+       /*
+               Takes the blocks at the trailing edges into account
+       */
+       bool dayNightDiffed(v3s16 blockpos);
 
        //core::aabbox3d<s16> getDisplayedBlockArea();
 
@@ -544,6 +554,11 @@ public:
                return MAPTYPE_CLIENT;
        }
 
+       void drop()
+       {
+               ISceneNode::drop();
+       }
+
        /*
                Forcefully get a sector from somewhere
        */
index 266587c12a06c3a2810b753b895a4ad2000cfe4c..7e23d295b07ec8933901bdbd2e519f63b75d0202 100644 (file)
@@ -29,6 +29,52 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        MapBlock
 */
 
+MapBlock::MapBlock(NodeContainer *parent, v3s16 pos, bool dummy):
+               m_parent(parent),
+               m_pos(pos),
+               changed(true),
+               is_underground(false),
+               m_mesh_expired(false),
+               m_day_night_differs(false),
+               m_objects(this)
+{
+       data = NULL;
+       if(dummy == false)
+               reallocate();
+
+       mesh_mutex.Init();
+
+       mesh = NULL;
+       /*for(s32 i=0; i<DAYNIGHT_CACHE_COUNT; i++)
+       {
+               mesh[i] = NULL;
+       }*/
+}
+
+MapBlock::~MapBlock()
+{
+       {
+               JMutexAutoLock lock(mesh_mutex);
+               
+               if(mesh)
+               {
+                       mesh->drop();
+                       mesh = NULL;
+               }
+               /*for(s32 i=0; i<DAYNIGHT_CACHE_COUNT; i++)
+               {
+                       if(mesh[i] != NULL)
+                       {
+                               mesh[i]->drop();
+                               mesh[i] = NULL;
+                       }
+               }*/
+       }
+
+       if(data)
+               delete[] data;
+}
+
 bool MapBlock::isValidPositionParent(v3s16 p)
 {
        if(isValidPosition(p))
@@ -68,10 +114,33 @@ void MapBlock::setNodeParent(v3s16 p, MapNode & n)
        }
 }
 
-FastFace * MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
-               v3s16 dir, v3f scale, v3f posRelative_f)
+MapNode MapBlock::getNodeParentNoEx(v3s16 p)
 {
-       FastFace *f = new FastFace;
+       if(isValidPosition(p) == false)
+       {
+               try{
+                       return m_parent->getNode(getPosRelative() + p);
+               }
+               catch(InvalidPositionException &e)
+               {
+                       return MapNode(CONTENT_IGNORE);
+               }
+       }
+       else
+       {
+               if(data == NULL)
+               {
+                       return MapNode(CONTENT_IGNORE);
+               }
+               return data[p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X];
+       }
+}
+
+void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
+               v3s16 dir, v3f scale, v3f posRelative_f,
+               core::array<FastFace> &dest)
+{
+       FastFace face;
        
        // Position is at the center of the cube.
        v3f pos = p * BS;
@@ -85,21 +154,39 @@ FastFace * MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
        vertex_pos[2] = v3f(-BS/2, BS/2,BS/2);
        vertex_pos[3] = v3f( BS/2, BS/2,BS/2);
        
-       for(u16 i=0; i<4; i++)
+       if(dir == v3s16(0,0,1))
        {
-               if(dir == v3s16(0,0,1))
+               for(u16 i=0; i<4; i++)
                        vertex_pos[i].rotateXZBy(0);
-               else if(dir == v3s16(0,0,-1))
+       }
+       else if(dir == v3s16(0,0,-1))
+       {
+               for(u16 i=0; i<4; i++)
                        vertex_pos[i].rotateXZBy(180);
-               else if(dir == v3s16(1,0,0))
+       }
+       else if(dir == v3s16(1,0,0))
+       {
+               for(u16 i=0; i<4; i++)
                        vertex_pos[i].rotateXZBy(-90);
-               else if(dir == v3s16(-1,0,0))
+       }
+       else if(dir == v3s16(-1,0,0))
+       {
+               for(u16 i=0; i<4; i++)
                        vertex_pos[i].rotateXZBy(90);
-               else if(dir == v3s16(0,1,0))
+       }
+       else if(dir == v3s16(0,1,0))
+       {
+               for(u16 i=0; i<4; i++)
                        vertex_pos[i].rotateYZBy(-90);
-               else if(dir == v3s16(0,-1,0))
+       }
+       else if(dir == v3s16(0,-1,0))
+       {
+               for(u16 i=0; i<4; i++)
                        vertex_pos[i].rotateYZBy(90);
+       }
 
+       for(u16 i=0; i<4; i++)
+       {
                vertex_pos[i].X *= scale.X;
                vertex_pos[i].Y *= scale.Y;
                vertex_pos[i].Z *= scale.Z;
@@ -125,20 +212,21 @@ FastFace * MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
 
        video::SColor c = video::SColor(alpha,li,li,li);
 
-       f->vertices[0] = video::S3DVertex(vertex_pos[0], zerovector, c,
+       face.vertices[0] = video::S3DVertex(vertex_pos[0], zerovector, c,
                        core::vector2d<f32>(0,1));
-       f->vertices[1] = video::S3DVertex(vertex_pos[1], zerovector, c,
+       face.vertices[1] = video::S3DVertex(vertex_pos[1], zerovector, c,
                        core::vector2d<f32>(abs_scale,1));
-       f->vertices[2] = video::S3DVertex(vertex_pos[2], zerovector, c,
+       face.vertices[2] = video::S3DVertex(vertex_pos[2], zerovector, c,
                        core::vector2d<f32>(abs_scale,0));
-       f->vertices[3] = video::S3DVertex(vertex_pos[3], zerovector, c,
+       face.vertices[3] = video::S3DVertex(vertex_pos[3], zerovector, c,
                        core::vector2d<f32>(0,0));
 
-       f->tile = tile;
+       face.tile = tile;
        //DEBUG
        //f->tile = TILE_STONE;
-
-       return f;
+       
+       dest.push_back(face);
+       //return f;
 }
        
 /*
@@ -146,15 +234,20 @@ FastFace * MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
        Order doesn't matter.
 
        If either of the nodes doesn't exist, light is 0.
+       
+       parameters:
+               daynight_ratio: 0...1000
+               n: getNodeParent(p)
+               n2: getNodeParent(p + face_dir)
+               face_dir: axis oriented unit vector from p to p2
 */
-u8 MapBlock::getFaceLight(u32 daylight_factor, v3s16 p, v3s16 face_dir)
+u8 MapBlock::getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
+               v3s16 face_dir)
 {
        try{
-               MapNode n = getNodeParent(p);
-               MapNode n2 = getNodeParent(p + face_dir);
                u8 light;
-               u8 l1 = n.getLightBlend(daylight_factor);
-               u8 l2 = n2.getLightBlend(daylight_factor);
+               u8 l1 = n.getLightBlend(daynight_ratio);
+               u8 l2 = n2.getLightBlend(daynight_ratio);
                if(l1 > l2)
                        light = l1;
                else
@@ -184,21 +277,20 @@ u8 MapBlock::getFaceLight(u32 daylight_factor, v3s16 p, v3s16 face_dir)
        Gets node tile from any place relative to block.
        Returns TILE_NODE if doesn't exist or should not be drawn.
 */
-TileSpec MapBlock::getNodeTile(v3s16 p, v3s16 face_dir)
+TileSpec MapBlock::getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir)
 {
        TileSpec spec;
 
-       spec.feature = TILEFEAT_NONE;
-       try{
-               MapNode n = getNodeParent(p);
-               
-               spec.id = n.getTile(face_dir);
-       }
-       catch(InvalidPositionException &e)
+       /*//DEBUG
        {
-               spec.id = TILE_NONE;
-       }
-       
+               spec.id = TILE_STONE;
+               return spec;
+       }*/
+
+       spec.feature = TILEFEAT_NONE;
+       //spec.id = TILE_STONE;
+       spec.id = mn.getTile(face_dir);
+
        /*
                Check temporary modifications on this node
        */
@@ -221,7 +313,7 @@ TileSpec MapBlock::getNodeTile(v3s16 p, v3s16 face_dir)
        return spec;
 }
 
-u8 MapBlock::getNodeContent(v3s16 p)
+u8 MapBlock::getNodeContent(v3s16 p, MapNode mn)
 {
        /*
                Check temporary modifications on this node
@@ -253,16 +345,8 @@ u8 MapBlock::getNodeContent(v3s16 p)
                        */
                }
        }
-       
-       try{
-               MapNode n = getNodeParent(p);
-               
-               return n.d;
-       }
-       catch(InvalidPositionException &e)
-       {
-               return CONTENT_IGNORE;
-       }
+
+       return mn.d;
 }
 
 /*
@@ -271,48 +355,47 @@ u8 MapBlock::getNodeContent(v3s16 p)
        face_dir: unit vector with only one of x, y or z
 */
 void MapBlock::updateFastFaceRow(
-               u32 daylight_factor,
+               u32 daynight_ratio,
+               v3f posRelative_f,
                v3s16 startpos,
                u16 length,
                v3s16 translate_dir,
+               v3f translate_dir_f,
                v3s16 face_dir,
-               core::list<FastFace*> &dest)
+               v3f face_dir_f,
+               core::array<FastFace> &dest)
 {
-       /*
-               Precalculate some variables
-       */
-       v3f translate_dir_f(translate_dir.X, translate_dir.Y,
-                       translate_dir.Z); // floating point conversion
-       v3f face_dir_f(face_dir.X, face_dir.Y,
-                       face_dir.Z); // floating point conversion
-       v3f posRelative_f(getPosRelative().X, getPosRelative().Y,
-                       getPosRelative().Z); // floating point conversion
-
        v3s16 p = startpos;
-       /*
-               Get face light at starting position
-       */
-       u8 light = getFaceLight(daylight_factor, p, face_dir);
        
        u16 continuous_tiles_count = 0;
        
-       TileSpec tile0 = getNodeTile(p, face_dir);
-       TileSpec tile1 = getNodeTile(p + face_dir, -face_dir);
+       MapNode n0 = getNodeParentNoEx(p);
+       MapNode n1 = getNodeParentNoEx(p + face_dir);
+
+       u8 light = getFaceLight(daynight_ratio, n0, n1, face_dir);
                
+       TileSpec tile0 = getNodeTile(n0, p, face_dir);
+       TileSpec tile1 = getNodeTile(n1, p + face_dir, -face_dir);
+
        for(u16 j=0; j<length; j++)
        {
                bool next_is_different = true;
                
                v3s16 p_next;
+               MapNode n0_next;
+               MapNode n1_next;
                TileSpec tile0_next;
                TileSpec tile1_next;
                u8 light_next = 0;
 
-               if(j != length - 1){
+               if(j != length - 1)
+               {
                        p_next = p + translate_dir;
-                       tile0_next = getNodeTile(p_next, face_dir);
-                       tile1_next = getNodeTile(p_next + face_dir, -face_dir);
-                       light_next = getFaceLight(daylight_factor, p_next, face_dir);
+                       n0_next = getNodeParentNoEx(p_next);
+                       n1_next = getNodeParentNoEx(p_next + face_dir);
+                       tile0_next = getNodeTile(n0_next, p_next, face_dir);
+                       tile1_next = getNodeTile(n1_next, p_next + face_dir, -face_dir);
+                       light_next = getFaceLight(daynight_ratio, n0_next, n1_next, face_dir);
 
                        if(tile0_next == tile0
                                        && tile1_next == tile1
@@ -331,8 +414,8 @@ void MapBlock::updateFastFaceRow(
                        */
                        //u8 mf = face_contents(tile0, tile1);
                        // This is hackish
-                       u8 content0 = getNodeContent(p);
-                       u8 content1 = getNodeContent(p + face_dir);
+                       u8 content0 = getNodeContent(p, n0);
+                       u8 content1 = getNodeContent(p + face_dir, n1);
                        u8 mf = face_contents(content0, content1);
                        
                        if(mf != 0)
@@ -352,26 +435,28 @@ void MapBlock::updateFastFaceRow(
                                        scale.Z = continuous_tiles_count;
                                }
                                
-                               FastFace *f;
+                               //FastFace *f;
 
                                // If node at sp (tile0) is more solid
                                if(mf == 1)
                                {
-                                       f = makeFastFace(tile0, light,
+                                       makeFastFace(tile0, light,
                                                        sp, face_dir, scale,
-                                                       posRelative_f);
+                                                       posRelative_f, dest);
                                }
                                // If node at sp is less solid (mf == 2)
                                else
                                {
-                                       f = makeFastFace(tile1, light,
+                                       makeFastFace(tile1, light,
                                                        sp+face_dir_f, -face_dir, scale,
-                                                       posRelative_f);
+                                                       posRelative_f, dest);
                                }
-                               dest.push_back(f);
+                               //dest.push_back(f);
                        }
 
                        continuous_tiles_count = 0;
+                       n0 = n0_next;
+                       n1 = n1_next;
                        tile0 = tile0_next;
                        tile1 = tile1_next;
                        light = light_next;
@@ -474,89 +559,101 @@ private:
        core::array<PreMeshBuffer> m_prebuffers;
 };
 
-void MapBlock::updateMesh(u32 daylight_factor)
+void MapBlock::updateMesh(u32 daynight_ratio)
 {
-       /*v3s16 p = getPosRelative();
-       std::cout<<"MapBlock("<<p.X<<","<<p.Y<<","<<p.Z<<")"
-                       <<"::updateMesh(): ";*/
-                       //<<"::updateMesh()"<<std::endl;
-       TimeTaker timer1("updateMesh()", g_device);
-       
+#if 0
        /*
-               TODO: Change this to directly generate the mesh (and get rid
-                     of FastFaces)
+               DEBUG: If mesh has been generated, don't generate it again
        */
+       {
+               JMutexAutoLock meshlock(mesh_mutex);
+               if(mesh != NULL)
+                       return;
+       }
+#endif
+       
+       // 4-21ms
+       //TimeTaker timer1("updateMesh()", g_device);
 
-       core::list<FastFace*> *fastfaces_new = new core::list<FastFace*>;
+       core::array<FastFace> fastfaces_new;
+       
+       v3f posRelative_f(getPosRelative().X, getPosRelative().Y,
+                       getPosRelative().Z); // floating point conversion
        
        /*
                We are including the faces of the trailing edges of the block.
                This means that when something changes, the caller must
                also update the meshes of the blocks at the leading edges.
 
-               NOTE: This is the slowest part of this method. The other parts
-                     take around 0ms, this takes around 15-70ms.
+               NOTE: This is the slowest part of this method.
        */
 
        /*
                Go through every y,z and get top faces in rows of x+
        */
        for(s16 y=0; y<MAP_BLOCKSIZE; y++){
-       //for(s16 y=-1; y<MAP_BLOCKSIZE; y++){
                for(s16 z=0; z<MAP_BLOCKSIZE; z++){
-                       updateFastFaceRow(daylight_factor,
+                       updateFastFaceRow(daynight_ratio, posRelative_f,
                                        v3s16(0,y,z), MAP_BLOCKSIZE,
-                                       v3s16(1,0,0),
-                                       v3s16(0,1,0),
-                                       *fastfaces_new);
+                                       v3s16(1,0,0), //dir
+                                       v3f  (1,0,0),
+                                       v3s16(0,1,0), //face dir
+                                       v3f  (0,1,0),
+                                       fastfaces_new);
                }
        }
        /*
                Go through every x,y and get right faces in rows of z+
        */
        for(s16 x=0; x<MAP_BLOCKSIZE; x++){
-       //for(s16 x=-1; x<MAP_BLOCKSIZE; x++){
                for(s16 y=0; y<MAP_BLOCKSIZE; y++){
-                       updateFastFaceRow(daylight_factor,
+                       updateFastFaceRow(daynight_ratio, posRelative_f,
                                        v3s16(x,y,0), MAP_BLOCKSIZE,
                                        v3s16(0,0,1),
+                                       v3f  (0,0,1),
                                        v3s16(1,0,0),
-                                       *fastfaces_new);
+                                       v3f  (1,0,0),
+                                       fastfaces_new);
                }
        }
        /*
                Go through every y,z and get back faces in rows of x+
        */
        for(s16 z=0; z<MAP_BLOCKSIZE; z++){
-       //for(s16 z=-1; z<MAP_BLOCKSIZE; z++){
                for(s16 y=0; y<MAP_BLOCKSIZE; y++){
-                       updateFastFaceRow(daylight_factor,
+                       updateFastFaceRow(daynight_ratio, posRelative_f,
                                        v3s16(0,y,z), MAP_BLOCKSIZE,
                                        v3s16(1,0,0),
+                                       v3f  (1,0,0),
                                        v3s16(0,0,1),
-                                       *fastfaces_new);
+                                       v3f  (0,0,1),
+                                       fastfaces_new);
                }
        }
 
+       // End of slow part
+
+       /*
+               Convert FastFaces to SMesh
+       */
+
        scene::SMesh *mesh_new = NULL;
        
        mesh_new = new scene::SMesh();
        
-       if(fastfaces_new->getSize() > 0)
+       if(fastfaces_new.size() > 0)
        {
                MeshCollector collector;
 
-               core::list<FastFace*>::Iterator i = fastfaces_new->begin();
-
-               for(; i != fastfaces_new->end(); i++)
+               for(u32 i=0; i<fastfaces_new.size(); i++)
                {
-                       FastFace *f = *i;
+                       FastFace &f = fastfaces_new[i];
 
                        const u16 indices[] = {0,1,2,2,3,0};
                        
-                       if(f->tile.feature == TILEFEAT_NONE)
+                       if(f.tile.feature == TILEFEAT_NONE)
                        {
-                               collector.append(g_tile_materials[f->tile.id], f->vertices, 4,
+                               collector.append(g_tile_materials[f.tile.id], f.vertices, 4,
                                                indices, 6);
                        }
                        else
@@ -569,7 +666,7 @@ void MapBlock::updateMesh(u32 daylight_factor)
                collector.fillMesh(mesh_new);
 
                // Use VBO for mesh (this just would set this for ever buffer)
-               mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
+               //mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
                
                /*std::cout<<"MapBlock has "<<fastfaces_new->getSize()<<" faces "
                                <<"and uses "<<mesh_new->getMeshBufferCount()
@@ -580,14 +677,14 @@ void MapBlock::updateMesh(u32 daylight_factor)
                Clear temporary FastFaces
        */
 
-       core::list<FastFace*>::Iterator i;
+       /*core::list<FastFace*>::Iterator i;
        i = fastfaces_new->begin();
        for(; i != fastfaces_new->end(); i++)
        {
                delete *i;
        }
        fastfaces_new->clear();
-       delete fastfaces_new;
+       delete fastfaces_new;*/
 
        /*
                Add special graphics:
@@ -697,8 +794,10 @@ void MapBlock::updateMesh(u32 daylight_factor)
 
        mesh_mutex.Lock();
 
-       scene::SMesh *mesh_old = mesh;
+       //scene::SMesh *mesh_old = mesh[daynight_i];
+       //mesh[daynight_i] = mesh_new;
 
+       scene::SMesh *mesh_old = mesh;
        mesh = mesh_new;
        setMeshExpired(false);
        
@@ -711,8 +810,20 @@ void MapBlock::updateMesh(u32 daylight_factor)
                {
                        IMeshBuffer *buf = mesh_old->getMeshBuffer(i);
                }*/
+               
+               /*dstream<<"mesh_old->getReferenceCount()="
+                               <<mesh_old->getReferenceCount()<<std::endl;
+               u32 c = mesh_old->getMeshBufferCount();
+               for(u32 i=0; i<c; i++)
+               {
+                       scene::IMeshBuffer *buf = mesh_old->getMeshBuffer(i);
+                       dstream<<"buf->getReferenceCount()="
+                                       <<buf->getReferenceCount()<<std::endl;
+               }*/
+
                // Drop the mesh
                mesh_old->drop();
+
                //delete mesh_old;
        }
 
@@ -721,6 +832,18 @@ void MapBlock::updateMesh(u32 daylight_factor)
        //std::cout<<"added "<<fastfaces.getSize()<<" faces."<<std::endl;
 }
 
+/*void MapBlock::updateMeshes(s32 first_i)
+{
+       assert(first_i >= 0 && first_i <= DAYNIGHT_CACHE_COUNT);
+       updateMesh(first_i);
+       for(s32 i=0; i<DAYNIGHT_CACHE_COUNT; i++)
+       {
+               if(i == first_i)
+                       continue;
+               updateMesh(i);
+       }
+}*/
+
 /*
        Propagates sunlight down through the block.
        Doesn't modify nodes that are not affected by sunlight.
@@ -874,6 +997,54 @@ void MapBlock::copyTo(VoxelManipulator &dst)
 {
 }*/
 
+
+void MapBlock::updateDayNightDiff()
+{
+       if(data == NULL)
+       {
+               m_day_night_differs = false;
+               return;
+       }
+
+       bool differs = false;
+
+       /*
+               Check if any lighting value differs
+       */
+       for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
+       {
+               MapNode &n = data[i];
+               if(n.getLight(LIGHTBANK_DAY) != n.getLight(LIGHTBANK_NIGHT))
+               {
+                       differs = true;
+                       break;
+               }
+       }
+
+       /*
+               If some lighting values differ, check if the whole thing is
+               just air. If it is, differ = false
+       */
+       if(differs)
+       {
+               bool only_air = true;
+               for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
+               {
+                       MapNode &n = data[i];
+                       if(n.d != CONTENT_AIR)
+                       {
+                               only_air = false;
+                               break;
+                       }
+               }
+               if(only_air)
+                       differs = false;
+       }
+
+       // Set member variable
+       m_day_night_differs = differs;
+}
+
 /*
        Serialization
 */
@@ -948,7 +1119,12 @@ void MapBlock::serialize(std::ostream &os, u8 version)
        else
        {
                // First byte
-               os.write((char*)&is_underground, 1);
+               u8 flags = 0;
+               if(is_underground)
+                       flags |= 1;
+               if(m_day_night_differs)
+                       flags |= 2;
+               os.write((char*)&flags, 1);
 
                u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
 
@@ -1065,9 +1241,10 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
        {
                u32 nodecount = MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
 
-               u8 t8;
-               is.read((char*)&t8, 1);
-               is_underground = t8;
+               u8 flags;
+               is.read((char*)&flags, 1);
+               is_underground = (flags & 1) ? true : false;
+               m_day_night_differs = (flags & 2) ? true : false;
 
                // Uncompress data
                std::ostringstream os(std::ios_base::binary);
index ff36e3a7d43447d70379cfaa1f02f0a8be12ebcd..2743d8397c9609ee3a1da839808d637d25215770 100644 (file)
@@ -89,51 +89,12 @@ class MapBlock : public NodeContainer
 {
 public:
 
-       /*
-               This used by Server's block creation stuff for not sending
-               blocks that are waiting a lighting update.
-
-               If true, the block needs some work by the one who set this
-               to true.
-
-               While true, nobody else should touch the block.
-       */
-       //bool is_incomplete;
-       
+       //scene::SMesh *mesh[DAYNIGHT_CACHE_COUNT];
        scene::SMesh *mesh;
        JMutex mesh_mutex;
 
-       MapBlock(NodeContainer *parent, v3s16 pos, bool dummy=false):
-                       m_parent(parent),
-                       m_pos(pos),
-                       changed(true),
-                       is_underground(false),
-                       m_mesh_expired(false),
-                       m_objects(this)
-                       //is_incomplete(false)
-       {
-               data = NULL;
-               if(dummy == false)
-                       reallocate();
-               mesh_mutex.Init();
-               mesh = NULL;
-       }
-
-       ~MapBlock()
-       {
-               {
-                       JMutexAutoLock lock(mesh_mutex);
-                       
-                       if(mesh != NULL)
-                       {
-                               mesh->drop();
-                               mesh = NULL;
-                       }
-               }
-
-               if(data)
-                       delete[] data;
-       }
+       MapBlock(NodeContainer *parent, v3s16 pos, bool dummy=false);
+       ~MapBlock();
        
        virtual u16 nodeContainerId() const
        {
@@ -302,6 +263,7 @@ public:
        bool isValidPositionParent(v3s16 p);
        MapNode getNodeParent(v3s16 p);
        void setNodeParent(v3s16 p, MapNode & n);
+       MapNode getNodeParentNoEx(v3s16 p);
 
        void drawbox(s16 x0, s16 y0, s16 z0, s16 w, s16 h, s16 d, MapNode node)
        {
@@ -311,13 +273,23 @@ public:
                                        setNode(x0+x, y0+y, z0+z, node);
        }
 
-       static FastFace * makeFastFace(TileSpec tile, u8 light, v3f p,
-                       v3s16 dir, v3f scale, v3f posRelative_f);
+       static void makeFastFace(TileSpec tile, u8 light, v3f p,
+                       v3s16 dir, v3f scale, v3f posRelative_f,
+                       core::array<FastFace> &dest);
+       
+       u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
+                       v3s16 face_dir);
        
-       u8 getFaceLight(u32 daylight_factor, v3s16 p, v3s16 face_dir);
+       u8 getFaceLight(u32 daynight_ratio, v3s16 p, v3s16 face_dir)
+       {
+               return getFaceLight(daynight_ratio,
+                               getNodeParentNoEx(p),
+                               getNodeParentNoEx(p + face_dir),
+                               face_dir);
+       }
        
-       TileSpec getNodeTile(v3s16 p, v3s16 face_dir);
-       u8 getNodeContent(v3s16 p);
+       TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir);
+       u8 getNodeContent(v3s16 p, MapNode mn);
 
        /*
                startpos:
@@ -325,14 +297,20 @@ public:
                face_dir: unit vector with only one of x, y or z
        */
        void updateFastFaceRow(
-                       u32 daylight_factor,
+                       u32 daynight_ratio,
+                       v3f posRelative_f,
                        v3s16 startpos,
                        u16 length,
                        v3s16 translate_dir,
+                       v3f translate_dir_f,
                        v3s16 face_dir,
-                       core::list<FastFace*> &dest);
+                       v3f face_dir_f,
+                       core::array<FastFace> &dest);
 
-       void updateMesh(u32 daylight_factor);
+       void updateMesh(u32 daynight_ratio);
+       /*void updateMesh(s32 daynight_i);
+       // Updates all DAYNIGHT_CACHE_COUNT meshes
+       void updateMeshes(s32 first_i=0);*/
 
        bool propagateSunlight(core::map<v3s16, bool> & light_sources);
        
@@ -429,6 +407,21 @@ public:
                m_temp_mods.clear();
        }
 
+       /*
+               Day-night lighting difference
+               
+               These methods don't care about neighboring blocks.
+               It means that to know if a block really doesn't need a mesh
+               update between day and night, the neighboring blocks have
+               to be taken into account.
+       */
+       void updateDayNightDiff();
+
+       bool dayNightDiffed()
+       {
+               return m_day_night_differs;
+       }
+
        /*
                Serialization
        */
@@ -480,6 +473,9 @@ private:
 
        bool m_mesh_expired;
        
+       // Whether day and night lighting differs
+       bool m_day_night_differs;
+       
        MapBlockObjectList m_objects;
        
        // Temporary modifications to nodes
index cd12feb0c7eb0faa7e917d6f8b1e6a249416544e..8b52b9447f36599a916655e88d18b45d116662ba 100644 (file)
@@ -339,17 +339,7 @@ void MapBlockObjectList::update(std::istream &is, u8 version,
                                        " id="<<id
                                        <<std::endl;*/
 
-                       if(type_id == MAPBLOCKOBJECT_TYPE_TEST)
-                       {
-                               // The constructors of objects shouldn't need
-                               // any more parameters than this.
-                               obj = new TestObject(m_block, id, pos);
-                       }
-                       else if(type_id == MAPBLOCKOBJECT_TYPE_TEST2)
-                       {
-                               obj = new Test2Object(m_block, id, pos);
-                       }
-                       else if(type_id == MAPBLOCKOBJECT_TYPE_SIGN)
+                       if(type_id == MAPBLOCKOBJECT_TYPE_SIGN)
                        {
                                obj = new SignObject(m_block, id, pos);
                        }
index 61bd6610de37bcca886b2a54606e21fe38d45b9f..8518d6b11fb2c23330151316b5c7a66212bc6021 100644 (file)
@@ -220,119 +220,6 @@ protected:
 };
 #endif
 
-class TestObject : public MapBlockObject
-{
-public:
-       // The constructor of every MapBlockObject should be like this
-       TestObject(MapBlock *block, s16 id, v3f pos):
-               MapBlockObject(block, id, pos),
-               m_node(NULL)
-       {
-       }
-       virtual ~TestObject()
-       {
-       }
-       
-       /*
-               Implementation interface
-       */
-       virtual u16 getTypeId() const
-       {
-               return MAPBLOCKOBJECT_TYPE_TEST;
-       }
-       virtual void serialize(std::ostream &os, u8 version)
-       {
-               serializeBase(os, version);
-
-               // Write subpos_c * 100
-               u8 buf[2];
-               writeU16(buf, m_subpos_c * 100);
-               os.write((char*)buf, 2);
-       }
-       virtual void update(std::istream &is, u8 version)
-       {
-               // Read subpos_c * 100
-               u8 buf[2];
-               is.read((char*)buf, 2);
-               m_subpos_c = (f32)readU16(buf) / 100;
-               
-               updateNodePos();
-       }
-       virtual bool serverStep(float dtime)
-       {
-               m_subpos_c += dtime * 3.0;
-
-               updateNodePos();
-
-               return false;
-       }
-       virtual void addToScene(scene::ISceneManager *smgr)
-       {
-               if(m_node != NULL)
-                       return;
-               
-               //dstream<<"Adding to scene"<<std::endl;
-
-               video::IVideoDriver* driver = smgr->getVideoDriver();
-               
-               scene::SMesh *mesh = new scene::SMesh();
-               scene::IMeshBuffer *buf = new scene::SMeshBuffer();
-               video::SColor c(255,255,255,255);
-               video::S3DVertex vertices[4] =
-               {
-                       video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
-                       video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
-                       video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
-                       video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
-               };
-               u16 indices[] = {0,1,2,2,3,0};
-               buf->append(vertices, 4, indices, 6);
-               // Set material
-               buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
-               buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
-               buf->getMaterial().setTexture
-                               (0, driver->getTexture("../data/player.png"));
-               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
-               buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
-               // Add to mesh
-               mesh->addMeshBuffer(buf);
-               buf->drop();
-               m_node = smgr->addMeshSceneNode(mesh, NULL);
-               mesh->drop();
-               m_node->setPosition(getAbsolutePos());
-       }
-       virtual void removeFromScene()
-       {
-               //dstream<<"Removing from scene"<<std::endl;
-               if(m_node != NULL)
-               {
-                       m_node->remove();
-                       m_node = NULL;
-               }
-       }
-
-       /*
-               Special methods
-       */
-       
-       void updateNodePos()
-       {
-               m_subpos = BS*2.0 * v3f(sin(m_subpos_c), sin(m_subpos_c+1.0), sin(-m_subpos_c));
-               
-               if(m_node != NULL)
-               {
-                       m_node->setPosition(getAbsolutePos() + m_subpos);
-               }
-       }
-       
-protected:
-       scene::IMeshSceneNode *m_node;
-       std::string m_text;
-
-       v3f m_subpos;
-       f32 m_subpos_c;
-};
-
 class MovingObject : public MapBlockObject
 {
 public:
@@ -398,134 +285,6 @@ protected:
        bool m_touching_ground;
 };
 
-class Test2Object : public MovingObject
-{
-public:
-       // The constructor of every MapBlockObject should be like this
-       Test2Object(MapBlock *block, s16 id, v3f pos):
-               MovingObject(block, id, pos),
-               m_node(NULL)
-       {
-               m_collision_box = new core::aabbox3d<f32>
-                               (-BS*0.3,0,-BS*0.3, BS*0.3,BS*1.7,BS*0.3);
-       }
-       virtual ~Test2Object()
-       {
-               delete m_collision_box;
-       }
-       
-       /*
-               Implementation interface
-       */
-       virtual u16 getTypeId() const
-       {
-               return MAPBLOCKOBJECT_TYPE_TEST2;
-       }
-       virtual void serialize(std::ostream &os, u8 version)
-       {
-               MovingObject::serialize(os, version);
-       }
-       virtual void update(std::istream &is, u8 version)
-       {
-               MovingObject::update(is, version);
-               
-               updateNodePos();
-       }
-
-       virtual bool serverStep(float dtime)
-       {
-               m_speed.X = 2*BS;
-               m_speed.Z = 0;
-
-               if(m_touching_ground)
-               {
-                       static float count = 0;
-                       count -= dtime;
-                       if(count < 0.0)
-                       {
-                               count += 1.0;
-                               m_speed.Y = 6.5*BS;
-                       }
-               }
-
-               move(dtime, v3f(0, -9.81*BS, 0));
-
-               updateNodePos();
-
-               return false;
-       }
-       
-       virtual void clientStep(float dtime)
-       {
-               m_pos += m_speed * dtime;
-
-               updateNodePos();
-       }
-       
-       virtual void addToScene(scene::ISceneManager *smgr)
-       {
-               if(m_node != NULL)
-                       return;
-               
-               //dstream<<"Adding to scene"<<std::endl;
-
-               video::IVideoDriver* driver = smgr->getVideoDriver();
-               
-               scene::SMesh *mesh = new scene::SMesh();
-               scene::IMeshBuffer *buf = new scene::SMeshBuffer();
-               video::SColor c(255,255,255,255);
-               video::S3DVertex vertices[4] =
-               {
-                       video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
-                       video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
-                       video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
-                       video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
-               };
-               u16 indices[] = {0,1,2,2,3,0};
-               buf->append(vertices, 4, indices, 6);
-               // Set material
-               buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
-               buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
-               buf->getMaterial().setTexture
-                               (0, driver->getTexture("../data/player.png"));
-               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
-               buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
-               // Add to mesh
-               mesh->addMeshBuffer(buf);
-               buf->drop();
-               m_node = smgr->addMeshSceneNode(mesh, NULL);
-               mesh->drop();
-               m_node->setPosition(getAbsolutePos());
-       }
-       virtual void removeFromScene()
-       {
-               //dstream<<"Removing from scene"<<std::endl;
-               if(m_node != NULL)
-               {
-                       m_node->remove();
-                       m_node = NULL;
-               }
-       }
-
-       /*
-               Special methods
-       */
-       
-       void updateNodePos()
-       {
-               //m_subpos = BS*2.0 * v3f(sin(m_subpos_c), sin(m_subpos_c+1.0), sin(-m_subpos_c));
-               
-               if(m_node != NULL)
-               {
-                       //m_node->setPosition(getAbsolutePos() + m_subpos);
-                       m_node->setPosition(getAbsolutePos());
-               }
-       }
-       
-protected:
-       scene::IMeshSceneNode *m_node;
-};
-
 class RatObject : public MovingObject
 {
 public:
index c15a2a2354eeaf6f134be3a8cbe62b6619e8e6d2..3206b580a370d90f5e5e8c06d8573e34b5574750 100644 (file)
@@ -43,7 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        8: (dev) server-initiated block transfers and all kinds of stuff
        9: (dev) block objects
        10: (dev) water pressure
-       11: (dev) zlib'd blocks
+       11: (dev) zlib'd blocks, block flags
 */
 // This represents an uninitialized or invalid format
 #define SER_FMT_VER_INVALID 255
index 6b026d9a76dd6f45ac5d83dfcab07e4c16792531..acb4003da393b4a9d757899d57411ee24f94c485 100644 (file)
@@ -285,6 +285,12 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
 {
        DSTACK(__FUNCTION_NAME);
        
+       // Increment timers
+       {
+               JMutexAutoLock lock(m_blocks_sent_mutex);
+               m_nearest_unsent_reset_timer += dtime;
+       }
+
        // Won't send anything if already sending
        {
                JMutexAutoLock lock(m_blocks_sending_mutex);
@@ -320,12 +326,13 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                        m_last_center = center;
                }
 
-               static float reset_counter = 0;
-               reset_counter += dtime;
-               if(reset_counter > 5.0)
+               /*dstream<<"m_nearest_unsent_reset_timer="
+                               <<m_nearest_unsent_reset_timer<<std::endl;*/
+               if(m_nearest_unsent_reset_timer > 5.0)
                {
-                       reset_counter = 0;
+                       m_nearest_unsent_reset_timer = 0;
                        m_nearest_unsent_d = 0;
+                       //dstream<<"Resetting m_nearest_unsent_d"<<std::endl;
                }
 
                last_nearest_unsent_d = m_nearest_unsent_d;
@@ -353,6 +360,21 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                                = LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS;
                }
        }
+       
+       u32 num_blocks_selected;
+       {
+               JMutexAutoLock lock(m_blocks_sending_mutex);
+               num_blocks_selected = m_blocks_sending.size();
+       }
+       
+       /*
+               next time d will be continued from the d from which the nearest
+               unsent block was found this time.
+
+               This is because not necessarily any of the blocks found this
+               time are actually sent.
+       */
+       s32 new_nearest_unsent_d = -1;
 
        // Serialization version used
        //u8 ser_version = serialization_version;
@@ -380,12 +402,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                        if(m_nearest_unsent_d != last_nearest_unsent_d)
                        {
                                d = m_nearest_unsent_d;
+                               last_nearest_unsent_d = m_nearest_unsent_d;
                        }
-                       else
-                       {
-                               m_nearest_unsent_d = d;
-                       }
-                       last_nearest_unsent_d = m_nearest_unsent_d;
                }
 
                /*
@@ -421,13 +439,13 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                                JMutexAutoLock lock(m_blocks_sending_mutex);
                                
                                // Limit is dynamically lowered when building
-                               if(m_blocks_sending.size()
+                               if(num_blocks_selected
                                                >= maximum_simultaneous_block_sends_now)
                                {
                                        /*dstream<<"Not sending more blocks. Queue full. "
                                                        <<m_blocks_sending.size()
                                                        <<std::endl;*/
-                                       return;
+                                       goto queue_full;
                                }
 
                                if(m_blocks_sending.find(p) != NULL)
@@ -460,7 +478,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                                if(m_blocks_sent.find(p) != NULL)
                                        continue;
                        }
-                                       
+
                        /*
                                Check if map has this block
                        */
@@ -498,6 +516,15 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                                continue;
                        }
 
+                       /*
+                               Record the lowest d from which a a block has been
+                               found being not sent and possibly to exist
+                       */
+                       if(new_nearest_unsent_d == -1 || d < new_nearest_unsent_d)
+                       {
+                               new_nearest_unsent_d = d;
+                       }
+                                       
                        /*
                                Add inexistent block to emerge queue.
                        */
@@ -531,10 +558,17 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
                        PrioritySortedBlockTransfer q((float)d, p, peer_id);
 
                        dest.push_back(q);
+
+                       num_blocks_selected += 1;
                }
        }
+queue_full:
 
-       // Don't add anything here. The loop breaks by returning.
+       if(new_nearest_unsent_d != -1)
+       {
+               JMutexAutoLock lock(m_blocks_sent_mutex);
+               m_nearest_unsent_d = new_nearest_unsent_d;
+       }
 }
 
 void RemoteClient::SendObjectData(
@@ -894,6 +928,12 @@ Server::Server(
        m_thread(this),
        m_emergethread(this)
 {
+       m_flowwater_timer = 0.0;
+       m_print_info_timer = 0.0;
+       m_objectdata_timer = 0.0;
+       m_emergethread_trigger_timer = 0.0;
+       m_savemap_timer = 0.0;
+       
        m_env_mutex.Init();
        m_con_mutex.Init();
        m_step_dtime_mutex.Init();
@@ -983,7 +1023,7 @@ void Server::AsyncRunStep()
        
        {
                JMutexAutoLock lock1(m_step_dtime_mutex);
-               m_step_dtime = 0.0;
+               m_step_dtime -= dtime;
        }
 
        //dstream<<"Server steps "<<dtime<<std::endl;
@@ -1018,7 +1058,7 @@ void Server::AsyncRunStep()
                else
                        interval = 0.25;
 
-               static float counter = 0.0;
+               float &counter = m_flowwater_timer;
                counter += dtime;
                if(counter >= 0.25 && m_flow_active_nodes.size() > 0)
                {
@@ -1082,7 +1122,7 @@ void Server::AsyncRunStep()
        
        // Periodically print some info
        {
-               static float counter = 0.0;
+               float &counter = m_print_info_timer;
                counter += dtime;
                if(counter >= 30.0)
                {
@@ -1208,7 +1248,7 @@ void Server::AsyncRunStep()
 
        // Send object positions
        {
-               static float counter = 0.0;
+               float &counter = m_objectdata_timer;
                counter += dtime;
                if(counter >= g_settings.getFloat("objectdata_interval"))
                {
@@ -1223,7 +1263,7 @@ void Server::AsyncRunStep()
        // Trigger emergethread (it gets somehow gets to a
        // non-triggered but bysy state sometimes)
        {
-               static float counter = 0.0;
+               float &counter = m_emergethread_trigger_timer;
                counter += dtime;
                if(counter >= 2.0)
                {
@@ -1235,7 +1275,7 @@ void Server::AsyncRunStep()
 
        // Save map
        {
-               static float counter = 0.0;
+               float &counter = m_savemap_timer;
                counter += dtime;
                if(counter >= SERVER_MAP_SAVE_INTERVAL)
                {
@@ -1589,14 +1629,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                if(action == 0)
                {
 
-                       u8 material;
+                       u8 content;
 
                        try
                        {
-                               // Get material at position
-                               material = m_env.getMap().getNode(p_under).d;
+                               // Get content at position
+                               content = m_env.getMap().getNode(p_under).d;
                                // If it's not diggable, do nothing
-                               if(content_diggable(material) == false)
+                               if(content_diggable(content) == false)
                                {
                                        return;
                                }
@@ -1615,7 +1655,16 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                        JMutexAutoLock(client->m_dig_mutex);
                        client->m_dig_tool_item = 0;
                        client->m_dig_position = p_under;
-                       client->m_dig_time_remaining = 1.0;
+                       float dig_time = 0.5;
+                       if(content == CONTENT_STONE)
+                       {
+                               dig_time = 1.5;
+                       }
+                       else if(content == CONTENT_TORCH)
+                       {
+                               dig_time = 0.0;
+                       }
+                       client->m_dig_time_remaining = dig_time;
                        
                        // Reset build time counter
                        getClient(peer->id)->m_time_from_building.set(0.0);
index 851a5ba67ab7e7e2c5a2f0cf4f3817f1a446ba2e..c20189eb106003f8e703fce2b6e2c92e4a281fab 100644 (file)
@@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "environment.h"
 #include "common_irrlicht.h"
 #include <string>
+#include "utility.h"
 
 #ifdef _WIN32
        #include <windows.h>
@@ -146,44 +147,6 @@ private:
        JMutex m_mutex;
 };
 
-class SimpleThread : public JThread
-{
-       bool run;
-       JMutex run_mutex;
-
-public:
-
-       SimpleThread():
-               JThread(),
-               run(true)
-       {
-               run_mutex.Init();
-       }
-
-       virtual ~SimpleThread()
-       {}
-
-       virtual void * Thread() = 0;
-
-       bool getRun()
-       {
-               JMutexAutoLock lock(run_mutex);
-               return run;
-       }
-       void setRun(bool a_run)
-       {
-               JMutexAutoLock lock(run_mutex);
-               run = a_run;
-       }
-
-       void stop()
-       {
-               setRun(false);
-               while(IsRunning())
-                       sleep_ms(100);
-       }
-};
-
 class Server;
 
 class ServerThread : public SimpleThread
@@ -281,6 +244,7 @@ public:
                serialization_version = SER_FMT_VER_INVALID;
                pending_serialization_version = SER_FMT_VER_INVALID;
                m_nearest_unsent_d = 0;
+               m_nearest_unsent_reset_timer = 0.0;
 
                m_blocks_sent_mutex.Init();
                m_blocks_sending_mutex.Init();
@@ -384,6 +348,7 @@ private:
        core::map<v3s16, bool> m_blocks_sent;
        s16 m_nearest_unsent_d;
        v3s16 m_last_center;
+       float m_nearest_unsent_reset_timer;
        JMutex m_blocks_sent_mutex;
        /*
                Blocks that are currently on the line.
@@ -467,6 +432,12 @@ private:
        void UpdateBlockWaterPressure(MapBlock *block,
                        core::map<v3s16, MapBlock*> &modified_blocks);
        
+       float m_flowwater_timer;
+       float m_print_info_timer;
+       float m_objectdata_timer;
+       float m_emergethread_trigger_timer;
+       float m_savemap_timer;
+       
        // NOTE: If connection and environment are both to be locked,
        // environment shall be locked first.
        JMutex m_env_mutex;
index 37785822c7ad66c0114c35c4c98b2360f95ecfe6..5161b22848244d7b7a40db416f6b72d10ad828a8 100644 (file)
@@ -56,7 +56,7 @@ void tile_materials_preload(TextureCache &cache)
                g_tile_materials[i].setFlag(video::EMF_BILINEAR_FILTER, false);
                g_tile_materials[i].setFlag(video::EMF_ANTI_ALIASING, video::EAAM_OFF);
                //if(i != TILE_WATER)
-               //g_tile_materials[i].setFlag(video::EMF_FOG_ENABLE, true);
+               g_tile_materials[i].setFlag(video::EMF_FOG_ENABLE, true);
                
                //g_tile_materials[i].setFlag(video::EMF_TEXTURE_WRAP, video::ETC_REPEAT);
                //g_tile_materials[i].setFlag(video::EMF_ANISOTROPIC_FILTER, false);
index f7e726f87b389418420e5b7714197a40543b9cd5..e4494948c1d9e77adfdf41151763b10a0c8e665f 100644 (file)
@@ -28,9 +28,18 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <fstream>
 #include <string>
 #include <sstream>
+#include <jthread.h>
 #include <jmutex.h>
 #include <jmutexautolock.h>
 
+#ifdef _WIN32
+       #include <windows.h>
+       #define sleep_ms(x) Sleep(x)
+#else
+       #include <unistd.h>
+       #define sleep_ms(x) usleep(x*1000)
+#endif
+
 #include "common_irrlicht.h"
 #include "debug.h"
 #include "strfnd.h"
@@ -1100,5 +1109,43 @@ private:
        JMutex m_mutex;
 };
 
+class SimpleThread : public JThread
+{
+       bool run;
+       JMutex run_mutex;
+
+public:
+
+       SimpleThread():
+               JThread(),
+               run(true)
+       {
+               run_mutex.Init();
+       }
+
+       virtual ~SimpleThread()
+       {}
+
+       virtual void * Thread() = 0;
+
+       bool getRun()
+       {
+               JMutexAutoLock lock(run_mutex);
+               return run;
+       }
+       void setRun(bool a_run)
+       {
+               JMutexAutoLock lock(run_mutex);
+               run = a_run;
+       }
+
+       void stop()
+       {
+               setRun(false);
+               while(IsRunning())
+                       sleep_ms(100);
+       }
+};
+
 #endif
 
index e94cba0f6a0885c18d72f25e01181eca2c8ec8a8..f8a98942cc7e72873803875a4c91791ce09a10d0 100644 (file)
@@ -741,11 +741,6 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
 
        m_data[m_area.index(removed_pos)].setLightBanks(light);
        
-       /*// NOTE: HACK: This has to be set to LIGHT_MAX so that
-       // unspreadLight will clear all light that came from this node.
-       // Otherwise there will be weird bugs
-       m_data[m_area.index(removed_pos)].setLight(LIGHT_MAX);*/
-
        // Mark removed_pos checked
        m_flags[m_area.index(removed_pos)] |= VOXELFLAG_CHECKED;