From d5ebad4e74da011777f9ba1a13fbb37d18c827b9 Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Mon, 4 Mar 2024 17:48:35 +0100 Subject: Added support for handling SMSG_NPC_COMMAND This only adds support for the NPC_CLOSE_DIALOG and NPC_CLEAR_DIALOG sub-commands. Closes #47 --- src/event.h | 2 + src/gui/npcdialog.cpp | 10 +++++ src/net/tmwa/npchandler.cpp | 91 ++++++++++++++++++++++++++++++++------------- src/net/tmwa/protocol.h | 17 +++++++++ 4 files changed, 94 insertions(+), 26 deletions(-) diff --git a/src/event.h b/src/event.h index d20f172f..0fc0c1ef 100644 --- a/src/event.h +++ b/src/event.h @@ -63,8 +63,10 @@ public: { Announcement, Being, + ClearDialog, Close, CloseAll, + CloseDialog, CloseSent, ConfigOptionChanged, Constructed, diff --git a/src/gui/npcdialog.cpp b/src/gui/npcdialog.cpp index 0ad9e959..4efa29eb 100644 --- a/src/gui/npcdialog.cpp +++ b/src/gui/npcdialog.cpp @@ -586,6 +586,11 @@ void NpcEventListener::event(Event::Channel channel, dialog->showNextButton(); } + else if (event.getType() == Event::ClearDialog) + { + if (NpcDialog *dialog = getDialog(event.getInt("id"), false)) + dialog->setText(std::string()); + } else if (event.getType() == Event::Close) { int id = event.getInt("id"); @@ -600,6 +605,11 @@ void NpcEventListener::event(Event::Channel channel, dialog->showCloseButton(); } + else if (event.getType() == Event::CloseDialog) + { + if (NpcDialog *dialog = getDialog(event.getInt("id"), false)) + dialog->setVisible(false); + } else if (event.getType() == Event::CloseAll) { NpcDialog::closeAll(); diff --git a/src/net/tmwa/npchandler.cpp b/src/net/tmwa/npchandler.cpp index 9bd15572..aeb8cf95 100644 --- a/src/net/tmwa/npchandler.cpp +++ b/src/net/tmwa/npchandler.cpp @@ -36,7 +36,7 @@ extern Net::NpcHandler *npcHandler; -static void parseMenu(Event *event, const std::string &options) +static void parseMenu(Event &event, const std::string &options) { std::istringstream iss(options); @@ -45,10 +45,10 @@ static void parseMenu(Event *event, const std::string &options) while (getline(iss, tmp, ':')) { count++; - event->setString("choice" + toString(count), tmp); + event.setString("choice" + toString(count), tmp); } - event->setInt("choiceCount", count); + event.setInt("choiceCount", count); } namespace TmwAthena { @@ -60,6 +60,7 @@ NpcHandler::NpcHandler() SMSG_NPC_MESSAGE, SMSG_NPC_NEXT, SMSG_NPC_CLOSE, + SMSG_NPC_COMMAND, SMSG_NPC_INT_INPUT, SMSG_NPC_STR_INPUT, 0 @@ -76,54 +77,92 @@ void NpcHandler::handleMessage(MessageIn &msg) } int npcId = msg.readInt32(); - Event *event = nullptr; switch (msg.getId()) { case SMSG_NPC_CHOICE: - event = new Event(Event::Menu); - event->setInt("id", npcId); + { + Event event { Event::Menu }; + event.setInt("id", npcId); parseMenu(event, msg.readString(msg.getLength() - 8)); - event->trigger(Event::NpcChannel); + event.trigger(Event::NpcChannel); break; + } case SMSG_NPC_MESSAGE: - event = new Event(Event::Message); - event->setInt("id", npcId); - event->setString("text", msg.readString(msg.getLength() - 8)); - event->trigger(Event::NpcChannel); + { + Event event { Event::Message }; + event.setInt("id", npcId); + event.setString("text", msg.readString(msg.getLength() - 8)); + event.trigger(Event::NpcChannel); break; + } - case SMSG_NPC_CLOSE: + case SMSG_NPC_CLOSE: + { // Show the close button - event = new Event(Event::Close); - event->setInt("id", npcId); - event->trigger(Event::NpcChannel); + Event event { Event::Close }; + event.setInt("id", npcId); + event.trigger(Event::NpcChannel); + break; + } + + case SMSG_NPC_COMMAND: + { + auto command = msg.readInt16(); + msg.readInt32(); // id + msg.readInt16(); // x + msg.readInt16(); // y + + switch (command) + { + case NPC_CLOSE_DIALOG: + { + Event event { Event::CloseDialog }; + event.setInt("id", npcId); + event.trigger(Event::NpcChannel); + break; + } + + case NPC_CLEAR_DIALOG: + { + Event event { Event::ClearDialog }; + event.setInt("id", npcId); + event.trigger(Event::NpcChannel); + break; + } + } + break; + } case SMSG_NPC_NEXT: + { // Show the next button - event = new Event(Event::Next); - event->setInt("id", npcId); - event->trigger(Event::NpcChannel); + Event event { Event::Next }; + event.setInt("id", npcId); + event.trigger(Event::NpcChannel); break; + } case SMSG_NPC_INT_INPUT: + { // Request for an integer - event = new Event(Event::IntegerInput); - event->setInt("id", npcId); - event->trigger(Event::NpcChannel); + Event event { Event::IntegerInput }; + event.setInt("id", npcId); + event.trigger(Event::NpcChannel); break; + } case SMSG_NPC_STR_INPUT: + { // Request for a string - event = new Event(Event::StringInput); - event->setInt("id", npcId); - event->trigger(Event::NpcChannel); + Event event { Event::StringInput }; + event.setInt("id", npcId); + event.trigger(Event::NpcChannel); break; } - - delete event; + } if (local_player->getCurrentAction() != Being::SIT) local_player->setAction(Being::STAND); diff --git a/src/net/tmwa/protocol.h b/src/net/tmwa/protocol.h index ea3d430e..e50948c5 100644 --- a/src/net/tmwa/protocol.h +++ b/src/net/tmwa/protocol.h @@ -60,6 +60,23 @@ enum SPRITE_VECTOREND }; +enum NpcCommand +{ + NPC_REQUEST_LANG = 0, + NPC_CAMERA_ACTOR = 1, + NPC_CAMERA_POS = 2, + NPC_CAMERA_RESTORE = 3, + NPC_CAMERA_RELATIVE = 4, + NPC_CLOSE_DIALOG = 5, + NPC_SHOW_AVATAR = 6, + NPC_SET_AVATAR_DIRECTION = 7, + NPC_SET_AVATAR_ACTION = 8, + NPC_CLEAR_DIALOG = 9, + NPC_REQUEST_ITEM = 10, + NPC_REQUEST_ITEM_INDEX = 11, + NPC_REQUEST_ITEMS = 12, +}; + static const int INVENTORY_OFFSET = 2; static const int STORAGE_OFFSET = 1; -- cgit v1.2.3-70-g09d2