summaryrefslogtreecommitdiff
path: root/src/client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.cpp')
-rw-r--r--src/client.cpp173
1 files changed, 131 insertions, 42 deletions
diff --git a/src/client.cpp b/src/client.cpp
index abe3500c..7dbbdc88 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -22,8 +22,10 @@
#include "client.h"
#include "main.h"
+#include "chatlog.h"
#include "configuration.h"
#include "emoteshortcut.h"
+#include "event.h"
#include "game.h"
#include "itemshortcut.h"
#include "keyboardconfig.h"
@@ -47,10 +49,8 @@
#include "gui/sdlinput.h"
#include "gui/serverdialog.h"
#include "gui/setup.h"
-#include "gui/theme.h"
#include "gui/unregisterdialog.h"
#include "gui/updatewindow.h"
-#include "gui/userpalette.h"
#include "gui/worldselectdialog.h"
#include "gui/widgets/button.h"
@@ -69,8 +69,11 @@
#include "resources/image.h"
#include "resources/itemdb.h"
#include "resources/monsterdb.h"
+#include "resources/specialdb.h"
#include "resources/npcdb.h"
#include "resources/resourcemanager.h"
+#include "resources/theme.h"
+#include "resources/userpalette.h"
#include "utils/gettext.h"
#include "utils/mkdir.h"
@@ -111,11 +114,14 @@ Configuration config; /**< XML file configuration reader */
Configuration branding; /**< XML branding information reader */
Configuration paths; /**< XML default paths information reader */
Logger *logger; /**< Log object */
+ChatLogger *chatLogger; /**< Chat log object */
KeyboardConfig keyboard;
UserPalette *userPalette;
Graphics *graphics;
+ItemDB *itemDb;
+
Sound sound;
void ErrorListener::action(const gcn::ActionEvent &)
@@ -166,6 +172,22 @@ int get_elapsed_time(int start_time)
* MILLISECONDS_IN_A_TICK;
}
+bool isDoubleClick(int selected)
+{
+ const Uint32 maximumDelay = 500;
+ static Uint32 lastTime = 0;
+ static int lastSelected = -1;
+
+ if (selected == lastSelected && lastTime + maximumDelay >= SDL_GetTicks())
+ {
+ lastTime = 0;
+ return true;
+ }
+
+ lastTime = SDL_GetTicks();
+ lastSelected = selected;
+ return false;
+}
// This anonymous namespace hides whatever is inside from other modules.
namespace {
@@ -188,8 +210,16 @@ public:
}
} loginListener;
-} // anonymous namespace
+class ServerChoiceListener : public gcn::ActionListener
+{
+public:
+ void action(const gcn::ActionEvent &)
+ {
+ Client::setState(STATE_CHOOSE_SERVER);
+ }
+} serverChoiceListener;
+} // anonymous namespace
Client *Client::mInstance = 0;
@@ -216,15 +246,22 @@ Client::Client(const Options &options):
if (!options.brandingPath.empty())
{
branding.init(options.brandingPath);
+ branding.setDefaultValues(getBrandingDefaults());
}
initRootDir();
initHomeDir();
initConfiguration();
+ chatLogger = new ChatLogger;
+ if (options.chatLogDir == "")
+ chatLogger->setLogDir(mLocalDataDir + std::string("/logs/"));
+ else
+ chatLogger->setLogDir(options.chatLogDir);
+
// Configure logger
logger->setLogFile(mLocalDataDir + std::string("/mana.log"));
- logger->setLogToStandardOut(config.getValue("logToStandardOut", 0));
+ logger->setLogToStandardOut(config.getBoolValue("logToStandardOut"));
// Log the mana version
logger->log("Mana %s", FULL_VERSION);
@@ -347,11 +384,11 @@ Client::Client(const Options &options):
graphics = new Graphics;
#endif
- const int width = (int) config.getValue("screenwidth", defaultScreenWidth);
- const int height = (int) config.getValue("screenheight", defaultScreenHeight);
+ const int width = config.getIntValue("screenwidth");
+ const int height = config.getIntValue("screenheight");
const int bpp = 0;
- const bool fullscreen = ((int) config.getValue("screen", 0) == 1);
- const bool hwaccel = ((int) config.getValue("hwaccel", 0) == 1);
+ const bool fullscreen = config.getBoolValue("screen");
+ const bool hwaccel = config.getBoolValue("hwaccel");
// Try to set the desired video mode
if (!graphics->setVideoMode(width, height, bpp, fullscreen, hwaccel))
@@ -374,13 +411,11 @@ Client::Client(const Options &options):
// Initialize sound engine
try
{
- if (config.getValue("sound", 0) == 1)
+ if (config.getBoolValue("sound"))
sound.init();
- sound.setSfxVolume((int) config.getValue("sfxVolume",
- defaultSfxVolume));
- sound.setMusicVolume((int) config.getValue("musicVolume",
- defaultMusicVolume));
+ sound.setSfxVolume(config.getIntValue("sfxVolume"));
+ sound.setMusicVolume(config.getIntValue("musicVolume"));
}
catch (const char *err)
{
@@ -405,25 +440,25 @@ Client::Client(const Options &options):
mCurrentServer.port = options.serverPort;
loginData.username = options.username;
loginData.password = options.password;
- loginData.remember = config.getValue("remember", 0);
+ loginData.remember = config.getBoolValue("remember");
loginData.registerLogin = false;
if (mCurrentServer.hostname.empty())
- {
- mCurrentServer.hostname = branding.getValue("defaultServer",
- "").c_str();
- }
+ mCurrentServer.hostname = branding.getValue("defaultServer","").c_str();
if (mCurrentServer.port == 0)
{
mCurrentServer.port = (short) branding.getValue("defaultPort",
- DEFAULT_PORT);
+ DEFAULT_PORT);
mCurrentServer.type = ServerInfo::parseType(
- branding.getValue("defaultServerType", "tmwathena"));
+ branding.getValue("defaultServerType", "tmwathena"));
}
+ if (chatLogger)
+ chatLogger->setServerName(mCurrentServer.hostname);
+
if (loginData.username.empty() && loginData.remember)
- loginData.username = config.getValue("username", "");
+ loginData.username = config.getStringValue("username");
if (mState != STATE_ERROR)
mState = STATE_CHOOSE_SERVER;
@@ -435,8 +470,16 @@ Client::Client(const Options &options):
// Initialize frame limiting
SDL_initFramerate(&mFpsManager);
- config.addListener("fpslimit", this);
- optionChanged("fpslimit");
+
+ listen(CHANNEL_CONFIG);
+
+ //TODO: fix having to fake a option changed event
+ Mana::Event fakeevent(EVENT_CONFIGOPTIONCHANGED);
+ fakeevent.setString("option", "fpslimit");
+ event(CHANNEL_CONFIG, fakeevent);
+
+ // Initialize PlayerInfo
+ PlayerInfo::init();
}
Client::~Client()
@@ -447,7 +490,7 @@ Client::~Client()
// Unload XML databases
ColorDB::unload();
EmoteDB::unload();
- ItemDB::unload();
+ delete itemDb;
MonsterDB::unload();
NPCDB::unload();
StatusEffect::unload();
@@ -577,10 +620,8 @@ int Client::exec()
- 3, 3);
top->add(mSetupButton);
- int screenWidth = (int) config.getValue("screenwidth",
- defaultScreenWidth);
- int screenHeight = (int) config.getValue("screenheight",
- defaultScreenHeight);
+ int screenWidth = config.getIntValue("screenwidth");
+ int screenHeight = config.getIntValue("screenheight");
mDesktop->setSize(screenWidth, screenHeight);
}
@@ -592,9 +633,12 @@ int Client::exec()
if (mState != mOldState)
{
- Net::GeneralHandler *generalHandler = Net::getGeneralHandler();
- if (generalHandler)
- generalHandler->stateChanged(mOldState, mState);
+ {
+ Mana::Event event(EVENT_STATECHANGE);
+ event.setInt("oldState", mOldState);
+ event.setInt("newState", mState);
+ event.trigger(CHANNEL_CLIENT);
+ }
if (mOldState == STATE_GAME)
{
@@ -751,17 +795,48 @@ int Client::exec()
// Read default paths file 'data/paths.xml'
paths.init("paths.xml", true);
+ paths.setDefaultValues(getPathsDefaults());
+
+ Mana::Event::trigger(CHANNEL_CLIENT, EVENT_DBSLOADING);
// Load XML databases
ColorDB::load();
- ItemDB::load();
+ switch (Net::getNetworkType())
+ {
+ case ServerInfo::TMWATHENA:
+ itemDb = new TmwAthena::TaItemDB;
+ break;
+ case ServerInfo::MANASERV:
+ itemDb = new ManaServ::ManaServItemDB;
+ break;
+ default:
+ // Nothing
+ itemDb = 0;
+ break;
+ }
+ if (!itemDb || !itemDb->isLoaded())
+ {
+ // Warn and return to login screen
+ errorMessage =
+ _("This server is missing needed world data. "
+ "Please contact the administrator(s).");
+ mCurrentDialog = new OkDialog(
+ _("ItemDB: Error while loading " ITEMS_DB_FILE "!"),
+ errorMessage);
+ mCurrentDialog->addActionListener(&serverChoiceListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
+ break;
+ }
Being::load(); // Hairstyles
MonsterDB::load();
+ SpecialDB::load();
NPCDB::load();
EmoteDB::load();
StatusEffect::load();
Units::loadUnits();
+ ActorSprite::load();
+
mDesktop->reloadWallpaper();
mState = STATE_GET_CHARACTERS;
@@ -787,7 +862,7 @@ int Client::exec()
mOptions.character, CharSelectDialog::Choose))
{
((CharSelectDialog*) mCurrentDialog)->selectByName(
- config.getValue("lastCharacter", ""),
+ config.getStringValue("lastCharacter"),
mOptions.chooseDefault ?
CharSelectDialog::Choose :
CharSelectDialog::Focus);
@@ -997,12 +1072,18 @@ int Client::exec()
return 0;
}
-void Client::optionChanged(const std::string &name)
+void Client::event(Channels channel, const Mana::Event &event)
{
- const int fpsLimit = (int) config.getValue("fpslimit", 60);
- mLimitFps = fpsLimit > 0;
- if (mLimitFps)
- SDL_setFramerate(&mFpsManager, fpsLimit);
+ if (channel == CHANNEL_CONFIG &&
+ event.getName() == EVENT_CONFIGOPTIONCHANGED &&
+ event.getString("option") == "fpslimit")
+ {
+ const int fpsLimit = config.getIntValue("fpslimit");
+ mLimitFps = fpsLimit > 0;
+ if (mLimitFps)
+ SDL_setFramerate(&mFpsManager, fpsLimit);
+ }
+
}
void Client::action(const gcn::ActionEvent &event)
@@ -1086,6 +1167,9 @@ void Client::initHomeDir()
mLocalDataDir = std::string(PHYSFS_getUserDir()) +
"/Library/Application Support/" +
branding.getValue("appName", "Mana");
+#elif defined __HAIKU__
+ mLocalDataDir = std::string(PHYSFS_getUserDir()) +
+ "/config/data/Mana";
#elif defined WIN32
mLocalDataDir = getSpecialFolderLocation(CSIDL_LOCAL_APPDATA);
if (mLocalDataDir.empty())
@@ -1110,6 +1194,10 @@ void Client::initHomeDir()
const std::string app = branding.getValue("appShort", "manasource");
#ifdef __APPLE__
mConfigDir = mLocalDataDir + "/" + app;
+#elif defined __HAIKU__
+ mConfigDir = std::string(PHYSFS_getUserDir()) +
+ "/config/settings/Mana" +
+ branding.getValue("appName", "manasource");
#elif defined WIN32
mConfigDir = getSpecialFolderLocation(CSIDL_APPDATA);
if (mConfigDir.empty())
@@ -1204,6 +1292,7 @@ void Client::initConfiguration()
{
fclose(configFile);
config.init(configPath);
+ config.setDefaultValues(getConfigDefaults());
}
}
@@ -1218,7 +1307,7 @@ void Client::initUpdatesDir()
// If updatesHost is currently empty, fill it from config file
if (mUpdateHost.empty())
{
- mUpdateHost = config.getValue("updatehost", "");
+ mUpdateHost = config.getStringValue("updatehost");
}
// Don't go out of range int he next check
@@ -1226,7 +1315,7 @@ void Client::initUpdatesDir()
return;
// Remove any trailing slash at the end of the update host
- if (mUpdateHost.at(mUpdateHost.size() - 1) == '/')
+ if (!mUpdateHost.empty() && mUpdateHost.at(mUpdateHost.size() - 1) == '/')
mUpdateHost.resize(mUpdateHost.size() - 1);
// Parse out any "http://" or "ftp://", and set the updates directory
@@ -1234,7 +1323,7 @@ void Client::initUpdatesDir()
pos = mUpdateHost.find("://");
if (pos != mUpdateHost.npos)
{
- if (pos + 3 < mUpdateHost.length())
+ if (pos + 3 < mUpdateHost.length() && !mUpdateHost.empty())
{
updates << "updates/" << mUpdateHost.substr(pos + 3);
mUpdatesDir = updates.str();
@@ -1305,7 +1394,7 @@ void Client::initScreenshotDir()
mScreenshotDir = std::string(PHYSFS_getUserDir()) + "Desktop";
#endif
- if (config.getValue("useScreenshotDirectorySuffix", true))
+ if (config.getBoolValue("useScreenshotDirectorySuffix"))
{
std::string configScreenshotSuffix =
config.getValue("screenshotDirectorySuffix",