From d5d10a30ceb4a9d6bbb19fe8cbcf878cd841cd53 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Fri, 30 Oct 2009 07:55:47 -0600 Subject: Support switching characters under eAthena --- src/game.cpp | 61 ++++++++++++++++++++-------------------- src/gui/quitdialog.cpp | 23 ++++++--------- src/gui/quitdialog.h | 3 +- src/gui/statuswindow.cpp | 4 +++ src/main.cpp | 60 ++++++++++++++++++++++++--------------- src/net/charhandler.h | 4 ++- src/net/ea/beinghandler.cpp | 3 ++ src/net/ea/charserverhandler.cpp | 7 +++++ src/net/ea/charserverhandler.h | 2 ++ src/net/ea/gamehandler.cpp | 18 ++++++++++++ src/net/ea/generalhandler.cpp | 1 + src/net/ea/protocol.h | 3 ++ src/net/manaserv/charhandler.cpp | 5 ++++ src/net/manaserv/charhandler.h | 2 ++ 14 files changed, 125 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/game.cpp b/src/game.cpp index ae079af2..03068769 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -97,7 +97,6 @@ std::string map_path; -bool done = false; volatile int tick_time; volatile int fps = 0, frame = 0; @@ -166,7 +165,7 @@ namespace { void action(const gcn::ActionEvent &event) { if (event.getId() == "yes" || event.getId() == "ok") - done = true; + state = STATE_EXIT; disconnectedDialog = NULL; } @@ -274,6 +273,8 @@ static void createGuiWindows() Net::getGeneralHandler()->guiWindowsLoaded(); } +#define del_0(X) { delete X; X = 0; } + /** * Destroy all the globally accessible gui windows */ @@ -281,42 +282,40 @@ static void destroyGuiWindows() { Net::getGeneralHandler()->guiWindowsUnloaded(); logger->setChatWindow(NULL); - delete localChatTab; // Need to do this first, so it can remove itself - delete chatWindow; - delete statusWindow; - delete miniStatusWindow; - delete buyDialog; - delete sellDialog; + del_0(localChatTab); // Need to do this first, so it can remove itself + del_0(chatWindow); + del_0(statusWindow); + del_0(miniStatusWindow); + del_0(buyDialog); + del_0(sellDialog); #ifdef EATHENA_SUPPORT - delete buySellDialog; + del_0(buySellDialog); #endif - delete inventoryWindow; - delete partyWindow; - delete npcDialog; - delete npcPostDialog; + del_0(inventoryWindow); + del_0(partyWindow); + del_0(npcDialog); + del_0(npcPostDialog); #ifdef MANASERV_SUPPORT - delete buddyWindow; - delete guildWindow; + del_0(buddyWindow); + del_0(guildWindow); #endif - delete skillDialog; - delete minimap; - delete equipmentWindow; - delete tradeWindow; - delete helpWindow; - delete debugWindow; - delete itemShortcutWindow; - delete emoteShortcutWindow; - delete storageWindow; - delete outfitWindow; - delete specialsWindow; + del_0(skillDialog); + del_0(minimap); + del_0(equipmentWindow); + del_0(tradeWindow); + del_0(helpWindow); + del_0(debugWindow); + del_0(itemShortcutWindow); + del_0(emoteShortcutWindow); + del_0(storageWindow); + del_0(outfitWindow); + del_0(specialsWindow); } Game::Game(): mLastTarget(Being::UNKNOWN), mLogicCounterId(0), mSecondsCounterId(0) { - done = false; - createGuiWindows(); mWindowMenu = new WindowMenu; @@ -454,7 +453,7 @@ void Game::logic() int gameTime = tick_time; mDrawTime = tick_time * MILLISECONDS_IN_A_TICK; - while (!done) + while (state == STATE_GAME) { if (Map *map = engine->getCurrentMap()) map->update(get_elapsed_time(gameTime)); @@ -738,7 +737,7 @@ void Game::handleInput() case KeyboardConfig::KEY_QUIT: if (!quitDialog) { - quitDialog = new QuitDialog(&done, &quitDialog); + quitDialog = new QuitDialog(&quitDialog); quitDialog->requestMoveToTop(); } else @@ -915,7 +914,7 @@ void Game::handleInput() // Quit event else if (event.type == SDL_QUIT) { - done = true; + state = STATE_EXIT; } // Push input to GUI when not used diff --git a/src/gui/quitdialog.cpp b/src/gui/quitdialog.cpp index 8003cb2c..4a5cfe33 100644 --- a/src/gui/quitdialog.cpp +++ b/src/gui/quitdialog.cpp @@ -26,10 +26,15 @@ #include "gui/widgets/button.h" #include "gui/widgets/radiobutton.h" +#include "net/charhandler.h" +#include "net/net.h" + #include "utils/gettext.h" -QuitDialog::QuitDialog(bool* quitGame, QuitDialog** pointerToMe): - Window(_("Quit"), true, NULL), mQuitGame(quitGame), mMyPointer(pointerToMe) +#include + +QuitDialog::QuitDialog(QuitDialog** pointerToMe): + Window(_("Quit"), true, NULL), mMyPointer(pointerToMe) { mLogoutQuit = new RadioButton(_("Quit"), "quitdialog"); @@ -104,27 +109,17 @@ void QuitDialog::action(const gcn::ActionEvent &event) } else if (mLogoutQuit->isSelected()) { - if ((state == STATE_GAME) && (mQuitGame)) - { - *mQuitGame = true; - } - state = STATE_EXIT; } else if (mSwitchAccountServer->isSelected()) { - if ((state == STATE_GAME) && (mQuitGame)) - { - *mQuitGame = true; - } - state = STATE_SWITCH_SERVER; } else if (mSwitchCharacter->isSelected()) { - if (mQuitGame) *mQuitGame = true; + assert(state == STATE_GAME); - state = STATE_SWITCH_CHARACTER; + Net::getCharHandler()->switchCharacter(); } } scheduleDelete(); diff --git a/src/gui/quitdialog.h b/src/gui/quitdialog.h index 252c283d..04ce6d16 100644 --- a/src/gui/quitdialog.h +++ b/src/gui/quitdialog.h @@ -43,7 +43,7 @@ class QuitDialog : public Window, public gcn::ActionListener * @quitGame; to be used for getting out of the while loop in Game * @pointerToMe will be set to NULL when the QuitDialog is destroyed */ - QuitDialog(bool *quitGame, QuitDialog **pointerToMe); + QuitDialog(QuitDialog **pointerToMe); /** * Destructor @@ -63,7 +63,6 @@ class QuitDialog : public Window, public gcn::ActionListener gcn::Button *mOkButton; gcn::Button *mCancelButton; - bool *mQuitGame; QuitDialog **mMyPointer; }; diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp index 8e31f350..de70457d 100644 --- a/src/gui/statuswindow.cpp +++ b/src/gui/statuswindow.cpp @@ -183,6 +183,10 @@ StatusWindow::StatusWindow(): std::string StatusWindow::update(int id) { + /*/ TODO get rid of this + if (!player_node) + return "";*/ + if (miniStatusWindow) miniStatusWindow->update(id); diff --git a/src/main.cpp b/src/main.cpp index 994ccc62..b8dc9f9b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -808,19 +808,9 @@ int main(int argc, char *argv[]) setupWindow = new Setup; gcn::Container *top = static_cast(gui->getTop()); - Desktop *desktop = new Desktop; - top->add(desktop); - ProgressBar *progressBar = new ProgressBar(0.0f, 100, 20, - gcn::Color(168, 116, 31)); - progressBar->setSmoothProgress(false); - gcn::Label *progressLabel = new Label; - top->add(progressBar, 5, top->getHeight() - 5 - progressBar->getHeight()); - top->add(progressLabel, 15 + progressBar->getWidth(), - progressBar->getY() + 4); - progressBar->setVisible(false); - gcn::Button *setupButton = new Button(_("Setup"), "Setup", &listener); - setupButton->setPosition(top->getWidth() - setupButton->getWidth() - 3, 3); - top->add(setupButton); + Desktop *desktop; + ProgressBar *progressBar; + Button *setupButton; sound.playMusic(branding.getValue("loginMusic", "Magick - Real.ogg")); @@ -845,12 +835,6 @@ int main(int argc, char *argv[]) loginData.username = config.getValue("username", ""); } - int screenWidth = (int) config.getValue("screenwidth", defaultScreenWidth); - int screenHeight = static_cast(config.getValue("screenheight", - defaultScreenHeight)); - - desktop->setSize(screenWidth, screenHeight); - if (state != STATE_ERROR) state = STATE_CHOOSE_SERVER; State oldstate = STATE_START; // We start with a status change @@ -876,7 +860,7 @@ int main(int argc, char *argv[]) if (event.key.keysym.sym == SDLK_ESCAPE) { if (!quitDialog) - quitDialog = new QuitDialog(NULL, &quitDialog); + quitDialog = new QuitDialog(&quitDialog); else quitDialog->requestMoveToTop(); } @@ -922,6 +906,36 @@ int main(int argc, char *argv[]) Net::getCharHandler()->setCharInfo(&charInfo); state = STATE_LOGIN; } + else if (oldstate == STATE_START || oldstate == STATE_GAME) + { + desktop = new Desktop; + top->add(desktop); + progressBar = new ProgressBar(0.0f, 100, 20, + gcn::Color(168, 116, 31)); + progressBar->setSmoothProgress(false); + Label *progressLabel = new Label; + top->add(progressBar, 5, top->getHeight() - 5 - + progressBar->getHeight()); + top->add(progressLabel, 15 + progressBar->getWidth(), + progressBar->getY() + 4); + progressBar->setVisible(false); + setupButton = new Button(_("Setup"), "Setup", &listener); + setupButton->setPosition(top->getWidth() - setupButton->getWidth() + - 3, 3); + top->add(setupButton); + + int screenWidth = (int) config.getValue("screenwidth", + defaultScreenWidth); + int screenHeight = (int) config.getValue("screenheight", + defaultScreenHeight); + + desktop->setSize(screenWidth, screenHeight); + } + + if (state == STATE_SWITCH_LOGIN && oldstate == STATE_GAME) + { + Net::getGameHandler()->clear(); + } if (state != oldstate) { @@ -1135,9 +1149,8 @@ int main(int argc, char *argv[]) delete game; game = 0; - state = STATE_EXIT; - - Net::getGeneralHandler()->unload(); + if (state == STATE_GAME) + state = STATE_EXIT; break; @@ -1271,6 +1284,7 @@ int main(int argc, char *argv[]) case STATE_EXIT: logger->log("State: EXIT"); + Net::getGeneralHandler()->unload(); break; case STATE_FORCE_QUIT: diff --git a/src/net/charhandler.h b/src/net/charhandler.h index 4cace541..0ad3c1b7 100644 --- a/src/net/charhandler.h +++ b/src/net/charhandler.h @@ -52,7 +52,9 @@ class CharHandler bool gender, int hairstyle, int hairColor, std::vector stats) = 0; - virtual void deleteCharacter(int slot, LocalPlayer *character) = 0; + virtual void deleteCharacter(int slot, LocalPlayer* character) = 0; + + virtual void switchCharacter() = 0; }; } // namespace Net diff --git a/src/net/ea/beinghandler.cpp b/src/net/ea/beinghandler.cpp index 80e9b350..2cc93f6e 100644 --- a/src/net/ea/beinghandler.cpp +++ b/src/net/ea/beinghandler.cpp @@ -118,6 +118,9 @@ void BeingHandler::handleMessage(MessageIn &msg) { case SMSG_BEING_VISIBLE: case SMSG_BEING_MOVE: + if (!beingManager) + return; + // Information about a being in range id = msg.readInt32(); speed = msg.readInt16(); diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp index b578fab9..f4b82aee 100644 --- a/src/net/ea/charserverhandler.cpp +++ b/src/net/ea/charserverhandler.cpp @@ -284,6 +284,13 @@ void CharServerHandler::deleteCharacter(int slot, LocalPlayer *character) outMsg.writeString("a@a.com", 40); } +void CharServerHandler::switchCharacter() +{ + // This is really a map-server packet + MessageOut outMsg(CMSG_PLAYER_RESTART); + outMsg.writeInt8(1); +} + void CharServerHandler::connect() { const Token &token = diff --git a/src/net/ea/charserverhandler.h b/src/net/ea/charserverhandler.h index 90e7372c..393ec15c 100644 --- a/src/net/ea/charserverhandler.h +++ b/src/net/ea/charserverhandler.h @@ -63,6 +63,8 @@ class CharServerHandler : public MessageHandler, public Net::CharHandler void deleteCharacter(int slot, LocalPlayer* character); + void switchCharacter(); + void connect(); protected: diff --git a/src/net/ea/gamehandler.cpp b/src/net/ea/gamehandler.cpp index 012e6f8c..f101e03a 100644 --- a/src/net/ea/gamehandler.cpp +++ b/src/net/ea/gamehandler.cpp @@ -35,6 +35,8 @@ #include "gui/widgets/chattab.h" +#include "gui/okdialog.h" + #include "utils/gettext.h" #include "utils/stringutils.h" @@ -51,6 +53,8 @@ GameHandler::GameHandler() SMSG_MAP_LOGIN_SUCCESS, SMSG_SERVER_PING, SMSG_WHO_ANSWER, + SMSG_CHAR_SWITCH_RESPONSE, + SMSG_MAP_QUIT_RESPONSE, 0 }; handledMessages = _messages; @@ -84,6 +88,20 @@ void GameHandler::handleMessage(MessageIn &msg) localChatTab->chatLog(strprintf(_("Online users: %d"), msg.readInt32()), BY_SERVER); break; + + case SMSG_CHAR_SWITCH_RESPONSE: + if (msg.readInt8()) + { + state = STATE_SWITCH_CHARACTER; + } + break; + + case SMSG_MAP_QUIT_RESPONSE: + if (msg.readInt8()) + { + new OkDialog(_("Game"), _("Request to quit denied!"), NULL); + } + break; } } diff --git a/src/net/ea/generalhandler.cpp b/src/net/ea/generalhandler.cpp index 78a10423..62a7c1aa 100644 --- a/src/net/ea/generalhandler.cpp +++ b/src/net/ea/generalhandler.cpp @@ -239,6 +239,7 @@ void GeneralHandler::guiWindowsLoaded() void GeneralHandler::guiWindowsUnloaded() { delete partyTab; + partyTab = 0; } void GeneralHandler::clearHandlers() diff --git a/src/net/ea/protocol.h b/src/net/ea/protocol.h index 8f3e40b5..1e093e91 100644 --- a/src/net/ea/protocol.h +++ b/src/net/ea/protocol.h @@ -65,7 +65,10 @@ static const int STORAGE_OFFSET = 1; #define SMSG_CHAR_MAP_INFO 0x0071 #define SMSG_CHAR_PASSWORD_RESPONSE 0x0062 /**< Custom packet reply to password change request */ +#define SMSG_CHAR_SWITCH_RESPONSE 0x00b3 + #define SMSG_MAP_LOGIN_SUCCESS 0x0073 /**< Contains starting location */ +#define SMSG_MAP_QUIT_RESPONSE 0x018b #define SMSG_PLAYER_UPDATE_1 0x01d8 #define SMSG_PLAYER_UPDATE_2 0x01d9 #define SMSG_PLAYER_MOVE 0x01da /**< A nearby player moves */ diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp index a1b014fa..e7a99e8d 100644 --- a/src/net/manaserv/charhandler.cpp +++ b/src/net/manaserv/charhandler.cpp @@ -382,4 +382,9 @@ void CharHandler::deleteCharacter(int slot, LocalPlayer* character) Net::AccountServer::Account::deleteCharacter(slot); } +void CharHandler::switchCharacter() +{ + // TODO +} + } // namespace ManaServ diff --git a/src/net/manaserv/charhandler.h b/src/net/manaserv/charhandler.h index dafe6431..5fa57faf 100644 --- a/src/net/manaserv/charhandler.h +++ b/src/net/manaserv/charhandler.h @@ -66,6 +66,8 @@ class CharHandler : public MessageHandler, public Net::CharHandler void deleteCharacter(int slot, LocalPlayer* character); + void switchCharacter(); + protected: void handleCharCreateResponse(MessageIn &msg); -- cgit v1.2.3-70-g09d2