+ This was left to be done by the old system and it sends only the
nearest ones.
-Vim conversion regexpes for moving to extended content type storage:
-%s/\(\.\|->\)d \([!=]=\)/\1getContent() \2/g
-%s/content_features(\([^.]*\)\.d)/content_features(\1)/g
-%s/\(\.\|->\)d = \([^;]*\);/\1setContent(\2);/g
-%s/\(getNodeNoExNoEmerge([^)]*)\)\.d/\1.getContent()/g
-%s/\(getNodeNoExNoEmerge(.*)\)\.d/\1.getContent()/g
-%s/\.d;/.getContent();/g
-%s/\(content_liquid\|content_flowing_liquid\|make_liquid_flowing\|content_pointable\)(\([^.]*\).d)/\1(\2.getContent())/g
-Other things to note:
-- node.d = node.param0 (only in raw serialization; use getContent() otherwise)
-- node.param = node.param1
-- node.dir = node.param2
-- content_walkable(node.d) etc should be changed to
- content_features(node).walkable etc
-- Also check for lines that store the result of getContent to a 8-bit
- variable and fix them (result of getContent() must be stored in
- content_t, which is 16-bit)
-
NOTE: Seeds in 1260:6c77e7dbfd29:
5721858502589302589:
Spawns you on a small sand island with a surface dungeon
Map:
----
-TODO: Mineral and ground material properties
- - This way mineral ground toughness can be calculated with just
- some formula, as well as tool strengths. Sounds too.
- - 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.
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
SUGG: 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: Move content_features to mapnode_content_features.{h,cpp} or so
-
-TODO: Fix item use() stuff; dropping a stack of cooked rats and eating
- it gives 3 hearts and consumes all the rats.
-
Making it more portable:
------------------------
*/
#ifdef NDEBUG
- #ifdef _WIN32
+ /*#ifdef _WIN32
#pragma message ("Disabling unit tests")
#else
#warning "Disabling unit tests"
- #endif
+ #endif*/
// Disable unit tests
#define ENABLE_TESTS 0
#else
#endif
#ifdef _MSC_VER
+#ifndef SERVER // Dedicated server isn't linked with Irrlicht
#pragma comment(lib, "Irrlicht.lib")
- //#pragma comment(lib, "jthread.lib")
- #pragma comment(lib, "zlibwapi.lib")
- #pragma comment(lib, "Shell32.lib")
// This would get rid of the console window
//#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif
+ #pragma comment(lib, "zlibwapi.lib")
+ #pragma comment(lib, "Shell32.lib")
+#endif
#include "irrlicht.h" // createDevice
#include "filesys.h"
#include "config.h"
#include "guiMainMenu.h"
-#include "mineral.h"
-#include "materials.h"
#include "game.h"
#include "keycode.h"
#include "tile.h"
+#include "chat.h"
#include "defaultsettings.h"
#include "gettext.h"
#include "settings.h"
#include "profiler.h"
#include "log.h"
-
-// This makes textures
-ITextureSource *g_texturesource = NULL;
+#include "mods.h"
/*
Settings.
Profiler *g_profiler = &main_profiler;
/*
- Random stuff
+ Debug streams
*/
+// Connection
+std::ostream *dout_con_ptr = &dummyout;
+std::ostream *derr_con_ptr = &verbosestream;
+//std::ostream *dout_con_ptr = &infostream;
+//std::ostream *derr_con_ptr = &errorstream;
+
+// Server
+std::ostream *dout_server_ptr = &infostream;
+std::ostream *derr_server_ptr = &errorstream;
+
+// Client
+std::ostream *dout_client_ptr = &infostream;
+std::ostream *derr_client_ptr = &errorstream;
+
+#ifndef SERVER
/*
- mainmenumanager.h
+ Random stuff
*/
+/* mainmenumanager.h */
+
gui::IGUIEnvironment* guienv = NULL;
gui::IGUIStaticText *guiroot = NULL;
MainMenuManager g_menumgr;
// Passed to menus to allow disconnecting and exiting
MainGameCallback *g_gamecallback = NULL;
+#endif
/*
- Debug streams
+ gettime.h implementation
*/
-// Connection
-std::ostream *dout_con_ptr = &dummyout;
-std::ostream *derr_con_ptr = &verbosestream;
-//std::ostream *dout_con_ptr = &infostream;
-//std::ostream *derr_con_ptr = &errorstream;
-
-// Server
-std::ostream *dout_server_ptr = &infostream;
-std::ostream *derr_server_ptr = &errorstream;
+#ifdef SERVER
-// Client
-std::ostream *dout_client_ptr = &infostream;
-std::ostream *derr_client_ptr = &errorstream;
+u32 getTimeMs()
+{
+ /* Use imprecise system calls directly (from porting.h) */
+ return porting::getTimeMs();
+}
-/*
- gettime.h implementation
-*/
+#else
// A small helper class
class TimeGetter
return g_timegetter->getTime();
}
+#endif
+
+class StderrLogOutput: public ILogOutput
+{
+public:
+ /* line: Full line with timestamp, level and thread */
+ void printLog(const std::string &line)
+ {
+ std::cerr<<line<<std::endl;
+ }
+} main_stderr_log_out;
+
+class DstreamNoStderrLogOutput: public ILogOutput
+{
+public:
+ /* line: Full line with timestamp, level and thread */
+ void printLog(const std::string &line)
+ {
+ dstream_no_stderr<<line<<std::endl;
+ }
+} main_dstream_no_stderr_log_out;
+
+#ifndef SERVER
+
/*
Event handler for Irrlicht
bool rightreleased;
};
+void drawMenuBackground(video::IVideoDriver* driver)
+{
+ core::dimension2d<u32> screensize = driver->getScreenSize();
+
+ video::ITexture *bgtexture =
+ driver->getTexture(getTexturePath("menubg.png").c_str());
+ if(bgtexture)
+ {
+ s32 scaledsize = 128;
+
+ // The important difference between destsize and screensize is
+ // that destsize is rounded to whole scaled pixels.
+ // These formulas use component-wise multiplication and division of v2u32.
+ v2u32 texturesize = bgtexture->getSize();
+ v2u32 sourcesize = texturesize * screensize / scaledsize + v2u32(1,1);
+ v2u32 destsize = scaledsize * sourcesize / texturesize;
+
+ // Default texture wrapping mode in Irrlicht is ETC_REPEAT.
+ driver->draw2DImage(bgtexture,
+ core::rect<s32>(0, 0, destsize.X, destsize.Y),
+ core::rect<s32>(0, 0, sourcesize.X, sourcesize.Y),
+ NULL, NULL, true);
+ }
+
+ video::ITexture *logotexture =
+ driver->getTexture(getTexturePath("menulogo.png").c_str());
+ if(logotexture)
+ {
+ v2s32 logosize(logotexture->getOriginalSize().Width,
+ logotexture->getOriginalSize().Height);
+ logosize *= 4;
+
+ video::SColor bgcolor(255,50,50,50);
+ core::rect<s32> bgrect(0, screensize.Height-logosize.Y-20,
+ screensize.Width, screensize.Height);
+ driver->draw2DRectangle(bgcolor, bgrect, NULL);
+
+ core::rect<s32> rect(0,0,logosize.X,logosize.Y);
+ rect += v2s32(screensize.Width/2,screensize.Height-10-logosize.Y);
+ rect -= v2s32(logosize.X/2, 0);
+ driver->draw2DImage(logotexture, rect,
+ core::rect<s32>(core::position2d<s32>(0,0),
+ core::dimension2di(logotexture->getSize())),
+ NULL, NULL, true);
+ }
+}
+
+#endif
+
// These are defined global so that they're not optimized too much.
// Can't change them to volatile.
s16 temp16;
void SpeedTests()
{
{
- dstream<<"The following test should take around 20ms."<<std::endl;
+ infostream<<"The following test should take around 20ms."<<std::endl;
TimeTaker timer("Testing std::string speed");
const u32 jj = 10000;
for(u32 j=0; j<jj; j++)
}
}
- dstream<<"All of the following tests should take around 100ms each."
+ infostream<<"All of the following tests should take around 100ms each."
<<std::endl;
{
}
{
- dstream<<"Around 5000/ms should do well here."<<std::endl;
+ infostream<<"Around 5000/ms should do well here."<<std::endl;
TimeTaker timer("Testing mutex speed");
JMutex m;
u32 dtime = timer.stop();
u32 per_ms = n / dtime;
- dstream<<"Done. "<<dtime<<"ms, "
+ infostream<<"Done. "<<dtime<<"ms, "
<<per_ms<<"/ms"<<std::endl;
}
}
-void drawMenuBackground(video::IVideoDriver* driver)
-{
- core::dimension2d<u32> screensize = driver->getScreenSize();
-
- video::ITexture *bgtexture =
- driver->getTexture(getTexturePath("mud.png").c_str());
- if(bgtexture)
- {
- s32 texturesize = 128;
- s32 tiled_y = screensize.Height / texturesize + 1;
- s32 tiled_x = screensize.Width / texturesize + 1;
-
- for(s32 y=0; y<tiled_y; y++)
- for(s32 x=0; x<tiled_x; x++)
- {
- core::rect<s32> rect(0,0,texturesize,texturesize);
- rect += v2s32(x*texturesize, y*texturesize);
- driver->draw2DImage(bgtexture, rect,
- core::rect<s32>(core::position2d<s32>(0,0),
- core::dimension2di(bgtexture->getSize())),
- NULL, NULL, true);
- }
- }
-
- video::ITexture *logotexture =
- driver->getTexture(getTexturePath("menulogo.png").c_str());
- if(logotexture)
- {
- v2s32 logosize(logotexture->getOriginalSize().Width,
- logotexture->getOriginalSize().Height);
- logosize *= 4;
-
- video::SColor bgcolor(255,50,50,50);
- core::rect<s32> bgrect(0, screensize.Height-logosize.Y-20,
- screensize.Width, screensize.Height);
- driver->draw2DRectangle(bgcolor, bgrect, NULL);
-
- core::rect<s32> rect(0,0,logosize.X,logosize.Y);
- rect += v2s32(screensize.Width/2,screensize.Height-10-logosize.Y);
- rect -= v2s32(logosize.X/2, 0);
- driver->draw2DImage(logotexture, rect,
- core::rect<s32>(core::position2d<s32>(0,0),
- core::dimension2di(logotexture->getSize())),
- NULL, NULL, true);
- }
-}
-
-class StderrLogOutput: public ILogOutput
-{
-public:
- /* line: Full line with timestamp, level and thread */
- void printLog(const std::string &line)
- {
- std::cerr<<line<<std::endl;
- }
-} main_stderr_log_out;
-
-class DstreamNoStderrLogOutput: public ILogOutput
-{
-public:
- /* line: Full line with timestamp, level and thread */
- void printLog(const std::string &line)
- {
- dstream_no_stderr<<line<<std::endl;
- }
-} main_dstream_no_stderr_log_out;
-
int main(int argc, char *argv[])
{
/*
// List all allowed options
core::map<std::string, ValueSpec> allowed_options;
- allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG));
- allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG,
- "Run server directly"));
+ allowed_options.insert("help", ValueSpec(VALUETYPE_FLAG,
+ "Show allowed options"));
allowed_options.insert("config", ValueSpec(VALUETYPE_STRING,
"Load configuration from specified file"));
- allowed_options.insert("port", ValueSpec(VALUETYPE_STRING));
- allowed_options.insert("address", ValueSpec(VALUETYPE_STRING));
- allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG));
- allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG));
- allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG));
- allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING));
-#ifdef _WIN32
- allowed_options.insert("dstream-on-stderr", ValueSpec(VALUETYPE_FLAG));
+ allowed_options.insert("port", ValueSpec(VALUETYPE_STRING,
+ "Set network port (UDP) to use"));
+ allowed_options.insert("disable-unittests", ValueSpec(VALUETYPE_FLAG,
+ "Disable unit tests"));
+ allowed_options.insert("enable-unittests", ValueSpec(VALUETYPE_FLAG,
+ "Enable unit tests"));
+ allowed_options.insert("map-dir", ValueSpec(VALUETYPE_STRING,
+ "Map directory (where everything in the world is stored)"));
+ allowed_options.insert("info-on-stderr", ValueSpec(VALUETYPE_FLAG,
+ "Print debug information to console"));
+#ifndef SERVER
+ allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG,
+ "Run speed tests"));
+ allowed_options.insert("address", ValueSpec(VALUETYPE_STRING,
+ "Address to connect to"));
+ allowed_options.insert("random-input", ValueSpec(VALUETYPE_FLAG,
+ "Enable random user input, for testing"));
+ allowed_options.insert("server", ValueSpec(VALUETYPE_FLAG,
+ "Run server directly"));
#endif
- allowed_options.insert("speedtests", ValueSpec(VALUETYPE_FLAG));
- allowed_options.insert("info-on-stderr", ValueSpec(VALUETYPE_FLAG));
Settings cmd_args;
Low-level initialization
*/
- bool disable_stderr = false;
-#ifdef _WIN32
- if(cmd_args.getFlag("dstream-on-stderr") == false)
- disable_stderr = true;
-#endif
-
- if(cmd_args.getFlag("info-on-stderr"))
+ if(cmd_args.getFlag("info-on-stderr") || cmd_args.getFlag("speedtests"))
log_add_output(&main_stderr_log_out, LMT_INFO);
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);
+ fs::CreateDir(porting::path_user);
- init_gettext((porting::path_data+DIR_DELIM+".."+DIR_DELIM+"locale").c_str());
+ init_gettext((porting::path_share+DIR_DELIM+".."+DIR_DELIM+"locale").c_str());
// Initialize debug streams
#ifdef RUN_IN_PLACE
std::string debugfile = DEBUGFILE;
#else
- std::string debugfile = porting::path_userdata+DIR_DELIM+DEBUGFILE;
+ std::string debugfile = porting::path_user+DIR_DELIM+DEBUGFILE;
#endif
+ bool disable_stderr = false;
debugstreams_init(disable_stderr, debugfile.c_str());
// Initialize debug stacks
debug_stacks_init();
else
{
core::array<std::string> filenames;
- filenames.push_back(porting::path_userdata +
+ filenames.push_back(porting::path_user +
DIR_DELIM + "minetest.conf");
-#ifdef RUN_IN_PLACE
- filenames.push_back(porting::path_userdata +
+ // Legacy configuration file location
+ filenames.push_back(porting::path_user +
DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
+#ifdef RUN_IN_PLACE
+ // Try also from a lower level (to aid having the same configuration
+ // for many RUN_IN_PLACE installs)
+ filenames.push_back(porting::path_user +
+ DIR_DELIM + ".." + DIR_DELIM + ".." + DIR_DELIM + "minetest.conf");
#endif
for(u32 i=0; i<filenames.size(); i++)
srand(time(0));
mysrand(time(0));
- /*
- Pre-initialize some stuff with a dummy irrlicht wrapper.
-
- These are needed for unit tests at least.
- */
-
- // Initial call with g_texturesource not set.
- init_mapnode();
- // Must be called before g_texturesource is created
- // (for texture atlas making)
- init_mineral();
-
/*
Run unit tests
*/
run_tests();
}
- /*for(s16 y=-100; y<100; y++)
- for(s16 x=-100; x<100; x++)
- {
- std::cout<<noise2d_gradient((double)x/10,(double)y/10, 32415)<<std::endl;
- }
- return 0;*/
-
/*
Game parameters
*/
port = 30000;
// Map directory
- std::string map_dir = porting::path_userdata+DIR_DELIM+"world";
+ std::string map_dir = porting::path_user + DIR_DELIM + "server" + DIR_DELIM + "worlds" + DIR_DELIM + "world";
if(cmd_args.exists("map-dir"))
map_dir = cmd_args.get("map-dir");
else if(g_settings->exists("map-dir"))
map_dir = g_settings->get("map-dir");
-
- // Run dedicated server if asked to
- if(cmd_args.getFlag("server"))
+ else{
+ // No map-dir option was specified.
+ // Check if the world is found from the default directory, and if
+ // not, see if the legacy world directory exists.
+ std::string legacy_map_dir = porting::path_user+DIR_DELIM+".."+DIR_DELIM+"world";
+ if(!fs::PathExists(map_dir) && fs::PathExists(legacy_map_dir)){
+ errorstream<<"Warning: Using legacy world directory \""
+ <<legacy_map_dir<<"\""<<std::endl;
+ map_dir = legacy_map_dir;
+ }
+ }
+
+ // Run dedicated server if asked to or no other option
+#ifdef SERVER
+ bool run_dedicated_server = true;
+#else
+ bool run_dedicated_server = cmd_args.getFlag("server");
+#endif
+ if(run_dedicated_server)
{
DSTACK("Dedicated server branch");
- // Create time getter
+ // Create time getter if built with Irrlicht
+#ifndef SERVER
g_timegetter = new SimpleTimeGetter();
+#endif
// Create server
- Server server(map_dir.c_str(), configpath);
+ Server server(map_dir, configpath, "mesetint");
server.start(port);
+ // ASCII art for the win!
+ actionstream
+ <<" .__ __ __ "<<std::endl
+ <<" _____ |__| ____ _____/ |_ ____ _______/ |_ "<<std::endl
+ <<" / \\| |/ \\_/ __ \\ __\\/ __ \\ / ___/\\ __\\"<<std::endl
+ <<"| Y Y \\ | | \\ ___/| | \\ ___/ \\___ \\ | | "<<std::endl
+ <<"|__|_| /__|___| /\\___ >__| \\___ >____ > |__| "<<std::endl
+ <<" \\/ \\/ \\/ \\/ \\/ "<<std::endl;
+ actionstream<<"Listening at port "<<port<<"."<<std::endl;
+
// Run server
dedicated_server_loop(server, kill);
return 0;
}
+#ifndef SERVER // Exclude from dedicated server build
/*
More parameters
if (device == 0)
return 1; // could not create selected driver.
+ /*
+ Continue initialization
+ */
+
+ video::IVideoDriver* driver = device->getVideoDriver();
+
+ // Disable mipmaps (because some of them look ugly)
+ driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
+
+ /*
+ This changes the minimum allowed number of vertices in a VBO.
+ Default is 500.
+ */
+ //driver->setMinHardwareBufferVertexCount(50);
+
// Set the window caption
device->setWindowCaption(L"Minetest [Main Menu]");
// Create game callback for menus
g_gamecallback = new MainGameCallback(device);
- // Create texture source
- g_texturesource = new TextureSource(device);
-
/*
Speed tests (done after irrlicht is loaded to get timer)
*/
else
input = new RealInputHandler(device, &receiver);
- /*
- Continue initialization
- */
-
- //video::IVideoDriver* driver = device->getVideoDriver();
-
- /*
- This changes the minimum allowed number of vertices in a VBO.
- Default is 500.
- */
- //driver->setMinHardwareBufferVertexCount(50);
-
scene::ISceneManager* smgr = device->getSceneManager();
guienv = device->getGUIEnvironment();
skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255,0,0,0));
skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255,0,0,0));
- /*
- Preload some textures and stuff
- */
-
- init_mapnode(); // Second call with g_texturesource set
-
/*
GUI stuff
*/
+ ChatBackend chat_backend;
+
/*
If an error occurs, this is set to something and the
menu-game loop is restarted. It is then displayed before
menudata.fancy_trees = g_settings->getBool("new_style_leaves");
menudata.smooth_lighting = g_settings->getBool("smooth_lighting");
menudata.clouds_3d = g_settings->getBool("enable_3d_clouds");
+ menudata.opaque_water = g_settings->getBool("opaque_water");
menudata.creative_mode = g_settings->getBool("creative_mode");
menudata.enable_damage = g_settings->getBool("enable_damage");
g_settings->set("new_style_leaves", itos(menudata.fancy_trees));
g_settings->set("smooth_lighting", itos(menudata.smooth_lighting));
g_settings->set("enable_3d_clouds", itos(menudata.clouds_3d));
+ g_settings->set("opaque_water", itos(menudata.opaque_water));
g_settings->set("creative_mode", itos(menudata.creative_mode));
g_settings->set("enable_damage", itos(menudata.enable_damage));
}
// Break out of menu-game loop to shut down cleanly
- if(device->run() == false)
+ if(device->run() == false || kill == true)
break;
- // Initialize mapnode again to enable changed graphics settings
- init_mapnode();
-
/*
Run game
*/
address,
port,
error_message,
- configpath
+ configpath,
+ chat_backend
);
} //try
errorstream<<"Socket error (port already in use?)"<<std::endl;
error_message = L"Socket error (port already in use?)";
}
+ catch(ModError &e)
+ {
+ errorstream<<e.what()<<std::endl;
+ error_message = narrow_to_wide(e.what()) + L"\nCheck debug.txt for details.";
+ }
#ifdef NDEBUG
catch(std::exception &e)
{
In the end, delete the Irrlicht device.
*/
device->drop();
+
+#endif // !SERVER
END_DEBUG_EXCEPTION_HANDLER(errorstream)