summaryrefslogtreecommitdiff
path: root/src/gui/npcdialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/npcdialog.cpp')
-rw-r--r--src/gui/npcdialog.cpp192
1 files changed, 171 insertions, 21 deletions
diff --git a/src/gui/npcdialog.cpp b/src/gui/npcdialog.cpp
index c4128588..590001b0 100644
--- a/src/gui/npcdialog.cpp
+++ b/src/gui/npcdialog.cpp
@@ -22,8 +22,11 @@
#include "gui/npcdialog.h"
#include "configuration.h"
-#include "npc.h"
+#include "event.h"
+#include "listener.h"
+#include "playerinfo.h"
+#include "gui/npcpostdialog.h"
#include "gui/setup.h"
#include "gui/widgets/button.h"
@@ -47,12 +50,29 @@
#define CAPTION_CLOSE _("Close")
#define CAPTION_SUBMIT _("Submit")
+typedef std::map<int, NpcDialog*> NpcDialogs;
+
+class NpcEventListener : public Mana::Listener
+{
+public:
+ void event(Channels 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)
: Window(_("NPC")),
mNpcId(npcId),
- mLogInteraction(config.getValue("logNpcInGui", true)),
+ mLogInteraction(config.getBoolValue("logNpcInGui")),
mDefaultInt(0),
mInputState(NPC_INPUT_NONE),
mActionState(NPC_ACTION_WAIT)
@@ -123,7 +143,9 @@ NpcDialog::NpcDialog(int npcId)
setVisible(true);
requestFocus();
- config.addListener("logNpcInGui", this);
+ listen(CHANNEL_CONFIG);
+ PlayerInfo::setNPCInteractionCount(PlayerInfo::getNPCInteractionCount()
+ + 1);
}
NpcDialog::~NpcDialog()
@@ -139,7 +161,10 @@ NpcDialog::~NpcDialog()
instances.remove(this);
- config.removeListener("logNpcInGui", this);
+ PlayerInfo::setNPCInteractionCount(PlayerInfo::getNPCInteractionCount()
+ - 1);
+
+ npcListener->removeDialog(mNpcId);
}
void NpcDialog::setText(const std::string &text)
@@ -192,26 +217,25 @@ void NpcDialog::action(const gcn::ActionEvent &event)
if (mInputState == NPC_INPUT_LIST)
{
- int choice = 0;
int selectedIndex = mItemList->getSelected();
if (selectedIndex >= (int) mItems.size() || selectedIndex < 0)
- {
return;
- }
- choice = selectedIndex + 1;
+
printText = mItems[selectedIndex];
- Net::getNpcHandler()->listInput(mNpcId, choice);
+ Net::getNpcHandler()->menuSelect(mNpcId, selectedIndex + 1);
}
else if (mInputState == NPC_INPUT_STRING)
{
printText = mTextField->getText();
+
Net::getNpcHandler()->stringInput(mNpcId, printText);
}
else if (mInputState == NPC_INPUT_INTEGER)
{
printText = strprintf("%d", mIntField->getValue());
+
Net::getNpcHandler()->integerInput(mNpcId, mIntField->getValue());
}
// addText will auto remove the input layout
@@ -256,6 +280,7 @@ void NpcDialog::nextDialog()
void NpcDialog::closeDialog()
{
Net::getNpcHandler()->closeDialog(mNpcId);
+ close();
}
int NpcDialog::getNumberOfElements()
@@ -281,15 +306,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;
@@ -371,11 +387,15 @@ void NpcDialog::setVisible(bool visible)
}
}
-void NpcDialog::optionChanged(const std::string &name)
+void NpcDialog::event(Channels channel, const Mana::Event &event)
{
- if (name == "logNpcInGui")
+ if (channel != CHANNEL_CONFIG)
+ return;
+
+ if (event.getName() == EVENT_CONFIGOPTIONCHANGED &&
+ event.getString("option") == "logNpcInGui")
{
- mLogInteraction = config.getValue("logNpcInGui", true);
+ mLogInteraction = config.getBoolValue("logNpcInGui");
}
}
@@ -409,6 +429,16 @@ void NpcDialog::closeAll()
}
}
+void NpcDialog::setup()
+{
+ if (npcListener)
+ return;
+
+ npcListener = new NpcEventListener();
+
+ npcListener->listen(CHANNEL_NPC);
+}
+
void NpcDialog::buildLayout()
{
clearLayout();
@@ -475,3 +505,123 @@ void NpcDialog::buildLayout()
mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll());
}
+
+void NpcEventListener::event(Channels channel,
+ const Mana::Event &event)
+{
+ if (channel != CHANNEL_NPC)
+ return;
+
+ if (event.getName() == EVENT_MESSAGE)
+ {
+ NpcDialog *dialog = getDialog(event.getInt("id"));
+
+ dialog->addText(event.getString("text"));
+ }
+ else if (event.getName() == EVENT_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() == EVENT_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() == EVENT_STRINGINPUT)
+ {
+ NpcDialog *dialog = getDialog(event.getInt("id"));
+
+ try
+ {
+ dialog->textRequest(event.getString("default"));
+ }
+ catch (Mana::BadEvent)
+ {
+ dialog->textRequest("");
+ }
+ }
+ else if (event.getName() == EVENT_NEXT)
+ {
+ int id = event.getInt("id");
+ NpcDialog *dialog = getDialog(id, false);
+
+ if (!dialog)
+ {
+ int mNpcId = id;
+ Net::getNpcHandler()->nextDialog(mNpcId);
+ return;
+ }
+
+ dialog->showNextButton();
+ }
+ else if (event.getName() == EVENT_CLOSE)
+ {
+ int id = event.getInt("id");
+ NpcDialog *dialog = getDialog(id, false);
+
+ if (!dialog)
+ {
+ int mNpcId = id;
+ Net::getNpcHandler()->closeDialog(mNpcId);
+ return;
+ }
+
+ dialog->showCloseButton();
+ }
+ else if (event.getName() == EVENT_CLOSEALL)
+ {
+ NpcDialog::closeAll();
+ }
+ else if (event.getName() == EVENT_END)
+ {
+ int id = event.getInt("id");
+ NpcDialog *dialog = getDialog(id, false);
+
+ if (dialog)
+ dialog->close();
+ }
+ else if (event.getName() == EVENT_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);
+}