diff --git a/src/client.cpp b/src/client.cpp index 4979829d1..d99b8d8df 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -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: "< #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]; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 6888fa497..065ff2e44 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -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 index 000000000..b195526d4 --- /dev/null +++ b/src/gettime.h @@ -0,0 +1,55 @@ +/* +Minetest-c55 +Copyright (C) 2010 celeron55, Perttu Ahola + +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 +#include + +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 diff --git a/src/inventory.cpp b/src/inventory.cpp index 079be8793..3899c9394 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -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") diff --git a/src/inventory.h b/src/inventory.h index 59ff89ed8..354111045 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -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(); /* diff --git a/src/main.cpp b/src/main.cpp index 6b5455965..8325680f2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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 a block has been sent to client -TODO: Stop player if focus of window is taken away (go to pause mode) - TODO: Combine MapBlock's face caches to so big pieces that VBO gets used - That is >500 vertices @@ -110,16 +108,6 @@ TODO: Cliffs, arcs TODO: Menus -TODO: Mobs - - Server: - - One single map container with ids as keys - - Client: - - ? -TODO: - Keep track of the place of the mob in the last few hundreth's - of a second - then, if a player hits it, take the value that is - avg_rtt/2 before the moment the packet is received. -TODO: - Scripting - TODO: Moving players more smoothly. Calculate moving animation in a way that doesn't make the player jump to the right place immediately when the server sends a new position @@ -158,8 +146,6 @@ Block object server side: - TODO: For incoming blocks, time difference is calculated and objects are stepped according to it. -TODO: Add config parameters for server's sending and generating distance - TODO: Copy the text of the last picked sign to inventory in creative mode @@ -172,13 +158,20 @@ TODO: Check what goes wrong with caching map to disk (Kray) TODO: Remove LazyMeshUpdater. It is not used as supposed. -TODO: Add server unused sector deletion settings to settings - TODO: TOSERVER_LEAVE +TODO: Better handling of objects and mobs + - Update brightness according to day-night blended light of node + in position + - Scripting? + Doing now: ====================================================================== +TODO: Get rid of g_irrlicht for server build + +TODO: Implement getGlobalTime for server build + - It is needed for controlling the time used for flowing water ====================================================================== @@ -226,7 +219,6 @@ Doing now: #include #include -#include #include #include #include "common_irrlicht.h" @@ -243,6 +235,8 @@ Doing now: #include "strfnd.h" #include "porting.h" #include "guiPauseMenu.h" +#include "irrlichtwrapper.h" +#include "gettime.h" IrrlichtWrapper *g_irrlicht; @@ -266,7 +260,6 @@ bool g_viewing_range_all = false; // inhibits glitches (dtime jitter) in the main loop. //float g_freetime_ratio = FREETIME_RATIO_MAX; - /* Settings. These are loaded from the config file. @@ -311,25 +304,19 @@ std::ostream *derr_server_ptr = &dstream; std::ostream *dout_client_ptr = &dstream; std::ostream *derr_client_ptr = &dstream; - /* - Timestamp stuff + gettime.h implementation */ -JMutex g_timestamp_mutex; -//std::string g_timestamp; - -std::string getTimestamp() +u32 getTimeMs() { - if(g_timestamp_mutex.IsInitialized()==false) - return ""; - JMutexAutoLock lock(g_timestamp_mutex); - //return g_timestamp; - time_t t = time(NULL); - struct tm *tm = localtime(&t); - char cs[20]; - strftime(cs, 20, "%H:%M:%S", tm); - return cs; + /* + Use irrlicht because it is more precise than porting.h's + getTimeMs() + */ + if(g_irrlicht == NULL) + return 0; + return g_irrlicht->getTime(); } class MyEventReceiver : public IEventReceiver @@ -1066,9 +1053,6 @@ int main(int argc, char *argv[]) sockets_init(); atexit(sockets_cleanup); - // Initialize timestamp mutex - g_timestamp_mutex.Init(); - /* Initialization */ @@ -1580,7 +1564,7 @@ int main(int argc, char *argv[]) // Info text std::wstring infotext; - //TimeTaker //timer1("//timer1", g_irrlicht); + //TimeTaker //timer1("//timer1"); // Time of frame without fps limit float busytime; @@ -1770,20 +1754,20 @@ int main(int argc, char *argv[]) */ { - //TimeTaker timer("client.step(dtime)", g_irrlicht); + //TimeTaker timer("client.step(dtime)"); client.step(dtime); //client.step(dtime_avg1); } if(server != NULL) { - //TimeTaker timer("server->step(dtime)", g_irrlicht); + //TimeTaker timer("server->step(dtime)"); server->step(dtime); } v3f player_position = client.getPlayerPosition(); - //TimeTaker //timer2("//timer2", g_irrlicht); + //TimeTaker //timer2("//timer2"); /* Mouse and camera control @@ -1837,12 +1821,12 @@ int main(int argc, char *argv[]) } else{ //client.m_env.getMap().updateCamera(camera_position, camera_direction); - //TimeTaker timer("client.updateCamera", g_irrlicht); + //TimeTaker timer("client.updateCamera"); client.updateCamera(camera_position, camera_direction); } //timer2.stop(); - //TimeTaker //timer3("//timer3", g_irrlicht); + //TimeTaker //timer3("//timer3"); /* Calculate what block is the crosshair pointing to @@ -2118,7 +2102,7 @@ int main(int argc, char *argv[]) dig_time_complete = 1.5; u16 dig_index = (u16)(3.99*dig_time/dig_time_complete); - if(dig_time > 0.2) + if(dig_time > 0.125) { //dstream<<"dig_index="<beginScene(true, true, bgcolor); //driver->beginScene(false, true, bgcolor); beginscenetime = timer.stop(true); @@ -2319,13 +2303,13 @@ int main(int argc, char *argv[]) //std::cout<drawAll()"<drawAll(); scenetime = timer.stop(true); } { - //TimeTaker timer9("auxiliary drawings", g_irrlicht); + //TimeTaker timer9("auxiliary drawings"); // 0ms driver->draw2DLine(displaycenter - core::vector2d(10,0), @@ -2336,7 +2320,7 @@ int main(int argc, char *argv[]) video::SColor(255,255,255,255)); //timer9.stop(); - //TimeTaker //timer10("//timer10", g_irrlicht); + //TimeTaker //timer10("//timer10"); video::SMaterial m; m.Thickness = 10; @@ -2359,7 +2343,7 @@ int main(int argc, char *argv[]) } //timer10.stop(); - //TimeTaker //timer11("//timer11", g_irrlicht); + //TimeTaker //timer11("//timer11"); /* Draw gui @@ -2369,7 +2353,7 @@ int main(int argc, char *argv[]) // End drawing { - TimeTaker timer("endScene", g_irrlicht); + TimeTaker timer("endScene"); driver->endScene(); endscenetime = timer.stop(true); } diff --git a/src/main.h b/src/main.h index 22b5157d7..e6bb1caac 100644 --- a/src/main.h +++ b/src/main.h @@ -20,18 +20,19 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef MAIN_HEADER #define MAIN_HEADER -#include -extern std::string getTimestamp(); -#define DTIME (getTimestamp()+": ") - -#include +#include "irrlichtwrapper.h" // Settings extern Settings g_settings; -#include +// A thread safe wrapper to irrlicht +// On a server build, this is always NULL. +extern IrrlichtWrapper *g_irrlicht; // Debug streams + +#include + 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 diff --git a/src/map.cpp b/src/map.cpp index 2a517c544..9a0952c75 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -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 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::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="<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 diff --git a/src/map.h b/src/map.h index 3b34cd899..2a3fa5061 100644 --- 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); diff --git a/src/mapblock.cpp b/src/mapblock.cpp index e2262544c..b2b5bc4f4 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -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 &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 */ diff --git a/src/mapblock.h b/src/mapblock.h index b5126b822..dc077c23f 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -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 &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; diff --git a/src/mapblockobject.cpp b/src/mapblockobject.cpp index 8b52b9447..779fe3fa7 100644 --- a/src/mapblockobject.cpp +++ b/src/mapblockobject.cpp @@ -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 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; diff --git a/src/mapblockobject.h b/src/mapblockobject.h index 1a403bfe1..c479bc959 100644 --- a/src/mapblockobject.h +++ b/src/mapblockobject.h @@ -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,9 +286,34 @@ public: m_speed = speed; } + + // Reimplementation shall call this. + virtual void updatePos(v3f pos) + { + 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; + } + + // Position where the object is drawn relative to block + virtual v3f getRelativeShowPos() + { + return m_showpos; + } + // Returns m_showpos relative to whole map + v3f getAbsoluteShowPos(); - virtual bool serverStep(float dtime) { return false; }; - virtual void clientStep(float dtime) {}; + virtual bool serverStep(float dtime, u32 daynight_ratio) + { return false; }; + virtual void clientStep(float dtime) + {}; /*virtual void addToScene(scene::ISceneManager *smgr) = 0; virtual void removeFromScene() = 0;*/ @@ -284,182 +322,21 @@ public: Special methods */ - // Moves with collision detection + // 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: 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 - (-BS*0.3,0,-BS*0.3, BS*0.3,BS*0.5,BS*0.3); - m_selection_box = new core::aabbox3d - (-BS*0.3,0,-BS*0.3, BS*0.3,BS*0.5,BS*0.3); - - m_counter1 = 0; - m_counter2 = 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) - { - 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; - - 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 "); - } - - /* - Special methods - */ - - void updateNodePos() - { - if(m_node != NULL) - { - m_node->setPosition(getAbsolutePos()); - m_node->setRotation(v3f(0, -m_yaw+180, 0)); - } - } - -protected: - scene::IMeshSceneNode *m_node; - float m_yaw; - - float m_counter1; - float m_counter2; + // 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; jgetMeshBuffer(j); + video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); + u16 vc = buf->getVertexCount(); + for(u16 i=0; i + (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3); + m_selection_box = new core::aabbox3d + (-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; jgetMeshBuffer(j); + video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices(); + u16 vc = buf->getVertexCount(); + for(u16 i=0; isetPosition(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 m_objects; MapBlock *m_block; + + u32 m_last_update_daynight_ratio; }; diff --git a/src/mapnode.h b/src/mapnode.h index 0e746af48..f52bd52e7 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -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) { diff --git a/src/porting.h b/src/porting.h index 5938b91d4..19ac5c6bb 100644 --- a/src/porting.h +++ b/src/porting.h @@ -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 + #define sleep_ms(x) Sleep(x) +#else + #include + #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 + inline u32 getTimeMs() + { + return GetTickCount(); + } +#else // Posix + #include + inline u32 getTimeMs() + { + struct timeb tb; + ftime(&tb); + return tb.time * 1000 + tb.millitm; + } +#endif + +} // namespace porting + #endif diff --git a/src/server.cpp b/src/server.cpp index 7582024d1..9e809bb9a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -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 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 */ diff --git a/src/server.h b/src/server.h index fddb097d0..c5a285490 100644 --- a/src/server.h +++ b/src/server.h @@ -398,6 +398,18 @@ public: //void SendSectorMeta(u16 peer_id, core::list ps, u8 ver); core::list 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: diff --git a/src/servermain.cpp b/src/servermain.cpp index 70f11cba3..ce0243e12 100644 --- a/src/servermain.cpp +++ b/src/servermain.cpp @@ -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 - #define sleep_ms(x) Sleep(x) -#else - #include - #define sleep_ms(x) usleep(x*1000) -#endif - #include #include #include @@ -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 */ diff --git a/src/tile.cpp b/src/tile.cpp index 23b1638d1..f2b131f4d 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -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] = diff --git a/src/utility.cpp b/src/utility.cpp index 3da2f48d5..7126cbbdc 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -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 "<getTime(); + u32 time2 = getTimeMs(); u32 dtime = time2 - m_time1; if(m_result != NULL) { diff --git a/src/utility.h b/src/utility.h index bfee15e61..484b5828b 100644 --- a/src/utility.h +++ b/src/utility.h @@ -28,18 +28,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include -#ifdef _WIN32 - #include - #define sleep_ms(x) Sleep(x) -#else - #include - #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; diff --git a/src/voxel.cpp b/src/voxel.cpp index 29f79992b..282ff5e7c 100644 --- a/src/voxel.cpp +++ b/src/voxel.cpp @@ -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 &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="<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;