diff options
-rw-r--r-- | src/game.cpp | 2 | ||||
-rw-r--r-- | src/gui/npcdialog.cpp | 159 | ||||
-rw-r--r-- | src/gui/npcdialog.h | 12 | ||||
-rw-r--r-- | src/net/manaserv/npchandler.cpp | 134 | ||||
-rw-r--r-- | src/net/manaserv/npchandler.h | 11 | ||||
-rw-r--r-- | src/net/manaserv/playerhandler.cpp | 6 | ||||
-rw-r--r-- | src/net/tmwa/npchandler.cpp | 132 | ||||
-rw-r--r-- | src/net/tmwa/npchandler.h | 11 | ||||
-rw-r--r-- | src/net/tmwa/playerhandler.cpp | 7 |
9 files changed, 281 insertions, 193 deletions
diff --git a/src/game.cpp b/src/game.cpp index 4e76061e..0994e5e4 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -177,6 +177,8 @@ static void createGuiWindows() logger->setChatWindow(chatWindow); } + NpcDialog::setup(); + Mana::EventManager::trigger("Game", Mana::Event("GuiWindowsLoaded")); } diff --git a/src/gui/npcdialog.cpp b/src/gui/npcdialog.cpp index c9eaff10..d76e8418 100644 --- a/src/gui/npcdialog.cpp +++ b/src/gui/npcdialog.cpp @@ -22,8 +22,10 @@ #include "gui/npcdialog.h" #include "configuration.h" +#include "listener.h" #include "playerinfo.h" +#include "gui/npcpostdialog.h" #include "gui/setup.h" #include "gui/widgets/button.h" @@ -47,6 +49,23 @@ #define CAPTION_CLOSE _("Close") #define CAPTION_SUBMIT _("Submit") +typedef std::map<int, NpcDialog*> NpcDialogs; + +class NpcEventListener : public Mana::Listener +{ +public: + void event(const std::string &channel, const Mana::Event &event); + + NpcDialog *getDialog(int id, bool make = true); + + void removeDialog(int id); + +private: + NpcDialogs mNpcDialogs; +}; + +static NpcEventListener *npcListener = NULL; + NpcDialog::DialogList NpcDialog::instances; NpcDialog::NpcDialog(int npcId) @@ -144,6 +163,8 @@ NpcDialog::~NpcDialog() config.removeListener("logNpcInGui", this); PlayerInfo::setNPCInteractionCount(PlayerInfo::getNPCInteractionCount() - 1); + + npcListener->removeDialog(mNpcId); } void NpcDialog::setText(const std::string &text) @@ -260,6 +281,7 @@ void NpcDialog::nextDialog() void NpcDialog::closeDialog() { Net::getNpcHandler()->closeDialog(mNpcId); + close(); } int NpcDialog::getNumberOfElements() @@ -285,15 +307,6 @@ void NpcDialog::addChoice(const std::string &choice) mItems.push_back(choice); } -void NpcDialog::parseListItems(const std::string &itemString) -{ - std::istringstream iss(itemString); - - std::string tmp; - while (getline(iss, tmp, ':')) - mItems.push_back(tmp); -} - void NpcDialog::textRequest(const std::string &defaultText) { mActionState = NPC_ACTION_INPUT; @@ -408,6 +421,16 @@ void NpcDialog::closeAll() } } +void NpcDialog::setup() +{ + if (npcListener) + return; + + npcListener = new NpcEventListener(); + + npcListener->listen("NPC"); +} + void NpcDialog::buildLayout() { clearLayout(); @@ -474,3 +497,121 @@ void NpcDialog::buildLayout() mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll()); } + +void NpcEventListener::event(const std::string &channel, + const Mana::Event &event) +{ + if (channel != "NPC") + return; + + if (event.getName() == "Message") + { + NpcDialog *dialog = getDialog(event.getInt("id")); + + dialog->addText(event.getString("text")); + } + else if (event.getName() == "Menu") + { + NpcDialog *dialog = getDialog(event.getInt("id")); + + dialog->choiceRequest(); + + int count = event.getInt("choiceCount"); + for (int i = 1; i <= count; i++) + dialog->addChoice(event.getString("choice" + toString(i))); + } + else if (event.getName() == "IntegerInput") + { + NpcDialog *dialog = getDialog(event.getInt("id")); + + int defaultValue = event.getInt("default", 0); + int min = event.getInt("min", 0); + int max = event.getInt("max", 2147483647); + + dialog->integerRequest(defaultValue, min, max); + } + else if (event.getName() == "StringInput") + { + NpcDialog *dialog = getDialog(event.getInt("id")); + + try + { + dialog->textRequest(event.getString("default")); + } + catch (Mana::BadEvent) + { + dialog->textRequest(""); + } + } + else if (event.getName() == "Next") + { + int id = event.getInt("id"); + NpcDialog *dialog = getDialog(id, false); + + if (!dialog) + { + Net::getNpcHandler()->nextDialog(id); + return; + } + + dialog->showNextButton(); + } + else if (event.getName() == "Close") + { + int id = event.getInt("id"); + NpcDialog *dialog = getDialog(id, false); + + if (!dialog) + { + Net::getNpcHandler()->closeDialog(id); + return; + } + + dialog->showCloseButton(); + } + else if (event.getName() == "CloseAll") + { + NpcDialog::closeAll(); + } + else if (event.getName() == "End") + { + int id = event.getInt("id"); + NpcDialog *dialog = getDialog(id, false); + + if (dialog) + dialog->close(); + } + else if (event.getName() == "Post") + { + new NpcPostDialog(event.getInt("id")); + } +} + +NpcDialog *NpcEventListener::getDialog(int id, bool make) +{ + NpcDialogs::iterator diag = mNpcDialogs.find(id); + NpcDialog *dialog = 0; + + if (diag == mNpcDialogs.end()) + { + // Empty dialogs don't help + if (make) + { + dialog = new NpcDialog(id); + mNpcDialogs[id] = dialog; + } + } + else + { + dialog = diag->second; + } + + return dialog; +} + +void NpcEventListener::removeDialog(int id) +{ + NpcDialogs::iterator it = mNpcDialogs.find(id); + if (it != mNpcDialogs.end()) + mNpcDialogs.erase(it); +} diff --git a/src/gui/npcdialog.h b/src/gui/npcdialog.h index 561cceb9..5850ecca 100644 --- a/src/gui/npcdialog.h +++ b/src/gui/npcdialog.h @@ -119,13 +119,6 @@ class NpcDialog : public Window, public gcn::ActionListener, void addChoice(const std::string &); /** - * Fills the options list for an NPC dialog. - * - * @param itemString A string with the options separated with colons. - */ - void parseListItems(const std::string &itemString); - - /** * Requests a text string from the user. */ void textRequest(const std::string &defaultText = ""); @@ -137,8 +130,7 @@ class NpcDialog : public Window, public gcn::ActionListener, /** * Requests a interger from the user. */ - void integerRequest(int defaultValue = 0, int min = 0, - int max = 2147483647); + void integerRequest(int defaultValue, int min, int max); void move(int amount); @@ -164,6 +156,8 @@ class NpcDialog : public Window, public gcn::ActionListener, */ static void closeAll(); + static void setup(); + private: typedef std::list<NpcDialog*> DialogList; static DialogList instances; diff --git a/src/net/manaserv/npchandler.cpp b/src/net/manaserv/npchandler.cpp index 509f26e1..09dccffe 100644 --- a/src/net/manaserv/npchandler.cpp +++ b/src/net/manaserv/npchandler.cpp @@ -22,15 +22,15 @@ #include "net/manaserv/npchandler.h" #include "actorspritemanager.h" - -#include "gui/npcdialog.h" -#include "gui/npcpostdialog.h" +#include "eventmanager.h" #include "net/manaserv/connection.h" #include "net/manaserv/messagein.h" #include "net/manaserv/messageout.h" #include "net/manaserv/protocol.h" +#include "utils/stringutils.h" + extern Net::NpcHandler *npcHandler; namespace ManaServ { @@ -61,70 +61,70 @@ void NpcHandler::handleMessage(Net::MessageIn &msg) return; } - int npcId = being->getId(); - NpcDialogs::iterator diag = mNpcDialogs.find(npcId); - NpcDialog *dialog; - - if (diag == mNpcDialogs.end()) - { - if (msg.getId() == GPMSG_NPC_ERROR || msg.getId() == GPMSG_NPC_CLOSE) - return; // Dialog is pointless in these cases - - dialog = new NpcDialog(npcId); - Wrapper wrap; - wrap.dialog = dialog; - mNpcDialogs[npcId] = wrap; - } - else - { - dialog = diag->second.dialog; - } + int npcId = being->getId(), count = 0; + Mana::Event *event = 0; switch (msg.getId()) { - case GPMSG_NPC_CHOICE: - dialog->choiceRequest(); - while (msg.getUnreadLength()) - { - dialog->addChoice(msg.readString()); - } - break; - - case GPMSG_NPC_NUMBER: - { - int min_num = msg.readInt32(); - int max_num = msg.readInt32(); - dialog->integerRequest(msg.readInt32(), min_num, max_num); - break; - } - - case GPMSG_NPC_STRING: - dialog->textRequest(""); - break; - - case GPMSG_NPC_POST: + case GPMSG_NPC_CHOICE: + event = new Mana::Event("Menu"); + event->setInt("id", npcId); + while (msg.getUnreadLength()) { - new NpcPostDialog(npcId); - break; + count++; + event->setString("choice" + toString(count), msg.readString()); } - - case GPMSG_NPC_ERROR: - dialog->close(); - if (diag != mNpcDialogs.end()) - { - mNpcDialogs.erase(diag); - } - break; - - case GPMSG_NPC_MESSAGE: - dialog->addText(msg.readString(msg.getUnreadLength())); - dialog->showNextButton(); - break; - - case GPMSG_NPC_CLOSE: - dialog->showCloseButton(); - break; + event->setInt("choiceCount", count); + Mana::EventManager::trigger("NPC", *event); + break; + + case GPMSG_NPC_NUMBER: + event = new Mana::Event("IntegerInput"); + event->setInt("id", npcId); + event->setInt("min", msg.readInt32()); + event->setInt("max", msg.readInt32()); + event->setInt("default", msg.readInt32()); + Mana::EventManager::trigger("NPC", *event); + break; + + case GPMSG_NPC_STRING: + event = new Mana::Event("StringInput"); + event->setInt("id", npcId); + Mana::EventManager::trigger("NPC", *event); + break; + + case GPMSG_NPC_POST: + event = new Mana::Event("Post"); + event->setInt("id", npcId); + Mana::EventManager::trigger("NPC", *event); + break; + + case GPMSG_NPC_ERROR: + event = new Mana::Event("End"); + event->setInt("id", npcId); + Mana::EventManager::trigger("NPC", *event); + break; + + case GPMSG_NPC_MESSAGE: + event = new Mana::Event("Message"); + event->setInt("id", npcId); + event->setString("text", msg.readString(msg.getUnreadLength())); + Mana::EventManager::trigger("NPC", *event); + delete event; + + event = new Mana::Event("Next"); + event->setInt("id", npcId); + Mana::EventManager::trigger("NPC", *event); + break; + + case GPMSG_NPC_CLOSE: + event = new Mana::Event("Close"); + event->setInt("id", npcId); + Mana::EventManager::trigger("NPC", *event); + break; } + + delete event; } void NpcHandler::talk(int npcId) @@ -146,13 +146,6 @@ void NpcHandler::closeDialog(int npcId) MessageOut msg(PGMSG_NPC_TALK_NEXT); msg.writeInt16(npcId); gameServerConnection->send(msg); - - NpcDialogs::iterator it = mNpcDialogs.find(npcId); - if (it != mNpcDialogs.end()) - { - (*it).second.dialog->close(); - mNpcDialogs.erase(it); - } } void NpcHandler::listInput(int npcId, int value) @@ -224,9 +217,4 @@ void NpcHandler::endShopping(int beingId) // TODO } -void NpcHandler::clearDialogs() -{ - mNpcDialogs.clear(); -} - } // namespace ManaServ diff --git a/src/net/manaserv/npchandler.h b/src/net/manaserv/npchandler.h index 689fdc1d..d66c1a48 100644 --- a/src/net/manaserv/npchandler.h +++ b/src/net/manaserv/npchandler.h @@ -28,8 +28,6 @@ #include <map> -class NpcDialog; - namespace ManaServ { class NpcHandler : public MessageHandler, public Net::NpcHandler @@ -65,15 +63,6 @@ class NpcHandler : public MessageHandler, public Net::NpcHandler void sellItem(int beingId, int itemId, int amount); void endShopping(int beingId); - - void clearDialogs(); - - private: - typedef struct { - NpcDialog* dialog; - } Wrapper; - typedef std::map<int, Wrapper> NpcDialogs; - NpcDialogs mNpcDialogs; }; } // namespace ManaServ diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp index 696ec037..2028afd9 100644 --- a/src/net/manaserv/playerhandler.cpp +++ b/src/net/manaserv/playerhandler.cpp @@ -24,6 +24,7 @@ #include "client.h" #include "effectmanager.h" +#include "eventmanager.h" #include "game.h" #include "localplayer.h" #include "log.h" @@ -41,7 +42,6 @@ #include "net/manaserv/defines.h" #include "net/manaserv/messagein.h" #include "net/manaserv/messageout.h" -#include "net/manaserv/npchandler.h" #include "net/manaserv/protocol.h" /** @@ -60,9 +60,7 @@ void RespawnRequestListener::action(const gcn::ActionEvent &event) { Net::getPlayerHandler()->respawn(); - ManaServ::NpcHandler *handler = - static_cast<ManaServ::NpcHandler*>(Net::getNpcHandler()); - handler->clearDialogs(); + Mana::EventManager::trigger("NPC", Mana::Event("CloseAll")); } extern Connection *gameServerConnection; diff --git a/src/net/tmwa/npchandler.cpp b/src/net/tmwa/npchandler.cpp index bd655fa6..485a8ff7 100644 --- a/src/net/tmwa/npchandler.cpp +++ b/src/net/tmwa/npchandler.cpp @@ -22,10 +22,9 @@ #include "net/tmwa/npchandler.h" #include "actorspritemanager.h" +#include "eventmanager.h" #include "localplayer.h" -#include "gui/npcdialog.h" - #include "net/messagein.h" #include "net/messageout.h" #include "net/net.h" @@ -33,10 +32,27 @@ #include "net/tmwa/protocol.h" +#include "utils/stringutils.h" + #include <SDL_types.h> extern Net::NpcHandler *npcHandler; +static void parseMenu(Mana::Event *event, const std::string &options) +{ + std::istringstream iss(options); + + int count = 0; + std::string tmp; + while (getline(iss, tmp, ':')) + { + count++; + event->setString("choice" + toString(count), tmp); + } + + event->setInt("choiceCount", count); +} + namespace TmwAthena { NpcHandler::NpcHandler() @@ -62,67 +78,55 @@ void NpcHandler::handleMessage(Net::MessageIn &msg) } int npcId = msg.readInt32(); - NpcDialogs::iterator diag = mNpcDialogs.find(npcId); - NpcDialog *dialog = 0; - - if (diag == mNpcDialogs.end()) - { - // Empty dialogs don't help - if (msg.getId() == SMSG_NPC_CLOSE) - { - closeDialog(npcId); - return; - } - else if (msg.getId() == SMSG_NPC_NEXT) - { - nextDialog(npcId); - return; - } - else - { - dialog = new NpcDialog(npcId); - Wrapper wrap; - wrap.dialog = dialog; - mNpcDialogs[npcId] = wrap; - } - } - else - { - dialog = diag->second.dialog; - } + Mana::Event *event = 0; switch (msg.getId()) { - case SMSG_NPC_CHOICE: - dialog->choiceRequest(); - dialog->parseListItems(msg.readString(msg.getLength() - 8)); - break; - - case SMSG_NPC_MESSAGE: - dialog->addText(msg.readString(msg.getLength() - 8)); - break; - - case SMSG_NPC_CLOSE: - // Show the close button - dialog->showCloseButton(); - break; - - case SMSG_NPC_NEXT: - // Show the next button - dialog->showNextButton(); - break; - - case SMSG_NPC_INT_INPUT: - // Request for an integer - dialog->integerRequest(0); - break; - - case SMSG_NPC_STR_INPUT: - // Request for a string - dialog->textRequest(""); - break; + case SMSG_NPC_CHOICE: + event = new Mana::Event("Menu"); + event->setInt("id", npcId); + parseMenu(event, msg.readString(msg.getLength() - 8)); + Mana::EventManager::trigger("NPC", *event); + break; + + case SMSG_NPC_MESSAGE: + event = new Mana::Event("Message"); + event->setInt("id", npcId); + event->setString("text", msg.readString(msg.getLength() - 8)); + Mana::EventManager::trigger("NPC", *event); + break; + + case SMSG_NPC_CLOSE: + // Show the close button + event = new Mana::Event("Close"); + event->setInt("id", npcId); + Mana::EventManager::trigger("NPC", *event); + break; + + case SMSG_NPC_NEXT: + // Show the next button + event = new Mana::Event("Next"); + event->setInt("id", npcId); + Mana::EventManager::trigger("NPC", *event); + break; + + case SMSG_NPC_INT_INPUT: + // Request for an integer + event = new Mana::Event("IntegerInput"); + event->setInt("id", npcId); + Mana::EventManager::trigger("NPC", *event); + break; + + case SMSG_NPC_STR_INPUT: + // Request for a string + event = new Mana::Event("StringInput"); + event->setInt("id", npcId); + Mana::EventManager::trigger("NPC", *event); + break; } + delete event; + if (player_node->getCurrentAction() != Being::SIT) player_node->setAction(Being::STAND); } @@ -144,13 +148,6 @@ void NpcHandler::closeDialog(int npcId) { MessageOut outMsg(CMSG_NPC_CLOSE); outMsg.writeInt32(npcId); - - NpcDialogs::iterator it = mNpcDialogs.find(npcId); - if (it != mNpcDialogs.end()) - { - (*it).second.dialog->close(); - mNpcDialogs.erase(it); - } } void NpcHandler::listInput(int npcId, int value) @@ -222,9 +219,4 @@ void NpcHandler::endShopping(int beingId) // TODO } -void NpcHandler::clearDialogs() -{ - mNpcDialogs.clear(); -} - } // namespace TmwAthena diff --git a/src/net/tmwa/npchandler.h b/src/net/tmwa/npchandler.h index bd696bdd..515f62df 100644 --- a/src/net/tmwa/npchandler.h +++ b/src/net/tmwa/npchandler.h @@ -29,8 +29,6 @@ #include <map> -class NpcDialog; - namespace TmwAthena { class NpcHandler : public MessageHandler, public Net::NpcHandler @@ -66,15 +64,6 @@ class NpcHandler : public MessageHandler, public Net::NpcHandler void sellItem(int beingId, int itemId, int amount); void endShopping(int beingId); - - void clearDialogs(); - - private: - typedef struct { - NpcDialog* dialog; - } Wrapper; - typedef std::map<int, Wrapper> NpcDialogs; - NpcDialogs mNpcDialogs; }; } // namespace TmwAthena diff --git a/src/net/tmwa/playerhandler.cpp b/src/net/tmwa/playerhandler.cpp index 733d4a88..98cbc8fb 100644 --- a/src/net/tmwa/playerhandler.cpp +++ b/src/net/tmwa/playerhandler.cpp @@ -31,7 +31,6 @@ #include "gui/buy.h" #include "gui/buysell.h" #include "gui/gui.h" -#include "gui/npcdialog.h" #include "gui/okdialog.h" #include "gui/sell.h" #include "gui/statuswindow.h" @@ -41,7 +40,6 @@ #include "net/messageout.h" #include "net/tmwa/protocol.h" -#include "net/tmwa/npchandler.h" #include "utils/stringutils.h" #include "utils/gettext.h" @@ -79,14 +77,11 @@ namespace { BuyDialog::closeAll(); BuySellDialog::closeAll(); - NpcDialog::closeAll(); SellDialog::closeAll(); viewport->closePopupMenu(); - TmwAthena::NpcHandler *handler = - static_cast<TmwAthena::NpcHandler*>(Net::getNpcHandler()); - handler->clearDialogs(); + Mana::EventManager::trigger("NPC", Mana::Event("CloseAll")); } } deathListener; |