diff --git a/Makefile b/Makefile index 7aacb4c4a..aaeb9d7e3 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # It's usually sufficient to change just the target name and source file list # and be sure that CXX is set to a valid compiler TARGET = test -SOURCE_FILES = irrlichtwrapper.cpp guiPauseMenu.cpp defaultsettings.cpp mapnode.cpp tile.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp +SOURCE_FILES = guiInventoryMenu.cpp irrlichtwrapper.cpp guiPauseMenu.cpp defaultsettings.cpp mapnode.cpp tile.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp SOURCES = $(addprefix src/, $(SOURCE_FILES)) BUILD_DIR = build OBJECTS = $(addprefix $(BUILD_DIR)/, $(SOURCE_FILES:.cpp=.o)) @@ -69,7 +69,7 @@ $(SERVER_BUILD_DIR): $(DESTPATH): $(OBJECTS) $(CXX) -o $@ $(OBJECTS) $(LDFLAGS) -$(FAST_DESTPATH): $(SOURCES) +$(FAST_DESTPATH): $(OBJECTS) $(CXX) -o $@ $(OBJECTS) $(LDFLAGS) -DUNITTEST_DISABLE $(SERVER_DESTPATH): $(SERVER_OBJECTS) diff --git a/data/pauseMenu.gui b/data/pauseMenu.gui index 543b3fb8a..0cf6c7adc 100644 Binary files a/data/pauseMenu.gui and b/data/pauseMenu.gui differ diff --git a/minetest.vcproj b/minetest.vcproj index 632feffff..4c99e6bb4 100644 --- a/minetest.vcproj +++ b/minetest.vcproj @@ -186,6 +186,10 @@ RelativePath=".\src\debug.cpp" > + + @@ -206,6 +210,10 @@ RelativePath=".\src\inventory.cpp" > + + diff --git a/src/client.cpp b/src/client.cpp index d99b8d8df..a5d035d3f 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -24,14 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "jmutexautolock.h" #include "main.h" #include - -#ifdef _WIN32 - #include - #define sleep_ms(x) Sleep(x) -#else - #include - #define sleep_ms(x) usleep(x*1000) -#endif +#include "porting.h" void * ClientUpdateThread::Thread() { diff --git a/src/constants.h b/src/constants.h index 7668c7451..8b7e77c42 100644 --- a/src/constants.h +++ b/src/constants.h @@ -57,7 +57,8 @@ with this program; if not, write to the Free Software Foundation, Inc., // Viewing range stuff //#define FREETIME_RATIO 0.15 -#define FREETIME_RATIO 0.0 +//#define FREETIME_RATIO 0.0 +#define FREETIME_RATIO 0.05 // Sectors are split to SECTOR_HEIGHTMAP_SPLIT^2 heightmaps #define SECTOR_HEIGHTMAP_SPLIT 2 diff --git a/src/debug.cpp b/src/debug.cpp index 346405939..df8cbeb22 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -21,15 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "debug.h" #include #include - -#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 "porting.h" /* Debug output diff --git a/src/environment.cpp b/src/environment.cpp index 386eb124d..7c236c355 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -103,6 +103,8 @@ void Environment::step(float dtime) i != m_players.end(); i++) { Player *player = *i; + + v3f playerpos = player->getPosition(); // Apply physics to local player if(player->isLocal()) @@ -135,12 +137,22 @@ void Environment::step(float dtime) */ player->move(dtime_part, *m_map); + /* + Update lighting on remote players on client + */ + u8 light = LIGHT_MAX; + try{ + // Get node at feet + v3s16 p = floatToInt(playerpos + v3f(0,BS/4,0)); + MapNode n = m_map->getNode(p); + light = n.getLightBlend(m_daynight_ratio); + } + catch(InvalidPositionException &e) {} + player->updateLight(light); + /* Add footsteps to grass */ - //TimeTaker footsteptimer("footstep", g_device); - // 0ms - v3f playerpos = player->getPosition(); // Get node that is at BS/4 under player v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0)); try{ @@ -163,7 +175,6 @@ void Environment::step(float dtime) catch(InvalidPositionException &e) { } - //footsteptimer.stop(); } } while(dtime > 0.001); diff --git a/src/guiPauseMenu.cpp b/src/guiPauseMenu.cpp index 676c145f2..73e406e18 100644 --- a/src/guiPauseMenu.cpp +++ b/src/guiPauseMenu.cpp @@ -21,8 +21,145 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "guiPauseMenu.h" +#include "debug.h" -void guiPauseMenu::scaleGui() // this function scales gui from the size stored in file to screen size +GUIPauseMenu::GUIPauseMenu(gui::IGUIEnvironment* env, + gui::IGUIElement* parent, s32 id, + IrrlichtDevice *dev): + IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, + core::rect(0,0,100,100)) +{ + m_dev = dev; + m_screensize_old = v2u32(0,0); + + resizeGui(); + + setVisible(false); +} + +GUIPauseMenu::~GUIPauseMenu() +{ +} + +void GUIPauseMenu::resizeGui() +{ + video::IVideoDriver* driver = Environment->getVideoDriver(); + v2u32 screensize = driver->getScreenSize(); + if(screensize == m_screensize_old) + return; + m_screensize_old = screensize; + + { + gui::IGUIElement *e = getElementFromId(256); + if(e != NULL) + e->remove(); + } + { + gui::IGUIElement *e = getElementFromId(257); + if(e != NULL) + e->remove(); + } + + core::rect rect( + screensize.X/2 - 560/2, + screensize.Y/2 - 300/2, + screensize.X/2 + 560/2, + screensize.Y/2 + 300/2 + ); + + DesiredRect = rect; + recalculateAbsolutePosition(false); + + v2s32 size = rect.getSize(); + + { + core::rect rect(0, 0, 140, 30); + rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2-25); + Environment->addButton(rect, this, 256, L"Continue"); + } + { + core::rect rect(0, 0, 140, 30); + rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25); + Environment->addButton(rect, this, 257, L"Exit"); + } +} + +void GUIPauseMenu::draw() +{ + if(!IsVisible) + return; + + gui::IGUISkin* skin = Environment->getSkin(); + if (!skin) + return; + video::IVideoDriver* driver = Environment->getVideoDriver(); + + video::SColor bgcolor(140,0,0,0); + driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect); + + gui::IGUIElement::draw(); +} + +bool GUIPauseMenu::OnEvent(const SEvent& event) +{ + if(event.EventType==EET_KEY_INPUT_EVENT) + { + if(event.KeyInput.Key==KEY_ESCAPE && event.KeyInput.PressedDown) + { + setVisible(false); + return true; + } + } + if(event.EventType==EET_GUI_EVENT) + { + if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST + && isVisible()) + { + if(!canTakeFocus(event.GUIEvent.Element)) + { + dstream<<"GUIPauseMenu: Not allowing focus change." + <getID()) + { + case 256: // continue + setVisible(false); + break; + case 257: // exit + m_dev->closeDevice(); + break; + } + } + } + + return Parent ? Parent->OnEvent(event) : false; +} + +#if 0 +GUIPauseMenu::GUIPauseMenu(IrrlichtDevice *device, IEventReceiver *recv): + dev(device), + oldRecv(recv) +{ + if(!dev) + return; + guienv=dev->getGUIEnvironment(); + + if (!loadMenu()) + return; + + device->setEventReceiver(this); // now WE are the input receiver! ahhaha! +} + +GUIPauseMenu::~GUIPauseMenu(void) +{ +} + +void GUIPauseMenu::scaleGui() // this function scales gui from the size stored in file to screen size { core::dimension2du screen=dev->getVideoDriver()->getScreenSize(); core::vector2di real=root->getAbsolutePosition().LowerRightCorner; // determine gui size stored in file (which is size of my menu root node) @@ -30,7 +167,7 @@ void guiPauseMenu::scaleGui() // this function scales gui from the size stored i float factorY=(float)screen.Height/(float)real.Y; scaleGui(guienv->getRootGUIElement(),factorX,factorY); } -void guiPauseMenu::scaleGui(gui::IGUIElement *node,float factorX,float factorY) // recursive set scale +void GUIPauseMenu::scaleGui(gui::IGUIElement *node,float factorX,float factorY) // recursive set scale { if((node->getParent() && node->getParent()->getID()==255) || node->getID()==255) // modify only menu's elements { @@ -47,7 +184,7 @@ void guiPauseMenu::scaleGui(gui::IGUIElement *node,float factorX,float factorY) scaleGui((*it),factorX,factorY); } -bool guiPauseMenu::loadMenu() +bool GUIPauseMenu::loadMenu() { guienv->loadGUI("../data/pauseMenu.gui"); @@ -65,19 +202,7 @@ bool guiPauseMenu::loadMenu() return true; } -guiPauseMenu::guiPauseMenu(IrrlichtDevice *device, IEventReceiver *recv) : dev(device), oldRecv(recv) -{ - if(!dev) - return; - guienv=dev->getGUIEnvironment(); - - if (!loadMenu()) - return; - - device->setEventReceiver(this); // now WE are the input receiver! ahhaha! -} - -bool guiPauseMenu::OnEvent(const SEvent& event) +bool GUIPauseMenu::OnEvent(const SEvent& event) { if(!dev->isWindowFocused()) setVisible(true); @@ -114,7 +239,5 @@ bool guiPauseMenu::OnEvent(const SEvent& event) return false; } +#endif -guiPauseMenu::~guiPauseMenu(void) -{ -} diff --git a/src/guiPauseMenu.h b/src/guiPauseMenu.h index 28ac02bc9..f26a26149 100644 --- a/src/guiPauseMenu.h +++ b/src/guiPauseMenu.h @@ -23,31 +23,64 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef GUIPAUSEMENU_HEADER #define GUIPAUSEMENU_HEADER -#include -using namespace irr; +#include "common_irrlicht.h" -class guiPauseMenu : public IEventReceiver +class GUIPauseMenu : public gui::IGUIElement { -private: - IrrlichtDevice *dev; - gui::IGUIEnvironment *guienv; - IEventReceiver *oldRecv; - - gui::IGUIStaticText *root; - - bool loadMenu(); - void scaleGui(); - void scaleGui(gui::IGUIElement *node,float factorX,float factorY); public: - guiPauseMenu(IrrlichtDevice *device,IEventReceiver *recv); + GUIPauseMenu(gui::IGUIEnvironment* env, + gui::IGUIElement* parent, s32 id, + IrrlichtDevice *dev); + ~GUIPauseMenu(); + + /* + Remove and re-add (or reposition) stuff + */ + void resizeGui(); + + void draw(); + + void launch() + { + setVisible(true); + Environment->setFocus(this); + } + + bool canTakeFocus(gui::IGUIElement *e) + { + return (e && (e == this || isMyChild(e))); + } + + bool OnEvent(const SEvent& event); + +private: + IrrlichtDevice *m_dev; + v2u32 m_screensize_old; +}; + +/*class GUIPauseMenu : public IEventReceiver +{ +public: + void scaleGui(); + + GUIPauseMenu(IrrlichtDevice *device,IEventReceiver *recv); + ~GUIPauseMenu(void); void setVisible(bool visible){root->setVisible(visible);}; bool isVisible(){return root->isVisible();}; bool OnEvent(const SEvent& event); - ~guiPauseMenu(void); -}; +private: + bool loadMenu(); + void scaleGui(gui::IGUIElement *node,float factorX,float factorY); + + IrrlichtDevice *dev; + gui::IGUIEnvironment *guienv; + IEventReceiver *oldRecv; + + gui::IGUIStaticText *root; +};*/ #endif diff --git a/src/inventory.h b/src/inventory.h index 354111045..c18aa5dce 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -196,7 +196,6 @@ private: std::string m_inventorystring; }; -//SUGGESTION: Split into ClientInventory and ServerInventory class Inventory { public: diff --git a/src/main.cpp b/src/main.cpp index 8325680f2..4b696236d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -161,17 +161,17 @@ TODO: Remove LazyMeshUpdater. It is not used as supposed. TODO: TOSERVER_LEAVE TODO: Better handling of objects and mobs - - Update brightness according to day-night blended light of node - in position - Scripting? + - There has to be some way to do it with less spaghetti code + - Make separate classes for client and server + - Client should not discriminate between blocks, server should + - Make other players utilize the same framework + +SUGG: Split Inventory into ClientInventory and ServerInventory 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 ====================================================================== @@ -208,15 +208,6 @@ TODO: Implement getGlobalTime for server build //#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup") #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 @@ -237,6 +228,8 @@ TODO: Implement getGlobalTime for server build #include "guiPauseMenu.h" #include "irrlichtwrapper.h" #include "gettime.h" +#include "porting.h" +#include "guiInventoryMenu.h" IrrlichtWrapper *g_irrlicht; @@ -276,7 +269,9 @@ extern void set_default_settings(); //u16 g_selected_material = 0; u16 g_selected_item = 0; -bool g_esc_pressed = false; +gui::IGUIEnvironment* guienv = NULL; +GUIPauseMenu *pauseMenu = NULL; +GUIInventoryMenu *inventoryMenu = NULL; std::wstring g_text_buffer; bool g_text_buffer_accepted = false; @@ -354,13 +349,35 @@ public: } } - if(event.KeyInput.Key == irr::KEY_ESCAPE) + if(pauseMenu != NULL) { - //TODO: Not used anymore? - if(g_game_focused == true) + if(event.KeyInput.Key == irr::KEY_ESCAPE) { - dstream<isVisible() + && !inventoryMenu->isVisible()) + { + dstream<launch(); + return true; + } + } + } + + if(inventoryMenu != NULL) + { + if(event.KeyInput.Key == irr::KEY_KEY_I) + { + if(g_game_focused == true + && !inventoryMenu->isVisible() + && !pauseMenu->isVisible()) + { + dstream<launch(); + return true; + } } } @@ -411,6 +428,7 @@ public: if(event.EventType == irr::EET_MOUSE_INPUT_EVENT) { + //dstream<<"MyEventReceiver: mouse input"<__| \\___ >____ > |__| "<getSceneManager(); - // Pause menu - guiPauseMenu pauseMenu(device, &receiver); - - gui::IGUIEnvironment* guienv = device->getGUIEnvironment(); + guienv = device->getGUIEnvironment(); gui::IGUISkin* skin = guienv->getSkin(); gui::IGUIFont* font = guienv->getFont("../data/fontlucida.png"); if(font) @@ -1457,12 +1470,33 @@ int main(int argc, char *argv[]) gui_loadingtext->remove(); - pauseMenu.setVisible(true); - /* Add some gui stuff */ + // This is a copy of the inventory that the client's environment has + Inventory local_inventory(PLAYER_INVENTORY_SIZE); + + GUIQuickInventory *quick_inventory = new GUIQuickInventory + (guienv, NULL, v2s32(10, 70), 5, &local_inventory); + + /* + We need some kind of a root node to be able to add + custom elements directly on the screen. + Otherwise they won't be automatically drawn. + */ + gui::IGUIStaticText *root = guienv->addStaticText(L"", + core::rect(0, 0, 10000, 10000)); + + // Pause menu + pauseMenu = new GUIPauseMenu(guienv, root, -1, device); + + // Inventory menu + inventoryMenu = new GUIInventoryMenu(guienv, root, -1, &local_inventory); + + pauseMenu->launch(); + //inventoryMenu->launch(); + // First line of debug text gui::IGUIStaticText *guitext = guienv->addStaticText( L"Minetest-c55", @@ -1481,12 +1515,6 @@ int main(int argc, char *argv[]) core::rect(100, 70, 100+400, 70+(textsize.Y+5)), false, false); - // This is a copy of the inventory that the client's environment has - Inventory local_inventory(PLAYER_INVENTORY_SIZE); - - GUIQuickInventory *quick_inventory = new GUIQuickInventory - (guienv, NULL, v2s32(10, 70), 5, &local_inventory); - /* Some statistics are collected in these */ @@ -1529,11 +1557,6 @@ int main(int argc, char *argv[]) //gui::IGUIWindow* input_window = NULL; gui::IGUIStaticText* input_guitext = NULL; - /* - Digging animation - */ - //f32 - /* Main loop */ @@ -1557,6 +1580,9 @@ int main(int argc, char *argv[]) */ v2u32 screensize = driver->getScreenSize(); core::vector2d displaycenter(screensize.X/2,screensize.Y/2); + + pauseMenu->resizeGui(); + inventoryMenu->resizeGui(); // Hilight boxes collected during the loop and displayed core::list< core::aabbox3d > hilightboxes; @@ -1714,6 +1740,11 @@ int main(int argc, char *argv[]) { break; }*/ + /*if(g_i_pressed) + { + inventoryMenu->setVisible(true); + g_i_pressed = false; + }*/ /* Player speed control @@ -1773,7 +1804,11 @@ int main(int argc, char *argv[]) Mouse and camera control */ - if((device->isWindowActive() && g_game_focused && !pauseMenu.isVisible()) + if((device->isWindowActive() + && g_game_focused + && !pauseMenu->isVisible() + && !inventoryMenu->isVisible() + ) || random_input) { if(!random_input) @@ -2250,6 +2285,7 @@ int main(int argc, char *argv[]) client.getLocalInventory(local_inventory); quick_inventory->setSelection(g_selected_item); quick_inventory->update(); + inventoryMenu->update(); } if(input_guitext != NULL) diff --git a/src/map.cpp b/src/map.cpp index 9a0952c75..839efbf5b 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -24,14 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include "utility.h" #include "voxel.h" - -#ifdef _WIN32 - #include - #define sleep_ms(x) Sleep(x) -#else - #include - #define sleep_ms(x) usleep(x*1000) -#endif +#include "porting.h" MapBlockPointerCache::MapBlockPointerCache(Map *map) { diff --git a/src/mapblockobject.cpp b/src/mapblockobject.cpp index 779fe3fa7..d5c9c997a 100644 --- a/src/mapblockobject.cpp +++ b/src/mapblockobject.cpp @@ -282,6 +282,7 @@ void RatObject::addToScene(scene::ISceneManager *smgr) buf->getMaterial().setTexture (0, driver->getTexture("../data/rat.png")); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; // Add to mesh mesh->addMeshBuffer(buf); @@ -292,6 +293,73 @@ void RatObject::addToScene(scene::ISceneManager *smgr) } #endif +#ifndef SERVER +/* + PlayerObject +*/ +void PlayerObject::addToScene(scene::ISceneManager *smgr) +{ + if(m_node != NULL) + return; + + video::IVideoDriver* driver = smgr->getVideoDriver(); + + // Attach a simple mesh to the player for showing an image + scene::SMesh *mesh = new scene::SMesh(); + { // Front + scene::IMeshBuffer *buf = new scene::SMeshBuffer(); + video::SColor c(255,255,255,255); + video::S3DVertex vertices[4] = + { + video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1), + video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1), + video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0), + video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0), + }; + u16 indices[] = {0,1,2,2,3,0}; + buf->append(vertices, 4, indices, 6); + // Set material + buf->getMaterial().setFlag(video::EMF_LIGHTING, false); + //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); + buf->getMaterial().setTexture(0, driver->getTexture("../data/player.png")); + buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); + //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + // Add to mesh + mesh->addMeshBuffer(buf); + buf->drop(); + } + { // Back + 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, 1,1), + video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1), + video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0), + video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0), + }; + u16 indices[] = {0,1,2,2,3,0}; + buf->append(vertices, 4, indices, 6); + // Set material + buf->getMaterial().setFlag(video::EMF_LIGHTING, false); + //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); + buf->getMaterial().setTexture(0, driver->getTexture("../data/player_back.png")); + buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); + buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + // Add to mesh + mesh->addMeshBuffer(buf); + buf->drop(); + } + + m_node = smgr->addMeshSceneNode(mesh, NULL); + mesh->drop(); + updateNodePos(); +} +#endif + /* MapBlockObjectList */ diff --git a/src/mapblockobject.h b/src/mapblockobject.h index c479bc959..30fa797f4 100644 --- a/src/mapblockobject.h +++ b/src/mapblockobject.h @@ -28,8 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "constants.h" #include "debug.h" -#define MAPBLOCKOBJECT_TYPE_TEST 0 -#define MAPBLOCKOBJECT_TYPE_TEST2 1 +#define MAPBLOCKOBJECT_TYPE_PLAYER 0 #define MAPBLOCKOBJECT_TYPE_SIGN 2 #define MAPBLOCKOBJECT_TYPE_RAT 3 // Used for handling selecting special stuff @@ -432,6 +431,7 @@ public: buf->getMaterial().setTexture (0, driver->getTexture("../data/sign.png")); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; // Add to mesh mesh->addMeshBuffer(buf); @@ -455,6 +455,7 @@ public: buf->getMaterial().setTexture (0, driver->getTexture("../data/sign_back.png")); buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true); buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; // Add to mesh mesh->addMeshBuffer(buf); @@ -710,10 +711,129 @@ protected: float m_counter1; float m_counter2; - v3f m_oldpos; float m_age; }; +/* + NOTE: Not used. +*/ +class PlayerObject : public MovingObject +{ +public: + PlayerObject(MapBlock *block, s16 id, v3f pos): + MovingObject(block, id, pos), + m_node(NULL) + { + m_collision_box = new core::aabbox3d + (-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);*/ + } + virtual ~PlayerObject() + { + if(m_collision_box) + delete m_collision_box; + if(m_selection_box) + delete m_selection_box; + } + + /* + Implementation interface + */ + virtual u16 getTypeId() const + { + return MAPBLOCKOBJECT_TYPE_PLAYER; + } + virtual void serialize(std::ostream &os, u8 version) + { + // Object data is generated from actual player + } + 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) + { + // Player is handled elsewhere. + // Die. + //return true; + // Actually, fail very loudly: + assert(0); + } + +#ifndef SERVER + virtual void clientStep(float 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; + + v3f m_oldpos; +}; + struct DistanceSortedObject { DistanceSortedObject(MapBlockObject *a_obj, f32 a_d) diff --git a/src/player.cpp b/src/player.cpp index 2c04f1f76..d38d5eac8 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -41,7 +41,159 @@ Player::~Player() { } -void Player::move(f32 dtime, Map &map) +// Y direction is ignored +void Player::accelerate(v3f target_speed, f32 max_increase) +{ + if(m_speed.X < target_speed.X - max_increase) + m_speed.X += max_increase; + else if(m_speed.X > target_speed.X + max_increase) + m_speed.X -= max_increase; + else if(m_speed.X < target_speed.X) + m_speed.X = target_speed.X; + else if(m_speed.X > target_speed.X) + m_speed.X = target_speed.X; + + if(m_speed.Z < target_speed.Z - max_increase) + m_speed.Z += max_increase; + else if(m_speed.Z > target_speed.Z + max_increase) + m_speed.Z -= max_increase; + else if(m_speed.Z < target_speed.Z) + m_speed.Z = target_speed.Z; + else if(m_speed.Z > target_speed.Z) + m_speed.Z = target_speed.Z; +} + +/* + RemotePlayer +*/ + +#ifndef SERVER + +RemotePlayer::RemotePlayer( + scene::ISceneNode* parent, + IrrlichtDevice *device, + s32 id): + scene::ISceneNode(parent, (device==NULL)?NULL:device->getSceneManager(), id), + m_text(NULL) +{ + m_box = core::aabbox3d(-BS/2,0,-BS/2,BS/2,BS*2,BS/2); + + if(parent != NULL && device != NULL) + { + // ISceneNode stores a member called SceneManager + scene::ISceneManager* mgr = SceneManager; + video::IVideoDriver* driver = mgr->getVideoDriver(); + gui::IGUIEnvironment* gui = device->getGUIEnvironment(); + + // Add a text node for showing the name + wchar_t wname[1] = {0}; + m_text = mgr->addTextSceneNode(gui->getBuiltInFont(), + wname, video::SColor(255,255,255,255), this); + m_text->setPosition(v3f(0, (f32)BS*2.1, 0)); + + // Attach a simple mesh to the player for showing an image + scene::SMesh *mesh = new scene::SMesh(); + { // Front + scene::IMeshBuffer *buf = new scene::SMeshBuffer(); + video::SColor c(255,255,255,255); + video::S3DVertex vertices[4] = + { + video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1), + video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1), + video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0), + video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0), + }; + u16 indices[] = {0,1,2,2,3,0}; + buf->append(vertices, 4, indices, 6); + // Set material + buf->getMaterial().setFlag(video::EMF_LIGHTING, false); + //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); + buf->getMaterial().setTexture(0, driver->getTexture("../data/player.png")); + buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + // Add to mesh + mesh->addMeshBuffer(buf); + buf->drop(); + } + { // Back + 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, 1,1), + video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1), + video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0), + video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0), + }; + u16 indices[] = {0,1,2,2,3,0}; + buf->append(vertices, 4, indices, 6); + // Set material + buf->getMaterial().setFlag(video::EMF_LIGHTING, false); + //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); + buf->getMaterial().setTexture(0, driver->getTexture("../data/player_back.png")); + buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); + buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + // Add to mesh + mesh->addMeshBuffer(buf); + buf->drop(); + } + m_node = mgr->addMeshSceneNode(mesh, this); + mesh->drop(); + m_node->setPosition(v3f(0,0,0)); + } +} + +RemotePlayer::~RemotePlayer() +{ + if(SceneManager != NULL) + ISceneNode::remove(); +} + +void RemotePlayer::updateName(const char *name) +{ + Player::updateName(name); + if(m_text != NULL) + { + wchar_t wname[PLAYERNAME_SIZE]; + mbstowcs(wname, m_name, strlen(m_name)+1); + m_text->setText(wname); + } +} + +void RemotePlayer::move(f32 dtime, Map &map) +{ + m_pos_animation_time_counter += dtime; + m_pos_animation_counter += dtime; + v3f movevector = m_position - 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; + + ISceneNode::setPosition(m_showpos); +} + +#endif + +#ifndef SERVER +/* + LocalPlayer +*/ + +LocalPlayer::LocalPlayer() +{ +} + +LocalPlayer::~LocalPlayer() +{ +} + +void LocalPlayer::move(f32 dtime, Map &map) { v3f position = getPosition(); v3f oldpos = position; @@ -202,141 +354,6 @@ void Player::move(f32 dtime, Map &map) setPosition(position); } -// Y direction is ignored -void Player::accelerate(v3f target_speed, f32 max_increase) -{ - if(m_speed.X < target_speed.X - max_increase) - m_speed.X += max_increase; - else if(m_speed.X > target_speed.X + max_increase) - m_speed.X -= max_increase; - else if(m_speed.X < target_speed.X) - m_speed.X = target_speed.X; - else if(m_speed.X > target_speed.X) - m_speed.X = target_speed.X; - - if(m_speed.Z < target_speed.Z - max_increase) - m_speed.Z += max_increase; - else if(m_speed.Z > target_speed.Z + max_increase) - m_speed.Z -= max_increase; - else if(m_speed.Z < target_speed.Z) - m_speed.Z = target_speed.Z; - else if(m_speed.Z > target_speed.Z) - m_speed.Z = target_speed.Z; -} - -/* - RemotePlayer -*/ - -#ifndef SERVER - -RemotePlayer::RemotePlayer( - scene::ISceneNode* parent, - IrrlichtDevice *device, - s32 id): - scene::ISceneNode(parent, (device==NULL)?NULL:device->getSceneManager(), id), - m_text(NULL) -{ - m_box = core::aabbox3d(-BS/2,0,-BS/2,BS/2,BS*2,BS/2); - - if(parent != NULL && device != NULL) - { - // ISceneNode stores a member called SceneManager - scene::ISceneManager* mgr = SceneManager; - video::IVideoDriver* driver = mgr->getVideoDriver(); - gui::IGUIEnvironment* gui = device->getGUIEnvironment(); - - // Add a text node for showing the name - wchar_t wname[1] = {0}; - m_text = mgr->addTextSceneNode(gui->getBuiltInFont(), - wname, video::SColor(255,255,255,255), this); - m_text->setPosition(v3f(0, (f32)BS*2.1, 0)); - - // Attach a simple mesh to the player for showing an image - scene::SMesh *mesh = new scene::SMesh(); - { // Front - scene::IMeshBuffer *buf = new scene::SMeshBuffer(); - video::SColor c(255,255,255,255); - video::S3DVertex vertices[4] = - { - video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1), - video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1), - video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0), - video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0), - }; - u16 indices[] = {0,1,2,2,3,0}; - buf->append(vertices, 4, indices, 6); - // Set material - buf->getMaterial().setFlag(video::EMF_LIGHTING, false); - //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); - buf->getMaterial().setTexture(0, driver->getTexture("../data/player.png")); - buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); - //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - // Add to mesh - mesh->addMeshBuffer(buf); - buf->drop(); - } - { // Back - 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, 1,1), - video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1), - video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0), - video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0), - }; - u16 indices[] = {0,1,2,2,3,0}; - buf->append(vertices, 4, indices, 6); - // Set material - buf->getMaterial().setFlag(video::EMF_LIGHTING, false); - //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false); - buf->getMaterial().setTexture(0, driver->getTexture("../data/player_back.png")); - buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false); - buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - // Add to mesh - mesh->addMeshBuffer(buf); - buf->drop(); - } - scene::IMeshSceneNode *node = mgr->addMeshSceneNode(mesh, this); - mesh->drop(); - node->setPosition(v3f(0,0,0)); - } -} - -RemotePlayer::~RemotePlayer() -{ - if(SceneManager != NULL) - ISceneNode::remove(); -} - -void RemotePlayer::updateName(const char *name) -{ - Player::updateName(name); - if(m_text != NULL) - { - wchar_t wname[PLAYERNAME_SIZE]; - mbstowcs(wname, m_name, strlen(m_name)+1); - m_text->setText(wname); - } -} - -#endif - -#ifndef SERVER -/* - LocalPlayer -*/ - -LocalPlayer::LocalPlayer() -{ -} - -LocalPlayer::~LocalPlayer() -{ -} - void LocalPlayer::applyControl(float dtime) { // Random constants diff --git a/src/player.h b/src/player.h index 7337eb6db..0b9f014c1 100644 --- a/src/player.h +++ b/src/player.h @@ -37,7 +37,8 @@ public: Player(); virtual ~Player(); - void move(f32 dtime, Map &map); + //void move(f32 dtime, Map &map); + virtual void move(f32 dtime, Map &map) = 0; v3f getSpeed() { @@ -94,6 +95,8 @@ public: virtual bool isLocal() const = 0; + virtual void updateLight(u8 light_at_pos) {}; + bool touching_ground; bool in_water; @@ -124,6 +127,10 @@ public: return false; } + void move(f32 dtime, Map &map) + { + } + private: }; @@ -163,8 +170,18 @@ public: void setPosition(v3f position) { + m_oldpos = m_showpos; + + 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; + Player::setPosition(position); - ISceneNode::setPosition(position); + //ISceneNode::setPosition(position); } virtual void setYaw(f32 yaw) @@ -180,9 +197,41 @@ public: void updateName(const char *name); + 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 m_box; + + v3f m_oldpos; + f32 m_pos_animation_counter; + f32 m_pos_animation_time; + f32 m_pos_animation_time_counter; + v3f m_showpos; }; #endif @@ -242,6 +291,8 @@ public: return true; } + void move(f32 dtime, Map &map); + void applyControl(float dtime); PlayerControl control; diff --git a/src/server.h b/src/server.h index c5a285490..d002d9f4c 100644 --- a/src/server.h +++ b/src/server.h @@ -29,14 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common_irrlicht.h" #include #include "utility.h" - -#ifdef _WIN32 - #include - #define sleep_ms(x) Sleep(x) -#else - #include - #define sleep_ms(x) usleep(x*1000) -#endif +#include "porting.h" struct QueuedBlockEmerge { diff --git a/src/servermain.cpp b/src/servermain.cpp index ce0243e12..0c2faa7ec 100644 --- a/src/servermain.cpp +++ b/src/servermain.cpp @@ -271,8 +271,6 @@ int main(int argc, char *argv[]) <<"| Y Y \\ | | \\ ___/| | \\ ___/ \\___ \\ | | "<__| \\___ >____ > |__| "< - -#ifdef _WIN32 - #include - #define sleep_ms(x) Sleep(x) -#else - #include - #define sleep_ms(x) usleep(x*1000) -#endif +#include "porting.h" /* Asserts that the exception occurs diff --git a/src/voxel.cpp b/src/voxel.cpp index 282ff5e7c..55cd73893 100644 --- a/src/voxel.cpp +++ b/src/voxel.cpp @@ -804,8 +804,10 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos, if(stoptime != 0) { u32 timenow = getTimeMs(); - if(timenow >= stoptime || - (stoptime < 0x80000000 && timenow > 0x80000000)) + // Well, it is a bit hard to guess because we don't know the + // start time... + bool overflow = timenow < stoptime - 100000; + if(timenow >= stoptime || overflow) { dstream<<"flowWater: stoptime reached"<