organizing stuff.
authorPerttu Ahola <celeron55@gmail.com>
Tue, 21 Dec 2010 16:08:24 +0000 (18:08 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 21 Dec 2010 16:08:24 +0000 (18:08 +0200)
23 files changed:
src/client.cpp
src/debug.h
src/defaultsettings.cpp
src/gettime.h [new file with mode: 0644]
src/inventory.cpp
src/inventory.h
src/main.cpp
src/main.h
src/map.cpp
src/map.h
src/mapblock.cpp
src/mapblock.h
src/mapblockobject.cpp
src/mapblockobject.h
src/mapnode.h
src/porting.h
src/server.cpp
src/server.h
src/servermain.cpp
src/tile.cpp
src/utility.cpp
src/utility.h
src/voxel.cpp

index 4979829d1cfd90f70ef4f90cfdc6f8f0bc3c161f..d99b8d8df101bf2aa3aca89523da3d2870a87d77 100644 (file)
@@ -368,7 +368,7 @@ void Client::step(float dtime)
                        try
                        {
                                block = m_env.getMap().getBlockNoCreate(p);
-                               block->stepObjects(dtime, false);
+                               block->stepObjects(dtime, false, m_env.getDayNightRatio());
                        }
                        catch(InvalidPositionException &e)
                        {
@@ -946,7 +946,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
                                NOTE: Be sure this is done in the main thread.
                        */
                        block->updateObjects(is, m_server_ser_ver,
-                                       m_device->getSceneManager());
+                                       m_device->getSceneManager(), m_env.getDayNightRatio());
                }
                
                /*dstream<<"Final delete queue size: "<<abs_to_delete.size()
index 44fcf4b5150f83aa20312efdad2e1cd7d6140f91..3f269176abcf889cf7fe06fff820382efde4b6d0 100644 (file)
@@ -17,11 +17,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-
-/*
-       Debug stuff
-*/
-
 #ifndef DEBUG_HEADER
 #define DEBUG_HEADER
 
@@ -31,11 +26,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <iostream>
 #include "common_irrlicht.h"
 #include "threads.h"
+#include "gettime.h"
 
 /*
        Debug output
 */
 
+#define DTIME (getTimestamp()+": ")
+
 #define DEBUGSTREAM_COUNT 2
 
 extern FILE *g_debugstreams[DEBUGSTREAM_COUNT];
index 6888fa4971c87f40cac3a24ce631ad68fc5b12e6..065ff2e44fbce83471cc836dfb5f5f25d2f89e0e 100644 (file)
@@ -41,7 +41,7 @@ void set_default_settings()
        // Server stuff
        g_settings.setDefault("creative_mode", "false");
        g_settings.setDefault("heightmap_blocksize", "32");
-       g_settings.setDefault("height_randmax", "constant 50.0");
+       g_settings.setDefault("height_randmax", "constant 45.0");
        g_settings.setDefault("height_randfactor", "constant 0.6");
        g_settings.setDefault("height_base", "linear 0 0 0");
        g_settings.setDefault("plants_amount", "1.0");
diff --git a/src/gettime.h b/src/gettime.h
new file mode 100644 (file)
index 0000000..b195526
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+Minetest-c55
+Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef GETTIME_HEADER
+#define GETTIME_HEADER
+
+#include "common_irrlicht.h"
+
+/*
+       Get a millisecond counter value.
+       Precision depends on implementation.
+       Overflows at any value above 10000000.
+
+       Implementation of this is done in:
+               Normal build: main.cpp
+               Server build: servermain.cpp
+*/
+extern u32 getTimeMs();
+
+/*
+       Timestamp stuff
+*/
+
+#include <time.h>
+#include <string>
+
+inline std::string getTimestamp()
+{
+       time_t t = time(NULL);
+       // This is not really thread-safe but it won't break anything
+       // except its own output, so just go with it.
+       struct tm *tm = localtime(&t);
+       char cs[20];
+       strftime(cs, 20, "%H:%M:%S", tm);
+       return cs;
+}
+
+
+#endif
index 079be87931a7558e2a9b9f044b3d71a4d13f4d9e..3899c9394186cdf3e5cac86ed81d115c64618c88 100644 (file)
@@ -76,7 +76,7 @@ InventoryItem* InventoryItem::deSerialize(std::istream &is)
 /*
        MapBlockObjectItem
 */
-
+#ifndef SERVER
 video::ITexture * MapBlockObjectItem::getImage()
 {
        if(m_inventorystring.substr(0,3) == "Rat")
@@ -89,6 +89,7 @@ video::ITexture * MapBlockObjectItem::getImage()
 
        return NULL;
 }
+#endif
 std::string MapBlockObjectItem::getText()
 {
        if(m_inventorystring.substr(0,3) == "Rat")
index 59ff89ed8bbd4c82dc49995ed287134f367d85a6..354111045852e0e893171c44bdcd67dbfd002362 100644 (file)
@@ -46,8 +46,10 @@ public:
        virtual void serialize(std::ostream &os) = 0;
        // Shall make an exact clone of the item
        virtual InventoryItem* clone() = 0;
+#ifndef SERVER
        // Shall return an image to show in the GUI (or NULL)
        virtual video::ITexture * getImage() { return NULL; }
+#endif
        // Shall return a text to show in the GUI
        virtual std::string getText() { return ""; }
 
@@ -175,7 +177,9 @@ public:
                return new MapBlockObjectItem(m_inventorystring);
        }
 
+#ifndef SERVER
        video::ITexture * getImage();
+#endif
        std::string getText();
 
        /*
index 6b545596519aa14819141a17f4ac2033751e8fa6..8325680f253080f72757d930a9537f75285aa323 100644 (file)
@@ -99,8 +99,6 @@ SUGG: A version number to blocks, which increments when the block is
          - This can then be used to make sure the most recent version of\r
            a block has been sent to client\r
 \r
-TODO: Stop player if focus of window is taken away (go to pause mode)\r
-\r
 TODO: Combine MapBlock's face caches to so big pieces that VBO\r
       gets used\r
       - That is >500 vertices\r
@@ -110,16 +108,6 @@ TODO: Cliffs, arcs
 \r
 TODO: Menus\r
 \r
-TODO: Mobs\r
-      - Server:\r
-        - One single map container with ids as keys\r
-      - Client:\r
-           - ?\r
-TODO: - Keep track of the place of the mob in the last few hundreth's\r
-        of a second - then, if a player hits it, take the value that is\r
-               avg_rtt/2 before the moment the packet is received.\r
-TODO: - Scripting\r
-\r
 TODO: Moving players more smoothly. Calculate moving animation\r
       in a way that doesn't make the player jump to the right place\r
          immediately when the server sends a new position\r
@@ -158,8 +146,6 @@ Block object server side:
            - TODO: For incoming blocks, time difference is calculated and\r
              objects are stepped according to it.\r
 \r
-TODO: Add config parameters for server's sending and generating distance\r
-\r
 TODO: Copy the text of the last picked sign to inventory in creative\r
       mode\r
 \r
@@ -172,13 +158,20 @@ TODO: Check what goes wrong with caching map to disk (Kray)
 \r
 TODO: Remove LazyMeshUpdater. It is not used as supposed.\r
 \r
-TODO: Add server unused sector deletion settings to settings\r
-\r
 TODO: TOSERVER_LEAVE\r
 \r
+TODO: Better handling of objects and mobs\r
+      - Update brightness according to day-night blended light of node\r
+           in position\r
+      - Scripting?\r
+\r
 Doing now:\r
 ======================================================================\r
 \r
+TODO: Get rid of g_irrlicht for server build\r
+\r
+TODO: Implement getGlobalTime for server build\r
+      - It is needed for controlling the time used for flowing water\r
 \r
 ======================================================================\r
 \r
@@ -226,7 +219,6 @@ Doing now:
 \r
 #include <iostream>\r
 #include <fstream>\r
-#include <time.h>\r
 #include <jmutexautolock.h>\r
 #include <locale.h>\r
 #include "common_irrlicht.h"\r
@@ -243,6 +235,8 @@ Doing now:
 #include "strfnd.h"\r
 #include "porting.h"\r
 #include "guiPauseMenu.h"\r
+#include "irrlichtwrapper.h"\r
+#include "gettime.h"\r
 \r
 IrrlichtWrapper *g_irrlicht;\r
 \r
@@ -266,7 +260,6 @@ bool g_viewing_range_all = false;
 // inhibits glitches (dtime jitter) in the main loop.\r
 //float g_freetime_ratio = FREETIME_RATIO_MAX;\r
 \r
-\r
 /*\r
        Settings.\r
        These are loaded from the config file.\r
@@ -311,25 +304,19 @@ std::ostream *derr_server_ptr = &dstream;
 std::ostream *dout_client_ptr = &dstream;\r
 std::ostream *derr_client_ptr = &dstream;\r
 \r
-\r
 /*\r
-       Timestamp stuff\r
+       gettime.h implementation\r
 */\r
 \r
