lightweight operation and simple AI\r
- Not practical; client would still need to show smooth movement.\r
\r
+SUGG: Make a system for pregenerating quick information for mapblocks, so\r
+ that the client can show them as cubes before they are actually sent\r
+ or even generated.\r
+\r
+SUGG: Erosion simulation at map generation time\r
+ - Simulate water flows, which would carve out dirt fast and\r
+ then turn stone into gravel and sand and relocate it.\r
+ - How about relocating minerals, too? Coal and gold in\r
+ downstream sand and gravel would be kind of cool\r
+ - This would need a better way of handling minerals, mainly\r
+ to have mineral content as a separate field. the first\r
+ parameter field is free for this.\r
+ - Simulate rock falling from cliffs when water has removed\r
+ enough solid rock from the bottom\r
+\r
Gaming ideas:\r
-------------\r
\r
\r
TODO: Better control of draw_control.wanted_max_blocks\r
\r
-TODO: Block mesh generator to tile properly on smooth lighting\r
+TODO: Further investigate the use of GPU lighting in addition to the\r
+ current one\r
\r
Configuration:\r
--------------\r
\r
FIXME: When disconnected to the menu, memory is not freed properly\r
\r
+TODO: Investigate how much the mesh generator thread gets used when\r
+ transferring map data\r
+\r
Server:\r
-------\r
\r
\r
FIXME: The new optimized map sending doesn't sometimes send enough blocks\r
from big caves and such\r
+FIXME: Block send distance configuration does not take effect for some reason\r
+\r
+TODO: Map saving should be done by EmergeThread\r
\r
-TODO: A list of "active blocks" in which stuff happens.\r
+SUGG: Map unloading based on sector reference is not very good, it keeps\r
+ unnecessary stuff in memory. I guess. Investigate this.\r
+\r
+TODO: When block is placed and it has param_type==CPT_FACEDIR_SIMPLE, set\r
+ the direction accordingly.\r
+\r
+Environment:\r
+------------\r
+\r
+TODO: A list of "active blocks" in which stuff happens. (+=done)\r
+ Add a never-resetted game timer to the server\r
+ Add a timestamp value to blocks\r
+ The simple rule: All blocks near some player are "active"\r
- NOTE: There is a simple move implementation now in collision.{h,cpp}\r
- NOTE: MovingObject will be deleted (MapBlockObject)\r
\r
+TODO: Add a long step function to objects that is called with the time\r
+ difference when block activates\r
+\r
Map:\r
----\r
\r
TODO: Mineral and ground material properties\r
- This way mineral ground toughness can be calculated with just\r
some formula, as well as tool strengths\r
+ - There are TODOs in appropriate files: material.h, content_mapnode.h\r
\r
TODO: Flowing water to actually contain flow direction information\r
- There is a space for this - it just has to be implemented.\r
\r
-SUGG: Erosion simulation at map generation time\r
- - Simulate water flows, which would carve out dirt fast and\r
- then turn stone into gravel and sand and relocate it.\r
- - How about relocating minerals, too? Coal and gold in\r
- downstream sand and gravel would be kind of cool\r
- - This would need a better way of handling minerals, mainly\r
- to have mineral content as a separate field. the first\r
- parameter field is free for this.\r
- - Simulate rock falling from cliffs when water has removed\r
- enough solid rock from the bottom\r
-\r
SUGG: Try out the notch way of generating maps, that is, make bunches\r
of low-res 3d noise and interpolate linearly.\r
\r
-Mapgen v2:\r
+Mapgen v2 (the current one):\r
* Possibly add some kind of erosion and other stuff\r
* Better water generation (spread it to underwater caverns but don't\r
fill dungeons that don't touch big water masses)\r
the other chunk making nasty straight walls when the other chunk\r
is generated. Fix it. Maybe just a special case if the ground is\r
flat?\r
+* Consider not updating this one and make a good mainly block-based\r
+ generator\r
+\r
+SUGG: Make two "modified states", one that forces the block to be saved at\r
+ the next save event, and one that makes the block to be saved at exit\r
+ time.\r
+\r
+TODO: Add a not_fully_generated flag to MapBlock, which would be set for\r
+ blocks that contain eg. trees from neighboring generations but haven't\r
+ been generated itself. This is required for the future generator.\r
\r
Misc. stuff:\r
------------\r
-* Make an "environment metafile" to store at least time of day\r
-* Move digging property stuff from material.{h,cpp} to mapnode.cpp...\r
- - Or maybe move content_features to material.{h,cpp}?\r
-* Maybe:\r
- Make a system for pregenerating quick information for mapblocks, so\r
- that the client can show them as cubes before they are actually sent\r
- or even generated.\r
+- Make sure server handles removing grass when a block is placed (etc)\r
+ - The client should not do it by itself\r
+- Block cube placement around player's head\r
+- Protocol version field\r
+- Consider getting some textures from cisoun's texture pack\r
+ - Ask from Cisoun\r
+- Make sure the fence implementation and data format is good\r
+ - Think about using same bits for material for fences and doors, for\r
+ example\r
+- Finish the ActiveBlockModifier stuff and use it for something\r
+- Move mineral to param2, increment map serialization version, add conversion\r
\r
Making it more portable:\r
------------------------\r
-* Some MSVC: std::sto* are defined without a namespace and collide\r
- with the ones in utility.h\r
+ \r
+Stuff to do before release:\r
+---------------------------\r
+\r
+Fixes to the current release:\r
+-----------------------------\r
+\r
+Stuff to do after release:\r
+---------------------------\r
\r
======================================================================\r
\r
#include "materials.h"\r
#include "game.h"\r
#include "keycode.h"\r
-#include "sha1.h"\r
-#include "base64.h"\r
\r
// This makes textures\r
ITextureSource *g_texturesource = NULL;\r
// This is located in defaultsettings.cpp\r
extern void set_default_settings();\r
\r
+// Global profiler\r
+Profiler g_profiler;\r
+\r
/*\r
Random stuff\r
*/\r
class TimeGetter\r
{\r
public:\r
- TimeGetter(IrrlichtDevice *device):\r
+ virtual u32 getTime() = 0;\r
+};\r
+\r
+// A precise irrlicht one\r
+class IrrlichtTimeGetter: public TimeGetter\r
+{\r
+public:\r
+ IrrlichtTimeGetter(IrrlichtDevice *device):\r
m_device(device)\r
{}\r
u32 getTime()\r
private:\r
IrrlichtDevice *m_device;\r
};\r
+// Not so precise one which works without irrlicht\r
+class SimpleTimeGetter: public TimeGetter\r
+{\r
+public:\r
+ u32 getTime()\r
+ {\r
+ return porting::getTimeMs();\r
+ }\r
+};\r
\r
// A pointer to a global instance of the time getter\r
+// TODO: why?\r
TimeGetter *g_timegetter = NULL;\r
\r
u32 getTimeMs()\r
\r
int main(int argc, char *argv[])\r
{\r
+ /*\r
+ Initialization\r
+ */\r
+\r
+ // Set locale. This is for forcing '.' as the decimal point.\r
+ std::locale::global(std::locale("C"));\r
+ // This enables printing all characters in bitmap font\r
+ setlocale(LC_CTYPE, "en_US");\r
+\r
/*\r
Parse command line\r
*/\r
disable_stderr = true;\r
#endif\r
\r
+ porting::signal_handler_init();\r
+ bool &kill = *porting::signal_handler_killstatus();\r
+ \r
+ // Initialize porting::path_data and porting::path_userdata\r
+ porting::initializePaths();\r
+\r
// Initialize debug streams\r
- debugstreams_init(disable_stderr, DEBUGFILE);\r
+#ifdef RUN_IN_PLACE\r
+ std::string debugfile = DEBUGFILE;\r
+#else\r
+ std::string debugfile = porting::path_userdata+"/"+DEBUGFILE;\r
+#endif\r
+ debugstreams_init(disable_stderr, debugfile.c_str());\r
// Initialize debug stacks\r
debug_stacks_init();\r
\r
DSTACK(__FUNCTION_NAME);\r
\r
- porting::signal_handler_init();\r
- bool &kill = *porting::signal_handler_killstatus();\r
- \r
- porting::initializePaths();\r
// Create user data directory\r
fs::CreateDir(porting::path_userdata);\r
\r
- // C-style stuff initialization\r
- initializeMaterialProperties();\r
+ // Init material properties table\r
+ //initializeMaterialProperties();\r
\r
// Debug handler\r
BEGIN_DEBUG_EXCEPTION_HANDLER\r
// Initialize default settings\r
set_default_settings();\r
\r
- // Set locale. This is for forcing '.' as the decimal point.\r
- std::locale::global(std::locale("C"));\r
- // This enables printing all characters in bitmap font\r
- setlocale(LC_CTYPE, "en_US");\r
-\r
// Initialize sockets\r
sockets_init();\r
atexit(sockets_cleanup);\r
\r
- /*\r
- Initialization\r
- */\r
-\r
/*\r
Read config file\r
*/\r
port = 30000;\r
\r
// Map directory\r
- std::string map_dir = porting::path_userdata+"/map";\r
+ std::string map_dir = porting::path_userdata+"/world";\r
if(cmd_args.exists("map-dir"))\r
map_dir = cmd_args.get("map-dir");\r
else if(g_settings.exists("map-dir"))\r
{\r
DSTACK("Dedicated server branch");\r
\r
+ // Create time getter\r
+ g_timegetter = new SimpleTimeGetter();\r
+ \r
// Create server\r
Server server(map_dir.c_str());\r
server.start(port);\r
device = device;\r
\r
// Create time getter\r
- g_timegetter = new TimeGetter(device);\r
+ g_timegetter = new IrrlichtTimeGetter(device);\r
\r
// Create game callback for menus\r
g_gamecallback = new MainGameCallback(device);\r
Preload some textures and stuff\r
*/\r
\r
- init_content_inventory_texture_paths();\r
init_mapnode(); // Second call with g_texturesource set\r
init_mineral();\r
\r
\r
playername = wide_to_narrow(menudata.name);\r
\r
- // Get an sha-1 hash of the player's name combined with\r
- // the password entered. That's what the server uses as\r
- // their password. (Exception : if the password field is\r
- // blank, we send a blank password - this is for backwards\r
- // compatibility with password-less players).\r
- if(menudata.password.length() > 0)\r
- {\r
- std::string slt=playername + wide_to_narrow(menudata.password);\r
- SHA1 *sha1 = new SHA1();\r
- sha1->addBytes(slt.c_str(), slt.length());\r
- unsigned char *digest = sha1->getDigest();\r
- password = base64_encode(digest, 20);\r
- free(digest);\r
- }\r
- else\r
- {\r
- password = "";\r
- }\r
+ password = translatePassword(playername, menudata.password);\r
\r
address = wide_to_narrow(menudata.address);\r
int newport = stoi(wide_to_narrow(menudata.port));\r
g_settings.set("creative_mode", itos(menudata.creative_mode));\r
g_settings.set("enable_damage", itos(menudata.enable_damage));\r
\r
- // Check for valid parameters, restart menu if invalid.\r
+ // NOTE: These are now checked server side; no need to do it\r
+ // here, so let's not do it here.\r
+ /*// Check for valid parameters, restart menu if invalid.\r
if(playername == "")\r
{\r
error_message = L"Name required.";\r
continue;\r
}\r
- \r
+ // Check that name has only valid chars\r
+ if(string_allowed(playername, PLAYERNAME_ALLOWED_CHARS)==false)\r
+ {\r
+ error_message = L"Characters allowed: "\r
+ +narrow_to_wide(PLAYERNAME_ALLOWED_CHARS);\r
+ continue;\r
+ }*/\r
+\r
// Save settings\r
g_settings.set("name", playername);\r
g_settings.set("address", address);\r