summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBertram <bertram@cegetel.net>2010-03-03 23:38:18 +0100
committerBertram <bertram@cegetel.net>2010-03-03 23:38:18 +0100
commit1e52781e7d425cffcc6a5319b4cb5bf5eebe2ea9 (patch)
tree596305e9bfd4ad8448efd477a43f86490b1974c5 /src
parent8cc31b582f372238ce6bd2c86888d312cf1fe5b2 (diff)
parentf5f7a7d5990d1133f714b6cd431aecf6a332fbd5 (diff)
downloadmana-1e52781e7d425cffcc6a5319b4cb5bf5eebe2ea9.tar.gz
mana-1e52781e7d425cffcc6a5319b4cb5bf5eebe2ea9.tar.bz2
mana-1e52781e7d425cffcc6a5319b4cb5bf5eebe2ea9.tar.xz
mana-1e52781e7d425cffcc6a5319b4cb5bf5eebe2ea9.zip
Merge branch 'master' of gitorious.org:mana/mana
Diffstat (limited to 'src')
-rw-r--r--src/being.h2
-rw-r--r--src/client.cpp427
-rw-r--r--src/client.h48
-rw-r--r--src/game.cpp49
-rw-r--r--src/gui/beingpopup.cpp21
-rw-r--r--src/gui/beingpopup.h8
-rw-r--r--src/gui/emotepopup.cpp8
-rw-r--r--src/gui/emotepopup.h3
-rw-r--r--src/gui/gui.cpp7
-rw-r--r--src/gui/gui.h3
-rw-r--r--src/gui/itempopup.cpp2
-rw-r--r--src/gui/itempopup.h3
-rw-r--r--src/gui/serverdialog.cpp284
-rw-r--r--src/gui/serverdialog.h16
-rw-r--r--src/gui/skilldialog.cpp32
-rw-r--r--src/gui/skin.cpp80
-rw-r--r--src/gui/skin.h19
-rw-r--r--src/gui/socialwindow.cpp10
-rw-r--r--src/gui/specialswindow.cpp3
-rw-r--r--src/gui/speechbubble.cpp3
-rw-r--r--src/gui/textdialog.h7
-rw-r--r--src/gui/viewport.cpp101
-rw-r--r--src/gui/viewport.h15
-rw-r--r--src/gui/widgets/avatarlistbox.cpp5
-rw-r--r--src/gui/widgets/button.cpp12
-rw-r--r--src/gui/widgets/checkbox.cpp12
-rw-r--r--src/gui/widgets/desktop.cpp12
-rw-r--r--src/gui/widgets/dropdown.cpp12
-rw-r--r--src/gui/widgets/emoteshortcutcontainer.cpp6
-rw-r--r--src/gui/widgets/itemcontainer.cpp6
-rw-r--r--src/gui/widgets/itemshortcutcontainer.cpp6
-rw-r--r--src/gui/widgets/playerbox.cpp6
-rw-r--r--src/gui/widgets/popup.cpp7
-rw-r--r--src/gui/widgets/popup.h8
-rw-r--r--src/gui/widgets/progressbar.cpp4
-rw-r--r--src/gui/widgets/progressindicator.cpp7
-rw-r--r--src/gui/widgets/radiobutton.cpp16
-rw-r--r--src/gui/widgets/resizegrip.cpp6
-rw-r--r--src/gui/widgets/resizegrip.h2
-rw-r--r--src/gui/widgets/scrollarea.cpp24
-rw-r--r--src/gui/widgets/slider.cpp6
-rw-r--r--src/gui/widgets/tab.cpp12
-rw-r--r--src/gui/widgets/textfield.cpp4
-rw-r--r--src/gui/widgets/window.cpp4
-rw-r--r--src/gui/widgets/window.h2
-rw-r--r--src/item.cpp6
-rw-r--r--src/keyboardconfig.cpp27
-rw-r--r--src/localplayer.cpp29
-rw-r--r--src/localplayer.h13
-rw-r--r--src/main.h29
-rw-r--r--src/net/download.cpp11
-rw-r--r--src/net/ea/generalhandler.cpp3
-rw-r--r--src/net/ea/generalhandler.h1
-rw-r--r--src/net/ea/messageout.cpp2
-rw-r--r--src/net/ea/network.cpp2
-rw-r--r--src/net/ea/network.h2
-rw-r--r--src/net/ea/npchandler.cpp2
-rw-r--r--src/net/guildhandler.h6
-rw-r--r--src/net/manaserv/guildhandler.h2
-rw-r--r--src/net/manaserv/messageout.cpp2
-rw-r--r--src/net/serverinfo.h13
-rw-r--r--src/npc.cpp2
-rw-r--r--src/npc.h2
-rw-r--r--src/resources/resourcemanager.cpp3
-rw-r--r--src/text.cpp4
-rw-r--r--src/utils/mkdir.cpp24
66 files changed, 886 insertions, 629 deletions
diff --git a/src/being.h b/src/being.h
index ff21825c..f1d98ba4 100644
--- a/src/being.h
+++ b/src/being.h
@@ -234,7 +234,7 @@ class Being : public Sprite, public ConfigListener
*/
virtual void setName(const std::string &name);
- const bool getShowName() const
+ bool getShowName() const
{ return mShowName; }
virtual void setShowName(bool doShowName);
diff --git a/src/client.cpp b/src/client.cpp
index cd40615b..dfa42034 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -192,13 +192,14 @@ public:
Client *Client::mInstance = 0;
Client::Client(const Options &options):
- options(options),
- currentDialog(0),
- quitDialog(0),
- desktop(0),
- setupButton(0),
- state(STATE_CHOOSE_SERVER),
- oldstate(STATE_START),
+ mOptions(options),
+ mCurrentDialog(0),
+ mQuitDialog(0),
+ mDesktop(0),
+ mSetupButton(0),
+ mState(STATE_CHOOSE_SERVER),
+ mOldState(STATE_START),
+ mIcon(0),
mLogicCounterId(0),
mSecondsCounterId(0),
mLimitFps(false)
@@ -214,18 +215,17 @@ Client::Client(const Options &options):
branding.init(options.brandingPath);
}
- initHomeDir(options);
+ initHomeDir();
+ initConfiguration();
// Configure logger
- logger->setLogFile(localDataDir + std::string("/mana.log"));
+ logger->setLogFile(mLocalDataDir + std::string("/mana.log"));
+ logger->setLogToStandardOut(config.getValue("logToStandardOut", 0));
// Log the mana version
logger->log("Mana %s", FULL_VERSION);
- initConfiguration(options);
- initScreenshotDir(options.screenshotDir);
-
- logger->setLogToStandardOut(config.getValue("logToStandardOut", 0));
+ initScreenshotDir();
// Initialize SDL
logger->log("Initializing SDL...");
@@ -243,19 +243,12 @@ Client::Client(const Options &options):
ResourceManager *resman = ResourceManager::getInstance();
- if (!resman->setWriteDir(localDataDir))
+ if (!resman->setWriteDir(mLocalDataDir))
{
logger->error(strprintf("%s couldn't be set as home directory! "
- "Exiting.", localDataDir.c_str()));
+ "Exiting.", mLocalDataDir.c_str()));
}
- // Add the local data directory to PhysicsFS search path
- resman->addToSearchPath(localDataDir, false);
-
- // Add the main data directories to our PhysicsFS search path
- if (!options.dataPath.empty())
- resman->addToSearchPath(options.dataPath, true);
- resman->addToSearchPath("data", true);
#if defined __APPLE__
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
@@ -267,10 +260,38 @@ Client::Client(const Options &options):
}
CFRelease(resourcesURL);
strncat(path, "/data", PATH_MAX - 1);
- resman->addToSearchPath(path, true);
+ resman->addToSearchPath(path, false);
+ mPackageDir = path;
+#else
+ resman->addToSearchPath(PKG_DATADIR "data", false);
+ mPackageDir = PKG_DATADIR "data";
+#endif
+
+ resman->addToSearchPath("data", false);
+
+ // Add branding/data to PhysFS search path
+ if (!options.brandingPath.empty())
+ {
+ std::string path = options.brandingPath;
+
+ // Strip blah.mana from the path
+#ifdef WIN32
+ int loc1 = path.find_last_of('/');
+ int loc2 = path.find_last_of('\\');
+ int loc = std::max(loc1, loc2);
#else
- resman->addToSearchPath(PKG_DATADIR "data", true);
+ int loc = path.find_last_of('/');
#endif
+ if (loc > 0)
+ resman->addToSearchPath(path.substr(0, loc + 1) + "data", false);
+ }
+
+ // Add the main data directories to our PhysicsFS search path
+ if (!options.dataPath.empty())
+ resman->addToSearchPath(options.dataPath, false);
+
+ // Add the local data directory to PhysicsFS search path
+ resman->addToSearchPath(mLocalDataDir, false);
#ifdef WIN32
static SDL_SysWMinfo pInfo;
@@ -281,17 +302,17 @@ Client::Client(const Options &options):
SetClassLong(pInfo.window, GCL_HICON, (LONG) icon);
}
#else
- icon = IMG_Load(resman->getPath(
+ mIcon = IMG_Load(resman->getPath(
branding.getValue("appIcon", "data/icons/mana.png")).c_str());
- if (icon)
+ if (mIcon)
{
- SDL_SetAlpha(icon, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
- SDL_WM_SetIcon(icon, NULL);
+ SDL_SetAlpha(mIcon, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
+ SDL_WM_SetIcon(mIcon, NULL);
}
#endif
#ifdef USE_OPENGL
- bool useOpenGL = !options.noOpenGL && (config.getValue("opengl", 0) == 1);
+ bool useOpenGL = !mOptions.noOpenGL && (config.getValue("opengl", 0) == 1);
// Setup image loading for the right image format
Image::setLoadAsOpenGL(useOpenGL);
@@ -319,10 +340,10 @@ Client::Client(const Options &options):
// Initialize for drawing
graphics->_beginDraw();
- // Initialize the item shortcuts.
- itemShortcut = new ItemShortcut;
+ SkinLoader::prepareThemePath();
- // Initialize the emote shortcuts.
+ // Initialize the item and emote shortcuts.
+ itemShortcut = new ItemShortcut;
emoteShortcut = new EmoteShortcut;
gui = new Gui(graphics);
@@ -340,7 +361,7 @@ Client::Client(const Options &options):
}
catch (const char *err)
{
- state = STATE_ERROR;
+ mState = STATE_ERROR;
errorMessage = err;
logger->log("Warning: %s", err);
}
@@ -357,28 +378,28 @@ Client::Client(const Options &options):
sound.playMusic(branding.getValue("loginMusic", "Magick - Real.ogg"));
// Initialize default server
- currentServer.hostname = options.serverName;
- currentServer.port = options.serverPort;
+ mCurrentServer.hostname = options.serverName;
+ mCurrentServer.port = options.serverPort;
loginData.username = options.username;
loginData.password = options.password;
loginData.remember = config.getValue("remember", 0);
loginData.registerLogin = false;
- if (currentServer.hostname.empty())
+ if (mCurrentServer.hostname.empty())
{
- currentServer.hostname = branding.getValue("defaultServer",
+ mCurrentServer.hostname = branding.getValue("defaultServer",
"server.themanaworld.org").c_str();
}
if (options.serverPort == 0)
{
- currentServer.port = (short) branding.getValue("defaultPort",
+ mCurrentServer.port = (short) branding.getValue("defaultPort",
DEFAULT_PORT);
}
if (loginData.username.empty() && loginData.remember)
loginData.username = config.getValue("username", "");
- if (state != STATE_ERROR)
- state = STATE_CHOOSE_SERVER;
+ if (mState != STATE_ERROR)
+ mState = STATE_CHOOSE_SERVER;
// Initialize logic and seconds counters
tick_time = 0;
@@ -400,8 +421,6 @@ Client::~Client()
delete itemShortcut;
delete emoteShortcut;
- config.write();
-
delete gui;
delete graphics;
@@ -421,10 +440,13 @@ Client::~Client()
ResourceManager::deleteInstance();
- SDL_FreeSurface(icon);
+ SDL_FreeSurface(mIcon);
logger->log("Quitting");
delete guiPalette;
+
+ config.write();
+
delete logger;
mInstance = 0;
@@ -437,7 +459,7 @@ int Client::exec()
Game *game = 0;
SDL_Event event;
- while (state != STATE_EXIT)
+ while (mState != STATE_EXIT)
{
bool handledEvents = false;
@@ -456,7 +478,7 @@ int Client::exec()
switch (event.type)
{
case SDL_QUIT:
- state = STATE_EXIT;
+ mState = STATE_EXIT;
break;
case SDL_KEYDOWN:
@@ -499,75 +521,75 @@ int Client::exec()
// TODO: Add connect timeouts
- if (state == STATE_CONNECT_GAME &&
+ if (mState == STATE_CONNECT_GAME &&
Net::getGameHandler()->isConnected())
{
Net::getLoginHandler()->disconnect();
}
- else if (state == STATE_CONNECT_SERVER && oldstate == STATE_CHOOSE_SERVER)
+ else if (mState == STATE_CONNECT_SERVER && mOldState == STATE_CHOOSE_SERVER)
{
- Net::connectToServer(currentServer);
+ Net::connectToServer(mCurrentServer);
}
- else if (state == STATE_CONNECT_SERVER &&
- oldstate != STATE_CHOOSE_SERVER &&
+ else if (mState == STATE_CONNECT_SERVER &&
+ mOldState != STATE_CHOOSE_SERVER &&
Net::getLoginHandler()->isConnected())
{
- state = STATE_LOGIN;
+ mState = STATE_LOGIN;
}
- else if (state == STATE_WORLD_SELECT && oldstate == STATE_UPDATE)
+ else if (mState == STATE_WORLD_SELECT && mOldState == STATE_UPDATE)
{
if (Net::getLoginHandler()->getWorlds().size() < 2)
{
- state = STATE_LOGIN;
+ mState = STATE_LOGIN;
}
}
- else if (oldstate == STATE_START ||
- (oldstate == STATE_GAME && state != STATE_GAME))
+ else if (mOldState == STATE_START ||
+ (mOldState == STATE_GAME && mState != STATE_GAME))
{
gcn::Container *top = static_cast<gcn::Container*>(gui->getTop());
- desktop = new Desktop;
- top->add(desktop);
- setupButton = new Button(_("Setup"), "Setup", this);
- setupButton->setPosition(top->getWidth() - setupButton->getWidth()
+ mDesktop = new Desktop;
+ top->add(mDesktop);
+ mSetupButton = new Button(_("Setup"), "Setup", this);
+ mSetupButton->setPosition(top->getWidth() - mSetupButton->getWidth()
- 3, 3);
- top->add(setupButton);
+ top->add(mSetupButton);
int screenWidth = (int) config.getValue("screenwidth",
defaultScreenWidth);
int screenHeight = (int) config.getValue("screenheight",
defaultScreenHeight);
- desktop->setSize(screenWidth, screenHeight);
+ mDesktop->setSize(screenWidth, screenHeight);
}
- if (state == STATE_SWITCH_LOGIN && oldstate == STATE_GAME)
+ if (mState == STATE_SWITCH_LOGIN && mOldState == STATE_GAME)
{
Net::getGameHandler()->disconnect();
}
- if (state != oldstate)
+ if (mState != mOldState)
{
- if (oldstate == STATE_GAME)
+ if (mOldState == STATE_GAME)
{
delete game;
game = 0;
}
- oldstate = state;
+ mOldState = mState;
// Get rid of the dialog of the previous state
- if (currentDialog)
+ if (mCurrentDialog)
{
- delete currentDialog;
- currentDialog = NULL;
+ delete mCurrentDialog;
+ mCurrentDialog = NULL;
}
// State has changed, while the quitDialog was active, it might
// not be correct anymore
- if (quitDialog)
- quitDialog->scheduleDelete();
+ if (mQuitDialog)
+ mQuitDialog->scheduleDelete();
- switch (state)
+ switch (mState)
{
case STATE_CHOOSE_SERVER:
logger->log("State: CHOOSE SERVER");
@@ -575,29 +597,29 @@ int Client::exec()
// Allow changing this using a server choice dialog
// We show the dialog box only if the command-line
// options weren't set.
- if (options.serverName.empty() && options.serverPort == 0)
+ if (mOptions.serverName.empty() && mOptions.serverPort == 0)
{
// Don't allow an alpha opacity
// lower than the default value
SkinLoader::instance()->setMinimumOpacity(0.8f);
- currentDialog = new ServerDialog(&currentServer,
- configDir);
+ mCurrentDialog = new ServerDialog(&mCurrentServer,
+ mConfigDir);
}
else
{
- state = STATE_CONNECT_SERVER;
+ mState = STATE_CONNECT_SERVER;
// Reset options so that cancelling or connect
// timeout will show the server dialog.
- options.serverName.clear();
- options.serverPort = 0;
+ mOptions.serverName.clear();
+ mOptions.serverPort = 0;
}
break;
case STATE_CONNECT_SERVER:
logger->log("State: CONNECT SERVER");
- currentDialog = new ConnectionDialog(
+ mCurrentDialog = new ConnectionDialog(
_("Connecting to server"), STATE_SWITCH_SERVER);
break;
@@ -607,24 +629,24 @@ int Client::exec()
// lower than the default value
SkinLoader::instance()->setMinimumOpacity(0.8f);
- if (options.username.empty()
- || options.password.empty())
+ if (mOptions.username.empty()
+ || mOptions.password.empty())
{
- currentDialog = new LoginDialog(&loginData);
+ mCurrentDialog = new LoginDialog(&loginData);
}
else
{
- state = STATE_LOGIN_ATTEMPT;
+ mState = STATE_LOGIN_ATTEMPT;
// Clear the password so that when login fails, the
// dialog will show up next time.
- options.password.clear();
+ mOptions.password.clear();
}
break;
case STATE_LOGIN_ATTEMPT:
logger->log("State: LOGIN ATTEMPT");
accountLogin(&loginData);
- currentDialog = new ConnectionDialog(
+ mCurrentDialog = new ConnectionDialog(
_("Logging in"), STATE_SWITCH_SERVER);
break;
@@ -636,19 +658,19 @@ int Client::exec()
if (worlds.size() == 0)
{
// Trust that the netcode knows what it's doing
- state = STATE_UPDATE;
+ mState = STATE_UPDATE;
}
else if (worlds.size() == 1)
{
Net::getLoginHandler()->chooseServer(0);
- state = STATE_UPDATE;
+ mState = STATE_UPDATE;
}
else
{
- currentDialog = new WorldSelectDialog(worlds);
- if (options.chooseDefault)
+ mCurrentDialog = new WorldSelectDialog(worlds);
+ if (mOptions.chooseDefault)
{
- ((WorldSelectDialog*) currentDialog)->action(
+ ((WorldSelectDialog*) mCurrentDialog)->action(
gcn::ActionEvent(NULL, "ok"));
}
}
@@ -657,27 +679,27 @@ int Client::exec()
case STATE_WORLD_SELECT_ATTEMPT:
logger->log("State: WORLD SELECT ATTEMPT");
- currentDialog = new ConnectionDialog(
+ mCurrentDialog = new ConnectionDialog(
_("Entering game world"), STATE_WORLD_SELECT);
break;
case STATE_UPDATE:
// Determine which source to use for the update host
- if (!options.updateHost.empty())
- updateHost = options.updateHost;
+ if (!mOptions.updateHost.empty())
+ mUpdateHost = mOptions.updateHost;
else
- updateHost = loginData.updateHost;
+ mUpdateHost = loginData.updateHost;
initUpdatesDir();
- if (options.skipUpdate)
+ if (mOptions.skipUpdate)
{
- state = STATE_LOAD_DATA;
+ mState = STATE_LOAD_DATA;
}
else
{
logger->log("State: UPDATE");
- currentDialog = new UpdaterWindow(updateHost,
- localDataDir + "/" + updatesDir,options.dataPath.empty());
+ mCurrentDialog = new UpdaterWindow(mUpdateHost,
+ mLocalDataDir + "/" + mUpdatesDir,mOptions.dataPath.empty());
}
break;
@@ -686,7 +708,7 @@ int Client::exec()
// If another data path has been set,
// we don't load any other files...
- if (options.dataPath.empty())
+ if (mOptions.dataPath.empty())
{
// Add customdata directory
ResourceManager::getInstance()->searchAndAddArchives(
@@ -705,15 +727,15 @@ int Client::exec()
StatusEffect::load();
Units::loadUnits();
- desktop->reloadWallpaper();
+ mDesktop->reloadWallpaper();
- state = STATE_GET_CHARACTERS;
+ mState = STATE_GET_CHARACTERS;
break;
case STATE_GET_CHARACTERS:
logger->log("State: GET CHARACTERS");
Net::getCharHandler()->requestCharacters();
- currentDialog = new ConnectionDialog(
+ mCurrentDialog = new ConnectionDialog(
_("Requesting characters"),
STATE_SWITCH_SERVER);
break;
@@ -724,14 +746,14 @@ int Client::exec()
// lower than the default value
SkinLoader::instance()->setMinimumOpacity(0.8f);
- currentDialog = new CharSelectDialog(&loginData);
+ mCurrentDialog = new CharSelectDialog(&loginData);
- if (!((CharSelectDialog*) currentDialog)->selectByName(
- options.character, CharSelectDialog::Choose))
+ if (!((CharSelectDialog*) mCurrentDialog)->selectByName(
+ mOptions.character, CharSelectDialog::Choose))
{
- ((CharSelectDialog*) currentDialog)->selectByName(
+ ((CharSelectDialog*) mCurrentDialog)->selectByName(
config.getValue("lastCharacter", ""),
- options.chooseDefault ?
+ mOptions.chooseDefault ?
CharSelectDialog::Choose :
CharSelectDialog::Focus);
}
@@ -742,7 +764,7 @@ int Client::exec()
logger->log("State: CONNECT GAME");
Net::getGameHandler()->connect();
- currentDialog = new ConnectionDialog(
+ mCurrentDialog = new ConnectionDialog(
_("Connecting to the game server"),
STATE_SWITCH_CHARACTER);
break;
@@ -761,12 +783,12 @@ int Client::exec()
// Allow any alpha opacity
SkinLoader::instance()->setMinimumOpacity(-1.0f);
- delete setupButton;
- delete desktop;
- setupButton = NULL;
- desktop = NULL;
+ delete mSetupButton;
+ delete mDesktop;
+ mSetupButton = NULL;
+ mDesktop = NULL;
- currentDialog = NULL;
+ mCurrentDialog = NULL;
logger->log("State: GAME");
game = new Game;
@@ -774,28 +796,28 @@ int Client::exec()
case STATE_LOGIN_ERROR:
logger->log("State: LOGIN ERROR");
- currentDialog = new OkDialog(_("Error"), errorMessage);
- currentDialog->addActionListener(&loginListener);
- currentDialog = NULL; // OkDialog deletes itself
+ mCurrentDialog = new OkDialog(_("Error"), errorMessage);
+ mCurrentDialog->addActionListener(&loginListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
break;
case STATE_ACCOUNTCHANGE_ERROR:
logger->log("State: ACCOUNT CHANGE ERROR");
- currentDialog = new OkDialog(_("Error"), errorMessage);
- currentDialog->addActionListener(&accountListener);
- currentDialog = NULL; // OkDialog deletes itself
+ mCurrentDialog = new OkDialog(_("Error"), errorMessage);
+ mCurrentDialog->addActionListener(&accountListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
break;
case STATE_REGISTER_PREP:
logger->log("State: REGISTER_PREP");
Net::getLoginHandler()->getRegistrationDetails();
- currentDialog = new ConnectionDialog(
+ mCurrentDialog = new ConnectionDialog(
_("Requesting registration details"), STATE_LOGIN);
break;
case STATE_REGISTER:
logger->log("State: REGISTER");
- currentDialog = new RegisterDialog(&loginData);
+ mCurrentDialog = new RegisterDialog(&loginData);
break;
case STATE_REGISTER_ATTEMPT:
@@ -805,7 +827,7 @@ int Client::exec()
case STATE_CHANGEPASSWORD:
logger->log("State: CHANGE PASSWORD");
- currentDialog = new ChangePasswordDialog(&loginData);
+ mCurrentDialog = new ChangePasswordDialog(&loginData);
break;
case STATE_CHANGEPASSWORD_ATTEMPT:
@@ -817,17 +839,17 @@ int Client::exec()
case STATE_CHANGEPASSWORD_SUCCESS:
logger->log("State: CHANGE PASSWORD SUCCESS");
- currentDialog = new OkDialog(_("Password Change"),
+ mCurrentDialog = new OkDialog(_("Password Change"),
_("Password changed successfully!"));
- currentDialog->addActionListener(&accountListener);
- currentDialog = NULL; // OkDialog deletes itself
+ mCurrentDialog->addActionListener(&accountListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
loginData.password = loginData.newPassword;
loginData.newPassword = "";
break;
case STATE_CHANGEEMAIL:
logger->log("State: CHANGE EMAIL");
- currentDialog = new ChangeEmailDialog(&loginData);
+ mCurrentDialog = new ChangeEmailDialog(&loginData);
break;
case STATE_CHANGEEMAIL_ATTEMPT:
@@ -837,15 +859,15 @@ int Client::exec()
case STATE_CHANGEEMAIL_SUCCESS:
logger->log("State: CHANGE EMAIL SUCCESS");
- currentDialog = new OkDialog(_("Email Change"),
+ mCurrentDialog = new OkDialog(_("Email Change"),
_("Email changed successfully!"));
- currentDialog->addActionListener(&accountListener);
- currentDialog = NULL; // OkDialog deletes itself
+ mCurrentDialog->addActionListener(&accountListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
break;
case STATE_UNREGISTER:
logger->log("State: UNREGISTER");
- currentDialog = new UnRegisterDialog(&loginData);
+ mCurrentDialog = new UnRegisterDialog(&loginData);
break;
case STATE_UNREGISTER_ATTEMPT:
@@ -858,12 +880,12 @@ int Client::exec()
logger->log("State: UNREGISTER SUCCESS");
Net::getLoginHandler()->disconnect();
- currentDialog = new OkDialog(_("Unregister Successful"),
+ mCurrentDialog = new OkDialog(_("Unregister Successful"),
_("Farewell, come back any time..."));
loginData.clear();
//The errorlistener sets the state to STATE_CHOOSE_SERVER
- currentDialog->addActionListener(&errorListener);
- currentDialog = NULL; // OkDialog deletes itself
+ mCurrentDialog->addActionListener(&errorListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
break;
case STATE_SWITCH_SERVER:
@@ -872,7 +894,7 @@ int Client::exec()
Net::getLoginHandler()->disconnect();
Net::getGameHandler()->disconnect();
- state = STATE_CHOOSE_SERVER;
+ mState = STATE_CHOOSE_SERVER;
break;
case STATE_SWITCH_LOGIN:
@@ -880,7 +902,7 @@ int Client::exec()
Net::getLoginHandler()->logout();
- state = STATE_LOGIN;
+ mState = STATE_LOGIN;
break;
case STATE_SWITCH_CHARACTER:
@@ -910,19 +932,19 @@ int Client::exec()
logger->log("State: FORCE QUIT");
if (Net::getGeneralHandler())
Net::getGeneralHandler()->unload();
- state = STATE_EXIT;
+ mState = STATE_EXIT;
break;
case STATE_ERROR:
logger->log("State: ERROR");
- currentDialog = new OkDialog(_("Error"), errorMessage);
- currentDialog->addActionListener(&errorListener);
- currentDialog = NULL; // OkDialog deletes itself
+ mCurrentDialog = new OkDialog(_("Error"), errorMessage);
+ mCurrentDialog->addActionListener(&errorListener);
+ mCurrentDialog = NULL; // OkDialog deletes itself
Net::getGameHandler()->disconnect();
break;
default:
- state = STATE_FORCE_QUIT;
+ mState = STATE_FORCE_QUIT;
break;
}
}
@@ -958,69 +980,64 @@ void Client::action(const gcn::ActionEvent &event)
* Initializes the home directory. On UNIX and FreeBSD, ~/.mana is used. On
* Windows and other systems we use the current working directory.
*/
-void Client::initHomeDir(const Options &options)
+void Client::initHomeDir()
{
- localDataDir = options.localDataDir;
+ mLocalDataDir = mOptions.localDataDir;
- if (localDataDir.empty())
+ if (mLocalDataDir.empty())
{
#ifdef __APPLE__
// Use Application Directory instead of .mana
- localDataDir = std::string(PHYSFS_getUserDir()) +
+ mLocalDataDir = std::string(PHYSFS_getUserDir()) +
"/Library/Application Support/" +
branding.getValue("appName", "Mana");
#elif defined WIN32
- localDataDir = getSpecialFolderLocation(CSIDL_LOCAL_APPDATA);
- if (localDataDir.empty())
- localDataDir = std::string(PHYSFS_getUserDir());
- localDataDir += "/Mana";
+ mLocalDataDir = getSpecialFolderLocation(CSIDL_LOCAL_APPDATA);
+ if (mLocalDataDir.empty())
+ mLocalDataDir = std::string(PHYSFS_getUserDir());
+ mLocalDataDir += "/Mana";
#else
- localDataDir = std::string(PHYSFS_getUserDir()) +
+ mLocalDataDir = std::string(PHYSFS_getUserDir()) +
"/.local/share/mana";
#endif
}
- if (mkdir_r(localDataDir.c_str()))
+ if (mkdir_r(mLocalDataDir.c_str()))
{
logger->error(strprintf(_("%s doesn't exist and can't be created! "
- "Exiting."), localDataDir.c_str()));
+ "Exiting."), mLocalDataDir.c_str()));
}
- configDir = options.configDir;
+ mConfigDir = mOptions.configDir;
- if (configDir.empty()){
+ if (mConfigDir.empty()){
#ifdef __APPLE__
- configDir = localDataDir;
+ mConfigDir = mLocalDataDir;
#elif defined WIN32
- configDir = getSpecialFolderLocation(CSIDL_APPDATA);
- if (configDir.empty())
- configDir = localDataDir;
+ mConfigDir = getSpecialFolderLocation(CSIDL_APPDATA);
+ if (mConfigDir.empty())
+ mConfigDir = mLocalDataDir;
else
- configDir += "/mana/" + branding.getValue("appName", "Mana");
+ mConfigDir += "/mana/" + branding.getValue("appName", "Mana");
#else
- configDir = std::string(PHYSFS_getUserDir()) +
+ mConfigDir = std::string(PHYSFS_getUserDir()) +
"/.config/mana/" + branding.getValue("appShort", "mana");
#endif
}
- if (mkdir_r(configDir.c_str()))
+ if (mkdir_r(mConfigDir.c_str()))
{
logger->error(strprintf(_("%s doesn't exist and can't be created! "
- "Exiting."), configDir.c_str()));
+ "Exiting."), mConfigDir.c_str()));
}
}
/**
* Initialize configuration.
*/
-void Client::initConfiguration(const Options &options)
+void Client::initConfiguration()
{
// Fill configuration with defaults
- logger->log("Initializing configuration...");
- std::string defaultHost = branding.getValue("defaultServer",
- "server.themanaworld.org");
- int defaultPort = (int) branding.getValue("defaultPort", DEFAULT_PORT);
- config.setValue("port", defaultPort);
config.setValue("hwaccel", false);
#if (defined __APPLE__ || defined WIN32) && defined USE_OPENGL
config.setValue("opengl", true);
@@ -1046,17 +1063,17 @@ void Client::initConfiguration(const Options &options)
FILE *configFile = 0;
std::string configPath;
- configPath = configDir + "/config.xml";
+ configPath = mConfigDir + "/config.xml";
configFile = fopen(configPath.c_str(), "r");
// If we can't read it, it doesn't exist !
- if (configFile == NULL)
+ if (!configFile)
{
// We reopen the file in write mode and we create it
configFile = fopen(configPath.c_str(), "wt");
}
- if (configFile == NULL)
+ if (!configFile)
{
logger->log("Can't create %s. Using defaults.", configPath.c_str());
}
@@ -1076,50 +1093,50 @@ void Client::initUpdatesDir()
std::stringstream updates;
// If updatesHost is currently empty, fill it from config file
- if (updateHost.empty())
+ if (mUpdateHost.empty())
{
- updateHost =
+ mUpdateHost =
config.getValue("updatehost", "http://updates.themanaworld.org/");
}
// Remove any trailing slash at the end of the update host
- if (updateHost.at(updateHost.size() - 1) == '/')
- updateHost.resize(updateHost.size() - 1);
+ if (mUpdateHost.at(mUpdateHost.size() - 1) == '/')
+ mUpdateHost.resize(mUpdateHost.size() - 1);
// Parse out any "http://" or "ftp://", and set the updates directory
size_t pos;
- pos = updateHost.find("://");
- if (pos != updateHost.npos)
+ pos = mUpdateHost.find("://");
+ if (pos != mUpdateHost.npos)
{
- if (pos + 3 < updateHost.length())
+ if (pos + 3 < mUpdateHost.length())
{
- updates << "updates/" << updateHost.substr(pos + 3);
- updatesDir = updates.str();
+ updates << "updates/" << mUpdateHost.substr(pos + 3);
+ mUpdatesDir = updates.str();
}
else
{
- logger->log("Error: Invalid update host: %s", updateHost.c_str());
+ logger->log("Error: Invalid update host: %s", mUpdateHost.c_str());
errorMessage = strprintf(_("Invalid update host: %s"),
- updateHost.c_str());
- state = STATE_ERROR;
+ mUpdateHost.c_str());
+ mState = STATE_ERROR;
}
}
else
{
logger->log("Warning: no protocol was specified for the update host");
- updates << "updates/" << updateHost;
- updatesDir = updates.str();
+ updates << "updates/" << mUpdateHost;
+ mUpdatesDir = updates.str();
}
ResourceManager *resman = ResourceManager::getInstance();
// Verify that the updates directory exists. Create if necessary.
- if (!resman->isDirectory("/" + updatesDir))
+ if (!resman->isDirectory("/" + mUpdatesDir))
{
- if (!resman->mkdir("/" + updatesDir))
+ if (!resman->mkdir("/" + mUpdatesDir))
{
#if defined WIN32
- std::string newDir = localDataDir + "\\" + updatesDir;
+ std::string newDir = mLocalDataDir + "\\" + mUpdatesDir;
std::string::size_type loc = newDir.find("/", 0);
while (loc != std::string::npos)
@@ -1134,43 +1151,39 @@ void Client::initUpdatesDir()
logger->log("Error: %s can't be made, but doesn't exist!",
newDir.c_str());
errorMessage = _("Error creating updates directory!");
- state = STATE_ERROR;
+ mState = STATE_ERROR;
}
#else
logger->log("Error: %s/%s can't be made, but doesn't exist!",
- localDataDir.c_str(), updatesDir.c_str());
+ mLocalDataDir.c_str(), mUpdatesDir.c_str());
errorMessage = _("Error creating updates directory!");
- state = STATE_ERROR;
+ mState = STATE_ERROR;
#endif
}
}
}
-void Client::initScreenshotDir(const std::string &dir)
+void Client::initScreenshotDir()
{
- if (!dir.empty())
- screenshotDir = dir;
+ if (!mOptions.screenshotDir.empty())
+ mScreenshotDir = mOptions.screenshotDir;
else
{
std::string configScreenshotDir =
config.getValue("screenshotDirectory", "");
if (!configScreenshotDir.empty())
- screenshotDir = configScreenshotDir;
+ mScreenshotDir = configScreenshotDir;
else
{
#ifdef WIN32
- screenshotDir = getSpecialFolderLocation(CSIDL_MYPICTURES);
- if (screenshotDir.empty())
- screenshotDir = getSpecialFolderLocation(CSIDL_DESKTOP);
+ mScreenshotDir = getSpecialFolderLocation(CSIDL_MYPICTURES);
+ if (mScreenshotDir.empty())
+ mScreenshotDir = getSpecialFolderLocation(CSIDL_DESKTOP);
#else
- screenshotDir = std::string(PHYSFS_getUserDir()) + "Desktop";
- // If ~/Desktop does not exist, we save screenshots in the user's home.
- struct stat statbuf;
- if (stat(screenshotDir.c_str(), &statbuf))
- screenshotDir = std::string(PHYSFS_getUserDir());
+ mScreenshotDir = std::string(PHYSFS_getUserDir()) + "Desktop";
#endif
}
- config.setValue("screenshotDirectory", screenshotDir);
+ config.setValue("screenshotDirectory", mScreenshotDir);
if (config.getValue("useScreenshotDirectorySuffix", true))
{
@@ -1180,20 +1193,12 @@ void Client::initScreenshotDir(const std::string &dir)
if (!configScreenshotSuffix.empty())
{
- screenshotDir += "/" + configScreenshotSuffix;
+ mScreenshotDir += "/" + configScreenshotSuffix;
config.setValue("screenshotDirectorySuffix",
configScreenshotSuffix);
}
}
}
-
- if (mkdir_r(screenshotDir.c_str()))
- {
- logger->log("Directory %s doesn't exist and can't be created! "
- "Setting screenshot directory to home.",
- screenshotDir.c_str());
- screenshotDir = std::string(PHYSFS_getUserDir());
- }
}
void Client::accountLogin(LoginData *loginData)
diff --git a/src/client.h b/src/client.h
index f0fdd508..233ee646 100644
--- a/src/client.h
+++ b/src/client.h
@@ -160,52 +160,56 @@ public:
int exec();
static void setState(State state)
- { instance()->state = state; }
+ { instance()->mState = state; }
static State getState()
- { return instance()->state; }
+ { return instance()->mState; }
+
+ static const std::string &getPackageDirectory()
+ { return instance()->mPackageDir; }
static const std::string &getConfigDirectory()
- { return instance()->configDir; }
+ { return instance()->mConfigDir; }
static const std::string &getLocalDataDirectory()
- { return instance()->localDataDir; }
+ { return instance()->mLocalDataDir; }
static const std::string &getScreenshotDirectory()
- { return instance()->screenshotDir; }
+ { return instance()->mScreenshotDir; }
void optionChanged(const std::string &name);
void action(const gcn::ActionEvent &event);
private:
- void initHomeDir(const Options &options);
- void initConfiguration(const Options &options);
+ void initHomeDir();
+ void initConfiguration();
void initUpdatesDir();
- void initScreenshotDir(const std::string &dir);
+ void initScreenshotDir();
void accountLogin(LoginData *loginData);
static Client *mInstance;
- Options options;
+ Options mOptions;
- std::string configDir;
- std::string localDataDir;
- std::string updateHost;
- std::string updatesDir;
- std::string screenshotDir;
+ std::string mPackageDir;
+ std::string mConfigDir;
+ std::string mLocalDataDir;
+ std::string mUpdateHost;
+ std::string mUpdatesDir;
+ std::string mScreenshotDir;
- ServerInfo currentServer;
+ ServerInfo mCurrentServer;
- Window *currentDialog;
- QuitDialog *quitDialog;
- Desktop *desktop;
- Button *setupButton;
+ Window *mCurrentDialog;
+ QuitDialog *mQuitDialog;
+ Desktop *mDesktop;
+ Button *mSetupButton;
- State state;
- State oldstate;
+ State mState;
+ State mOldState;
- SDL_Surface *icon;
+ SDL_Surface *mIcon;
SDL_TimerID mLogicCounterId;
SDL_TimerID mSecondsCounterId;
diff --git a/src/game.cpp b/src/game.cpp
index b3670641..0f45d436 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -82,6 +82,7 @@
#include "resources/resourcemanager.h"
#include "utils/gettext.h"
+#include "utils/mkdir.h"
#include <guichan/exception.hpp>
#include <guichan/focushandler.hpp>
@@ -268,25 +269,17 @@ Game::~Game()
destroyGuiWindows();
- delete beingManager;
- delete player_node;
- delete floorItemManager;
- delete channelManager;
- delete commandHandler;
- delete joystick;
- delete particleEngine;
- delete viewport;
-
- viewport->setMap(NULL);
-
- delete mCurrentMap;
+ del_0(beingManager)
+ del_0(player_node)
+ del_0(floorItemManager)
+ del_0(channelManager)
+ del_0(commandHandler)
+ del_0(joystick)
+ del_0(particleEngine)
+ del_0(viewport)
+ del_0(mCurrentMap)
map_path = "";
- player_node = NULL;
- beingManager = NULL;
- floorItemManager = NULL;
- joystick = NULL;
-
mInstance = 0;
}
@@ -300,14 +293,24 @@ static bool saveScreenshot()
std::stringstream filenameSuffix;
std::stringstream filename;
std::fstream testExists;
+ std::string screenshotDirectory = Client::getScreenshotDirectory();
bool found = false;
+ if (mkdir_r(screenshotDirectory.c_str()) != 0)
+ {
+ logger->log("Directory %s doesn't exist and can't be created! "
+ "Setting screenshot directory to home.",
+ screenshotDirectory.c_str());
+ screenshotDirectory = std::string(PHYSFS_getUserDir());
+ }
+
do {
screenshotCount++;
filenameSuffix.str("");
filename.str("");
- filename << Client::getScreenshotDirectory() << "/";
- filenameSuffix << "Mana_Screenshot_" << screenshotCount << ".png";
+ filename << screenshotDirectory << "/";
+ filenameSuffix << branding.getValue("appShort", "Mana")
+ << "_Screenshot_" << screenshotCount << ".png";
filename << filenameSuffix.str();
testExists.open(filename.str().c_str(), std::ios::in);
found = !testExists.is_open();
@@ -593,8 +596,12 @@ void Game::handleInput()
case KeyboardConfig::KEY_PICKUP:
{
const Vector &pos = player_node->getPosition();
- Uint16 x = (int) pos.x / 32;
- Uint16 y = (int) pos.y / 32;
+ Map *map = viewport->getCurrentMap();
+ Uint16 x = (int) pos.x / map->getTileWidth();
+ Uint16 y = (int) (pos.y - 1)
+ / map->getTileHeight();
+ // y - 1 needed to fix position, otherwise, it's
+ // off under eAthena.
FloorItem *item =
floorItemManager->findByCoordinates(x, y);
diff --git a/src/gui/beingpopup.cpp b/src/gui/beingpopup.cpp
index 7fd99371..33fdff44 100644
--- a/src/gui/beingpopup.cpp
+++ b/src/gui/beingpopup.cpp
@@ -27,7 +27,7 @@
#include "gui/gui.h"
#include "gui/palette.h"
-#include "gui/widgets/textbox.h"
+#include "gui/widgets/label.h"
#include "utils/gettext.h"
#include "utils/stringutils.h"
@@ -39,14 +39,14 @@ BeingPopup::BeingPopup():
Popup("BeingPopup")
{
// Being Name
- mBeingName = new TextBox();
+ mBeingName = new Label("A");
mBeingName->setFont(boldFont);
mBeingName->setPosition(getPadding(), getPadding());
- const int fontHeight = getFont()->getHeight();
+ const int fontHeight = mBeingName->getHeight() + getPadding();
// Being's party
- mBeingParty = new TextBox();
+ mBeingParty = new Label("A");
mBeingParty->setPosition(getPadding(), fontHeight);
add(mBeingName);
@@ -69,12 +69,15 @@ void BeingPopup::show(int x, int y, Player *p)
if (!(p->getPartyName().empty()))
{
- mBeingName->setTextWrapped(p->getName(), 196);
- mBeingParty->setTextWrapped(strprintf(_("Party: %s"),
- p->getPartyName().c_str()), 196);
+ mBeingName->setCaption(p->getName());
+ mBeingName->adjustSize();
- int minWidth = std::max(mBeingName->getMinWidth(),
- mBeingParty->getMinWidth());
+ mBeingParty->setCaption(strprintf(_("Party: %s"),
+ p->getPartyName().c_str()));
+ mBeingParty->adjustSize();
+
+ int minWidth = std::max(mBeingName->getWidth(),
+ mBeingParty->getWidth());
const int height = getFont()->getHeight();
diff --git a/src/gui/beingpopup.h b/src/gui/beingpopup.h
index 078b84d9..71d9dd2a 100644
--- a/src/gui/beingpopup.h
+++ b/src/gui/beingpopup.h
@@ -23,10 +23,8 @@
#include "gui/widgets/popup.h"
-#include <guichan/mouselistener.hpp>
-
+class Label;
class Player;
-class TextBox;
/**
* A popup that displays information about a being.
@@ -52,8 +50,8 @@ class BeingPopup : public Popup
// TODO: Add a version for monsters, NPCs, etc?
private:
- TextBox *mBeingName;
- TextBox *mBeingParty;
+ Label *mBeingName;
+ Label *mBeingParty;
static gcn::Color getColor();
};
diff --git a/src/gui/emotepopup.cpp b/src/gui/emotepopup.cpp
index 2711161e..2161e04c 100644
--- a/src/gui/emotepopup.cpp
+++ b/src/gui/emotepopup.cpp
@@ -29,10 +29,11 @@
#include "localplayer.h"
#include "log.h"
+#include "gui/skin.h"
+
#include "resources/emotedb.h"
#include "resources/image.h"
#include "resources/iteminfo.h"
-#include "resources/resourcemanager.h"
#include "utils/dtor.h"
@@ -56,8 +57,7 @@ EmotePopup::EmotePopup():
mEmotes.push_back(EmoteDB::getAnimation(i));
}
- ResourceManager *resman = ResourceManager::getInstance();
- mSelectionImage = resman->getImage("graphics/gui/selection.png");
+ mSelectionImage = SkinLoader::getImageFromTheme("selection.png");
if (!mSelectionImage)
logger->error("Unable to load selection.png");
@@ -119,6 +119,8 @@ void EmotePopup::mousePressed(gcn::MouseEvent &event)
void EmotePopup::mouseMoved(gcn::MouseEvent &event)
{
+ Popup::mouseMoved(event);
+
mHoveredEmoteIndex = getIndexAt(event.getX(), event.getY());
}
diff --git a/src/gui/emotepopup.h b/src/gui/emotepopup.h
index de957925..62a3f24a 100644
--- a/src/gui/emotepopup.h
+++ b/src/gui/emotepopup.h
@@ -42,8 +42,7 @@ namespace gcn {
*
* \ingroup GUI
*/
-class EmotePopup : public Popup,
- public gcn::MouseListener
+class EmotePopup : public Popup
{
public:
/**
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index e82a33b9..1e36523c 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -26,7 +26,6 @@
#include "gui/sdlinput.h"
#include "gui/skin.h"
#include "gui/truetypefont.h"
-#include "gui/viewport.h"
#include "gui/widgets/window.h"
#include "gui/widgets/windowcontainer.h"
@@ -95,6 +94,7 @@ Gui::Gui(Graphics *graphics):
// Initialize top GUI widget
WindowContainer *guiTop = new WindowContainer;
+ guiTop->setFocusable(true);
guiTop->setDimension(gcn::Rectangle(0, 0,
graphics->getWidth(), graphics->getHeight()));
guiTop->setOpaque(false);
@@ -209,9 +209,8 @@ void Gui::setUseCustomCursor(bool customCursor)
SDL_ShowCursor(SDL_DISABLE);
// Load the mouse cursor
- ResourceManager *resman = ResourceManager::getInstance();
- mMouseCursors =
- resman->getImageSet("graphics/gui/mouse.png", 40, 40);
+ mMouseCursors = SkinLoader::getImageSetFromTheme("mouse.png",
+ 40, 40);
if (!mMouseCursors)
logger->error("Unable to load mouse cursors.");
diff --git a/src/gui/gui.h b/src/gui/gui.h
index 7bd76c4a..112abcee 100644
--- a/src/gui/gui.h
+++ b/src/gui/gui.h
@@ -107,6 +107,9 @@ class Gui : public gcn::Gui
CURSOR_RESIZE_DOWN,
CURSOR_RESIZE_DOWN_LEFT,
CURSOR_RESIZE_DOWN_RIGHT,
+ CURSOR_FIGHT,
+ CURSOR_PICKUP,
+ CURSOR_TALK,
CURSOR_TOTAL
};
diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp
index c22a9c33..1d41449d 100644
--- a/src/gui/itempopup.cpp
+++ b/src/gui/itempopup.cpp
@@ -168,6 +168,8 @@ gcn::Color ItemPopup::getColor(ItemType type)
void ItemPopup::mouseMoved(gcn::MouseEvent &event)
{
+ Popup::mouseMoved(event);
+
// When the mouse moved on top of the popup, hide it
setVisible(false);
}
diff --git a/src/gui/itempopup.h b/src/gui/itempopup.h
index 79aba523..67d1eb2f 100644
--- a/src/gui/itempopup.h
+++ b/src/gui/itempopup.h
@@ -34,8 +34,7 @@ class TextBox;
/**
* A popup that displays information about an item.
*/
-class ItemPopup : public Popup,
- public gcn::MouseListener
+class ItemPopup : public Popup
{
public:
/**
diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp
index f439420b..e9f76436 100644
--- a/src/gui/serverdialog.cpp
+++ b/src/gui/serverdialog.cpp
@@ -49,23 +49,17 @@
#define MAX_SERVERLIST 5
-ServerInfo::Type stringToServerType(const std::string &type)
+static ServerInfo::Type stringToServerType(const std::string &type)
{
if (compareStrI(type, "eathena") == 0)
- {
return ServerInfo::EATHENA;
- }
else if (compareStrI(type, "manaserv") == 0)
- {
return ServerInfo::MANASERV;
- }
- else
- {
- return ServerInfo::UNKNOWN;
- }
+
+ return ServerInfo::UNKNOWN;
}
-std::string serverTypeToString(ServerInfo::Type type)
+static std::string serverTypeToString(ServerInfo::Type type)
{
switch (type)
{
@@ -78,6 +72,18 @@ std::string serverTypeToString(ServerInfo::Type type)
}
}
+static unsigned short defaultPortForServerType(ServerInfo::Type type)
+{
+ switch (type)
+ {
+ default:
+ case ServerInfo::EATHENA:
+ return 6901;
+ case ServerInfo::MANASERV:
+ return 9601;
+ }
+}
+
ServersListModel::ServersListModel(ServerInfos *servers, ServerDialog *parent):
mServers(servers),
mParent(parent)
@@ -138,33 +144,33 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir):
mServerNameField = new TextField(mServerInfo->hostname);
mPortField = new TextField(toString(mServerInfo->port));
- ServerInfo currentServer;
- // Add the most used servers from config if they are not in the online list
- std::string currentConfig = "";
- for (int i = 0; i <= MAX_SERVERLIST; i++)
+ // Add the most used servers from config
+ for (int i = 0; i <= MAX_SERVERLIST; ++i)
{
- currentServer.clear();
-
- currentConfig = "MostUsedServerName" + toString(i);
- currentServer.hostname = config.getValue(currentConfig, "");
+ const std::string index = toString(i);
+ const std::string nameKey = "MostUsedServerName" + index;
+ const std::string typeKey = "MostUsedServerType" + index;
+ const std::string portKey = "MostUsedServerPort" + index;
- currentConfig = "MostUsedServerPort" + toString(i);
- currentServer.port = (short) config.getValue(currentConfig,
- DEFAULT_PORT);
+ ServerInfo server;
+ server.hostname = config.getValue(nameKey, "");
+ server.type = stringToServerType(config.getValue(typeKey, ""));
- currentConfig = "MostUsedServerType" + toString(i);
- currentServer.type = stringToServerType(config
- .getValue(currentConfig, ""));
+ const int defaultPort = defaultPortForServerType(server.type);
+ server.port = (unsigned short) config.getValue(portKey, defaultPort);
- if (!currentServer.hostname.empty() && currentServer.port != 0)
+ if (server.isValid())
{
- mServers.push_back(currentServer);
+ server.save = true;
+ mServers.push_back(server);
}
}
mServersListModel = new ServersListModel(&mServers, this);
mServersList = new ListBox(mServersListModel);
+ mServersList->addMouseListener(this);
+
ScrollArea *usedScroll = new ScrollArea(mServersList);
usedScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
@@ -175,7 +181,8 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir):
mQuitButton = new Button(_("Quit"), "quit", this);
mConnectButton = new Button(_("Connect"), "connect", this);
- mManualEntryButton = new Button(_("Add Entry"), "addEntry", this);
+ mManualEntryButton = new Button(_("Custom Server"), "addEntry", this);
+ mDeleteButton = new Button(_("Delete"), "remove", this);
mServerNameField->setActionEventId("connect");
mPortField->setActionEventId("connect");
@@ -184,20 +191,20 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir):
mPortField->addActionListener(this);
mManualEntryButton->addActionListener(this);
mServersList->addSelectionListener(this);
- mServersList->setSelected(0);
usedScroll->setVerticalScrollAmount(0);
place(0, 0, serverLabel);
- place(1, 0, mServerNameField, 3).setPadding(3);
+ place(1, 0, mServerNameField, 4).setPadding(3);
place(0, 1, portLabel);
- place(1, 1, mPortField, 3).setPadding(3);
+ place(1, 1, mPortField, 4).setPadding(3);
place(0, 2, typeLabel);
- place(1, 2, mTypeField, 3).setPadding(3);
- place(0, 3, usedScroll, 4, 5).setPadding(3);
- place(0, 8, mDescription, 4);
+ place(1, 2, mTypeField, 4).setPadding(3);
+ place(0, 3, usedScroll, 5, 5).setPadding(3);
+ place(0, 8, mDescription, 5);
place(0, 9, mManualEntryButton);
- place(2, 9, mQuitButton);
- place(3, 9, mConnectButton);
+ place(1, 9, mDeleteButton);
+ place(3, 9, mQuitButton);
+ place(4, 9, mConnectButton);
// Make sure the list has enough height
getLayout().setRowHeight(3, 80);
@@ -208,6 +215,7 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir):
center();
setFieldsReadOnly(true);
+ mServersList->setSelected(0); // Do this after for the Delete button
setVisible(true);
if (mServerNameField->getText().empty())
@@ -247,7 +255,8 @@ void ServerDialog::action(const gcn::ActionEvent &event)
else if (event.getId() == "connect")
{
// Check login
- if (mServerNameField->getText().empty() || mPortField->getText().empty())
+ if (mServerNameField->getText().empty()
+ || mPortField->getText().empty())
{
OkDialog *dlg = new OkDialog(_("Error"),
_("Please type both the address and the port of a server."));
@@ -261,7 +270,6 @@ void ServerDialog::action(const gcn::ActionEvent &event)
// First, look if the entry is a new one.
ServerInfo currentServer;
- ServerInfo tempServer;
currentServer.hostname = mServerNameField->getText();
currentServer.port = (short) atoi(mPortField->getText().c_str());
switch (mTypeField->getSelected())
@@ -284,21 +292,27 @@ void ServerDialog::action(const gcn::ActionEvent &event)
serverTypeToString(currentServer.type));
// now add the rest of the list...
- std::string currentConfig = "";
int configCount = 1;
- for (int i = 0; i < mServersListModel->getNumberOfElements(); i++)
+ for (int i = 0; i < mServersListModel->getNumberOfElements(); ++i)
{
- tempServer = mServersListModel->getServer(i);
+ const ServerInfo server = mServersListModel->getServer(i);
+
+ // Only save servers that were loaded from settings
+ if (!server.save)
+ continue;
// ensure, that our server will not be added twice
- if (tempServer != currentServer)
+ if (server != currentServer)
{
- currentConfig = "MostUsedServerName" + toString(configCount);
- config.setValue(currentConfig, toString(tempServer.hostname));
- currentConfig = "MostUsedServerPort" + toString(configCount);
- config.setValue(currentConfig, toString(tempServer.port));
- currentConfig = "MostUsedServerType" + toString(configCount);
- config.setValue(currentConfig, serverTypeToString(tempServer.type));
+ const std::string index = toString(configCount);
+ const std::string nameKey = "MostUsedServerName" + index;
+ const std::string typeKey = "MostUsedServerType" + index;
+ const std::string portKey = "MostUsedServerPort" + index;
+
+ config.setValue(nameKey, toString(server.hostname));
+ config.setValue(typeKey, serverTypeToString(server.type));
+ config.setValue(portKey, toString(server.port));
+
configCount++;
}
@@ -321,6 +335,12 @@ void ServerDialog::action(const gcn::ActionEvent &event)
{
setFieldsReadOnly(false);
}
+ else if (event.getId() == "remove")
+ {
+ int index = mServersList->getSelected();
+ mServersList->setSelected(0);
+ mServersListModel->remove(index);
+ }
}
void ServerDialog::keyPressed(gcn::KeyEvent &keyEvent)
@@ -337,11 +357,14 @@ void ServerDialog::keyPressed(gcn::KeyEvent &keyEvent)
}
}
-void ServerDialog::valueChanged(const gcn::SelectionEvent &event)
+void ServerDialog::valueChanged(const gcn::SelectionEvent &)
{
const int index = mServersList->getSelected();
if (index == -1)
+ {
+ mDeleteButton->setEnabled(false);
return;
+ }
// Update the server and post fields according to the new selection
const ServerInfo myServer = mServersListModel->getServer(index);
@@ -350,16 +373,27 @@ void ServerDialog::valueChanged(const gcn::SelectionEvent &event)
mPortField->setText(toString(myServer.port));
switch (myServer.type)
{
- case ServerInfo::UNKNOWN:
- mTypeField->setSelected(2);
- break;
case ServerInfo::EATHENA:
+ case ServerInfo::UNKNOWN:
mTypeField->setSelected(0);
break;
case ServerInfo::MANASERV:
mTypeField->setSelected(1);
+ break;
}
setFieldsReadOnly(true);
+
+ mDeleteButton->setEnabled(myServer.save);
+}
+
+void ServerDialog::mouseClicked(gcn::MouseEvent &mouseEvent)
+{
+ if (mouseEvent.getClickCount() == 2 &&
+ mouseEvent.getSource() == mServersList)
+ {
+ action(gcn::ActionEvent(mConnectButton,
+ mConnectButton->getActionEventId()));
+ }
}
void ServerDialog::logic()
@@ -391,39 +425,38 @@ void ServerDialog::logic()
Window::logic();
}
-void ServerDialog::setFieldsReadOnly(const bool readOnly)
+void ServerDialog::setFieldsReadOnly(bool readOnly)
{
- if (readOnly)
+ if (!readOnly)
{
- mServerNameField->setEnabled(false);
- mPortField->setEnabled(false);
- mManualEntryButton->setVisible(true);
- mDescription->setVisible(true);
- }
- else
- {
- mManualEntryButton->setVisible(false);
-
- mDescription->setVisible(false);
mDescription->setCaption(std::string());
mServersList->setSelected(-1);
mServerNameField->setText(std::string());
- mServerNameField->setEnabled(true);
-
- mPortField->setText(toString(DEFAULT_PORT));
- mPortField->setEnabled(true);
+ mPortField->setText(std::string());
mServerNameField->requestFocus();
}
+
+ mManualEntryButton->setEnabled(readOnly);
+ mDeleteButton->setEnabled(false);
+ mDescription->setVisible(readOnly);
+
+ mServerNameField->setEnabled(!readOnly);
+ mPortField->setEnabled(!readOnly);
+ mTypeField->setEnabled(!readOnly);
}
void ServerDialog::downloadServerList()
{
- // try to load the configuration value for the onlineServerList
- std::string listFile = config.getValue("onlineServerList", "void");
- // if there is no entry, try to load the file from the default updatehost
- if (listFile == "void")
+ // Try to load the configuration value for the onlineServerList
+ std::string listFile = branding.getValue("onlineServerList", std::string());
+
+ if (listFile.empty())
+ listFile = config.getValue("onlineServerList", std::string());
+
+ // Fall back to manasource.org when neither branding nor config set it
+ if (listFile.empty())
listFile = "http://manasource.org/serverlist.xml";
mDownload = new Net::Download(this, listFile, &downloadUpdate);
@@ -433,65 +466,74 @@ void ServerDialog::downloadServerList()
void ServerDialog::loadServers()
{
- ServerInfo currentServer;
+ XML::Document doc(mDir + "/serverlist.xml", false);
+ xmlNodePtr rootNode = doc.rootNode();
- xmlDocPtr doc = xmlReadFile((mDir + "/serverlist.xml").c_str(), NULL, 0);
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "serverlist"))
+ {
+ logger->log("Error loading server list!");
+ return;
+ }
- if (doc != NULL)
+ int version = XML::getProperty(rootNode, "version", 0);
+ if (version != 1)
{
- xmlNodePtr rootNode = xmlDocGetRootElement(doc);
- int version = XML::getProperty(rootNode, "version", 3);
+ logger->log("Error: unsupported online server list version: %d",
+ version);
+ return;
+ }
+
+ for_each_xml_child_node(serverNode, rootNode)
+ {
+ if (!xmlStrEqual(serverNode->name, BAD_CAST "server"))
+ continue;
+
+ ServerInfo server;
+
+ std::string type = XML::getProperty(serverNode, "type", "unknown");
- if (version != 1)
+ server.type = stringToServerType(type);
+ server.name = XML::getProperty(serverNode, "name", std::string());
+
+ if (server.type == ServerInfo::UNKNOWN)
{
- logger->log("Online server list has wrong version");
- return;
+ logger->log("Unknown server type: %s", type.c_str());
+ continue;
}
- for_each_xml_child_node(server, rootNode)
+ for_each_xml_child_node(subNode, serverNode)
{
- if (xmlStrEqual(server->name, BAD_CAST "server"))
- {
- std::string type = XML::getProperty(server, "type", "unknown");
-
- currentServer.clear();
- currentServer.name = XML::getProperty(server, "name", std::string());
+ if (!xmlStrEqual(subNode->name, BAD_CAST "connection"))
+ continue;
- for_each_xml_child_node(subnode, server)
- {
- if (xmlStrEqual(subnode->name, BAD_CAST "connection"))
- {
- currentServer.type = stringToServerType(type);
- currentServer.hostname = XML::getProperty(subnode, "hostname", std::string());
- currentServer.port = XML::getProperty(subnode, "port", DEFAULT_PORT);
- }
- }
+ server.hostname = XML::getProperty(subNode, "hostname", "");
+ server.port = XML::getProperty(subNode, "port", 0);
+ if (server.port == 0)
+ {
+ // If no port is given, use the default for the given type
+ server.port = defaultPortForServerType(server.type);
+ }
+ }
- MutexLocker lock(&mMutex);
- // add the server to the local list (if it's not already present)
- ServerInfos::iterator it;
- bool found = false;
- for (it = mServers.begin(); it != mServers.end(); it++)
- {
- if ((*it) == currentServer)
- {
- (*it).name = currentServer.name;
- found = true;
- break;
- }
- }
-
- if (!found)
- mServers.push_back(currentServer);
+ MutexLocker lock(&mMutex);
+ // Add the server to the local list if it's not already present
+ ServerInfos::iterator it;
+ bool found = false;
+ for (it = mServers.begin(); it != mServers.end(); it++)
+ {
+ if ((*it) == server)
+ {
+ // Use the name listed in the server list
+ (*it).name = server.name;
+ found = true;
+ break;
}
}
- xmlFreeDoc(doc);
+ if (!found)
+ mServers.push_back(server);
}
-
- MutexLocker lock(&mMutex);
- mDownloadStatus = DOWNLOADING_COMPLETE;
}
int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status,
@@ -518,9 +560,12 @@ int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status,
{
float progress = (float) remaining / total;
- if (progress != progress) progress = 0.0f; // check for NaN
- if (progress < 0.0f) progress = 0.0f; // no idea how this could ever happen, but why not check for it anyway.
- if (progress > 1.0f) progress = 1.0f;
+ if (progress != progress)
+ progress = 0.0f; // check for NaN
+ else if (progress < 0.0f)
+ progress = 0.0f; // no idea how this could ever happen, but why not check for it anyway.
+ else if (progress > 1.0f)
+ progress = 1.0f;
MutexLocker lock(&sd->mMutex);
sd->mDownloadStatus = DOWNLOADING_IN_PROGRESS;
@@ -530,6 +575,9 @@ int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status,
if (finished)
{
sd->loadServers();
+
+ MutexLocker lock(&sd->mMutex);
+ sd->mDownloadStatus = DOWNLOADING_COMPLETE;
}
return 0;
diff --git a/src/gui/serverdialog.h b/src/gui/serverdialog.h
index c4af6ab2..3d7dca9d 100644
--- a/src/gui/serverdialog.h
+++ b/src/gui/serverdialog.h
@@ -32,6 +32,7 @@
#include <guichan/actionlistener.hpp>
#include <guichan/keylistener.hpp>
#include <guichan/listmodel.hpp>
+#include <guichan/mouselistener.hpp>
#include <guichan/selectionlistener.hpp>
#include <string>
@@ -68,18 +69,24 @@ class ServersListModel : public gcn::ListModel
ServerInfo getServer(int elementIndex) const
{ return mServers->at(elementIndex); }
+ /**
+ * Removes the entry.
+ */
+ void remove(int elementIndex)
+ { mServers->erase(mServers->begin() + elementIndex); }
+
private:
ServerInfos *mServers;
ServerDialog *mParent;
};
/**
- * Server and Port List Model
+ * Server Type List Model
*/
class TypeListModel : public gcn::ListModel
{
public:
- TypeListModel() { };
+ TypeListModel() {}
/**
* Used to get number of line in the list
@@ -128,6 +135,8 @@ class ServerDialog : public Window,
*/
void valueChanged(const gcn::SelectionEvent &event);
+ void mouseClicked(gcn::MouseEvent &mouseEvent);
+
void logic();
protected:
@@ -143,7 +152,7 @@ class ServerDialog : public Window,
static int downloadUpdate(void *ptr, DownloadStatus status,
size_t total, size_t remaining);
- void setFieldsReadOnly(const bool readOnly);
+ void setFieldsReadOnly(bool readOnly);
TextField *mServerNameField;
TextField *mPortField;
@@ -151,6 +160,7 @@ class ServerDialog : public Window,
Button *mQuitButton;
Button *mConnectButton;
Button *mManualEntryButton;
+ Button *mDeleteButton;
ListBox *mServersList;
ServersListModel *mServersListModel;
diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp
index 78c5c998..09c7ccb2 100644
--- a/src/gui/skilldialog.cpp
+++ b/src/gui/skilldialog.cpp
@@ -25,6 +25,7 @@
#include "log.h"
#include "gui/setup.h"
+#include "gui/skin.h"
#include "gui/widgets/button.h"
#include "gui/widgets/container.h"
@@ -76,7 +77,7 @@ struct SkillInfo
icon->decRef();
}
- void setIcon(std::string iconPath)
+ void setIcon(const std::string &iconPath)
{
ResourceManager *res = ResourceManager::getInstance();
if (!iconPath.empty())
@@ -85,7 +86,7 @@ struct SkillInfo
}
else
{
- icon = res->getImage("graphics/gui/unknown-item.png");
+ icon = SkinLoader::getImageFromTheme("unknown-item.png");
}
}
@@ -99,11 +100,19 @@ typedef std::vector<SkillInfo*> SkillList;
class SkillModel : public gcn::ListModel
{
public:
- int getNumberOfElements() { return mVisibleSkills.size(); }
- SkillInfo *getSkillAt(int i) { return mVisibleSkills.at(i); }
- std::string getElementAt(int i) { return getSkillAt(i)->name; }
+ int getNumberOfElements()
+ { return mVisibleSkills.size(); }
+
+ SkillInfo *getSkillAt(int i) const
+ { return mVisibleSkills.at(i); }
+
+ std::string getElementAt(int i)
+ { return getSkillAt(i)->name; }
+
void updateVisibilities();
- void addSkill(SkillInfo *info) { mSkills.push_back(info); }
+
+ void addSkill(SkillInfo *info)
+ { mSkills.push_back(info); }
private:
SkillList mSkills;
@@ -119,7 +128,11 @@ public:
SkillInfo *getSelectedInfo()
{
- return static_cast<SkillModel*>(mListModel)->getSkillAt(getSelected());
+ const int selected = getSelected();
+ if (selected < 0 || selected > mListModel->getNumberOfElements())
+ return 0;
+
+ return static_cast<SkillModel*>(mListModel)->getSkillAt(selected);
}
void draw(gcn::Graphics *gcnGraphics)
@@ -216,9 +229,8 @@ void SkillDialog::action(const gcn::ActionEvent &event)
if (tab)
{
- SkillInfo *info = tab->getSelectedInfo();
-
- Net::getPlayerHandler()->increaseSkill(info->id);
+ if (SkillInfo *info = tab->getSelectedInfo())
+ Net::getPlayerHandler()->increaseSkill(info->id);
}
}
else if (event.getId() == "close")
diff --git a/src/gui/skin.cpp b/src/gui/skin.cpp
index a682bf8f..22153720 100644
--- a/src/gui/skin.cpp
+++ b/src/gui/skin.cpp
@@ -23,22 +23,26 @@
#include "gui/skin.h"
+#include "client.h"
#include "configuration.h"
#include "configlistener.h"
#include "log.h"
#include "resources/image.h"
+#include "resources/imageset.h"
#include "resources/resourcemanager.h"
#include "utils/dtor.h"
#include "utils/stringutils.h"
#include "utils/xml.h"
+#include <physfs.h>
+
#include <algorithm>
+std::string SkinLoader::mThemePath;
SkinLoader *SkinLoader::mInstance = 0;
-
class SkinConfigListener : public ConfigListener
{
public:
@@ -197,7 +201,7 @@ Skin *SkinLoader::readSkin(const std::string &filename)
logger->log("Loading skin '%s'.", filename.c_str());
- XML::Document doc(filename);
+ XML::Document doc(resolveThemePath(filename));
xmlNodePtr rootNode = doc.rootNode();
if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset"))
@@ -215,8 +219,7 @@ Skin *SkinLoader::readSkin(const std::string &filename)
logger->log("SkinLoader::load(): <skinset> defines "
"'%s' as a skin image.", skinSetImage.c_str());
- ResourceManager *resman = ResourceManager::getInstance();
- Image *dBorders = resman->getImage("graphics/gui/" + skinSetImage);
+ Image *dBorders = SkinLoader::getImageFromTheme(skinSetImage);
ImageRect border;
// iterate <widget>'s
@@ -286,8 +289,8 @@ Skin *SkinLoader::readSkin(const std::string &filename)
logger->log("Finished loading skin.");
// Hard-coded for now until we update the above code to look for window buttons
- Image *closeImage = resman->getImage("graphics/gui/close_button.png");
- Image *sticky = resman->getImage("graphics/gui/sticky_button.png");
+ Image *closeImage = SkinLoader::getImageFromTheme("close_button.png");
+ Image *sticky = SkinLoader::getImageFromTheme("sticky_button.png");
Image *stickyImageUp = sticky->getSubImage(0, 0, 15, 15);
Image *stickyImageDown = sticky->getSubImage(15, 0, 15, 15);
sticky->decRef();
@@ -297,3 +300,68 @@ Skin *SkinLoader::readSkin(const std::string &filename)
skin->updateAlpha(mMinimumOpacity);
return skin;
}
+
+bool SkinLoader::tryThemePath(std::string themePath)
+{
+ if (!themePath.empty())
+ {
+ themePath = "graphics/gui/" + themePath;
+ if (PHYSFS_exists(themePath.c_str()))
+ {
+ mThemePath = themePath;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void SkinLoader::prepareThemePath()
+{
+ // Try theme from settings
+ if (tryThemePath(config.getValue("theme", "")))
+ return;
+
+ // Try theme from branding
+ if (tryThemePath(branding.getValue("theme", "")))
+ return;
+
+ // Use default
+ mThemePath = "graphics/gui";
+}
+
+std::string SkinLoader::resolveThemePath(const std::string &path)
+{
+ // Need to strip off any dye info for the existence tests
+ int pos = path.find('|');
+ std::string file;
+ if (pos > 0)
+ file = path.substr(0, pos);
+ else
+ file = path;
+
+ // Might be a valid path already
+ if (PHYSFS_exists(file.c_str()))
+ return path;
+
+ // Try the theme
+ file = getThemePath() + "/" + file;
+ if (PHYSFS_exists(file.c_str()))
+ return getThemePath() + "/" + path;
+
+ // Backup
+ return "graphics/gui/" + path;
+}
+
+Image *SkinLoader::getImageFromTheme(const std::string &path)
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ return resman->getImage(resolveThemePath(path));
+}
+
+ImageSet *SkinLoader::getImageSetFromTheme(const std::string &path,
+ int w, int h)
+{
+ ResourceManager *resman = ResourceManager::getInstance();
+ return resman->getImageSet(resolveThemePath(path), w, h);
+}
diff --git a/src/gui/skin.h b/src/gui/skin.h
index 15d55972..091d3001 100644
--- a/src/gui/skin.h
+++ b/src/gui/skin.h
@@ -31,6 +31,7 @@
class ConfigListener;
class Image;
+class ImageSet;
class Skin
{
@@ -101,11 +102,24 @@ class SkinLoader
static SkinLoader *instance();
static void deleteInstance();
+ static void prepareThemePath();
+ static std::string getThemePath() { return mThemePath; }
+
+ /**
+ * Returns the patch to the given gui resource relative to the theme
+ * or, if it isn't in the theme, relative to 'graphics/gui'.
+ */
+ static std::string resolveThemePath(const std::string &path);
+
+ static Image *getImageFromTheme(const std::string &path);
+ static ImageSet *getImageSetFromTheme(const std::string &path,
+ int w, int h);
+
/**
* Loads a skin.
*/
Skin *load(const std::string &filename,
- const std::string &defaultPath);
+ const std::string &defaultPath = getThemePath());
/**
* Updates the alpha values of all of the skins.
@@ -141,8 +155,11 @@ class SkinLoader
*/
ConfigListener *mSkinConfigListener;
+ static std::string mThemePath;
static SkinLoader *mInstance;
+ static bool tryThemePath(std::string themePath);
+
/**
* Tells if the current skins opacity
* should not get less than the given value
diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp
index 26184cae..5da8018c 100644
--- a/src/gui/socialwindow.cpp
+++ b/src/gui/socialwindow.cpp
@@ -235,7 +235,8 @@ public:
mBrowserBox->setOpaque(false);
mBrowserBox->setLinkHandler(this);
- mBrowserBox->addRow(strprintf("@@guild|%s@@", _("Create Guild")));
+ if (Net::getGuildHandler()->isSupported())
+ mBrowserBox->addRow(strprintf("@@guild|%s@@", _("Create Guild")));
mBrowserBox->addRow(strprintf("@@party|%s@@", _("Create Party")));
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
@@ -425,7 +426,10 @@ void SocialWindow::action(const gcn::ActionEvent &event)
}
else if (event.getId() == "create")
{
- mCreatePopup->show(mCreateButton);
+ if (Net::getGuildHandler()->isSupported())
+ mCreatePopup->show(mCreateButton);
+ else
+ showPartyCreate();
}
else if (event.getId() == "invite")
{
@@ -564,7 +568,7 @@ void SocialWindow::showPartyCreate()
}
mPartyCreateDialog = new TextDialog(_("Party Name"),
- _("Choose your part's name."), this);
+ _("Choose your party's name."), this);
mPartyCreateDialog->setOKButtonActionId("create party");
mPartyCreateDialog->addActionListener(this);
}
diff --git a/src/gui/specialswindow.cpp b/src/gui/specialswindow.cpp
index 1513dcf1..3ca0f037 100644
--- a/src/gui/specialswindow.cpp
+++ b/src/gui/specialswindow.cpp
@@ -24,6 +24,7 @@
#include "log.h"
#include "gui/setup.h"
+#include "gui/skin.h"
#include "gui/widgets/button.h"
#include "gui/widgets/container.h"
@@ -219,7 +220,7 @@ SpecialEntry::SpecialEntry(SpecialInfo *info) :
if (!info->icon.empty())
mIcon = new Icon(info->icon);
else
- mIcon = new Icon("graphics/gui/unknown-item.png");
+ mIcon = new Icon(SkinLoader::resolveThemePath("unknown-item.png"));
mIcon->setPosition(1, 0);
add(mIcon);
diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp
index 3a87992b..f02965d1 100644
--- a/src/gui/speechbubble.cpp
+++ b/src/gui/speechbubble.cpp
@@ -25,6 +25,7 @@
#include "graphics.h"
#include "gui/gui.h"
+#include "gui/skin.h"
#include "gui/widgets/textbox.h"
@@ -33,7 +34,7 @@
#include <guichan/widgets/label.hpp>
SpeechBubble::SpeechBubble():
- Popup("Speech", "graphics/gui/speechbubble.xml")
+ Popup("Speech", "speechbubble.xml")
{
setContentSize(140, 46);
setMinWidth(29);
diff --git a/src/gui/textdialog.h b/src/gui/textdialog.h
index 6db09e71..825d9ddc 100644
--- a/src/gui/textdialog.h
+++ b/src/gui/textdialog.h
@@ -43,8 +43,7 @@ public:
*/
TextDialog(const std::string &title, const std::string &msg,
Window *parent = NULL);
-
-
+
~TextDialog();
/**
@@ -61,8 +60,8 @@ public:
* Set the OK button action id
*/
void setOKButtonActionId(const std::string &name);
-
- static const bool isActive() { return instances > 0; }
+
+ static bool isActive() { return instances > 0; }
private:
static int instances;
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index 763d0c43..1451b935 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -53,10 +53,7 @@ Viewport::Viewport():
mMouseY(0),
mPixelViewX(0.0f),
mPixelViewY(0.0f),
- mTileViewX(0),
- mTileViewY(0),
mShowDebugPath(false),
- mVisibleNames(false),
mPlayerFollowMouse(false),
mLocalWalkTime(-1)
{
@@ -67,21 +64,20 @@ Viewport::Viewport():
mScrollRadius = (int) config.getValue("ScrollRadius", 0);
mScrollCenterOffsetX = (int) config.getValue("ScrollCenterOffsetX", 0);
mScrollCenterOffsetY = (int) config.getValue("ScrollCenterOffsetY", 0);
- mVisibleNames = config.getValue("visiblenames", 1);
config.addListener("ScrollLaziness", this);
config.addListener("ScrollRadius", this);
- config.addListener("visiblenames", this);
mPopupMenu = new PopupMenu;
mBeingPopup = new BeingPopup;
+
+ setFocusable(true);
}
Viewport::~Viewport()
{
delete mPopupMenu;
-
- config.removeListener("visiblenames", this);
+ delete mBeingPopup;
}
void Viewport::setMap(Map *map)
@@ -109,10 +105,6 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
Graphics *graphics = static_cast<Graphics*>(gcnGraphics);
- // Ensure the client doesn't freak out if a feature localplayer uses
- // is dependent on a map.
- player_node->setMapInitialized(true);
-
// Avoid freaking out when tick_time overflows
if (tick_time < lastTick)
{
@@ -184,9 +176,6 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
mPixelViewY = viewYmax;
}
- mTileViewX = (int) (mPixelViewX + 16) / 32;
- mTileViewY = (int) (mPixelViewY + 16) / 32;
-
// Draw tiles and sprites
if (mMap)
{
@@ -312,25 +301,18 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
const int pixelX = event.getX() + (int) mPixelViewX;
const int pixelY = event.getY() + (int) mPixelViewY;
- const int tileX = pixelX / mMap->getTileWidth();
- const int tileY = pixelY / mMap->getTileHeight();
// Right click might open a popup
if (event.getButton() == gcn::MouseEvent::RIGHT)
{
- Being *being;
- FloorItem *floorItem;
-
- if ((being = beingManager->findBeingByPixel(pixelX, pixelY)) &&
- being != player_node)
+ if (mHoverBeing && mHoverBeing != player_node)
{
- mPopupMenu->showPopup(event.getX(), event.getY(), being);
+ mPopupMenu->showPopup(event.getX(), event.getY(), mHoverBeing);
return;
}
- else if ((floorItem = floorItemManager->findByCoordinates(tileX,
- tileY)))
+ else if (mHoverItem)
{
- mPopupMenu->showPopup(event.getX(), event.getY(), floorItem);
+ mPopupMenu->showPopup(event.getX(), event.getY(), mHoverItem);
return;
}
}
@@ -345,35 +327,32 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
// Left click can cause different actions
if (event.getButton() == gcn::MouseEvent::LEFT)
{
- FloorItem *item;
- Being *being;
-
// Interact with some being
- if ((being = beingManager->findBeingByPixel(pixelX, pixelY)))
+ if (mHoverBeing)
{
- switch (being->getType())
+ switch (mHoverBeing->getType())
{
// Talk to NPCs
case Being::NPC:
- dynamic_cast<NPC*>(being)->talk();
+ static_cast<NPC*>(mHoverBeing)->talk();
break;
// Attack or walk to monsters or players
case Being::MONSTER:
case Being::PLAYER:
// Ignore it if its dead
- if (!being->isAlive())
+ if (!mHoverBeing->isAlive())
break;
- if (player_node->withinAttackRange(being) ||
+ if (player_node->withinAttackRange(mHoverBeing) ||
keyboard.isKeyActive(keyboard.KEY_ATTACK))
{
- player_node->attack(being,
+ player_node->attack(mHoverBeing,
!keyboard.isKeyActive(keyboard.KEY_TARGET));
}
else
{
- player_node->setGotoTarget(being);
+ player_node->setGotoTarget(mHoverBeing);
}
break;
default:
@@ -381,9 +360,9 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
}
// Picks up a item if we clicked on one
}
- else if ((item = floorItemManager->findByCoordinates(tileX, tileY)))
+ else if (mHoverItem)
{
- player_node->pickUp(item);
+ player_node->pickUp(mHoverItem);
}
else if (player_node->getCurrentAction() == Being::SIT)
{
@@ -433,8 +412,10 @@ void Viewport::mouseDragged(gcn::MouseEvent &event)
if (mLocalWalkTime != player_node->getWalkTime())
{
mLocalWalkTime = player_node->getWalkTime();
- int destX = event.getX() / 32 + mTileViewX;
- int destY = event.getY() / 32 + mTileViewY;
+ int destX = (event.getX() + mPixelViewX + 16) /
+ mMap->getTileWidth();
+ int destY = (event.getY() + mPixelViewY + 16) /
+ mMap->getTileHeight();
player_node->setDestination(destX, destY);
}
}
@@ -464,9 +445,6 @@ void Viewport::optionChanged(const std::string &name)
{
mScrollLaziness = (int) config.getValue("ScrollLaziness", 32);
mScrollRadius = (int) config.getValue("ScrollRadius", 32);
-
- if (name == "visiblenames")
- mVisibleNames = config.getValue("visiblenames", 1);
}
void Viewport::mouseMoved(gcn::MouseEvent &event)
@@ -478,11 +456,42 @@ void Viewport::mouseMoved(gcn::MouseEvent &event)
const int x = (event.getX() + (int) mPixelViewX);
const int y = (event.getY() + (int) mPixelViewY);
- mSelectedBeing = beingManager->findBeingByPixel(x, y);
- if (Player *p = dynamic_cast<Player*>(mSelectedBeing))
+ mHoverBeing = beingManager->findBeingByPixel(x, y);
+ if (Player *p = dynamic_cast<Player*>(mHoverBeing))
mBeingPopup->show(getMouseX(), getMouseY(), p);
else
mBeingPopup->setVisible(false);
+
+ mHoverItem = floorItemManager->findByCoordinates(x / mMap->getTileWidth(),
+ y / mMap->getTileHeight());
+
+ if (mHoverBeing)
+ {
+ switch (mHoverBeing->getType())
+ {
+ // NPCs
+ case Being::NPC:
+ gui->setCursorType(Gui::CURSOR_TALK);
+ break;
+
+ // Monsters
+ case Being::MONSTER:
+ gui->setCursorType(Gui::CURSOR_FIGHT);
+ break;
+ default:
+ gui->setCursorType(Gui::CURSOR_POINTER);
+ break;
+ }
+ // Item mouseover
+ }
+ else if (mHoverItem)
+ {
+ gui->setCursorType(Gui::CURSOR_PICKUP);
+ }
+ else
+ {
+ gui->setCursorType(Gui::CURSOR_POINTER);
+ }
}
void Viewport::toggleDebugPath()
@@ -496,3 +505,7 @@ void Viewport::toggleDebugPath()
}
}
+void Viewport::hideBeingPopup()
+{
+ mBeingPopup->setVisible(false);
+}
diff --git a/src/gui/viewport.h b/src/gui/viewport.h
index 5b92d950..e4944cd6 100644
--- a/src/gui/viewport.h
+++ b/src/gui/viewport.h
@@ -152,6 +152,11 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
*/
Map *getCurrentMap() const { return mMap; }
+ /**
+ * Hides the BeingPopup.
+ */
+ void hideBeingPopup();
+
private:
/**
* Finds a path from the player to the mouse, and draws it. This is for
@@ -179,20 +184,18 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
int mMouseY; /**< Current mouse position in pixels. */
float mPixelViewX; /**< Current viewpoint in pixels. */
float mPixelViewY; /**< Current viewpoint in pixels. */
- int mTileViewX; /**< Current viewpoint in tiles. */
- int mTileViewY; /**< Current viewpoint in tiles. */
int mShowDebugPath; /**< Show a path from player to pointer. */
- bool mVisibleNames; /**< Show target names. */
bool mPlayerFollowMouse;
int mLocalWalkTime; /**< Timestamp before the next walk can be sent. */
PopupMenu *mPopupMenu; /**< Popup menu. */
- Being *mSelectedBeing; /**< Current selected being. */
- BeingPopup *mBeingPopup;
+ Being *mHoverBeing; /**< Being mouse is currently over. */
+ FloorItem *mHoverItem; /**< FloorItem mouse is currently over. */
+ BeingPopup *mBeingPopup; /**< Being information popup. */
};
-extern Viewport *viewport; /**< The viewport */
+extern Viewport *viewport; /**< The viewport. */
#endif
diff --git a/src/gui/widgets/avatarlistbox.cpp b/src/gui/widgets/avatarlistbox.cpp
index f5a9ea18..92386739 100644
--- a/src/gui/widgets/avatarlistbox.cpp
+++ b/src/gui/widgets/avatarlistbox.cpp
@@ -25,6 +25,7 @@
#include "gui/chat.h"
#include "gui/gui.h"
#include "gui/palette.h"
+#include "gui/skin.h"
#include "resources/image.h"
#include "resources/resourcemanager.h"
@@ -44,8 +45,8 @@ AvatarListBox::AvatarListBox(AvatarListModel *model):
if (instances == 1)
{
- onlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-green.png");
- offlineIcon = ResourceManager::getInstance()->getImage("graphics/gui/circle-gray.png");
+ onlineIcon = SkinLoader::getImageFromTheme("circle-green.png");
+ offlineIcon = SkinLoader::getImageFromTheme("circle-gray.png");
}
setWidth(200);
diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp
index 6589c96e..36a47859 100644
--- a/src/gui/widgets/button.cpp
+++ b/src/gui/widgets/button.cpp
@@ -28,7 +28,6 @@
#include "gui/skin.h"
#include "resources/image.h"
-#include "resources/resourcemanager.h"
#include "utils/dtor.h"
@@ -54,10 +53,10 @@ struct ButtonData
};
static ButtonData const data[BUTTON_COUNT] = {
- { "graphics/gui/button.png", 0, 0 },
- { "graphics/gui/buttonhi.png", 9, 4 },
- { "graphics/gui/buttonpress.png", 16, 19 },
- { "graphics/gui/button_disabled.png", 25, 23 }
+ { "button.png", 0, 0 },
+ { "buttonhi.png", 9, 4 },
+ { "buttonpress.png", 16, 19 },
+ { "button_disabled.png", 25, 23 }
};
ImageRect Button::button[BUTTON_COUNT];
@@ -85,14 +84,13 @@ void Button::init()
if (mInstances == 0)
{
// Load the skin
- ResourceManager *resman = ResourceManager::getInstance();
Image *btn[BUTTON_COUNT];
int a, x, y, mode;
for (mode = 0; mode < BUTTON_COUNT; mode++)
{
- btn[mode] = resman->getImage(data[mode].file);
+ btn[mode] = SkinLoader::getImageFromTheme(data[mode].file);
a = 0;
for (y = 0; y < 3; y++)
{
diff --git a/src/gui/widgets/checkbox.cpp b/src/gui/widgets/checkbox.cpp
index dc6d94b3..0fefbfe9 100644
--- a/src/gui/widgets/checkbox.cpp
+++ b/src/gui/widgets/checkbox.cpp
@@ -28,7 +28,6 @@
#include "gui/skin.h"
#include "resources/image.h"
-#include "resources/resourcemanager.h"
int CheckBox::instances = 0;
float CheckBox::mAlpha = 1.0;
@@ -45,8 +44,7 @@ CheckBox::CheckBox(const std::string &caption, bool selected):
{
if (instances == 0)
{
- ResourceManager *resman = ResourceManager::getInstance();
- Image *checkBox = resman->getImage("graphics/gui/checkbox.png");
+ Image *checkBox = SkinLoader::getImageFromTheme("checkbox.png");
checkBoxNormal = checkBox->getSubImage(0, 0, 9, 10);
checkBoxChecked = checkBox->getSubImage(9, 0, 9, 10);
checkBoxDisabled = checkBox->getSubImage(18, 0, 9, 10);
@@ -114,21 +112,29 @@ void CheckBox::drawBox(gcn::Graphics* graphics)
Image *box;
if (isEnabled())
+ {
if (isSelected())
+ {
if (mHasMouse)
box = checkBoxCheckedHi;
else
box = checkBoxChecked;
+ }
else
+ {
if (mHasMouse)
box = checkBoxNormalHi;
else
box = checkBoxNormal;
+ }
+ }
else
+ {
if (isSelected())
box = checkBoxDisabledChecked;
else
box = checkBoxDisabled;
+ }
updateAlpha();
diff --git a/src/gui/widgets/desktop.cpp b/src/gui/widgets/desktop.cpp
index e7cd949a..2a80cc11 100644
--- a/src/gui/widgets/desktop.cpp
+++ b/src/gui/widgets/desktop.cpp
@@ -20,6 +20,7 @@
#include "gui/widgets/desktop.h"
+#include "configuration.h"
#include "graphics.h"
#include "log.h"
#include "main.h"
@@ -32,6 +33,8 @@
#include "resources/resourcemanager.h"
#include "resources/wallpaper.h"
+#include "utils/stringutils.h"
+
Desktop::Desktop()
: mWallpaper(0)
{
@@ -39,7 +42,14 @@ Desktop::Desktop()
Wallpaper::loadWallpapers();
- mVersionLabel = new Label(FULL_VERSION);
+ std::string appName = branding.getValue("appName", "");
+
+ if (appName.empty())
+ mVersionLabel = new Label(FULL_VERSION);
+ else
+ mVersionLabel = new Label(strprintf("%s (Mana %s)", appName.c_str(),
+ FULL_VERSION));
+
mVersionLabel->setBackgroundColor(gcn::Color(255, 255, 255, 128));
add(mVersionLabel, 25, 2);
}
diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp
index 32b42553..eb0cdef2 100644
--- a/src/gui/widgets/dropdown.cpp
+++ b/src/gui/widgets/dropdown.cpp
@@ -32,7 +32,6 @@
#include "gui/widgets/scrollarea.h"
#include "resources/image.h"
-#include "resources/resourcemanager.h"
#include "utils/dtor.h"
@@ -54,17 +53,16 @@ DropDown::DropDown(gcn::ListModel *listModel):
if (instances == 0)
{
// Load the background skin
- ResourceManager *resman = ResourceManager::getInstance();
// Get the button skin
buttons[1][0] =
- resman->getImage("graphics/gui/vscroll_up_default.png");
+ SkinLoader::getImageFromTheme("vscroll_up_default.png");
buttons[0][0] =
- resman->getImage("graphics/gui/vscroll_down_default.png");
+ SkinLoader::getImageFromTheme("vscroll_down_default.png");
buttons[1][1] =
- resman->getImage("graphics/gui/vscroll_up_pressed.png");
+ SkinLoader::getImageFromTheme("vscroll_up_pressed.png");
buttons[0][1] =
- resman->getImage("graphics/gui/vscroll_down_pressed.png");
+ SkinLoader::getImageFromTheme("vscroll_down_pressed.png");
buttons[0][0]->setAlpha(mAlpha);
buttons[0][1]->setAlpha(mAlpha);
@@ -72,7 +70,7 @@ DropDown::DropDown(gcn::ListModel *listModel):
buttons[1][1]->setAlpha(mAlpha);
// get the border skin
- Image *boxBorder = resman->getImage("graphics/gui/deepbox.png");
+ Image *boxBorder = SkinLoader::getImageFromTheme("deepbox.png");
int gridx[4] = {0, 3, 28, 31};
int gridy[4] = {0, 3, 28, 31};
int a = 0, x, y;
diff --git a/src/gui/widgets/emoteshortcutcontainer.cpp b/src/gui/widgets/emoteshortcutcontainer.cpp
index 41be172f..dd13c679 100644
--- a/src/gui/widgets/emoteshortcutcontainer.cpp
+++ b/src/gui/widgets/emoteshortcutcontainer.cpp
@@ -32,10 +32,10 @@
#include "log.h"
#include "gui/palette.h"
+#include "gui/skin.h"
#include "resources/emotedb.h"
#include "resources/image.h"
-#include "resources/resourcemanager.h"
#include "utils/dtor.h"
@@ -49,9 +49,7 @@ EmoteShortcutContainer::EmoteShortcutContainer():
addMouseListener(this);
addWidgetListener(this);
- ResourceManager *resman = ResourceManager::getInstance();
-
- mBackgroundImg = resman->getImage("graphics/gui/item_shortcut_bgr.png");
+ mBackgroundImg = SkinLoader::getImageFromTheme("item_shortcut_bgr.png");
mBackgroundImg->setAlpha(config.getValue("guialpha", 0.8));
diff --git a/src/gui/widgets/itemcontainer.cpp b/src/gui/widgets/itemcontainer.cpp
index f801822c..b4270912 100644
--- a/src/gui/widgets/itemcontainer.cpp
+++ b/src/gui/widgets/itemcontainer.cpp
@@ -32,6 +32,7 @@
#include "gui/outfitwindow.h"
#include "gui/palette.h"
#include "gui/sdlinput.h"
+#include "gui/skin.h"
#include "gui/viewport.h"
#include "net/net.h"
@@ -39,7 +40,6 @@
#include "resources/image.h"
#include "resources/iteminfo.h"
-#include "resources/resourcemanager.h"
#include "utils/stringutils.h"
@@ -67,9 +67,7 @@ ItemContainer::ItemContainer(Inventory *inventory, bool forceQuantity):
mItemPopup = new ItemPopup;
setFocusable(true);
- ResourceManager *resman = ResourceManager::getInstance();
-
- mSelImg = resman->getImage("graphics/gui/selection.png");
+ mSelImg = SkinLoader::getImageFromTheme("selection.png");
if (!mSelImg)
logger->error("Unable to load selection.png");
diff --git a/src/gui/widgets/itemshortcutcontainer.cpp b/src/gui/widgets/itemshortcutcontainer.cpp
index 66e053d8..92a3e7d0 100644
--- a/src/gui/widgets/itemshortcutcontainer.cpp
+++ b/src/gui/widgets/itemshortcutcontainer.cpp
@@ -32,11 +32,11 @@
#include "gui/inventorywindow.h"
#include "gui/itempopup.h"
#include "gui/palette.h"
+#include "gui/skin.h"
#include "gui/viewport.h"
#include "resources/image.h"
#include "resources/iteminfo.h"
-#include "resources/resourcemanager.h"
#include "utils/stringutils.h"
@@ -50,9 +50,7 @@ ItemShortcutContainer::ItemShortcutContainer():
mItemPopup = new ItemPopup;
- ResourceManager *resman = ResourceManager::getInstance();
-
- mBackgroundImg = resman->getImage("graphics/gui/item_shortcut_bgr.png");
+ mBackgroundImg = SkinLoader::getImageFromTheme("item_shortcut_bgr.png");
mMaxItems = itemShortcut->getItemCount();
mBackgroundImg->setAlpha(config.getValue("guialpha", 0.8));
diff --git a/src/gui/widgets/playerbox.cpp b/src/gui/widgets/playerbox.cpp
index 23da2afd..24395db7 100644
--- a/src/gui/widgets/playerbox.cpp
+++ b/src/gui/widgets/playerbox.cpp
@@ -26,8 +26,9 @@
#include "graphics.h"
#include "player.h"
+#include "gui/skin.h"
+
#include "resources/image.h"
-#include "resources/resourcemanager.h"
#include "utils/dtor.h"
@@ -43,8 +44,7 @@ PlayerBox::PlayerBox(const Player *player):
if (instances == 0)
{
// Load the background skin
- ResourceManager *resman = ResourceManager::getInstance();
- Image *textbox = resman->getImage("graphics/gui/deepbox.png");
+ Image *textbox = SkinLoader::getImageFromTheme("deepbox.png");
int bggridx[4] = {0, 3, 28, 31};
int bggridy[4] = {0, 3, 28, 31};
int a = 0, x, y;
diff --git a/src/gui/widgets/popup.cpp b/src/gui/widgets/popup.cpp
index 391b0eed..970b21ec 100644
--- a/src/gui/widgets/popup.cpp
+++ b/src/gui/widgets/popup.cpp
@@ -27,6 +27,7 @@
#include "log.h"
#include "gui/skin.h"
+#include "gui/viewport.h"
#include "gui/widgets/windowcontainer.h"
@@ -186,3 +187,9 @@ void Popup::position(int x, int y)
setVisible(true);
requestMoveToTop();
}
+
+void Popup::mouseMoved(gcn::MouseEvent &event)
+{
+ if (viewport)
+ viewport->hideBeingPopup();
+}
diff --git a/src/gui/widgets/popup.h b/src/gui/widgets/popup.h
index 449c2f7b..5c9164f6 100644
--- a/src/gui/widgets/popup.h
+++ b/src/gui/widgets/popup.h
@@ -28,6 +28,8 @@
#include "gui/widgets/container.h"
+#include <guichan/mouselistener.hpp>
+
class Skin;
class WindowContainer;
@@ -43,7 +45,7 @@ class WindowContainer;
*
* \ingroup GUI
*/
-class Popup : public Container
+class Popup : public Container, public gcn::MouseListener
{
public:
/**
@@ -55,7 +57,7 @@ class Popup : public Container
* @param skin The location where the Popup's skin XML can be found.
*/
Popup(const std::string &name = "",
- const std::string &skin = "graphics/gui/gui.xml");
+ const std::string &skin = "window.xml");
/**
* Destructor. Deletes all the added widgets.
@@ -94,6 +96,8 @@ class Popup : public Container
*/
void setLocationRelativeTo(gcn::Widget *widget);
+ void mouseMoved(gcn::MouseEvent &event);
+
/**
* Sets the minimum width of the popup.
*/
diff --git a/src/gui/widgets/progressbar.cpp b/src/gui/widgets/progressbar.cpp
index db2a8692..31c32132 100644
--- a/src/gui/widgets/progressbar.cpp
+++ b/src/gui/widgets/progressbar.cpp
@@ -30,7 +30,6 @@
#include "gui/skin.h"
#include "resources/image.h"
-#include "resources/resourcemanager.h"
#include "utils/dtor.h"
@@ -59,8 +58,7 @@ ProgressBar::ProgressBar(float progress,
if (mInstances == 0)
{
- ResourceManager *resman = ResourceManager::getInstance();
- Image *dBorders = resman->getImage("graphics/gui/vscroll_grey.png");
+ Image *dBorders = SkinLoader::getImageFromTheme("vscroll_grey.png");
mBorder.grid[0] = dBorders->getSubImage(0, 0, 4, 4);
mBorder.grid[1] = dBorders->getSubImage(4, 0, 3, 4);
mBorder.grid[2] = dBorders->getSubImage(7, 0, 4, 4);
diff --git a/src/gui/widgets/progressindicator.cpp b/src/gui/widgets/progressindicator.cpp
index d1b6bb87..f88f6045 100644
--- a/src/gui/widgets/progressindicator.cpp
+++ b/src/gui/widgets/progressindicator.cpp
@@ -20,6 +20,8 @@
#include "progressindicator.h"
+#include "gui/skin.h"
+
#include "resources/animation.h"
#include "resources/imageset.h"
#include "resources/resourcemanager.h"
@@ -31,9 +33,8 @@
ProgressIndicator::ProgressIndicator()
{
- ResourceManager *rm = ResourceManager::getInstance();
- ImageSet *images = rm->getImageSet("graphics/gui/progress-indicator.png",
- 32, 32);
+ ImageSet *images =
+ SkinLoader::getImageSetFromTheme("progress-indicator.png", 32, 32);
Animation *anim = new Animation;
for (ImageSet::size_type i = 0; i < images->size(); ++i)
diff --git a/src/gui/widgets/radiobutton.cpp b/src/gui/widgets/radiobutton.cpp
index adbc4dd7..41c8faf7 100644
--- a/src/gui/widgets/radiobutton.cpp
+++ b/src/gui/widgets/radiobutton.cpp
@@ -24,8 +24,9 @@
#include "configuration.h"
#include "graphics.h"
+#include "gui/skin.h"
+
#include "resources/image.h"
-#include "resources/resourcemanager.h"
int RadioButton::instances = 0;
float RadioButton::mAlpha = 1.0;
@@ -43,13 +44,12 @@ RadioButton::RadioButton(const std::string &caption, const std::string &group,
{
if (instances == 0)
{
- ResourceManager *resman = ResourceManager::getInstance();
- radioNormal = resman->getImage("graphics/gui/radioout.png");
- radioChecked = resman->getImage("graphics/gui/radioin.png");
- radioDisabled = resman->getImage("graphics/gui/radioout.png");
- radioDisabledChecked = resman->getImage("graphics/gui/radioin.png");
- radioNormalHi = resman->getImage("graphics/gui/radioout_highlight.png");
- radioCheckedHi = resman->getImage("graphics/gui/radioin_highlight.png");
+ radioNormal = SkinLoader::getImageFromTheme("radioout.png");
+ radioChecked = SkinLoader::getImageFromTheme("radioin.png");
+ radioDisabled = SkinLoader::getImageFromTheme("radioout.png");
+ radioDisabledChecked = SkinLoader::getImageFromTheme("radioin.png");
+ radioNormalHi = SkinLoader::getImageFromTheme("radioout_highlight.png");
+ radioCheckedHi = SkinLoader::getImageFromTheme("radioin_highlight.png");
radioNormal->setAlpha(mAlpha);
radioChecked->setAlpha(mAlpha);
radioDisabled->setAlpha(mAlpha);
diff --git a/src/gui/widgets/resizegrip.cpp b/src/gui/widgets/resizegrip.cpp
index 106118da..d0b9b845 100644
--- a/src/gui/widgets/resizegrip.cpp
+++ b/src/gui/widgets/resizegrip.cpp
@@ -24,8 +24,9 @@
#include "configuration.h"
#include "graphics.h"
+#include "gui/skin.h"
+
#include "resources/image.h"
-#include "resources/resourcemanager.h"
#include <guichan/graphics.hpp>
@@ -38,8 +39,7 @@ ResizeGrip::ResizeGrip(const std::string &image)
if (mInstances == 0)
{
// Load the grip image
- ResourceManager *resman = ResourceManager::getInstance();
- gripImage = resman->getImage(image);
+ gripImage = SkinLoader::getImageFromTheme(image);
gripImage->setAlpha(mAlpha);
}
diff --git a/src/gui/widgets/resizegrip.h b/src/gui/widgets/resizegrip.h
index 4cc195cc..5ef93f29 100644
--- a/src/gui/widgets/resizegrip.h
+++ b/src/gui/widgets/resizegrip.h
@@ -39,7 +39,7 @@ class ResizeGrip : public gcn::Widget
/**
* Constructor.
*/
- ResizeGrip(const std::string &image = "graphics/gui/resize.png");
+ ResizeGrip(const std::string &image = "resize.png");
/**
* Destructor.
diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp
index b3e28329..dea99e8e 100644
--- a/src/gui/widgets/scrollarea.cpp
+++ b/src/gui/widgets/scrollarea.cpp
@@ -27,7 +27,6 @@
#include "gui/skin.h"
#include "resources/image.h"
-#include "resources/resourcemanager.h"
#include "utils/dtor.h"
@@ -96,8 +95,7 @@ void ScrollArea::init()
if (instances == 0)
{
// Load the background skin
- ResourceManager *resman = ResourceManager::getInstance();
- Image *textbox = resman->getImage("graphics/gui/deepbox.png");
+ Image *textbox = SkinLoader::getImageFromTheme("deepbox.png");
const int bggridx[4] = {0, 3, 28, 31};
const int bggridy[4] = {0, 3, 28, 31};
int a = 0, x, y;
@@ -118,8 +116,8 @@ void ScrollArea::init()
textbox->decRef();
// Load vertical scrollbar skin
- Image *vscroll = resman->getImage("graphics/gui/vscroll_grey.png");
- Image *vscrollHi = resman->getImage("graphics/gui/vscroll_highlight.png");
+ Image *vscroll = SkinLoader::getImageFromTheme("vscroll_grey.png");
+ Image *vscrollHi = SkinLoader::getImageFromTheme("vscroll_highlight.png");
int vsgridx[4] = {0, 4, 7, 11};
int vsgridy[4] = {0, 4, 15, 19};
@@ -147,21 +145,21 @@ void ScrollArea::init()
vscrollHi->decRef();
buttons[UP][0] =
- resman->getImage("graphics/gui/vscroll_up_default.png");
+ SkinLoader::getImageFromTheme("vscroll_up_default.png");
buttons[DOWN][0] =
- resman->getImage("graphics/gui/vscroll_down_default.png");
+ SkinLoader::getImageFromTheme("vscroll_down_default.png");
buttons[LEFT][0] =
- resman->getImage("graphics/gui/hscroll_left_default.png");
+ SkinLoader::getImageFromTheme("hscroll_left_default.png");
buttons[RIGHT][0] =
- resman->getImage("graphics/gui/hscroll_right_default.png");
+ SkinLoader::getImageFromTheme("hscroll_right_default.png");
buttons[UP][1] =
- resman->getImage("graphics/gui/vscroll_up_pressed.png");
+ SkinLoader::getImageFromTheme("vscroll_up_pressed.png");
buttons[DOWN][1] =
- resman->getImage("graphics/gui/vscroll_down_pressed.png");
+ SkinLoader::getImageFromTheme("vscroll_down_pressed.png");
buttons[LEFT][1] =
- resman->getImage("graphics/gui/hscroll_left_pressed.png");
+ SkinLoader::getImageFromTheme("hscroll_left_pressed.png");
buttons[RIGHT][1] =
- resman->getImage("graphics/gui/hscroll_right_pressed.png");
+ SkinLoader::getImageFromTheme("hscroll_right_pressed.png");
}
instances++;
diff --git a/src/gui/widgets/slider.cpp b/src/gui/widgets/slider.cpp
index f02c6b5c..af36518a 100644
--- a/src/gui/widgets/slider.cpp
+++ b/src/gui/widgets/slider.cpp
@@ -27,7 +27,6 @@
#include "gui/skin.h"
#include "resources/image.h"
-#include "resources/resourcemanager.h"
Image *Slider::hStart, *Slider::hMid, *Slider::hEnd, *Slider::hGrip;
Image *Slider::vStart, *Slider::vMid, *Slider::vEnd, *Slider::vGrip;
@@ -83,9 +82,8 @@ void Slider::init()
// Load resources
if (mInstances == 0)
{
- ResourceManager *resman = ResourceManager::getInstance();
- Image *slider = resman->getImage("graphics/gui/slider.png");
- Image *sliderHi = resman->getImage("graphics/gui/slider_hilight.png");
+ Image *slider = SkinLoader::getImageFromTheme("slider.png");
+ Image *sliderHi = SkinLoader::getImageFromTheme("slider_hilight.png");
x = 0; y = 0;
w = 15; h = 6;
diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp
index 68dc2190..17145eae 100644
--- a/src/gui/widgets/tab.cpp
+++ b/src/gui/widgets/tab.cpp
@@ -30,7 +30,6 @@
#include "gui/widgets/tabbedarea.h"
#include "resources/image.h"
-#include "resources/resourcemanager.h"
#include "utils/dtor.h"
@@ -55,10 +54,10 @@ struct TabData
};
static TabData const data[TAB_COUNT] = {
- { "graphics/gui/tab.png", 0, 0 },
- { "graphics/gui/tab_hilight.png", 9, 4 },
- { "graphics/gui/tabselected.png", 16, 19 },
- { "graphics/gui/tab.png", 25, 23 }
+ { "tab.png", 0, 0 },
+ { "tab_hilight.png", 9, 4 },
+ { "tabselected.png", 16, 19 },
+ { "tab.png", 25, 23 }
};
ImageRect Tab::tabImg[TAB_COUNT];
@@ -91,14 +90,13 @@ void Tab::init()
if (mInstances == 0)
{
// Load the skin
- ResourceManager *resman = ResourceManager::getInstance();
Image *tab[TAB_COUNT];
int a, x, y, mode;
for (mode = 0; mode < TAB_COUNT; mode++)
{
- tab[mode] = resman->getImage(data[mode].file);
+ tab[mode] = SkinLoader::getImageFromTheme(data[mode].file);
a = 0;
for (y = 0; y < 3; y++)
{
diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp
index 278b4cb9..e599c37d 100644
--- a/src/gui/widgets/textfield.cpp
+++ b/src/gui/widgets/textfield.cpp
@@ -29,7 +29,6 @@
#include "gui/skin.h"
#include "resources/image.h"
-#include "resources/resourcemanager.h"
#include "utils/copynpaste.h"
#include "utils/dtor.h"
@@ -53,8 +52,7 @@ TextField::TextField(const std::string &text, bool loseFocusOnTab):
if (instances == 0)
{
// Load the skin
- ResourceManager *resman = ResourceManager::getInstance();
- Image *textbox = resman->getImage("graphics/gui/deepbox.png");
+ Image *textbox = SkinLoader::getImageFromTheme("deepbox.png");
int gridx[4] = {0, 3, 28, 31};
int gridy[4] = {0, 3, 28, 31};
int a = 0, x, y;
diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp
index 8505f552..83c918cf 100644
--- a/src/gui/widgets/window.cpp
+++ b/src/gui/widgets/window.cpp
@@ -27,6 +27,7 @@
#include "gui/gui.h"
#include "gui/palette.h"
#include "gui/skin.h"
+#include "gui/viewport.h"
#include "gui/widgets/layout.h"
#include "gui/widgets/resizegrip.h"
@@ -430,6 +431,9 @@ void Window::mouseMoved(gcn::MouseEvent &event)
default:
gui->setCursorType(Gui::CURSOR_POINTER);
}
+
+ if (viewport)
+ viewport->hideBeingPopup();
}
void Window::mouseDragged(gcn::MouseEvent &event)
diff --git a/src/gui/widgets/window.h b/src/gui/widgets/window.h
index a54016bc..b72be9d4 100644
--- a/src/gui/widgets/window.h
+++ b/src/gui/widgets/window.h
@@ -57,7 +57,7 @@ class Window : public gcn::Window, gcn::WidgetListener
* @param skin The location where the window's skin XML can be found.
*/
Window(const std::string &caption = "Window", bool modal = false,
- Window *parent = NULL, const std::string &skin = "graphics/gui/gui.xml");
+ Window *parent = NULL, const std::string &skin = "window.xml");
/**
* Destructor. Deletes all the added widgets.
diff --git a/src/item.cpp b/src/item.cpp
index e20ef57a..378c7efe 100644
--- a/src/item.cpp
+++ b/src/item.cpp
@@ -21,6 +21,8 @@
#include "item.h"
+#include "gui/skin.h"
+
#include "resources/image.h"
#include "resources/iteminfo.h"
#include "resources/resourcemanager.h"
@@ -60,8 +62,8 @@ void Item::setId(int id)
mDrawImage = resman->getImage(imagePath);
if (!mImage)
- mImage = resman->getImage("graphics/gui/unknown-item.png");
+ mImage = SkinLoader::getImageFromTheme("unknown-item.png");
if (!mDrawImage)
- mDrawImage = resman->getImage("graphics/gui/unknown-item.png");
+ mDrawImage = SkinLoader::getImageFromTheme("unknown-item.png");
}
diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp
index 8d1f0bcd..7b462c25 100644
--- a/src/keyboardconfig.cpp
+++ b/src/keyboardconfig.cpp
@@ -156,15 +156,24 @@ bool KeyboardConfig::hasConflicts()
{
for (j = i, j++; j < KEY_TOTAL; j++)
{
- // Allow for item shortcut and emote keys to overlap
- // as well as emote and ignore keys, but no other keys
- if (!((((i >= KEY_SHORTCUT_1) && (i <= KEY_SHORTCUT_12)) &&
- ((j >= KEY_EMOTE_1) && (j <= KEY_EMOTE_12))) ||
- ((i == KEY_TOGGLE_CHAT) && (j == KEY_OK)) ||
- ((i == KEY_EMOTE) &&
- (j == KEY_IGNORE_INPUT_1 || j == KEY_IGNORE_INPUT_2))) &&
- (mKey[i].value == mKey[j].value)
- )
+ // Allow collisions between shortcut and emote keys
+ if ((i >= KEY_SHORTCUT_1 && i <= KEY_SHORTCUT_12) && (j >= KEY_EMOTE_1 && j <= KEY_EMOTE_12))
+ continue;
+
+ // Why?
+ if (i == KEY_TOGGLE_CHAT && j == KEY_OK)
+ continue;
+
+ // Ignore keys can collide with anything.
+ if (j == KEY_IGNORE_INPUT_1 || j == KEY_IGNORE_INPUT_2)
+ continue;
+
+ // If the one of the keys is not set, then no conflict can happen.
+ if (mKey[i].value == -1 || mKey[j].value == -1)
+ continue;
+
+ // Finally test to see if a conflict DOES exist.
+ if (mKey[i].value == mKey[j].value)
{
mBindError = strprintf(_("Conflict \"%s\" and \"%s\" keys. "
"Resolve them, or gameplay may result"
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 8ce03bba..8c918a97 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -43,6 +43,7 @@
#include "gui/ministatus.h"
#include "gui/palette.h"
#include "gui/skilldialog.h"
+#include "gui/skin.h"
#include "gui/statuswindow.h"
#include "gui/storagewindow.h"
@@ -102,11 +103,6 @@ LocalPlayer::LocalPlayer(int id, int job):
mLocalWalkTime(-1),
mMessageTime(0)
{
- // Variable to keep the local player from doing certain actions before a map
- // is initialized. e.g. drawing a player's name using the TextManager, since
- // it appears to be dependant upon map coordinates for updating drawing.
- mMapInitialized = false;
-
mUpdateName = true;
mTextColor = &guiPalette->getColor(Palette::PLAYER);
@@ -1050,18 +1046,12 @@ void LocalPlayer::handleStatusEffect(StatusEffect *effect, int effectId)
void LocalPlayer::initTargetCursor()
{
// Load target cursors
- loadTargetCursor("graphics/gui/target-cursor-blue-s.png", 44, 35,
- false, TC_SMALL);
- loadTargetCursor("graphics/gui/target-cursor-red-s.png", 44, 35,
- true, TC_SMALL);
- loadTargetCursor("graphics/gui/target-cursor-blue-m.png", 62, 44,
- false, TC_MEDIUM);
- loadTargetCursor("graphics/gui/target-cursor-red-m.png", 62, 44,
- true, TC_MEDIUM);
- loadTargetCursor("graphics/gui/target-cursor-blue-l.png", 82, 60,
- false, TC_LARGE);
- loadTargetCursor("graphics/gui/target-cursor-red-l.png", 82, 60,
- true, TC_LARGE);
+ loadTargetCursor("target-cursor-blue-s.png", 44, 35, false, TC_SMALL);
+ loadTargetCursor("target-cursor-red-s.png", 44, 35, true, TC_SMALL);
+ loadTargetCursor("target-cursor-blue-m.png", 62, 44, false, TC_MEDIUM);
+ loadTargetCursor("target-cursor-red-m.png", 62, 44, true, TC_MEDIUM);
+ loadTargetCursor("target-cursor-blue-l.png", 82, 60, false, TC_LARGE);
+ loadTargetCursor("target-cursor-red-l.png", 82, 60, true, TC_LARGE);
}
void LocalPlayer::loadTargetCursor(const std::string &filename,
@@ -1071,9 +1061,8 @@ void LocalPlayer::loadTargetCursor(const std::string &filename,
assert(size > -1);
assert(size < 3);
- ResourceManager *resman = ResourceManager::getInstance();
-
- ImageSet *currentImageSet = resman->getImageSet(filename, width, height);
+ ImageSet *currentImageSet = SkinLoader::getImageSetFromTheme(filename,
+ width, height);
Animation *anim = new Animation;
for (unsigned int i = 0; i < currentImageSet->size(); ++i)
diff --git a/src/localplayer.h b/src/localplayer.h
index 919b5540..69fd4d0f 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -391,17 +391,6 @@ class LocalPlayer : public Player
*/
bool getCheckNameSetting() const { return mUpdateName; }
- /**
- * Set if the current map is initialized.
- */
- void setMapInitialized(bool initialized)
- { mMapInitialized = initialized; }
-
- /**
- * Tells if the current map is initialized.
- */
- bool isMapInitialized() const { return mMapInitialized; }
-
/** Keeps the Equipment related values */
const std::auto_ptr<Equipment> mEquipment;
@@ -410,8 +399,6 @@ class LocalPlayer : public Player
/** Whether or not the name settings have changed */
bool mUpdateName;
- bool mMapInitialized; /**< Whether or not the map is available yet */
-
virtual void handleStatusEffect(StatusEffect *effect, int effectId);
// Colors don't change for local player
diff --git a/src/main.h b/src/main.h
index 03e0c7b3..3f30ef14 100644
--- a/src/main.h
+++ b/src/main.h
@@ -55,7 +55,7 @@
#elif defined WIN32
#include "winver.h"
#elif defined __APPLE__
-#define PACKAGE_VERSION "0.0.29.1"
+#define PACKAGE_VERSION "1.0.0"
#endif
#ifdef PACKAGE_VERSION
@@ -64,6 +64,33 @@
#define FULL_VERSION "Unknown Version"
#endif
+#ifdef PACKAGE_OS
+// If it's already been defined, let's not change it
+#elif defined __APPLE__
+#define PACKAGE_OS "Apple"
+#elif defined __FreeBSD__ || defined __DragonFly__
+#define PACKAGE_OS "FreeBSD"
+#elif defined __NetBSD__
+#define PACKAGE_OS "NetBSD"
+#elif defined __OpenBSD__
+#define PACKAGE_OS "OpenBSD"
+#elif defined __linux__ || defined __linux
+#define PACKAGE_OS "Linux"
+#elif defined __GNU__
+#define PACKAGE_OS "GNU Hurd"
+#elif defined WIN32 || defined _WIN32 || defined __WIN32__ || defined __NT__ \
+ || defined WIN64 || defined _WIN64 || defined __WIN64__
+#define PACKAGE_OS "Windows"
+#else
+#define PACKAGE_OS "Other"
+#endif
+
+#ifdef PACKAGE_VERSION
+#define PACKAGE_EXTENDED_VERSION "Mana/" PACKAGE_VERSION " (" PACKAGE_OS "; %s)"
+#else
+#define PACKAGE_EXTENDED_VERSION "Mana (" PACKAGE_OS "; %s)"
+#endif
+
#ifndef PKG_DATADIR
#define PKG_DATADIR ""
#endif
diff --git a/src/net/download.cpp b/src/net/download.cpp
index ba5b6b35..2b96a6b9 100644
--- a/src/net/download.cpp
+++ b/src/net/download.cpp
@@ -20,9 +20,12 @@
#include "net/download.h"
+#include "configuration.h"
#include "log.h"
#include "main.h"
+#include "utils/stringutils.h"
+
#include <curl/curl.h>
#include <SDL.h>
@@ -217,11 +220,9 @@ int Download::downloadThread(void *ptr)
curl_easy_setopt(d->mCurl, CURLOPT_WRITEDATA, file);
}
-#ifdef PACKAGE_VERSION
- curl_easy_setopt(d->mCurl, CURLOPT_USERAGENT, "Mana/" PACKAGE_VERSION);
-#else
- curl_easy_setopt(d->mCurl, CURLOPT_USERAGENT, "Mana");
-#endif
+ curl_easy_setopt(d->mCurl, CURLOPT_USERAGENT,
+ strprintf(PACKAGE_EXTENDED_VERSION, branding
+ .getValue("appShort", "mana").c_str()).c_str());
curl_easy_setopt(d->mCurl, CURLOPT_ERRORBUFFER, d->mError);
curl_easy_setopt(d->mCurl, CURLOPT_URL, d->mUrl.c_str());
curl_easy_setopt(d->mCurl, CURLOPT_NOPROGRESS, 0);
diff --git a/src/net/ea/generalhandler.cpp b/src/net/ea/generalhandler.cpp
index 6ca853fb..021ae08d 100644
--- a/src/net/ea/generalhandler.cpp
+++ b/src/net/ea/generalhandler.cpp
@@ -38,6 +38,7 @@
#include "net/ea/chathandler.h"
#include "net/ea/charserverhandler.h"
#include "net/ea/gamehandler.h"
+#include "net/ea/guildhandler.h"
#include "net/ea/inventoryhandler.h"
#include "net/ea/itemhandler.h"
#include "net/ea/loginhandler.h"
@@ -79,6 +80,7 @@ GeneralHandler::GeneralHandler():
mCharHandler(new CharServerHandler),
mChatHandler(new ChatHandler),
mGameHandler(new GameHandler),
+ mGuildHandler(new GuildHandler),
mInventoryHandler(new InventoryHandler),
mItemHandler(new ItemHandler),
mLoginHandler(new LoginHandler),
@@ -162,6 +164,7 @@ void GeneralHandler::load()
mNetwork->registerHandler(mChatHandler.get());
mNetwork->registerHandler(mCharHandler.get());
mNetwork->registerHandler(mGameHandler.get());
+ mNetwork->registerHandler(mGuildHandler.get());
mNetwork->registerHandler(mInventoryHandler.get());
mNetwork->registerHandler(mItemHandler.get());
mNetwork->registerHandler(mLoginHandler.get());
diff --git a/src/net/ea/generalhandler.h b/src/net/ea/generalhandler.h
index 579b27b5..464f8bc8 100644
--- a/src/net/ea/generalhandler.h
+++ b/src/net/ea/generalhandler.h
@@ -60,6 +60,7 @@ class GeneralHandler : public MessageHandler, public Net::GeneralHandler
MessageHandlerPtr mCharHandler;
MessageHandlerPtr mChatHandler;
MessageHandlerPtr mGameHandler;
+ MessageHandlerPtr mGuildHandler;
MessageHandlerPtr mInventoryHandler;
MessageHandlerPtr mItemHandler;
MessageHandlerPtr mLoginHandler;
diff --git a/src/net/ea/messageout.cpp b/src/net/ea/messageout.cpp
index 9e7f2b15..844580a9 100644
--- a/src/net/ea/messageout.cpp
+++ b/src/net/ea/messageout.cpp
@@ -125,4 +125,4 @@ void MessageOut::writeCoordinates(unsigned short x, unsigned short y,
data[2] |= direction;
}
-}
+} // namespace EAthena
diff --git a/src/net/ea/network.cpp b/src/net/ea/network.cpp
index 3b8ad509..0467241f 100644
--- a/src/net/ea/network.cpp
+++ b/src/net/ea/network.cpp
@@ -475,4 +475,4 @@ Uint16 Network::readWord(int pos)
#endif
}
-}
+} // namespace EAthena
diff --git a/src/net/ea/network.h b/src/net/ea/network.h
index baaefb4a..0b391bf0 100644
--- a/src/net/ea/network.h
+++ b/src/net/ea/network.h
@@ -125,6 +125,6 @@ class Network
static Network *mInstance;
};
-}
+} // namespace EAthena
#endif // NET_EA_NETWORK_H
diff --git a/src/net/ea/npchandler.cpp b/src/net/ea/npchandler.cpp
index 06a39045..dfd56cf1 100644
--- a/src/net/ea/npchandler.cpp
+++ b/src/net/ea/npchandler.cpp
@@ -72,10 +72,12 @@ void NpcHandler::handleMessage(Net::MessageIn &msg)
if (msg.getId() == SMSG_NPC_CLOSE)
{
closeDialog(npcId);
+ return;
}
else if (msg.getId() == SMSG_NPC_NEXT)
{
nextDialog(npcId);
+ return;
}
else
{
diff --git a/src/net/guildhandler.h b/src/net/guildhandler.h
index 75683944..1696b2d5 100644
--- a/src/net/guildhandler.h
+++ b/src/net/guildhandler.h
@@ -32,6 +32,10 @@ namespace Net {
class GuildHandler
{
public:
+ virtual ~GuildHandler() {}
+
+ virtual bool isSupported() { return false; }
+
virtual void create(const std::string &name) = 0;
virtual void invite(int guildId, const std::string &name) = 0;
@@ -56,8 +60,6 @@ class GuildHandler
bool response) = 0;
virtual void endAlliance(int guildId, int otherGuildId) = 0;
-
- virtual ~GuildHandler() {}
};
}
diff --git a/src/net/manaserv/guildhandler.h b/src/net/manaserv/guildhandler.h
index 1b6d51b5..9929d135 100644
--- a/src/net/manaserv/guildhandler.h
+++ b/src/net/manaserv/guildhandler.h
@@ -33,6 +33,8 @@ class GuildHandler : public Net::GuildHandler, public MessageHandler
public:
GuildHandler();
+ bool isSupported() { return true; }
+
void handleMessage(Net::MessageIn &msg);
void create(const std::string &name);
diff --git a/src/net/manaserv/messageout.cpp b/src/net/manaserv/messageout.cpp
index 887d91d6..8779c5f6 100644
--- a/src/net/manaserv/messageout.cpp
+++ b/src/net/manaserv/messageout.cpp
@@ -61,4 +61,4 @@ void MessageOut::writeInt32(Sint32 value)
mPos += 4;
}
-}
+} // namespace ManaServ
diff --git a/src/net/serverinfo.h b/src/net/serverinfo.h
index ae06984b..63d50ce4 100644
--- a/src/net/serverinfo.h
+++ b/src/net/serverinfo.h
@@ -41,10 +41,13 @@ public:
std::string hostname;
unsigned short port;
+ bool save;
+
ServerInfo()
{
type = UNKNOWN;
port = 0;
+ save = false;
}
ServerInfo(const ServerInfo &info)
@@ -53,6 +56,12 @@ public:
name = info.name;
hostname = info.hostname;
port = info.port;
+ save = info.save;
+ }
+
+ bool isValid() const
+ {
+ return !(hostname.empty() || port == 0 || type == UNKNOWN);
}
void clear()
@@ -63,13 +72,13 @@ public:
port = 0;
}
- bool operator==(const ServerInfo &other)
+ bool operator==(const ServerInfo &other) const
{
return (type == other.type && hostname == other.hostname &&
port == other.port);
}
- bool operator!=(const ServerInfo &other)
+ bool operator!=(const ServerInfo &other) const
{
return (type != other.type || hostname != other.hostname ||
port != other.port);
diff --git a/src/npc.cpp b/src/npc.cpp
index d104e840..38aecab8 100644
--- a/src/npc.cpp
+++ b/src/npc.cpp
@@ -86,7 +86,7 @@ void NPC::setSprite(unsigned int slot, int id, const std::string &color)
// Do nothing
}
-const bool NPC::isTalking()
+bool NPC::isTalking()
{
return NpcDialog::isActive() || BuyDialog::isActive() ||
SellDialog::isActive() || BuySellDialog::isActive() ||
diff --git a/src/npc.h b/src/npc.h
index e4207ea7..c7db58f1 100644
--- a/src/npc.h
+++ b/src/npc.h
@@ -55,7 +55,7 @@ class NPC : public Player
virtual int getNumberOfLayers() const
{ return 1; }
- static const bool isTalking();
+ static bool isTalking();
protected:
/**
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index 8b5ecca3..24f346f7 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -21,6 +21,7 @@
#include "resources/resourcemanager.h"
+#include "client.h"
#include "log.h"
#include "resources/dye.h"
@@ -211,7 +212,7 @@ std::string ResourceManager::getPath(const std::string &file)
else
{
// if not found in search path return the default path
- path = std::string(PKG_DATADIR) + std::string("data") + "/" + file;
+ path = Client::getPackageDirectory() + "/" + file;
}
return path;
diff --git a/src/text.cpp b/src/text.cpp
index 0b6b77ea..ce09146f 100644
--- a/src/text.cpp
+++ b/src/text.cpp
@@ -28,6 +28,7 @@
#include "gui/gui.h"
#include "gui/palette.h"
+#include "gui/skin.h"
#include "resources/resourcemanager.h"
#include "resources/image.h"
@@ -49,8 +50,7 @@ Text::Text(const std::string &text, int x, int y,
if (textManager == 0)
{
textManager = new TextManager;
- ResourceManager *resman = ResourceManager::getInstance();
- Image *sbImage = resman->getImage("graphics/gui/bubble.png|W:#"
+ Image *sbImage = SkinLoader::getImageFromTheme("bubble.png|W:#"
+ config.getValue("speechBubblecolor", "000000"));
mBubble.grid[0] = sbImage->getSubImage(0, 0, 5, 5);
mBubble.grid[1] = sbImage->getSubImage(5, 0, 5, 5);
diff --git a/src/utils/mkdir.cpp b/src/utils/mkdir.cpp
index 223abe71..43f5264e 100644
--- a/src/utils/mkdir.cpp
+++ b/src/utils/mkdir.cpp
@@ -24,10 +24,10 @@
#if defined WIN32
#include <windows.h>
-#else
-#include <sys/stat.h>
#endif
+#include <sys/stat.h>
+
#ifdef _MKDIR_TEST_
// compile with -D_MKDIR_TEST_ to get a standalone binary
#include <cstdio>
@@ -67,12 +67,24 @@ int mkdir_r(const char *pathname) {
*p = '/';
continue;
}
+
+ // check if the name already exists, but not as directory
+ struct stat statbuf;
+ if (!stat(tmp, &statbuf))
+ {
+ if (S_ISDIR(statbuf.st_mode))
+ {
+ *p = '/';
+ continue;
+ }
+ else
+ return -1;
+ }
+
#if defined WIN32
- if (!CreateDirectory(tmp, 0) &&
- GetLastError() != ERROR_ALREADY_EXISTS)
+ if (!CreateDirectory(tmp, 0))
#else
- if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) &&
- errno != EEXIST)
+ if (mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
#endif
{
#if defined WIN32