-JMutex g_timestamp_mutex;\r
-//std::string g_timestamp;\r
-\r
-std::string getTimestamp()\r
+u32 getTimeMs()\r
 {\r
-       if(g_timestamp_mutex.IsInitialized()==false)\r
-               return "";\r
-       JMutexAutoLock lock(g_timestamp_mutex);\r
-       //return g_timestamp;\r
-       time_t t = time(NULL);\r
-       struct tm *tm = localtime(&t);\r
-       char cs[20];\r
-       strftime(cs, 20, "%H:%M:%S", tm);\r
-       return cs;\r
+       /*\r
+               Use irrlicht because it is more precise than porting.h's\r
+               getTimeMs()\r
+       */\r
+       if(g_irrlicht == NULL)\r
+               return 0;\r
+       return g_irrlicht->getTime();\r
 }\r
 \r
 class MyEventReceiver : public IEventReceiver\r
@@ -1066,9 +1053,6 @@ int main(int argc, char *argv[])
        sockets_init();\r
        atexit(sockets_cleanup);\r
        \r
-       // Initialize timestamp mutex\r
-       g_timestamp_mutex.Init();\r
-\r
        /*\r
                Initialization\r
        */\r
@@ -1580,7 +1564,7 @@ int main(int argc, char *argv[])
                // Info text\r
                std::wstring infotext;\r
 \r
-               //TimeTaker //timer1("//timer1", g_irrlicht);\r
+               //TimeTaker //timer1("//timer1");\r
                \r
                // Time of frame without fps limit\r
                float busytime;\r
@@ -1770,20 +1754,20 @@ int main(int argc, char *argv[])
                */\r
                \r
                {\r
-                       //TimeTaker timer("client.step(dtime)", g_irrlicht);\r
+                       //TimeTaker timer("client.step(dtime)");\r
                        client.step(dtime);\r
                        //client.step(dtime_avg1);\r
                }\r
 \r
                if(server != NULL)\r
                {\r
-                       //TimeTaker timer("server->step(dtime)", g_irrlicht);\r
+                       //TimeTaker timer("server->step(dtime)");\r
                        server->step(dtime);\r
                }\r
 \r
                v3f player_position = client.getPlayerPosition();\r
                \r
-               //TimeTaker //timer2("//timer2", g_irrlicht);\r
+               //TimeTaker //timer2("//timer2");\r
 \r
                /*\r
                        Mouse and camera control\r
@@ -1837,12 +1821,12 @@ int main(int argc, char *argv[])
                }\r
                else{\r
                        //client.m_env.getMap().updateCamera(camera_position, camera_direction);\r
-                       //TimeTaker timer("client.updateCamera", g_irrlicht);\r
+                       //TimeTaker timer("client.updateCamera");\r
                        client.updateCamera(camera_position, camera_direction);\r
                }\r
                \r
                //timer2.stop();\r
-               //TimeTaker //timer3("//timer3", g_irrlicht);\r
+               //TimeTaker //timer3("//timer3");\r
 \r
                /*\r
                        Calculate what block is the crosshair pointing to\r
@@ -2118,7 +2102,7 @@ int main(int argc, char *argv[])
                                        dig_time_complete = 1.5;\r
 \r
                                u16 dig_index = (u16)(3.99*dig_time/dig_time_complete);\r
-                               if(dig_time > 0.2)\r
+                               if(dig_time > 0.125)\r
                                {\r
                                        //dstream<<"dig_index="<<dig_index<<std::endl;\r
                                        client.setTempMod(nodepos, NodeMod(NODEMOD_CRACK, dig_index));\r
@@ -2194,7 +2178,7 @@ int main(int argc, char *argv[])
                        Update gui stuff (0ms)\r
                */\r
 \r
