try
{
block = m_env.getMap().getBlockNoCreate(p);
- block->stepObjects(dtime, false);
+ block->stepObjects(dtime, false, m_env.getDayNightRatio());
}
catch(InvalidPositionException &e)
{
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()
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-
-/*
- Debug stuff
-*/
-
#ifndef DEBUG_HEADER
#define DEBUG_HEADER
#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];
// 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");
--- /dev/null
+/*
+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
/*
MapBlockObjectItem
*/
-
+#ifndef SERVER
video::ITexture * MapBlockObjectItem::getImage()
{
if(m_inventorystring.substr(0,3) == "Rat")
return NULL;
}
+#endif
std::string MapBlockObjectItem::getText()
{
if(m_inventorystring.substr(0,3) == "Rat")
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 ""; }
return new MapBlockObjectItem(m_inventorystring);
}
+#ifndef SERVER
video::ITexture * getImage();
+#endif
std::string getText();
/*
- 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
\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
- 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
\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
\r
#include <iostream>\r
#include <fstream>\r
-#include <time.h>\r
#include <jmutexautolock.h>\r
#include <locale.h>\r
#include "common_irrlicht.h"\r
#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
// 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
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
sockets_init();\r
atexit(sockets_cleanup);\r
\r
- // Initialize timestamp mutex\r
- g_timestamp_mutex.Init();\r
-\r
/*\r
Initialization\r
*/\r
// 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
*/\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
}\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
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
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
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
//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
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
}\r
\r
//timer10.stop();\r
- //TimeTaker //timer11("//timer11", g_irrlicht);\r
+ //TimeTaker //timer11("//timer11");\r
\r
/*\r
Draw gui\r
\r
// End drawing\r
{\r
- TimeTaker timer("endScene", g_irrlicht);\r
+ TimeTaker timer("endScene");\r
driver->endScene();\r
endscenetime = timer.stop(true);\r
}\r
#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;
#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
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{
}
{
- //TimeTaker timer("unspreadLight", g_irrlicht);
+ //TimeTaker timer("unspreadLight");
unspreadLight(bank, unlight_from, light_sources, modified_blocks);
}
// - Find out why it works
{
- //TimeTaker timer("spreadLight", g_irrlicht);
+ //TimeTaker timer("spreadLight");
spreadLight(bank, light_sources, modified_blocks);
}
*/
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;
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[] =
{
#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();
b->updateMesh(daynight_ratio);
}
catch(InvalidPositionException &e){}
+ // Leading edge
try{
v3s16 p = blockpos + v3s16(-1,0,0);
MapBlock *b = getBlockNoCreate(p);
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
return true;
}
catch(InvalidPositionException &e){}
+ // Leading edges
try{
v3s16 p = blockpos + v3s16(-1,0,0);
MapBlock *b = getBlockNoCreate(p);
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;
}
*/
if(version >= 9)
{
- block->updateObjects(is, version, NULL);
+ block->updateObjects(is, version, NULL, 0);
}
if(created_new)
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)
#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);
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<<")"
#if 0
void MapVoxelManipulator::emerge(VoxelArea a)
{
- TimeTaker timer1("emerge", g_irrlicht, &emerge_time);
+ TimeTaker timer1("emerge", &emerge_time);
v3s16 size = a.getExtent();
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;
if(m_area.getExtent() == v3s16(0,0,0))
return;
- //TimeTaker timer1("blitBack", g_irrlicht);
+ //TimeTaker timer1("blitBack");
/*
Initialize block cache
// 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);
#endif
/*
- Takes the blocks at the leading edges into account
+ Takes the blocks at the edges into account
*/
bool dayNightDiffed(v3s16 blockpos);
data = NULL;
if(dummy == false)
reallocate();
+
+ m_spawn_timer = -10000;
#ifndef SERVER
m_mesh_expired = false;
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;
// 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);
}
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()
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
*/
}
#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);
}
// 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();
}
{
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)
{
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
*/
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();
bool m_day_night_differs;
MapBlockObjectList m_objects;
+
+ // Object spawning stuff
+ float m_spawn_timer;
#ifndef SERVER
bool m_mesh_expired;
/*
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)"
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;
}
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
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
*/
}
void MapBlockObjectList::update(std::istream &is, u8 version,
- scene::ISceneManager *smgr)
+ scene::ISceneManager *smgr, u32 daynight_ratio)
{
JMutexAutoLock lock(m_mutex);
}
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);
{
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.
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);
delete obj;
m_objects.remove(id);
}
+
+ m_last_update_daynight_ratio = daynight_ratio;
}
s16 MapBlockObjectList::getFreeId() throw(ContainerFullException)
return n->getValue();
}
-void MapBlockObjectList::step(float dtime, bool server)
+void MapBlockObjectList::step(float dtime, bool server, u32 daynight_ratio)
{
DSTACK(__FUNCTION_NAME);
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);
{
MapBlockObject *obj = i.getNode()->getValue();
- f32 d = (obj->m_pos - origin).getLength();
+ f32 d = (obj->getRelativeShowPos() - origin).getLength();
if(d > max_d)
continue;
#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;
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();
// 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) {};
// 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 ""; }
{
assert(0);
}
- virtual bool serverStep(float dtime)
+ virtual bool serverStep(float dtime, u32 daynight_ratio)
{
assert(0);
}
// 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;
}
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
updateSceneNode();
}
- virtual bool serverStep(float dtime)
+ virtual bool serverStep(float dtime, u32 daynight_ratio)
{
return false;
}
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()
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)
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);
/*
// 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
// Key is id
core::map<s16, MapBlockObject*> m_objects;
MapBlock *m_block;
+
+ u32 m_last_update_daynight_ratio;
};
}
// 0 <= daylight_factor <= 1000
+ // 0 <= return value <= LIGHT_SUN
u8 getLightBlend(u32 daylight_factor)
{
u8 l = ((daylight_factor * getLight(LIGHTBANK_DAY)
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)
{
#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
- 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);
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++)
// 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
*/
//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:
/*
=============================== NOTES ==============================
-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>
#include "constants.h"
#include "strfnd.h"
#include "porting.h"
-
-// Dummy variable
-IrrlichtDevice *g_device = NULL;
+//#include "irrlichtwrapper.h"
/*
Settings.
/*
- 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[])
sockets_init();
atexit(sockets_cleanup);
- // Initialize timestamp mutex
- g_timestamp_mutex.Init();
-
/*
Initialization
*/
*/
#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] =
#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)
{
#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];
class TimeTaker
{
public:
- TimeTaker(const char *name, IrrlichtWrapper *irrlicht, u32 *result=NULL);
+ TimeTaker(const char *name, u32 *result=NULL);
~TimeTaker()
{
private:
const char *m_name;
- IrrlichtWrapper *m_irrlicht;
u32 m_time1;
bool m_running;
u32 *m_result;
#include "map.h"
// For TimeTaker
-#include "main.h"
#include "utility.h"
+#include "gettime.h"
/*
Debug stuff
if(m_area.contains(area))
return;
- TimeTaker timer("addArea", g_irrlicht, &addarea_time);
+ TimeTaker timer("addArea", &addarea_time);
// Calculate new area
VoxelArea new_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();
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);
//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);
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))
{
u32 stoptime = 0;
- if(g_irrlicht != NULL)
- {
- stoptime = g_irrlicht->getTime() + timelimit;
- }
+ stoptime = getTimeMs() + timelimit;
// Count of handled active nodes
u32 handled_count = 0;