X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fmain.cpp;h=0001d33ecb71caa8855dcd4f39848c4684638d97;hb=423109e64c9e723f9f2a52e3537892f584383865;hp=1f178ab6e085c462d934cf8271504f70eb4d6844;hpb=28300953667b6a44efb5be6b2c612993de060636;p=dragonfireclient.git diff --git a/src/main.cpp b/src/main.cpp index 1f178ab6e..0001d33ec 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ /* Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola +Copyright (C) 2010-2011 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 @@ -27,10 +27,35 @@ NOTE: Global locale is now set at initialization NOTE: If VBO (EHM_STATIC) is used, remember to explicitly free the hardware buffer (it is not freed automatically) -Random suggeestions (AKA very old suggestions that haven't been done): ----------------------------------------------------------------------- - -SUGG: Fix address to be ipv6 compatible +NOTE: A random to-do list saved here as documentation: +A list of "active blocks" in which stuff happens. (+=done) + + Add a never-resetted game timer to the server + + Add a timestamp value to blocks + + The simple rule: All blocks near some player are "active" + - Do stuff in real time in active blocks + + Handle objects + - Grow grass, delete leaves without a tree + - Spawn some mobs based on some rules + - Transform cobble to mossy cobble near water + - Run a custom script + - ...And all kinds of other dynamic stuff + + Keep track of when a block becomes active and becomes inactive + + When a block goes inactive: + + Store objects statically to block + + Store timer value as the timestamp + + When a block goes active: + + Create active objects out of static objects + - Simulate the results of what would have happened if it would have + been active for all the time + - Grow a lot of grass and so on + + Initially it is fine to send information about every active object + to every player. Eventually it should be modified to only send info + about the nearest ones. + + This was left to be done by the old system and it sends only the + nearest ones. + +Old, wild and random suggestions that probably won't be done: +------------------------------------------------------------- SUGG: If player is on ground, mainly fetch ground-level blocks @@ -75,24 +100,52 @@ SUGG: Make the amount of blocks sending to client and the total SUGG: Meshes of blocks could be split into 6 meshes facing into different directions and then only those drawn that need to be -SUGG: Calculate lighting per vertex to get a lighting effect like in - bartwe's game - SUGG: Background music based on cellular automata? http://www.earslap.com/projectslab/otomata +SUGG: Simple light color information to air + +SUGG: Server-side objects could be moved based on nodes to enable very + lightweight operation and simple AI + - Not practical; client would still need to show smooth movement. + +SUGG: Make a system for pregenerating quick information for mapblocks, so + that the client can show them as cubes before they are actually sent + or even generated. + +SUGG: Erosion simulation at map generation time + - This might be plausible if larger areas of map were pregenerated + without lighting (which is slow) + - Simulate water flows, which would carve out dirt fast and + then turn stone into gravel and sand and relocate it. + - How about relocating minerals, too? Coal and gold in + downstream sand and gravel would be kind of cool + - This would need a better way of handling minerals, mainly + to have mineral content as a separate field. the first + parameter field is free for this. + - Simulate rock falling from cliffs when water has removed + enough solid rock from the bottom + +SUGG: For non-mapgen FarMesh: Add a per-sector database to store surface + stuff as simple flags/values + - Light? + - A building? + And at some point make the server send this data to the client too, + instead of referring to the noise functions + - Ground height + - Surface ground type + - Trees? Gaming ideas: ------------- - Aim for something like controlling a single dwarf in Dwarf Fortress - - The player could go faster by a crafting a boat, or riding an animal - - Random NPC traders. what else? Game content: ------------- + - When furnace is destroyed, move items to player's inventory - Add lots of stuff - Glass blocks @@ -124,6 +177,10 @@ Game content: - A bomb - A spread-items-on-map routine for the bomb, and for dying players +- Fighting: + - Proper sword swing simulation + - Player should get damage from colliding to a wall at high speed + Documentation: -------------- @@ -133,12 +190,10 @@ Build system / running: Networking and serialization: ----------------------------- -TODO: Get rid of GotSplitPacketException - -GUI: ----- +SUGG: Fix address to be ipv6 compatible -TODO: Configuration menu, at least for keys +User Interface: +--------------- Graphics: --------- @@ -154,22 +209,32 @@ SUGG: Make fetching sector's blocks more efficient when rendering sectors that have very large amounts of blocks (on client) - Is this necessary at all? -TODO: Flowing water animation - SUGG: Draw cubes in inventory directly with 3D drawing commands, so that animating them is easier. SUGG: Option for enabling proper alpha channel for textures + +TODO: Flowing water animation + TODO: A setting for enabling bilinear filtering for textures TODO: Better control of draw_control.wanted_max_blocks -TODO: Get player texture (and some others) from the specified texture - directory +TODO: Further investigate the use of GPU lighting in addition to the + current one -SUGG: Simple light color information to air +TODO: Artificial (night) light could be more yellow colored than sunlight. + - This is technically doable. + - Also the actual colors of the textures could be made less colorful + in the dark but it's a bit more difficult. + +SUGG: Somehow make the night less colorful -TODO: Block mesh generator to tile properly on smooth lighting +TODO: Occlusion culling + - At the same time, move some of the renderMap() block choosing code + to the same place as where the new culling happens. + - Shoot some rays per frame and when ready, make a new list of + blocks for usage of renderMap and give it a new pointer to it. Configuration: -------------- @@ -195,6 +260,9 @@ TODO: Don't update all meshes always on single node changes, but FIXME: When disconnected to the menu, memory is not freed properly +TODO: Investigate how much the mesh generator thread gets used when + transferring map data + Server: ------- @@ -206,21 +274,38 @@ FIXME: Server sometimes goes into some infinite PeerNotFoundException loop * Fix the problem with the server constantly saving one or a few blocks? List the first saved block, maybe it explains. - It is probably caused by oscillating water + - TODO: Investigate if this still happens (this is a very old one) * Make a small history check to transformLiquids to detect and log continuous oscillations, in such detail that they can be fixed. +FIXME: The new optimized map sending doesn't sometimes send enough blocks + from big caves and such +FIXME: Block send distance configuration does not take effect for some reason + +Environment: +------------ + +TODO: Add proper hooks to when adding and removing active blocks + +TODO: Finish the ActiveBlockModifier stuff and use it for something + Objects: -------- -TODO: Get rid of MapBlockObjects and use ActiveObjects +TODO: Get rid of MapBlockObjects and use only ActiveObjects + - Skipping the MapBlockObject data is nasty - there is no "total + length" stored; have to make a SkipMBOs function which contains + enough of the current code to skip them properly. SUGG: MovingObject::move and Player::move are basically the same. combine them. - - NOTE: Player::move is more up-to-date. - - NOTE: There is a simple move implementation now in collision.{h,cpp} + - NOTE: This is a bit tricky because player has the sneaking ability + - NOTE: Player::move is more up-to-date. + - NOTE: There is a simple move implementation now in collision.{h,cpp} + - NOTE: MovingObject will be deleted (MapBlockObject) -SUGG: Server-side objects could be moved based on nodes to enable very - lightweight operation and simple AI +TODO: Add a long step function to objects that is called with the time + difference when block activates Map: ---- @@ -228,48 +313,46 @@ SUGG: Server-side objects could be moved based on nodes to enable very TODO: Mineral and ground material properties - This way mineral ground toughness can be calculated with just some formula, as well as tool strengths + - There are TODOs in appropriate files: material.h, content_mapnode.h TODO: Flowing water to actually contain flow direction information - There is a space for this - it just has to be implemented. -SUGG: Erosion simulation at map generation time - - Simulate water flows, which would carve out dirt fast and - then turn stone into gravel and sand and relocate it. - - How about relocating minerals, too? Coal and gold in - downstream sand and gravel would be kind of cool - - This would need a better way of handling minerals, mainly - to have mineral content as a separate field. the first - parameter field is free for this. - - Simulate rock falling from cliffs when water has removed - enough solid rock from the bottom - -SUGG: Try out the notch way of generating maps, that is, make bunches - of low-res 3d noise and interpolate linearly. - -Mapgen v2: -* Possibly add some kind of erosion and other stuff -* Better water generation (spread it to underwater caverns but don't - fill dungeons that don't touch big water masses) -* When generating a chunk and the neighboring chunk doesn't have mud - and stuff yet and the ground is fairly flat, the mud will flow to - the other chunk making nasty straight walls when the other chunk - is generated. Fix it. Maybe just a special case if the ground is - flat? +TODO: Consider smoothening cave floors after generating them Misc. stuff: ------------ -* Make an "environment metafile" to store at least time of day -* Move digging property stuff from material.{h,cpp} to mapnode.cpp... - - Or maybe move content_features to material.{h,cpp}? -* Maybe: - Make a system for pregenerating quick information for mapblocks, so - that the client can show them as cubes before they are actually sent - or even generated. +TODO: Make sure server handles removing grass when a block is placed (etc) + - The client should not do it by itself + - NOTE: I think nobody does it currently... +TODO: Block cube placement around player's head +TODO: Protocol version field +TODO: Think about using same bits for material for fences and doors, for + example +TODO: Move mineral to param2, increment map serialization version, add + conversion + +TODO: Restart irrlicht completely when coming back to main menu from game. + - This gets rid of everything that is stored in irrlicht's caches. + +TODO: Merge bahamada's audio stuff (clean patch available) + +TODO: Merge key configuration menu (no clean patch available) Making it more portable: ------------------------ -* Some MSVC: std::sto* are defined without a namespace and collide - with the ones in utility.h + +Stuff to do before release: +--------------------------- + +Fixes to the current release: +----------------------------- + +Stuff to do after release: +--------------------------- + +Doing currently: +---------------- ====================================================================== @@ -299,16 +382,12 @@ Making it more portable: #include #include -//#include #include #include "main.h" #include "common_irrlicht.h" #include "debug.h" -//#include "map.h" -//#include "player.h" #include "test.h" #include "server.h" -//#include "client.h" #include "constants.h" #include "porting.h" #include "gettime.h" @@ -317,10 +396,12 @@ Making it more portable: #include "config.h" #include "guiMainMenu.h" #include "mineral.h" -//#include "noise.h" -//#include "tile.h" #include "materials.h" #include "game.h" +#include "keycode.h" +#include "tile.h" + +#include "gettext.h" // This makes textures ITextureSource *g_texturesource = NULL; @@ -334,6 +415,9 @@ Settings g_settings; // This is located in defaultsettings.cpp extern void set_default_settings(); +// Global profiler +Profiler g_profiler; + /* Random stuff */ @@ -384,7 +468,14 @@ std::ostream *derr_client_ptr = &dstream; class TimeGetter { public: - TimeGetter(IrrlichtDevice *device): + virtual u32 getTime() = 0; +}; + +// A precise irrlicht one +class IrrlichtTimeGetter: public TimeGetter +{ +public: + IrrlichtTimeGetter(IrrlichtDevice *device): m_device(device) {} u32 getTime() @@ -396,8 +487,18 @@ class TimeGetter private: IrrlichtDevice *m_device; }; +// Not so precise one which works without irrlicht +class SimpleTimeGetter: public TimeGetter +{ +public: + u32 getTime() + { + return porting::getTimeMs(); + } +}; // A pointer to a global instance of the time getter +// TODO: why? TimeGetter *g_timegetter = NULL; u32 getTimeMs() @@ -716,7 +817,8 @@ class RandomInputHandler : public InputHandler if(counter1 < 0.0) { counter1 = 0.1*Rand(1, 40); - keydown[irr::KEY_SPACE] = !keydown[irr::KEY_SPACE]; + keydown[getKeySetting("keymap_jump")] = + !keydown[getKeySetting("keymap_jump")]; } } { @@ -725,7 +827,8 @@ class RandomInputHandler : public InputHandler if(counter1 < 0.0) { counter1 = 0.1*Rand(1, 40); - keydown[irr::KEY_KEY_E] = !keydown[irr::KEY_KEY_E]; + keydown[getKeySetting("keymap_special1")] = + !keydown[getKeySetting("keymap_special1")]; } } { @@ -734,7 +837,8 @@ class RandomInputHandler : public InputHandler if(counter1 < 0.0) { counter1 = 0.1*Rand(1, 40); - keydown[irr::KEY_KEY_W] = !keydown[irr::KEY_KEY_W]; + keydown[getKeySetting("keymap_forward")] = + !keydown[getKeySetting("keymap_forward")]; } } { @@ -743,7 +847,8 @@ class RandomInputHandler : public InputHandler if(counter1 < 0.0) { counter1 = 0.1*Rand(1, 40); - keydown[irr::KEY_KEY_A] = !keydown[irr::KEY_KEY_A]; + keydown[getKeySetting("keymap_left")] = + !keydown[getKeySetting("keymap_left")]; } } { @@ -903,7 +1008,7 @@ void drawMenuBackground(video::IVideoDriver* driver) core::dimension2d screensize = driver->getScreenSize(); video::ITexture *bgtexture = - driver->getTexture(porting::getDataPath("mud.png").c_str()); + driver->getTexture(getTexturePath("mud.png").c_str()); if(bgtexture) { s32 texturesize = 128; @@ -923,7 +1028,7 @@ void drawMenuBackground(video::IVideoDriver* driver) } video::ITexture *logotexture = - driver->getTexture(porting::getDataPath("menulogo.png").c_str()); + driver->getTexture(getTexturePath("menulogo.png").c_str()); if(logotexture) { v2s32 logosize(logotexture->getOriginalSize().Width, @@ -947,6 +1052,14 @@ void drawMenuBackground(video::IVideoDriver* driver) int main(int argc, char *argv[]) { + /* + Initialization + */ + + // Set locale. This is for forcing '.' as the decimal point. + std::locale::global(std::locale("C")); + // This enables printing all characters in bitmap font + setlocale(LC_CTYPE, "en_US"); /* Parse command line */ @@ -1010,28 +1123,37 @@ int main(int argc, char *argv[]) disable_stderr = true; #endif - // Initialize debug streams - debugstreams_init(disable_stderr, DEBUGFILE); - // Initialize debug stacks - debug_stacks_init(); - - DSTACK(__FUNCTION_NAME); - porting::signal_handler_init(); bool &kill = *porting::signal_handler_killstatus(); + // Initialize porting::path_data and porting::path_userdata porting::initializePaths(); + // Create user data directory fs::CreateDir(porting::path_userdata); - - // C-style stuff initialization - initializeMaterialProperties(); + + init_gettext((porting::path_userdata+"/locale").c_str()); + + // Initialize debug streams +#ifdef RUN_IN_PLACE + std::string debugfile = DEBUGFILE; +#else + std::string debugfile = porting::path_userdata+"/"+DEBUGFILE; +#endif + debugstreams_init(disable_stderr, debugfile.c_str()); + // Initialize debug stacks + debug_stacks_init(); + + DSTACK(__FUNCTION_NAME); + + // Init material properties table + //initializeMaterialProperties(); // Debug handler BEGIN_DEBUG_EXCEPTION_HANDLER // Print startup message - dstream<setWindowCaption(L"Minetest [Main Menu]"); // Create time getter - g_timegetter = new TimeGetter(device); + g_timegetter = new IrrlichtTimeGetter(device); // Create game callback for menus g_gamecallback = new MainGameCallback(device); @@ -1277,7 +1397,7 @@ int main(int argc, char *argv[]) guienv = device->getGUIEnvironment(); gui::IGUISkin* skin = guienv->getSkin(); - gui::IGUIFont* font = guienv->getFont(porting::getDataPath("fontlucida.png").c_str()); + gui::IGUIFont* font = guienv->getFont(getTexturePath("fontlucida.png").c_str()); if(font) skin->setFont(font); else @@ -1301,7 +1421,6 @@ int main(int argc, char *argv[]) Preload some textures and stuff */ - init_content_inventory_texture_paths(); init_mapnode(); // Second call with g_texturesource set init_mineral(); @@ -1316,11 +1435,15 @@ int main(int argc, char *argv[]) */ std::wstring error_message = L""; + // The password entered during the menu screen, + std::string password; + /* Menu-game loop */ while(device->run() && kill == false) { + // This is used for catching disconnects try { @@ -1400,6 +1523,10 @@ int main(int argc, char *argv[]) guienv->drawAll(); driver->endScene(); + + // On some computers framerate doesn't seem to be + // automatically limited + sleep_ms(25); } // Break out of menu-game loop to shut down cleanly @@ -1420,6 +1547,9 @@ int main(int argc, char *argv[]) } playername = wide_to_narrow(menudata.name); + + password = translatePassword(playername, menudata.password); + address = wide_to_narrow(menudata.address); int newport = stoi(wide_to_narrow(menudata.port)); if(newport != 0) @@ -1429,13 +1559,22 @@ int main(int argc, char *argv[]) g_settings.set("creative_mode", itos(menudata.creative_mode)); g_settings.set("enable_damage", itos(menudata.enable_damage)); - // Check for valid parameters, restart menu if invalid. + // NOTE: These are now checked server side; no need to do it + // here, so let's not do it here. + /*// Check for valid parameters, restart menu if invalid. if(playername == "") { error_message = L"Name required."; continue; } - + // Check that name has only valid chars + if(string_allowed(playername, PLAYERNAME_ALLOWED_CHARS)==false) + { + error_message = L"Characters allowed: " + +narrow_to_wide(PLAYERNAME_ALLOWED_CHARS); + continue; + }*/ + // Save settings g_settings.set("name", playername); g_settings.set("address", address); @@ -1466,6 +1605,7 @@ int main(int argc, char *argv[]) font, map_dir, playername, + password, address, port, error_message