-               //TimeTaker guiupdatetimer("Gui updating", g_irrlicht);\r
+               //TimeTaker guiupdatetimer("Gui updating");\r
                \r
                {\r
                        wchar_t temptext[150];\r
@@ -2304,11 +2288,11 @@ int main(int argc, char *argv[])
                        Drawing begins\r
                */\r
 \r
-               TimeTaker drawtimer("Drawing", g_irrlicht);\r
+               TimeTaker drawtimer("Drawing");\r
 \r
                \r
                {\r
-                       TimeTaker timer("beginScene", g_irrlicht);\r
+                       TimeTaker timer("beginScene");\r
                        driver->beginScene(true, true, bgcolor);\r
                        //driver->beginScene(false, true, bgcolor);\r
                        beginscenetime = timer.stop(true);\r
@@ -2319,13 +2303,13 @@ int main(int argc, char *argv[])
                //std::cout<<DTIME<<"smgr->drawAll()"<<std::endl;\r
                \r
                {\r
-                       TimeTaker timer("smgr", g_irrlicht);\r
+                       TimeTaker timer("smgr");\r
                        smgr->drawAll();\r
                        scenetime = timer.stop(true);\r
                }\r
                \r
                {\r
-               //TimeTaker timer9("auxiliary drawings", g_irrlicht);\r
+               //TimeTaker timer9("auxiliary drawings");\r
                // 0ms\r
 \r
                driver->draw2DLine(displaycenter - core::vector2d<s32>(10,0),\r
@@ -2336,7 +2320,7 @@ int main(int argc, char *argv[])
                                video::SColor(255,255,255,255));\r
 \r
                //timer9.stop();\r
-               //TimeTaker //timer10("//timer10", g_irrlicht);\r
+               //TimeTaker //timer10("//timer10");\r
                \r
                video::SMaterial m;\r
                m.Thickness = 10;\r
@@ -2359,7 +2343,7 @@ int main(int argc, char *argv[])
                }\r
 \r
                //timer10.stop();\r
-               //TimeTaker //timer11("//timer11", g_irrlicht);\r
+               //TimeTaker //timer11("//timer11");\r
 \r
                /*\r
                        Draw gui\r
@@ -2369,7 +2353,7 @@ int main(int argc, char *argv[])
                \r
                // End drawing\r
                {\r
-                       TimeTaker timer("endScene", g_irrlicht);\r
+                       TimeTaker timer("endScene");\r
                        driver->endScene();\r
                        endscenetime = timer.stop(true);\r
                }\r
index 22b5157d70250c7c3d6ae324bed939819ada6393..e6bb1caacea2511a96473f91dc7ea5e9bf499bf9 100644 (file)
@@ -20,18 +20,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef MAIN_HEADER
 #define MAIN_HEADER
 
-#include <string>
-extern std::string getTimestamp();
-#define DTIME (getTimestamp()+": ")
-
-#include <jmutex.h>
+#include "irrlichtwrapper.h"
 
 // Settings
 extern Settings g_settings;
 
-#include <fstream>
+// A thread safe wrapper to irrlicht
+// On a server build, this is always NULL.
+extern IrrlichtWrapper *g_irrlicht;
 
 // Debug streams
+
+#include <fstream>
+
 extern std::ostream *dout_con_ptr;
 extern std::ostream *derr_con_ptr;
 extern std::ostream *dout_client_ptr;
@@ -46,14 +47,5 @@ extern std::ostream *derr_server_ptr;
 #define dout_server (*dout_server_ptr)
 #define derr_server (*derr_server_ptr)
 
-/*#ifndef SERVER
-       #include "utility.h"
-       extern TextureCache g_texturecache;
-#endif*/
-
-#include "irrlichtwrapper.h"
-//extern IrrlichtDevice *g_device;
-extern IrrlichtWrapper *g_irrlicht;
-
 #endif
 
index 2a517c544448b33c705f33686920509acb3c077e..9a0952c753567cd1cdadd6800a1ab0af9aae68bf 100644 (file)
@@ -152,6 +152,21 @@ MapBlock * Map::getBlockNoCreate(v3s16 p3d)
        return block;
 }
 
+MapBlock * Map::getBlockNoCreateNoEx(v3s16 p3d)
+{
+       try
+       {
+               v2s16 p2d(p3d.X, p3d.Z);
+               MapSector * sector = getSectorNoGenerate(p2d);
+               MapBlock *block = sector->getBlockNoCreate(p3d.Y);
+               return block;
+       }
+       catch(InvalidPositionException &e)
+       {
+               return NULL;
+       }
+}
+
 f32 Map::getGroundHeight(v2s16 p, bool generate)
 {
        try{
@@ -740,7 +755,7 @@ void Map::updateLighting(enum LightBank bank,
        }
        
        {
-               //TimeTaker timer("unspreadLight", g_irrlicht);
+               //TimeTaker timer("unspreadLight");
                unspreadLight(bank, unlight_from, light_sources, modified_blocks);
        }
        
@@ -759,7 +774,7 @@ void Map::updateLighting(enum LightBank bank,
        //       - Find out why it works
 
        {
-               //TimeTaker timer("spreadLight", g_irrlicht);
+               //TimeTaker timer("spreadLight");
                spreadLight(bank, light_sources, modified_blocks);
        }
        
@@ -813,6 +828,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
        */
 
        v3s16 toppos = p + v3s16(0,1,0);
+       v3s16 bottompos = p + v3s16(0,-1,0);
 
        bool node_under_sunlight = true;
        core::map<v3s16, bool> light_sources;
@@ -832,6 +848,26 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
        catch(InvalidPositionException &e)
        {
        }
+       
+       if(n.d != CONTENT_TORCH)
+       {
+               /*
+                       If there is grass below, change it to mud
+               */
+               try{
+                       MapNode bottomnode = getNode(bottompos);
+                       
+                       if(bottomnode.d == CONTENT_GRASS
+                                       || bottomnode.d == CONTENT_GRASS_FOOTSTEPS)
+                       {
+                               bottomnode.d = CONTENT_MUD;
+                               setNode(bottompos, bottomnode);
+                       }
+               }
+               catch(InvalidPositionException &e)
+               {
+               }
+       }
 
        enum LightBank banks[] =
        {
@@ -1065,7 +1101,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
 #ifndef SERVER
 void Map::expireMeshes(bool only_daynight_diffed)
 {
-       TimeTaker timer("expireMeshes()", g_irrlicht);
+       TimeTaker timer("expireMeshes()");
 
        core::map<v2s16, MapSector*>::Iterator si;
        si = m_sectors.getIterator();
@@ -1109,6 +1145,7 @@ void Map::updateMeshes(v3s16 blockpos, u32 daynight_ratio)
                b->updateMesh(daynight_ratio);
        }
        catch(InvalidPositionException &e){}
+       // Leading edge
        try{
                v3s16 p = blockpos + v3s16(-1,0,0);
                MapBlock *b = getBlockNoCreate(p);
@@ -1127,6 +1164,25 @@ void Map::updateMeshes(v3s16 blockpos, u32 daynight_ratio)
                b->updateMesh(daynight_ratio);
        }
        catch(InvalidPositionException &e){}
+       /*// Trailing edge
+       try{
+               v3s16 p = blockpos + v3s16(1,0,0);
+               MapBlock *b = getBlockNoCreate(p);
+               b->updateMesh(daynight_ratio);
+       }
+       catch(InvalidPositionException &e){}
+       try{
+               v3s16 p = blockpos + v3s16(0,1,0);
+               MapBlock *b = getBlockNoCreate(p);
+               b->updateMesh(daynight_ratio);
+       }
+       catch(InvalidPositionException &e){}
+       try{
+               v3s16 p = blockpos + v3s16(0,0,1);
+               MapBlock *b = getBlockNoCreate(p);
+               b->updateMesh(daynight_ratio);
+       }
+       catch(InvalidPositionException &e){}*/
 }
 
 #endif
@@ -1140,6 +1196,7 @@ bool Map::dayNightDiffed(v3s16 blockpos)
                        return true;
        }
        catch(InvalidPositionException &e){}
+       // Leading edges
        try{
                v3s16 p = blockpos + v3s16(-1,0,0);
                MapBlock *b = getBlockNoCreate(p);
@@ -1161,6 +1218,28 @@ bool Map::dayNightDiffed(v3s16 blockpos)
                        return true;
        }
        catch(InvalidPositionException &e){}
+       // Trailing edges
+       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;
 }
@@ -2567,7 +2646,7 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, MapSecto
        */
        if(version >= 9)
        {
-               block->updateObjects(is, version, NULL);
+               block->updateObjects(is, version, NULL, 0);
        }
 
        if(created_new)
@@ -2985,21 +3064,56 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
 
 v3s16 ClientMap::setTempMod(v3s16 p, NodeMod mod)
 {
-       v3s16 blockpos = getNodeBlockPos(p);
-       MapBlock * blockref = getBlockNoCreate(blockpos);
-       v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
-
-       blockref->setTempMod(relpos, mod);
-       return blockpos;
+       /*
+               Add it to all blocks touching it
+       */
+       v3s16 dirs[7] = {
+               v3s16(0,0,0), // this
+               v3s16(0,0,1), // back
+               v3s16(0,1,0), // top
+               v3s16(1,0,0), // right
+               v3s16(0,0,-1), // front
+               v3s16(0,-1,0), // bottom
+               v3s16(-1,0,0), // left
+       };
+       for(u16 i=0; i<7; i++)
+       {
+               v3s16 p2 = p + dirs[i];
+               // Block position of neighbor (or requested) node
+               v3s16 blockpos = getNodeBlockPos(p2);
+               MapBlock * blockref = getBlockNoCreateNoEx(blockpos);
+               if(blockref == NULL)
+                       continue;
+               // Relative position of requested node
+               v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
+               blockref->setTempMod(relpos, mod);
+       }
+       return getNodeBlockPos(p);
 }
 v3s16 ClientMap::clearTempMod(v3s16 p)
 {
-       v3s16 blockpos = getNodeBlockPos(p);
-       MapBlock * blockref = getBlockNoCreate(blockpos);
-       v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
-
-       blockref->clearTempMod(relpos);
-       return blockpos;
+       v3s16 dirs[7] = {
+               v3s16(0,0,0), // this
+               v3s16(0,0,1), // back
+               v3s16(0,1,0), // top
+               v3s16(1,0,0), // right
+               v3s16(0,0,-1), // front
+               v3s16(0,-1,0), // bottom
+               v3s16(-1,0,0), // left
+       };
+       for(u16 i=0; i<7; i++)
+       {
+               v3s16 p2 = p + dirs[i];
+               // Block position of neighbor (or requested) node
+               v3s16 blockpos = getNodeBlockPos(p2);
+               MapBlock * blockref = getBlockNoCreateNoEx(blockpos);
+               if(blockref == NULL)
+                       continue;
+               // Relative position of requested node
+               v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
+               blockref->clearTempMod(relpos);
+       }
+       return getNodeBlockPos(p);
 }
 
 void ClientMap::PrintInfo(std::ostream &out)
@@ -3027,7 +3141,7 @@ MapVoxelManipulator::~MapVoxelManipulator()
 #if 1
 void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id)
 {
-       TimeTaker timer1("emerge", g_irrlicht, &emerge_time);
+       TimeTaker timer1("emerge", &emerge_time);
 
        // Units of these are MapBlocks
        v3s16 p_min = getNodeBlockPos(a.MinEdge);
@@ -3051,7 +3165,7 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id)
                bool block_data_inexistent = false;
                try
                {
-                       TimeTaker timer1("emerge load", g_irrlicht, &emerge_load_time);
+                       TimeTaker timer1("emerge load", &emerge_load_time);
 
                        /*dstream<<"Loading block (caller_id="<<caller_id<<")"
                                        <<" ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
@@ -3092,7 +3206,7 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id)
 #if 0
 void MapVoxelManipulator::emerge(VoxelArea a)
 {
-       TimeTaker timer1("emerge", g_irrlicht, &emerge_time);
+       TimeTaker timer1("emerge", &emerge_time);
        
        v3s16 size = a.getExtent();
        
@@ -3111,7 +3225,7 @@ void MapVoxelManipulator::emerge(VoxelArea a)
                        continue;
                try
                {
-                       TimeTaker timer1("emerge load", g_irrlicht, &emerge_load_time);
+                       TimeTaker timer1("emerge load", &emerge_load_time);
                        MapNode n = m_map->getNode(a.MinEdge + p);
                        m_data[i] = n;
                        m_flags[i] = 0;
@@ -3136,7 +3250,7 @@ void MapVoxelManipulator::blitBack
        if(m_area.getExtent() == v3s16(0,0,0))
                return;
        
-       //TimeTaker timer1("blitBack", g_irrlicht);
+       //TimeTaker timer1("blitBack");
        
        /*
                Initialize block cache
index 3b34cd899e4edbb3e75bda9c3b2dc89998021f07..2a3fa5061b30744da0ee7b6db5521112b2bae981 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -274,7 +274,8 @@ public:
        
        // Returns InvalidPositionException if not found
        MapBlock * getBlockNoCreate(v3s16 p);
-       //virtual MapBlock * getBlock(v3s16 p, bool generate=true);
+       // Returns NULL if not found
+       MapBlock * getBlockNoCreateNoEx(v3s16 p);
        
        // Returns InvalidPositionException if not found
        f32 getGroundHeight(v2s16 p, bool generate=false);
@@ -386,7 +387,7 @@ public:
 #endif
 
        /*
-               Takes the blocks at the leading edges into account
+               Takes the blocks at the edges into account
        */
        bool dayNightDiffed(v3s16 blockpos);
 
index e2262544cdac2a6f10daa57a1dca21c80d7b4658..b2b5bc4f44f9fb99f67e98419ec0e6c06c20214c 100644 (file)
@@ -40,6 +40,8 @@ MapBlock::MapBlock(NodeContainer *parent, v3s16 pos, bool dummy):
        data = NULL;
        if(dummy == false)
                reallocate();
+       
+       m_spawn_timer = -10000;
 
 #ifndef SERVER
        m_mesh_expired = false;
@@ -237,8 +239,8 @@ void MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
 
        v3f zerovector = v3f(0,0,0);
        
-       u8 li = decode_light(light);
-       //u8 li = 150;
+       //u8 li = decode_light(light);
+       u8 li = light;
 
        u8 alpha = 255;
 
@@ -435,14 +437,14 @@ void MapBlock::updateFastFaceRow(
                                // If node at sp (tile0) is more solid
                                if(mf == 1)
                                {
-                                       makeFastFace(tile0, light,
+                                       makeFastFace(tile0, decode_light(light),
                                                        sp, face_dir, scale,
                                                        posRelative_f, dest);
                                }
                                // If node at sp is less solid (mf == 2)
                                else
                                {
-                                       makeFastFace(tile1, light,
+                                       makeFastFace(tile1, decode_light(light),
                                                        sp+face_dir_f, -face_dir, scale,
                                                        posRelative_f, dest);
                                }
@@ -992,6 +994,52 @@ void MapBlock::copyTo(VoxelManipulator &dst)
                core::array<DistanceSortedObject> &dest)
 {
 }*/
+void MapBlock::stepObjects(float dtime, bool server, u32 daynight_ratio)
+{
+       /*
+               Step objects
+       */
+       m_objects.step(dtime, server, daynight_ratio);
+       
+       /*
+               Spawn some objects at random.
+
+               Use dayNightDiffed() to approximate being near ground level
+       */
+       if(m_spawn_timer < -999)
+       {
+               m_spawn_timer = 60;
+       }
+       if(dayNightDiffed() == true && getObjectCount() == 0)
+       {
+               m_spawn_timer -= dtime;
+               if(m_spawn_timer <= 0.0)
+               {
+                       m_spawn_timer += rand() % 300;
+                       
+                       v2s16 p2d(
+                               (rand()%(MAP_BLOCKSIZE-1))+0,
+                               (rand()%(MAP_BLOCKSIZE-1))+0
+                       );
+
+                       s16 y = getGroundLevel(p2d);
+                       
+                       if(y >= 0)
+                       {
+                               v3s16 p(p2d.X, y+1, p2d.Y);
+
+                               if(getNode(p).d == CONTENT_AIR
+                                               && getNode(p).getLightBlend(daynight_ratio) <= 11)
+                               {
+                                       RatObject *obj = new RatObject(NULL, -1, intToFloat(p));
+                                       addObject(obj);
+                               }
+                       }
+               }
+       }
+
+       setChangedFlag();
+}
 
 
 void MapBlock::updateDayNightDiff()
@@ -1041,6 +1089,31 @@ void MapBlock::updateDayNightDiff()
        m_day_night_differs = differs;
 }
 
+s16 MapBlock::getGroundLevel(v2s16 p2d)
+{
+       if(isDummy())
+               return -3;
+       try
+       {
+               s16 y = MAP_BLOCKSIZE-1;
+               for(; y>=0; y--)
+               {
+                       if(is_ground_content(getNodeRef(p2d.X, y, p2d.Y).d))
+                       {
+                               if(y == MAP_BLOCKSIZE-1)
+                                       return -2;
+                               else
+                                       return y;
+                       }
+               }
+               return -1;
+       }
+       catch(InvalidPositionException &e)
+       {
+               return -3;
+       }
+}
+
 /*
        Serialization
 */
index b5126b8225560c4984dc2b8d3583925ea82a61e6..dc077c23f4acc358042adfec9a306ce24d3c7ef0 100644 (file)
@@ -281,6 +281,7 @@ public:
        }
        
 #ifndef SERVER
+       // light = 0...255
        static void makeFastFace(TileSpec tile, u8 light, v3f p,
                        v3s16 dir, v3f scale, v3f posRelative_f,
                        core::array<FastFace> &dest);
@@ -325,9 +326,9 @@ public:
        }
        // If smgr!=NULL, new objects are added to the scene
        void updateObjects(std::istream &is, u8 version,
-                       scene::ISceneManager *smgr)
+                       scene::ISceneManager *smgr, u32 daynight_ratio)
        {
-               m_objects.update(is, version, smgr);
+               m_objects.update(is, version, smgr, daynight_ratio);
 
                setChangedFlag();
        }
@@ -358,12 +359,11 @@ public:
        {
                return m_objects.getLock();
        }
-       void stepObjects(float dtime, bool server)
-       {
-               m_objects.step(dtime, server);
 
-               setChangedFlag();
-       }
+       /*
+               Moves objects, deletes objects and spawns new objects
+       */
+       void stepObjects(float dtime, bool server, u32 daynight_ratio);
 
        /*void wrapObject(MapBlockObject *object)
        {
@@ -427,6 +427,20 @@ public:
                return m_day_night_differs;
        }
 
+       /*
+               Miscellaneous stuff
+       */
+       
+       /*
+               Tries to measure ground level.
+               Return value:
+                       -1 = only air
+                       -2 = only ground
+                       -3 = random fail
+                       0...MAP_BLOCKSIZE-1 = ground level
+       */
+       s16 getGroundLevel(v2s16 p2d);
+
        /*
                Serialization
        */
@@ -454,6 +468,8 @@ private:
 
        MapNode & getNodeRef(s16 x, s16 y, s16 z)
        {
+               if(data == NULL)
+                       throw InvalidPositionException();
                if(x < 0 || x >= MAP_BLOCKSIZE) throw InvalidPositionException();
                if(y < 0 || y >= MAP_BLOCKSIZE) throw InvalidPositionException();
                if(z < 0 || z >= MAP_BLOCKSIZE) throw InvalidPositionException();
@@ -491,6 +507,9 @@ private:
        bool m_day_night_differs;
        
        MapBlockObjectList m_objects;
+
+       // Object spawning stuff
+       float m_spawn_timer;
        
 #ifndef SERVER
        bool m_mesh_expired;
index 8b52b9447f36599a916655e88d18b45d116662ba..779fe3fa71d0257c208c20d00082f880039e4259 100644 (file)
@@ -46,6 +46,17 @@ void MapBlockObject::setBlockChanged()
 /*
        MovingObject
 */
+
+v3f MovingObject::getAbsoluteShowPos()
+{
+       if(m_block == NULL)
+               return m_pos;
+       
+       // getPosRelative gets nodepos relative to map origin
+       v3f blockpos = intToFloat(m_block->getPosRelative());
+       return blockpos + m_showpos;
+}
+
 void MovingObject::move(float dtime, v3f acceleration)
 {
        DSTACK("%s: typeid=%i, pos=(%f,%f,%f), speed=(%f,%f,%f)"
@@ -97,7 +108,7 @@ void MovingObject::move(float dtime, v3f acceleration)
        float speedlength = m_speed.getLength();
        f32 dtime_max_increment;
        if(fabs(speedlength) > 0.001)
-               dtime_max_increment = 0.1*BS / speedlength;
+               dtime_max_increment = 0.05*BS / speedlength;
        else
                dtime_max_increment = 0.5;
        
@@ -151,14 +162,14 @@ void MovingObject::move(float dtime, v3f acceleration)
                        }
                        catch(InvalidPositionException &e)
                        {
-                               // Doing nothing here will block the player from
+                               // Doing nothing here will block the object from
                                // walking over map borders
                        }
 
                        core::aabbox3d<f32> nodebox = Map::getNodeBox(
                                        v3s16(x,y,z));
                        
-                       // See if the player is touching ground
+                       // See if the object is touching ground
                        if(
                                        fabs(nodebox.MaxEdge.Y-objectbox.MinEdge.Y) < d
                                        && nodebox.MaxEdge.X-d > objectbox.MinEdge.X
@@ -227,6 +238,60 @@ void MovingObject::move(float dtime, v3f acceleration)
        m_pos = position;
 }
 
+void MovingObject::simpleMove(float dtime)
+{
+       m_pos_animation_time_counter += dtime;
+       m_pos_animation_counter += dtime;
+       v3f movevector = m_pos - m_oldpos;
+       f32 moveratio;
+       if(m_pos_animation_time < 0.001)
+               moveratio = 1.0;
+       else
+               moveratio = m_pos_animation_counter / m_pos_animation_time;
+       if(moveratio > 1.5)
+               moveratio = 1.5;
+       m_showpos = m_oldpos + movevector * moveratio;
+}
+
+#ifndef SERVER
+/*
+       RatObject
+*/
+void RatObject::addToScene(scene::ISceneManager *smgr)
+{
+       if(m_node != NULL)
+               return;
+       
+       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,-BS/4,0, 0,0,0, c, 0,1),
+               video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
+               video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
+               video::S3DVertex(-BS/2,BS/4,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/rat.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();
+       updateNodePos();
+}
+#endif
+
 /*
        MapBlockObjectList
 */
@@ -265,7 +330,7 @@ void MapBlockObjectList::serialize(std::ostream &os, u8 version)
 }
 
 void MapBlockObjectList::update(std::istream &is, u8 version,
-               scene::ISceneManager *smgr)
+               scene::ISceneManager *smgr, u32 daynight_ratio)
 {
        JMutexAutoLock lock(m_mutex);
 
@@ -349,11 +414,14 @@ void MapBlockObjectList::update(std::istream &is, u8 version,
                        }
                        else
                        {
+                               // This is fatal because we cannot know the length
+                               // of the object's data
                                throw SerializationError
                                ("MapBlockObjectList::update(): Unknown MapBlockObject type");
                        }
 
                        if(smgr != NULL)
+                               //obj->addToScene(smgr, daynight_ratio);
                                obj->addToScene(smgr);
 
                        n->setValue(obj);
@@ -362,6 +430,11 @@ void MapBlockObjectList::update(std::istream &is, u8 version,
                {
                        obj = n->getValue();
                        obj->updatePos(pos);
+                       /*if(daynight_ratio != m_last_update_daynight_ratio)
+                       {
+                               obj->removeFromScene();
+                               obj->addToScene(smgr, daynight_ratio);
+                       }*/
                }
 
                // Now there is an object in obj.
@@ -369,6 +442,21 @@ void MapBlockObjectList::update(std::istream &is, u8 version,
                
                obj->update(is, version);
                
+               /*
+                       Update light on client
+               */
+               if(smgr != NULL)
+               {
+                       u8 light = LIGHT_MAX;
+                       try{
+                               v3s16 relpos_i = floatToInt(obj->m_pos);
+                               MapNode n = m_block->getNodeParent(relpos_i);
+                               light = n.getLightBlend(daynight_ratio);
+                       }
+                       catch(InvalidPositionException &e) {}
+                       obj->updateLight(light);
+               }
+               
                // Remove from deletion list
                if(ids_to_delete.find(id) != NULL)
                        ids_to_delete.remove(id);
@@ -390,6 +478,8 @@ void MapBlockObjectList::update(std::istream &is, u8 version,
                delete obj;
                m_objects.remove(id);
        }
+
+       m_last_update_daynight_ratio = daynight_ratio;
 }
 
 s16 MapBlockObjectList::getFreeId() throw(ContainerFullException)
@@ -492,7 +582,7 @@ MapBlockObject * MapBlockObjectList::get(s16 id)
                return n->getValue();
 }
 
-void MapBlockObjectList::step(float dtime, bool server)
+void MapBlockObjectList::step(float dtime, bool server, u32 daynight_ratio)
 {
        DSTACK(__FUNCTION_NAME);
        
@@ -514,7 +604,17 @@ void MapBlockObjectList::step(float dtime, bool server)
 
                        if(server)
                        {
-                               bool to_delete = obj->serverStep(dtime);
+                               // Update light
+                               u8 light = LIGHT_MAX;
+                               try{
+                                       v3s16 relpos_i = floatToInt(obj->m_pos);
+                                       MapNode n = m_block->getNodeParent(relpos_i);
+                                       light = n.getLightBlend(daynight_ratio);
+                               }
+                               catch(InvalidPositionException &e) {}
+                               obj->updateLight(light);
+                               
+                               bool to_delete = obj->serverStep(dtime, daynight_ratio);
 
                                if(to_delete)
                                        ids_to_delete.insert(obj->m_id, true);
@@ -669,7 +769,7 @@ void MapBlockObjectList::getObjects(v3f origin, f32 max_d,
        {
                MapBlockObject *obj = i.getNode()->getValue();
 
-               f32 d = (obj->m_pos - origin).getLength();
+               f32 d = (obj->getRelativeShowPos() - origin).getLength();
 
                if(d > max_d)
                        continue;
index 1a403bfe16d60a6cd191baa13ebe0cee45d1dba1..c479bc959bfa07d40b2c37de8f36c4fe96111678 100644 (file)
@@ -33,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define MAPBLOCKOBJECT_TYPE_SIGN 2
 #define MAPBLOCKOBJECT_TYPE_RAT 3
 // Used for handling selecting special stuff
-//#define MAPBLOCKOBJECT_TYPE_PSEUDO 4
+//#define MAPBLOCKOBJECT_TYPE_PSEUDO 1000
 
 class MapBlock;
 
@@ -81,6 +81,11 @@ public:
                os.write((char*)buf, 2);
        }
        
+       // Position where the object is drawn relative to block
+       virtual v3f getRelativeShowPos()
+       {
+               return m_pos;
+       }
        // Get floating point position on map
        v3f getAbsolutePos();
 
@@ -134,12 +139,14 @@ public:
        // Typical dtimes are 0.2 and 10000.
        // A return value of true requests deletion of the object by the caller.
        // NOTE: Only server calls this.
-       virtual bool serverStep(float dtime) { return false; };
+       virtual bool serverStep(float dtime, u32 daynight_ratio)
+       { return false; };
 
 #ifdef SERVER
        void clientStep(float dtime) {};
        void addToScene(void *smgr) {};
        void removeFromScene() {};
+       void updateLight(u8 light_at_pos) {};
 #else
        // This should do slight animations only or so
        virtual void clientStep(float dtime) {};
@@ -148,11 +155,14 @@ public:
        //       same as the current state
        // Shall add and remove relevant scene nodes for rendering the
        // object in the game world
-       virtual void addToScene(scene::ISceneManager *smgr) {};
+       virtual void addToScene(scene::ISceneManager *smgr) = 0;
        // Shall remove stuff from the scene
        // Should return silently if there is nothing to remove
        // NOTE: This has to be called before calling destructor
-       virtual void removeFromScene() {};
+       virtual void removeFromScene() = 0;
+       
+       // 0 <= light_at_pos <= LIGHT_SUN
+       virtual void updateLight(u8 light_at_pos) {};
 #endif
 
        virtual std::string infoText() { return ""; }
@@ -209,7 +219,7 @@ public:
        {
                assert(0);
        }
-       virtual bool serverStep(float dtime)
+       virtual bool serverStep(float dtime, u32 daynight_ratio)
        {
                assert(0);
        }
@@ -233,7 +243,10 @@ public:
        // The constructor of every MapBlockObject should be like this
        MovingObject(MapBlock *block, s16 id, v3f pos):
                MapBlockObject(block, id, pos),
-               m_speed(0,0,0)
+               m_speed(0,0,0),
+               m_oldpos(pos),
+               m_pos_animation_time(0),
+               m_showpos(pos)
        {
                m_touching_ground = false;
        }
@@ -273,193 +286,57 @@ public:
 
                m_speed = speed;
        }
-
-       virtual bool serverStep(float dtime) { return false; };
-       virtual void clientStep(float dtime) {};
        
-       /*virtual void addToScene(scene::ISceneManager *smgr) = 0;
-       virtual void removeFromScene() = 0;*/
-
-       /*
-               Special methods
-       */
-       
-       // Moves with collision detection
-       void move(float dtime, v3f acceleration);
-       
-protected:
-       v3f m_speed;
-       bool m_touching_ground;
-};
-
-class RatObject : public MovingObject
-{
-public:
-       RatObject(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*0.5,BS*0.3);
-               m_selection_box = new core::aabbox3d<f32>
-                               (-BS*0.3,0,-BS*0.3, BS*0.3,BS*0.5,BS*0.3);
-
-               m_counter1 = 0;
-               m_counter2 = 0;
-       }
-       virtual ~RatObject()
+       // Reimplementation shall call this.
+       virtual void updatePos(v3f pos)
        {
-               delete m_collision_box;
-               delete m_selection_box;
+               m_oldpos = m_showpos;
+               m_pos = pos;
+               
+               if(m_pos_animation_time < 0.001 || m_pos_animation_time > 1.0)
+                       m_pos_animation_time = m_pos_animation_time_counter;
+               else
+                       m_pos_animation_time = m_pos_animation_time * 0.9
+                                       + m_pos_animation_time_counter * 0.1;
+               m_pos_animation_time_counter = 0;
+               m_pos_animation_counter = 0;
        }
        
-       /*
-               Implementation interface
-       */
-       virtual u16 getTypeId() const
-       {
-               return MAPBLOCKOBJECT_TYPE_RAT;
-       }
-       virtual void serialize(std::ostream &os, u8 version)
-       {
-               MovingObject::serialize(os, version);
-               u8 buf[2];
-
-               // Write yaw * 10
-               writeS16(buf, m_yaw * 10);
-               os.write((char*)buf, 2);
-
-       }
-       virtual void update(std::istream &is, u8 version)
+       // Position where the object is drawn relative to block
+       virtual v3f getRelativeShowPos()
        {
-               MovingObject::update(is, version);
-               u8 buf[2];
-               
-               // Read yaw * 10
-               is.read((char*)buf, 2);
-               s16 yaw_i = readS16(buf);
-               m_yaw = (f32)yaw_i / 10;
-
-               updateNodePos();
+               return m_showpos;
        }
+       // Returns m_showpos relative to whole map
+       v3f getAbsoluteShowPos();
 
-       virtual bool serverStep(float dtime)
-       {
-               v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
-
-               f32 speed = 2*BS;
-
-               m_speed.X = speed * dir.X;
-               m_speed.Z = speed * dir.Z;
-
-               if(m_touching_ground && (m_oldpos - m_pos).getLength() < dtime*speed/2)
-               {
-                       m_counter1 -= dtime;
-                       if(m_counter1 < 0.0)
-                       {
-                               m_counter1 += 1.0;
-                               m_speed.Y = 5.0*BS;
-                       }
-               }
-
-               {
-                       m_counter2 -= dtime;
-                       if(m_counter2 < 0.0)
-                       {
-                               m_counter2 += (float)(rand()%100)/100*3.0;
-                               m_yaw += ((float)(rand()%200)-100)/100*180;
-                               m_yaw = wrapDegrees(m_yaw);
-                       }
-               }
-
-               m_oldpos = m_pos;
-
-               //m_yaw += dtime*90;
-
-               move(dtime, v3f(0, -9.81*BS, 0));
-
-               updateNodePos();
-
-               return false;
-       }
-#ifndef SERVER
+       virtual bool serverStep(float dtime, u32 daynight_ratio)
+       { return false; };
        virtual void clientStep(float dtime)
-       {
-               m_pos += m_speed * dtime;
-
-               updateNodePos();
-       }
+       {};
        
-       virtual void addToScene(scene::ISceneManager *smgr)
-       {
-               if(m_node != NULL)
-                       return;
-               
-               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/rat.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()
-       {
-               if(m_node != NULL)
-               {
-                       m_node->remove();
-                       m_node = NULL;
-               }
-       }
-#endif
-
-       virtual std::string getInventoryString()
-       {
-               // There must be a space after the name
-               // Or does there?
-               return std::string("Rat ");
-       }
+       /*virtual void addToScene(scene::ISceneManager *smgr) = 0;
+       virtual void removeFromScene() = 0;*/
 
        /*
                Special methods
        */
        
-       void updateNodePos()
-       {
-               if(m_node != NULL)
-               {
-                       m_node->setPosition(getAbsolutePos());
-                       m_node->setRotation(v3f(0, -m_yaw+180, 0));
-               }
-       }
+       // Move with collision detection, server side
+       void move(float dtime, v3f acceleration);
+
+       // Move from old position to new position, client side
+       void simpleMove(float dtime);
        
 protected:
-       scene::IMeshSceneNode *m_node;
-       float m_yaw;
-
-       float m_counter1;
-       float m_counter2;
+       v3f m_speed;
+       bool m_touching_ground;
+       // Client-side moving
        v3f m_oldpos;
+       f32 m_pos_animation_counter;
+       f32 m_pos_animation_time;
+       f32 m_pos_animation_time_counter;
+       v3f m_showpos;
 };
 
 class SignObject : public MapBlockObject
@@ -524,7 +401,7 @@ public:
 
                updateSceneNode();
        }
-       virtual bool serverStep(float dtime)
+       virtual bool serverStep(float dtime, u32 daynight_ratio)
        {
                return false;
        }
@@ -596,6 +473,28 @@ public:
                        m_node = NULL;
                }
        }
+       virtual void updateLight(u8 light_at_pos)
+       {
+               if(m_node == NULL)
+                       return;
+
+               u8 li = decode_light(light_at_pos);
+               video::SColor color(255,li,li,li);
+
+               scene::IMesh *mesh = m_node->getMesh();
+               
+               u16 mc = mesh->getMeshBufferCount();
+               for(u16 j=0; j<mc; j++)
+               {
+                       scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+                       video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
+                       u16 vc = buf->getVertexCount();
+                       for(u16 i=0; i<vc; i++)
+                       {
+                               vertices[i].Color = color;
+                       }
+               }
+       }
 #endif
 
        virtual std::string infoText()
@@ -644,6 +543,177 @@ protected:
        f32 m_yaw;
 };
 
+class RatObject : public MovingObject
+{
+public:
+       RatObject(MapBlock *block, s16 id, v3f pos):
+               MovingObject(block, id, pos),
+               m_node(NULL)
+       {
+               m_collision_box = new core::aabbox3d<f32>
+                               (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);
+               m_selection_box = new core::aabbox3d<f32>
+                               (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);
+
+               m_counter1 = 0;
+               m_counter2 = 0;
+               m_age = 0;
+       }
+       virtual ~RatObject()
+       {
+               delete m_collision_box;
+               delete m_selection_box;
+       }
+       
+       /*
+               Implementation interface
+       */
+       virtual u16 getTypeId() const
+       {
+               return MAPBLOCKOBJECT_TYPE_RAT;
+       }
+       virtual void serialize(std::ostream &os, u8 version)
+       {
+               MovingObject::serialize(os, version);
+               u8 buf[2];
+
+               // Write yaw * 10
+               writeS16(buf, m_yaw * 10);
+               os.write((char*)buf, 2);
+
+       }
+       virtual void update(std::istream &is, u8 version)
+       {
+               MovingObject::update(is, version);
+               u8 buf[2];
+               
+               // Read yaw * 10
+               is.read((char*)buf, 2);
+               s16 yaw_i = readS16(buf);
+               m_yaw = (f32)yaw_i / 10;
+
+               updateNodePos();
+       }
+
+       virtual bool serverStep(float dtime, u32 daynight_ratio)
+       {
+               m_age += dtime;
+               if(m_age > 60)
+                       // Die
+                       return true;
+
+               v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
+
+               f32 speed = 2*BS;
+
+               m_speed.X = speed * dir.X;
+               m_speed.Z = speed * dir.Z;
+
+               if(m_touching_ground && (m_oldpos - m_pos).getLength() < dtime*speed/2)
+               {
+                       m_counter1 -= dtime;
+                       if(m_counter1 < 0.0)
+                       {
+                               m_counter1 += 1.0;
+                               m_speed.Y = 5.0*BS;
+                       }
+               }
+
+               {
+                       m_counter2 -= dtime;
+                       if(m_counter2 < 0.0)
+                       {
+                               m_counter2 += (float)(rand()%100)/100*3.0;
+                               m_yaw += ((float)(rand()%200)-100)/100*180;
+                               m_yaw = wrapDegrees(m_yaw);
+                       }
+               }
+
+               m_oldpos = m_pos;
+
+               //m_yaw += dtime*90;
+
+               move(dtime, v3f(0, -9.81*BS, 0));
+
+               //updateNodePos();
+
+               return false;
+       }
+#ifndef SERVER
+       virtual void clientStep(float dtime)
+       {
+               //m_pos += m_speed * dtime;
+               MovingObject::simpleMove(dtime);
+
+               updateNodePos();
+       }
+       
+       virtual void addToScene(scene::ISceneManager *smgr);
+
+       virtual void removeFromScene()
+       {
+               if(m_node == NULL)
+                       return;
+
+               m_node->remove();
+               m_node = NULL;
+       }
+
+       virtual void updateLight(u8 light_at_pos)
+       {
+               if(m_node == NULL)
+                       return;
+
+               u8 li = decode_light(light_at_pos);
+               video::SColor color(255,li,li,li);
+
+               scene::IMesh *mesh = m_node->getMesh();
+               
+               u16 mc = mesh->getMeshBufferCount();
+               for(u16 j=0; j<mc; j++)
+               {
+                       scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+                       video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
+                       u16 vc = buf->getVertexCount();
+                       for(u16 i=0; i<vc; i++)
+                       {
+                               vertices[i].Color = color;
+                       }
+               }
+       }
+       
+#endif
+
+       virtual std::string getInventoryString()
+       {
+               // There must be a space after the name
+               // Or does there?
+               return std::string("Rat ");
+       }
+
+       /*
+               Special methods
+       */
+       
+       void updateNodePos()
+       {
+               if(m_node == NULL)
+                       return;
+
+               m_node->setPosition(getAbsoluteShowPos());
+               m_node->setRotation(v3f(0, -m_yaw+180, 0));
+       }
+       
+protected:
+       scene::IMeshSceneNode *m_node;
+       float m_yaw;
+
+       float m_counter1;
+       float m_counter2;
+       v3f m_oldpos;
+       float m_age;
+};
+
 struct DistanceSortedObject
 {
        DistanceSortedObject(MapBlockObject *a_obj, f32 a_d)
@@ -666,12 +736,16 @@ class MapBlockObjectList
 public:
        MapBlockObjectList(MapBlock *block);
        ~MapBlockObjectList();
+
        // Writes the count, id, the type id and the parameters of all objects
        void serialize(std::ostream &os, u8 version);
+
        // Reads ids, type_ids and parameters.
        // Creates, updates and deletes objects.
        // If smgr!=NULL, new objects are added to the scene
-       void update(std::istream &is, u8 version, scene::ISceneManager *smgr);
+       void update(std::istream &is, u8 version, scene::ISceneManager *smgr,
+                       u32 daynight_ratio);
+
        // Finds a new unique id
        s16 getFreeId() throw(ContainerFullException);
        /*
@@ -706,7 +780,7 @@ public:
 
        // Steps all objects and if server==true, removes those that
        // want to be removed
-       void step(float dtime, bool server);
+       void step(float dtime, bool server, u32 daynight_ratio);
 
        // Wraps an object that wants to move onto this block from an another
        // Returns true if wrapping was impossible
@@ -727,6 +801,8 @@ private:
        // Key is id
        core::map<s16, MapBlockObject*> m_objects;
        MapBlock *m_block;
+
+       u32 m_last_update_daynight_ratio;
 };
 
 
index 0e746af48dd47ae4f5b51ea42bfbc469770d0c7c..f52bd52e700273ca2f718eef304093e30da812c7 100644 (file)
@@ -399,6 +399,7 @@ struct MapNode
        }
        
        // 0 <= daylight_factor <= 1000
+       // 0 <= return value <= LIGHT_SUN
        u8 getLightBlend(u32 daylight_factor)
        {
                u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY)
@@ -411,6 +412,17 @@ struct MapNode
                        l = max;
                return l;
        }
+       /*// 0 <= daylight_factor <= 1000
+       // 0 <= return value <= 255
+       u8 getLightBlend(u32 daylight_factor)
+       {
+               u8 daylight = decode_light(getLight(LIGHTBANK_DAY));
+               u8 nightlight = decode_light(getLight(LIGHTBANK_NIGHT));
+               u8 mix = ((daylight_factor * daylight
+                       + (1000-daylight_factor) * nightlight)
+                       )/1000;
+               return mix;
+       }*/
 
        void setLight(enum LightBank bank, u8 a_light)
        {
index 5938b91d4b783ac96100fa415f6d9537038cb298..19ac5c6bb920f7ff8c69b163e7e62b46e02ed550 100644 (file)
@@ -24,11 +24,48 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef PORTING_HEADER
 #define PORTING_HEADER
 
+// Included for u64 and such
+#include "common_irrlicht.h"
+
 #ifdef _WIN32
        #define SWPRINTF_CHARSTRING L"%S"
 #else
        #define SWPRINTF_CHARSTRING L"%s"
 #endif
 
+#ifdef _WIN32
+       #include <windows.h>
+       #define sleep_ms(x) Sleep(x)
+#else
+       #include <unistd.h>
+       #define sleep_ms(x) usleep(x*1000)
+#endif
+
+namespace porting
+{
+
+/*
+       Resolution is 10-20ms.
+       Remember to check for overflows.
+       Overflow can occur at any value higher than 10000000.
+*/
+#ifdef _WIN32 // Windows
+       #include <windows.h>
+       inline u32 getTimeMs()
+       {
+               return GetTickCount();
+       }
+#else // Posix
+       #include <sys/timeb.h>
+       inline u32 getTimeMs()
+       {
+               struct timeb tb;
+               ftime(&tb);
+               return tb.time * 1000 + tb.millitm;
+       }
+#endif
+
+} // namespace porting
+
 #endif
 
index 7582024d143c1de2c645a347a791554d9b595abe..9e809bb9a0a72339e8e392175f0faaa311c265c2 100644 (file)
@@ -663,8 +663,6 @@ void RemoteClient::SendObjectData(
                - Add blocks to emerge queue if they are not found
 
                SUGGESTION: These could be ignored from the backside of the player
-
-               TODO: Keep track of total size of packet and stop when it is too big
        */
 
        Player *player = server->m_env.getPlayer(peer_id);
@@ -675,13 +673,11 @@ void RemoteClient::SendObjectData(
        v3s16 center_nodepos = floatToInt(playerpos);
        v3s16 center = getNodeBlockPos(center_nodepos);
 
-       //s16 d_max = ACTIVE_OBJECT_D_BLOCKS;
        s16 d_max = g_settings.getS16("active_object_range");
        
        // Number of blocks whose objects were written to bos
        u16 blockcount = 0;
 
-       //core::map<v3s16, MapBlock*> blocks;
        std::ostringstream bos(std::ios_base::binary);
 
        for(s16 d = 0; d <= d_max; d++)
@@ -710,18 +706,20 @@ void RemoteClient::SendObjectData(
                        // Get block
                        MapBlock *block = server->m_env.getMap().getBlockNoCreate(p);
 
-                       // Skip block if there are no objects
-                       if(block->getObjectCount() == 0)
-                               continue;
-                       
-                       // Step block if not in stepped_blocks and add to stepped_blocks
+                       /*
+                               Step block if not in stepped_blocks and add to stepped_blocks.
+                       */
                        if(stepped_blocks.find(p) == NULL)
                        {
-                               block->stepObjects(dtime, true);
+                               block->stepObjects(dtime, true, server->getDayNightRatio());
                                stepped_blocks.insert(p, true);
                                block->setChangedFlag();
                        }
 
+                       // Skip block if there are no objects
+                       if(block->getObjectCount() == 0)
+                               continue;
+                       
                        /*
                                Write objects
                        */
index fddb097d027b16f6608d67d015bbcf58ec0b3376..c5a285490aa34e20ea21995ab72c1bb4fdbc48b7 100644 (file)
@@ -398,6 +398,18 @@ public:
        //void SendSectorMeta(u16 peer_id, core::list<v2s16> ps, u8 ver);
 
        core::list<PlayerInfo> getPlayerInfo();
+
+       u32 getDayNightRatio()
+       {
+               s32 d = 8;
+               s32 t = (((m_time_of_day.get() + 24000/d/2)%24000)/(24000/d));
+               if(t == d/4 || t == (d-d/4))
+                       return 600;
+               else if(t < d/4 || t > (d-d/4))
+                       return 300;
+               else
+                       return 1000;
+       }
        
 private:
 
index 70f11cba3ac6006f765f801b6132c03a90880704..ce0243e123f1b7894637fabe3d4a4c73d44782c4 100644 (file)
@@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 /*
 =============================== NOTES ==============================
 
-TODO: Move the default settings into some separate file
 
 */
 
@@ -49,15 +48,6 @@ TODO: Move the default settings into some separate file
 #pragma comment(lib, "zlibwapi.lib")
 #endif
 
-#ifdef _WIN32
-       #define WIN32_LEAN_AND_MEAN
-       #include <windows.h>
-       #define sleep_ms(x) Sleep(x)
-#else
-       #include <unistd.h>
-       #define sleep_ms(x) usleep(x*1000)
-#endif
-
 #include <iostream>
 #include <fstream>
 #include <time.h>
@@ -75,9 +65,7 @@ TODO: Move the default settings into some separate file
 #include "constants.h"
 #include "strfnd.h"
 #include "porting.h"
-
-// Dummy variable
-IrrlichtDevice *g_device = NULL;
+//#include "irrlichtwrapper.h"
 
 /*
        Settings.
@@ -106,21 +94,15 @@ std::ostream *derr_client_ptr = &dstream;
 
 
 /*
-       Timestamp stuff
+       gettime.h implementation
 */
 
-JMutex g_timestamp_mutex;
-
-std::string getTimestamp()
+u32 getTimeMs()
 {
-       if(g_timestamp_mutex.IsInitialized()==false)
-               return "";
-       JMutexAutoLock lock(g_timestamp_mutex);
-       time_t t = time(NULL);
-       struct tm *tm = localtime(&t);
-       char cs[20];
-       strftime(cs, 20, "%H:%M:%S", tm);
-       return cs;
+       /*
+               Use imprecise system calls directly (from porting.h)
+       */
+       return porting::getTimeMs();
 }
 
 int main(int argc, char *argv[])
@@ -211,9 +193,6 @@ int main(int argc, char *argv[])
        sockets_init();
        atexit(sockets_cleanup);
        
-       // Initialize timestamp mutex
-       g_timestamp_mutex.Init();
-
        /*
                Initialization
        */
index 23b1638d1be6fd96450fe637ceb3ea007ddab213..f2b131f4d47ce7169c56070f6ad6063c9ffde99a 100644 (file)
@@ -18,7 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "tile.h"
-#include "irrlichtwrapper.h"
+#include "main.h"
 
 // A mapping from tiles to paths of textures
 const char * g_tile_texture_paths[TILES_COUNT] =
index 3da2f48d56766f947c218827ab417b3a7d0ebc97..7126cbbdc57a3f2bdcaa2335d4977c1388560cbe 100644 (file)
@@ -23,33 +23,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "utility.h"
 #include "irrlichtwrapper.h"
+#include "gettime.h"
 
-TimeTaker::TimeTaker(const char *name, IrrlichtWrapper *irrlicht, u32 *result)
+TimeTaker::TimeTaker(const char *name, u32 *result)
 {
        m_name = name;
-       m_irrlicht = irrlicht;
        m_result = result;
        m_running = true;
-       if(irrlicht == NULL)
-       {
-               m_time1 = 0;
-               return;
-       }
-       m_time1 = m_irrlicht->getTime();
+       m_time1 = getTimeMs();
 }
 
 u32 TimeTaker::stop(bool quiet)
 {
        if(m_running)
        {
-               if(m_irrlicht == NULL)
-               {
-                       /*if(quiet == false)
-                               std::cout<<"Couldn't measure time for "<<m_name
-                                               <<": irrlicht==NULL"<<std::endl;*/
-                       return 0;
-               }
-               u32 time2 = m_irrlicht->getTime();
+               u32 time2 = getTimeMs();
                u32 dtime = time2 - m_time1;
                if(m_result != NULL)
                {
index bfee15e61b491bbb11b0d68354720ccc2a3d6a7d..484b5828b12c74c3986bcce33343dca6a0325713 100644 (file)
@@ -28,18 +28,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #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"
 #include "exceptions.h"
+#include "porting.h"
 
 extern const v3s16 g_26dirs[26];
 
@@ -404,7 +397,7 @@ class IrrlichtWrapper;
 class TimeTaker
 {
 public:
-       TimeTaker(const char *name, IrrlichtWrapper *irrlicht, u32 *result=NULL);
+       TimeTaker(const char *name, u32 *result=NULL);
 
        ~TimeTaker()
        {
@@ -415,7 +408,6 @@ public:
 
 private:
        const char *m_name;
-       IrrlichtWrapper *m_irrlicht;
        u32 m_time1;
        bool m_running;
        u32 *m_result;
index 29f79992b750f1b30211685ad7539c6c92b6bcf9..282ff5e7c6cc12216a7e2e369a1f61e305751d6e 100644 (file)
@@ -21,8 +21,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "map.h"
 
 // For TimeTaker
-#include "main.h"
 #include "utility.h"
+#include "gettime.h"
 
 /*
        Debug stuff
@@ -138,7 +138,7 @@ void VoxelManipulator::addArea(VoxelArea area)
        if(m_area.contains(area))
                return;
        
-       TimeTaker timer("addArea", g_irrlicht, &addarea_time);
+       TimeTaker timer("addArea", &addarea_time);
 
        // Calculate new area
        VoxelArea new_area;
@@ -290,7 +290,7 @@ void VoxelManipulator::interpolate(VoxelArea area)
 void VoxelManipulator::clearFlag(u8 flags)
 {
        // 0-1ms on moderate area
-       TimeTaker timer("clearFlag", g_irrlicht, &clearflag_time);
+       TimeTaker timer("clearFlag", &clearflag_time);
 
        v3s16 s = m_area.getExtent();
 
@@ -539,8 +539,7 @@ void VoxelManipulator::updateAreaWaterPressure(VoxelArea a,
                core::map<v3s16, u8> &active_nodes,
                bool checked3_is_clear)
 {
-       TimeTaker timer("updateAreaWaterPressure", g_irrlicht,
-                       &updateareawaterpressure_time);
+       TimeTaker timer("updateAreaWaterPressure", &updateareawaterpressure_time);
 
        emerge(a, 3);
        
@@ -653,7 +652,7 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
        //dstream<<"s1="<<s1<<", s2="<<s2<<std::endl;
 
        {
-       TimeTaker timer1("flowWater pre", g_irrlicht, &flowwater_pre_time);
+       TimeTaker timer1("flowWater pre", &flowwater_pre_time);
        
        // Load neighboring nodes
        emerge(VoxelArea(removed_pos - v3s16(1,1,1), removed_pos + v3s16(1,1,1)), 4);
@@ -802,9 +801,9 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
                                debugprint, stoptime);
        }
        
-       if(stoptime != 0 && g_irrlicht != NULL)
+       if(stoptime != 0)
        {
-               u32 timenow = g_irrlicht->getTime();
+               u32 timenow = getTimeMs();
                if(timenow >= stoptime ||
                                (stoptime < 0x80000000 && timenow > 0x80000000))
                {
@@ -876,10 +875,7 @@ void VoxelManipulator::flowWater(
 
 
        u32 stoptime = 0;
-       if(g_irrlicht != NULL)
-       {
-               stoptime = g_irrlicht->getTime() + timelimit;
-       }
+       stoptime = getTimeMs() + timelimit;
 
        // Count of handled active nodes
        u32 handled_count = 0;