forked from mirror/openmw-tes3mp
Refactor dialogue GUI to talk to the dialogue manager, not the other way around and not both ways.
- Fix memory leaks in DialogueWindow - Fix Link objects being deleted from their own event handler
This commit is contained in:
parent
476bec41c5
commit
2ce79e07a4
14 changed files with 231 additions and 150 deletions
|
@ -2,6 +2,8 @@
|
||||||
#define GAME_MWBASE_DIALOGUEMANAGER_H
|
#define GAME_MWBASE_DIALOGUEMANAGER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@ -42,24 +44,29 @@ namespace MWBase
|
||||||
|
|
||||||
virtual bool isInChoice() const = 0;
|
virtual bool isInChoice() const = 0;
|
||||||
|
|
||||||
virtual void startDialogue (const MWWorld::Ptr& actor) = 0;
|
typedef std::pair<std::string, std::string> Response; // title, text
|
||||||
|
virtual bool startDialogue (const MWWorld::Ptr& actor, Response& response) = 0;
|
||||||
|
|
||||||
virtual void addTopic (const std::string& topic) = 0;
|
virtual void addTopic (const std::string& topic) = 0;
|
||||||
|
|
||||||
virtual void askQuestion (const std::string& question,int choice) = 0;
|
virtual void addChoice (const std::string& text,int choice) = 0;
|
||||||
|
virtual const std::vector<std::pair<std::string, int> >& getChoices() = 0;
|
||||||
|
|
||||||
|
virtual bool isGoodbye() = 0;
|
||||||
|
|
||||||
virtual void goodbye() = 0;
|
virtual void goodbye() = 0;
|
||||||
|
|
||||||
virtual void say(const MWWorld::Ptr &actor, const std::string &topic) = 0;
|
virtual void say(const MWWorld::Ptr &actor, const std::string &topic) = 0;
|
||||||
|
|
||||||
//calbacks for the GUI
|
virtual Response keywordSelected (const std::string& keyword) = 0;
|
||||||
virtual void keywordSelected (const std::string& keyword) = 0;
|
|
||||||
virtual void goodbyeSelected() = 0;
|
virtual void goodbyeSelected() = 0;
|
||||||
virtual void questionAnswered (int answer) = 0;
|
virtual Response questionAnswered (int answer) = 0;
|
||||||
|
|
||||||
virtual bool checkServiceRefused () = 0;
|
virtual std::list<std::string> getAvailableTopics() = 0;
|
||||||
|
|
||||||
virtual void persuade (int type) = 0;
|
virtual bool checkServiceRefused (Response& response) = 0;
|
||||||
|
|
||||||
|
virtual Response persuade (int type) = 0;
|
||||||
virtual int getTemporaryDispositionChange () const = 0;
|
virtual int getTemporaryDispositionChange () const = 0;
|
||||||
|
|
||||||
/// @note This change is temporary and gets discarded when dialogue ends.
|
/// @note This change is temporary and gets discarded when dialogue ends.
|
||||||
|
|
|
@ -140,7 +140,6 @@ namespace MWBase
|
||||||
virtual bool isAllowed (MWGui::GuiWindow wnd) const = 0;
|
virtual bool isAllowed (MWGui::GuiWindow wnd) const = 0;
|
||||||
|
|
||||||
/// \todo investigate, if we really need to expose every single lousy UI element to the outside world
|
/// \todo investigate, if we really need to expose every single lousy UI element to the outside world
|
||||||
virtual MWGui::DialogueWindow* getDialogueWindow() = 0;
|
|
||||||
virtual MWGui::InventoryWindow* getInventoryWindow() = 0;
|
virtual MWGui::InventoryWindow* getInventoryWindow() = 0;
|
||||||
virtual MWGui::CountDialog* getCountDialog() = 0;
|
virtual MWGui::CountDialog* getCountDialog() = 0;
|
||||||
virtual MWGui::ConfirmationDialog* getConfirmationDialog() = 0;
|
virtual MWGui::ConfirmationDialog* getConfirmationDialog() = 0;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include <components/esm/loaddial.hpp>
|
#include <components/esm/loaddial.hpp>
|
||||||
#include <components/esm/loadinfo.hpp>
|
#include <components/esm/loadinfo.hpp>
|
||||||
|
@ -33,8 +34,6 @@
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
#include "../mwgui/dialogue.hpp"
|
|
||||||
|
|
||||||
#include "../mwscript/compilercontext.hpp"
|
#include "../mwscript/compilercontext.hpp"
|
||||||
#include "../mwscript/interpretercontext.hpp"
|
#include "../mwscript/interpretercontext.hpp"
|
||||||
#include "../mwscript/extensions.hpp"
|
#include "../mwscript/extensions.hpp"
|
||||||
|
@ -59,6 +58,7 @@ namespace MWDialogue
|
||||||
{
|
{
|
||||||
mChoice = -1;
|
mChoice = -1;
|
||||||
mIsInChoice = false;
|
mIsInChoice = false;
|
||||||
|
mGoodbye = false;
|
||||||
mCompilerContext.setExtensions (&extensions);
|
mCompilerContext.setExtensions (&extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,17 +99,15 @@ namespace MWDialogue
|
||||||
if (mActorKnownTopics.count( topicId ))
|
if (mActorKnownTopics.count( topicId ))
|
||||||
mKnownTopics.insert( topicId );
|
mKnownTopics.insert( topicId );
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTopics();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::startDialogue (const MWWorld::Ptr& actor)
|
bool DialogueManager::startDialogue (const MWWorld::Ptr& actor, Response& response)
|
||||||
{
|
{
|
||||||
updateGlobals();
|
updateGlobals();
|
||||||
|
|
||||||
// Dialogue with dead actor (e.g. through script) should not be allowed.
|
// Dialogue with dead actor (e.g. through script) should not be allowed.
|
||||||
if (actor.getClass().getCreatureStats(actor).isDead())
|
if (actor.getClass().getCreatureStats(actor).isDead())
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
mLastTopic = "";
|
mLastTopic = "";
|
||||||
mPermanentDispositionChange = 0;
|
mPermanentDispositionChange = 0;
|
||||||
|
@ -117,6 +115,8 @@ namespace MWDialogue
|
||||||
|
|
||||||
mChoice = -1;
|
mChoice = -1;
|
||||||
mIsInChoice = false;
|
mIsInChoice = false;
|
||||||
|
mGoodbye = false;
|
||||||
|
mChoices.clear();
|
||||||
|
|
||||||
mActor = actor;
|
mActor = actor;
|
||||||
|
|
||||||
|
@ -125,8 +125,6 @@ namespace MWDialogue
|
||||||
|
|
||||||
mActorKnownTopics.clear();
|
mActorKnownTopics.clear();
|
||||||
|
|
||||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
|
||||||
|
|
||||||
//greeting
|
//greeting
|
||||||
const MWWorld::Store<ESM::Dialogue> &dialogs =
|
const MWWorld::Store<ESM::Dialogue> &dialogs =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
|
||||||
|
@ -140,10 +138,6 @@ namespace MWDialogue
|
||||||
// Search a response (we do not accept a fallback to "Info refusal" here)
|
// Search a response (we do not accept a fallback to "Info refusal" here)
|
||||||
if (const ESM::DialInfo *info = filter.search (*it, false))
|
if (const ESM::DialInfo *info = filter.search (*it, false))
|
||||||
{
|
{
|
||||||
//initialise the GUI
|
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue);
|
|
||||||
win->startDialogue(actor, actor.getClass().getName (actor));
|
|
||||||
|
|
||||||
creatureStats.talkedToPlayer();
|
creatureStats.talkedToPlayer();
|
||||||
|
|
||||||
if (!info->mSound.empty())
|
if (!info->mSound.empty())
|
||||||
|
@ -152,29 +146,23 @@ namespace MWDialogue
|
||||||
}
|
}
|
||||||
|
|
||||||
// first topics update so that parseText knows the keywords to highlight
|
// first topics update so that parseText knows the keywords to highlight
|
||||||
updateTopics();
|
updateActorKnownTopics();
|
||||||
|
|
||||||
parseText (info->mResponse);
|
parseText (info->mResponse);
|
||||||
|
|
||||||
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
|
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
|
||||||
win->addResponse (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext), "", false);
|
response = Response ("", Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
|
||||||
executeScript (info->mResultScript, mActor);
|
executeScript (info->mResultScript, mActor);
|
||||||
mLastTopic = it->mId;
|
mLastTopic = it->mId;
|
||||||
|
|
||||||
// update topics again to accommodate changes resulting from executeScript
|
// update topics again to accommodate changes resulting from executeScript
|
||||||
updateTopics();
|
updateActorKnownTopics();
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
// No greetings found. The dialogue window should not be shown.
|
|
||||||
// If this is a companion, we must show the companion window directly (used by BM_bear_be_unique).
|
|
||||||
bool isCompanion = !mActor.getClass().getScript(mActor).empty()
|
|
||||||
&& mActor.getRefData().getLocals().getIntVar(mActor.getClass().getScript(mActor), "companion");
|
|
||||||
if (isCompanion)
|
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Companion, mActor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DialogueManager::compile (const std::string& cmd, std::vector<Interpreter::Type_Code>& code, const MWWorld::Ptr& actor)
|
bool DialogueManager::compile (const std::string& cmd, std::vector<Interpreter::Type_Code>& code, const MWWorld::Ptr& actor)
|
||||||
|
@ -252,8 +240,9 @@ namespace MWDialogue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::executeTopic (const std::string& topic)
|
DialogueManager::Response DialogueManager::executeTopic (const std::string& topic)
|
||||||
{
|
{
|
||||||
|
DialogueManager::Response response;
|
||||||
Filter filter (mActor, mChoice, mTalkedTo);
|
Filter filter (mActor, mChoice, mTalkedTo);
|
||||||
|
|
||||||
const MWWorld::Store<ESM::Dialogue> &dialogues =
|
const MWWorld::Store<ESM::Dialogue> &dialogues =
|
||||||
|
@ -261,8 +250,6 @@ namespace MWDialogue
|
||||||
|
|
||||||
const ESM::Dialogue& dialogue = *dialogues.find (topic);
|
const ESM::Dialogue& dialogue = *dialogues.find (topic);
|
||||||
|
|
||||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
|
||||||
|
|
||||||
const ESM::DialInfo* info = filter.search(dialogue, true);
|
const ESM::DialInfo* info = filter.search(dialogue, true);
|
||||||
if (info)
|
if (info)
|
||||||
{
|
{
|
||||||
|
@ -287,7 +274,7 @@ namespace MWDialogue
|
||||||
title = topic;
|
title = topic;
|
||||||
|
|
||||||
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
|
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
|
||||||
win->addResponse (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext), title);
|
response = Response(title, Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
|
||||||
|
|
||||||
if (dialogue.mType == ESM::Dialogue::Topic)
|
if (dialogue.mType == ESM::Dialogue::Topic)
|
||||||
{
|
{
|
||||||
|
@ -308,11 +295,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
mLastTopic = topic;
|
mLastTopic = topic;
|
||||||
}
|
}
|
||||||
else
|
return response;
|
||||||
{
|
|
||||||
// no response found, print a fallback text
|
|
||||||
win->addResponse ("…", topic);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ESM::Dialogue *DialogueManager::searchDialogue(const std::string& id)
|
const ESM::Dialogue *DialogueManager::searchDialogue(const std::string& id)
|
||||||
|
@ -325,11 +308,10 @@ namespace MWDialogue
|
||||||
MWBase::Environment::get().getWorld()->updateDialogueGlobals();
|
MWBase::Environment::get().getWorld()->updateDialogueGlobals();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::updateTopics()
|
void DialogueManager::updateActorKnownTopics()
|
||||||
{
|
{
|
||||||
updateGlobals();
|
updateGlobals();
|
||||||
|
|
||||||
std::list<std::string> keywordList;
|
|
||||||
mActorKnownTopics.clear();
|
mActorKnownTopics.clear();
|
||||||
|
|
||||||
const MWWorld::Store<ESM::Dialogue> &dialogs =
|
const MWWorld::Store<ESM::Dialogue> &dialogs =
|
||||||
|
@ -345,35 +327,42 @@ namespace MWDialogue
|
||||||
{
|
{
|
||||||
std::string lower = Misc::StringUtils::lowerCase(iter->mId);
|
std::string lower = Misc::StringUtils::lowerCase(iter->mId);
|
||||||
mActorKnownTopics.insert (lower);
|
mActorKnownTopics.insert (lower);
|
||||||
|
|
||||||
//does the player know the topic?
|
|
||||||
if (mKnownTopics.count(lower))
|
|
||||||
{
|
|
||||||
keywordList.push_back (iter->mId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
}
|
||||||
|
|
||||||
|
std::list<std::string> DialogueManager::getAvailableTopics()
|
||||||
|
{
|
||||||
|
updateActorKnownTopics();
|
||||||
|
|
||||||
|
std::list<std::string> keywordList;
|
||||||
|
|
||||||
|
for (const std::string& topic : mActorKnownTopics)
|
||||||
|
{
|
||||||
|
//does the player know the topic?
|
||||||
|
if (mKnownTopics.count(Misc::StringUtils::lowerCase(topic)))
|
||||||
|
keywordList.push_back(topic);
|
||||||
|
}
|
||||||
|
|
||||||
// sort again, because the previous sort was case-sensitive
|
// sort again, because the previous sort was case-sensitive
|
||||||
keywordList.sort(Misc::StringUtils::ciLess);
|
keywordList.sort(Misc::StringUtils::ciLess);
|
||||||
win->setKeywords(keywordList);
|
return keywordList;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::keywordSelected (const std::string& keyword)
|
DialogueManager::Response DialogueManager::keywordSelected (const std::string& keyword)
|
||||||
{
|
{
|
||||||
|
Response response;
|
||||||
if(!mIsInChoice)
|
if(!mIsInChoice)
|
||||||
{
|
{
|
||||||
const ESM::Dialogue* dialogue = searchDialogue(keyword);
|
const ESM::Dialogue* dialogue = searchDialogue(keyword);
|
||||||
if (dialogue && dialogue->mType == ESM::Dialogue::Topic)
|
if (dialogue && dialogue->mType == ESM::Dialogue::Topic)
|
||||||
{
|
{
|
||||||
executeTopic (keyword);
|
response = executeTopic (keyword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return response;
|
||||||
updateTopics();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DialogueManager::isInChoice() const
|
bool DialogueManager::isInChoice() const
|
||||||
|
@ -383,8 +372,6 @@ namespace MWDialogue
|
||||||
|
|
||||||
void DialogueManager::goodbyeSelected()
|
void DialogueManager::goodbyeSelected()
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue);
|
|
||||||
|
|
||||||
// Apply disposition change to NPC's base disposition
|
// Apply disposition change to NPC's base disposition
|
||||||
if (mActor.getClass().isNpc())
|
if (mActor.getClass().isNpc())
|
||||||
{
|
{
|
||||||
|
@ -400,9 +387,10 @@ namespace MWDialogue
|
||||||
mTemporaryDispositionChange = 0;
|
mTemporaryDispositionChange = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::questionAnswered (int answer)
|
DialogueManager::Response DialogueManager::questionAnswered (int answer)
|
||||||
{
|
{
|
||||||
mChoice = answer;
|
mChoice = answer;
|
||||||
|
DialogueManager::Response response;
|
||||||
|
|
||||||
const ESM::Dialogue* dialogue = searchDialogue(mLastTopic);
|
const ESM::Dialogue* dialogue = searchDialogue(mLastTopic);
|
||||||
if (dialogue)
|
if (dialogue)
|
||||||
|
@ -418,10 +406,10 @@ namespace MWDialogue
|
||||||
|
|
||||||
mChoice = -1;
|
mChoice = -1;
|
||||||
mIsInChoice = false;
|
mIsInChoice = false;
|
||||||
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->clearChoices();
|
mChoices.clear();
|
||||||
|
|
||||||
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
|
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
|
||||||
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addResponse (Interpreter::fixDefinesDialog(text, interpreterContext));
|
response = Response("", Interpreter::fixDefinesDialog(text, interpreterContext));
|
||||||
|
|
||||||
// Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group,
|
// Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group,
|
||||||
// in which case it should not be added to the journal.
|
// in which case it should not be added to the journal.
|
||||||
|
@ -441,32 +429,39 @@ namespace MWDialogue
|
||||||
{
|
{
|
||||||
mChoice = -1;
|
mChoice = -1;
|
||||||
mIsInChoice = false;
|
mIsInChoice = false;
|
||||||
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->clearChoices();
|
mChoices.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTopics();
|
updateActorKnownTopics();
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::askQuestion (const std::string& question, int choice)
|
void DialogueManager::addChoice (const std::string& text, int choice)
|
||||||
{
|
{
|
||||||
mIsInChoice = true;
|
mIsInChoice = true;
|
||||||
|
|
||||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
mChoices.push_back(std::make_pair(text, choice));
|
||||||
win->addChoice(question, choice);
|
}
|
||||||
|
|
||||||
|
const std::vector<std::pair<std::string, int> >& DialogueManager::getChoices()
|
||||||
|
{
|
||||||
|
return mChoices;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DialogueManager::isGoodbye()
|
||||||
|
{
|
||||||
|
return mGoodbye;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::goodbye()
|
void DialogueManager::goodbye()
|
||||||
{
|
{
|
||||||
mIsInChoice = true;
|
mIsInChoice = false;
|
||||||
|
mGoodbye = true;
|
||||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
|
||||||
|
|
||||||
win->goodbye();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueManager::persuade(int type)
|
DialogueManager::Response DialogueManager::persuade(int type)
|
||||||
{
|
{
|
||||||
bool success;
|
bool success;
|
||||||
float temp, perm;
|
float temp, perm;
|
||||||
|
@ -515,7 +510,7 @@ namespace MWDialogue
|
||||||
text = "Bribe";
|
text = "Bribe";
|
||||||
}
|
}
|
||||||
|
|
||||||
executeTopic (text + (success ? " Success" : " Fail"));
|
return executeTopic (text + (success ? " Success" : " Fail"));
|
||||||
}
|
}
|
||||||
|
|
||||||
int DialogueManager::getTemporaryDispositionChange() const
|
int DialogueManager::getTemporaryDispositionChange() const
|
||||||
|
@ -528,7 +523,7 @@ namespace MWDialogue
|
||||||
mTemporaryDispositionChange += delta;
|
mTemporaryDispositionChange += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DialogueManager::checkServiceRefused()
|
bool DialogueManager::checkServiceRefused(Response& response)
|
||||||
{
|
{
|
||||||
Filter filter (mActor, mChoice, mTalkedTo);
|
Filter filter (mActor, mChoice, mTalkedTo);
|
||||||
|
|
||||||
|
@ -536,7 +531,6 @@ namespace MWDialogue
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Dialogue>();
|
||||||
|
|
||||||
const ESM::Dialogue& dialogue = *dialogues.find ("Service Refusal");
|
const ESM::Dialogue& dialogue = *dialogues.find ("Service Refusal");
|
||||||
MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow();
|
|
||||||
|
|
||||||
std::vector<const ESM::DialInfo *> infos = filter.list (dialogue, false, false, true);
|
std::vector<const ESM::DialInfo *> infos = filter.list (dialogue, false, false, true);
|
||||||
if (!infos.empty())
|
if (!infos.empty())
|
||||||
|
@ -550,8 +544,7 @@ namespace MWDialogue
|
||||||
|
|
||||||
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
|
MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor);
|
||||||
|
|
||||||
win->addResponse (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext),
|
response = Response(gmsts.find ("sServiceRefusal")->getString(), Interpreter::fixDefinesDialog(info->mResponse, interpreterContext));
|
||||||
gmsts.find ("sServiceRefusal")->getString());
|
|
||||||
|
|
||||||
executeScript (info->mResultScript, mActor);
|
executeScript (info->mResultScript, mActor);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -41,19 +41,22 @@ namespace MWDialogue
|
||||||
int mChoice;
|
int mChoice;
|
||||||
std::string mLastTopic; // last topic ID, lowercase
|
std::string mLastTopic; // last topic ID, lowercase
|
||||||
bool mIsInChoice;
|
bool mIsInChoice;
|
||||||
|
bool mGoodbye;
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, int> > mChoices;
|
||||||
|
|
||||||
float mTemporaryDispositionChange;
|
float mTemporaryDispositionChange;
|
||||||
float mPermanentDispositionChange;
|
float mPermanentDispositionChange;
|
||||||
|
|
||||||
void parseText (const std::string& text);
|
void parseText (const std::string& text);
|
||||||
|
|
||||||
void updateTopics();
|
void updateActorKnownTopics();
|
||||||
void updateGlobals();
|
void updateGlobals();
|
||||||
|
|
||||||
bool compile (const std::string& cmd, std::vector<Interpreter::Type_Code>& code, const MWWorld::Ptr& actor);
|
bool compile (const std::string& cmd, std::vector<Interpreter::Type_Code>& code, const MWWorld::Ptr& actor);
|
||||||
void executeScript (const std::string& script, const MWWorld::Ptr& actor);
|
void executeScript (const std::string& script, const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
void executeTopic (const std::string& topic);
|
Response executeTopic (const std::string& topic);
|
||||||
|
|
||||||
const ESM::Dialogue* searchDialogue(const std::string& id);
|
const ESM::Dialogue* searchDialogue(const std::string& id);
|
||||||
|
|
||||||
|
@ -65,24 +68,29 @@ namespace MWDialogue
|
||||||
|
|
||||||
virtual bool isInChoice() const;
|
virtual bool isInChoice() const;
|
||||||
|
|
||||||
virtual void startDialogue (const MWWorld::Ptr& actor);
|
virtual bool startDialogue (const MWWorld::Ptr& actor, Response& response);
|
||||||
|
|
||||||
|
std::list<std::string> getAvailableTopics();
|
||||||
|
|
||||||
virtual void addTopic (const std::string& topic);
|
virtual void addTopic (const std::string& topic);
|
||||||
|
|
||||||
virtual void askQuestion (const std::string& question,int choice);
|
virtual void addChoice (const std::string& text,int choice);
|
||||||
|
const std::vector<std::pair<std::string, int> >& getChoices();
|
||||||
|
|
||||||
|
virtual bool isGoodbye();
|
||||||
|
|
||||||
virtual void goodbye();
|
virtual void goodbye();
|
||||||
|
|
||||||
virtual bool checkServiceRefused ();
|
virtual bool checkServiceRefused (Response& response);
|
||||||
|
|
||||||
virtual void say(const MWWorld::Ptr &actor, const std::string &topic);
|
virtual void say(const MWWorld::Ptr &actor, const std::string &topic);
|
||||||
|
|
||||||
//calbacks for the GUI
|
//calbacks for the GUI
|
||||||
virtual void keywordSelected (const std::string& keyword);
|
virtual Response keywordSelected (const std::string& keyword);
|
||||||
virtual void goodbyeSelected();
|
virtual void goodbyeSelected();
|
||||||
virtual void questionAnswered (int answer);
|
virtual Response questionAnswered (int answer);
|
||||||
|
|
||||||
virtual void persuade (int type);
|
virtual Response persuade (int type);
|
||||||
virtual int getTemporaryDispositionChange () const;
|
virtual int getTemporaryDispositionChange () const;
|
||||||
|
|
||||||
/// @note This change is temporary and gets discarded when dialogue ends.
|
/// @note This change is temporary and gets discarded when dialogue ends.
|
||||||
|
|
|
@ -68,7 +68,9 @@ namespace MWGui
|
||||||
else /*if (sender == mBribe1000Button)*/
|
else /*if (sender == mBribe1000Button)*/
|
||||||
type = MWBase::MechanicsManager::PT_Bribe1000;
|
type = MWBase::MechanicsManager::PT_Bribe1000;
|
||||||
|
|
||||||
MWBase::Environment::get().getDialogueManager()->persuade(type);
|
MWBase::DialogueManager::Response response = MWBase::Environment::get().getDialogueManager()->persuade(type);
|
||||||
|
|
||||||
|
eventPersuadeMsg(response.first, response.second);
|
||||||
|
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
}
|
}
|
||||||
|
@ -214,30 +216,26 @@ namespace MWGui
|
||||||
|
|
||||||
void Choice::activated()
|
void Choice::activated()
|
||||||
{
|
{
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
|
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
|
||||||
MWBase::Environment::get().getDialogueManager()->questionAnswered(mChoiceId);
|
eventChoiceActivated(mChoiceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Topic::activated()
|
void Topic::activated()
|
||||||
{
|
{
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
|
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
|
||||||
MWBase::Environment::get().getDialogueManager()->keywordSelected(mTopicId);
|
eventTopicActivated(mTopicId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Goodbye::activated()
|
void Goodbye::activated()
|
||||||
{
|
{
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
|
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
|
||||||
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
eventActivated();
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
DialogueWindow::DialogueWindow()
|
DialogueWindow::DialogueWindow()
|
||||||
: WindowBase("openmw_dialogue_window.layout")
|
: WindowBase("openmw_dialogue_window.layout")
|
||||||
, mEnabled(false)
|
|
||||||
, mGoodbye(false)
|
, mGoodbye(false)
|
||||||
, mPersuasionDialog()
|
, mPersuasionDialog()
|
||||||
{
|
{
|
||||||
|
@ -245,13 +243,14 @@ namespace MWGui
|
||||||
center();
|
center();
|
||||||
|
|
||||||
mPersuasionDialog.setVisible(false);
|
mPersuasionDialog.setVisible(false);
|
||||||
|
mPersuasionDialog.eventPersuadeMsg += MyGUI::newDelegate(this, &DialogueWindow::onPersuadeResult);
|
||||||
|
|
||||||
//History view
|
//History view
|
||||||
getWidget(mHistory, "History");
|
getWidget(mHistory, "History");
|
||||||
|
|
||||||
//Topics list
|
//Topics list
|
||||||
getWidget(mTopicsList, "TopicsList");
|
getWidget(mTopicsList, "TopicsList");
|
||||||
mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic);
|
mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectListItem);
|
||||||
|
|
||||||
getWidget(mGoodbyeButton, "ByeButton");
|
getWidget(mGoodbyeButton, "ByeButton");
|
||||||
mGoodbyeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
|
mGoodbyeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked);
|
||||||
|
@ -269,15 +268,27 @@ namespace MWGui
|
||||||
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize);
|
mMainWidget->castType<MyGUI::Window>()->eventWindowChangeCoord += MyGUI::newDelegate(this, &DialogueWindow::onWindowResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DialogueWindow::~DialogueWindow()
|
||||||
|
{
|
||||||
|
mPersuasionDialog.eventPersuadeMsg.clear();
|
||||||
|
|
||||||
|
deleteLater();
|
||||||
|
for (Link* link : mLinks)
|
||||||
|
delete link;
|
||||||
|
for (auto link : mTopicLinks)
|
||||||
|
delete link.second;
|
||||||
|
for (auto history : mHistoryContents)
|
||||||
|
delete history;
|
||||||
|
}
|
||||||
|
|
||||||
void DialogueWindow::onTradeComplete()
|
void DialogueWindow::onTradeComplete()
|
||||||
{
|
{
|
||||||
addResponse(MyGUI::LanguageManager::getInstance().replaceTags("#{sBarterDialog5}"));
|
addResponse("", MyGUI::LanguageManager::getInstance().replaceTags("#{sBarterDialog5}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DialogueWindow::exit()
|
bool DialogueWindow::exit()
|
||||||
{
|
{
|
||||||
if ((!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice())
|
if ((MWBase::Environment::get().getDialogueManager()->isInChoice()))
|
||||||
&& !mGoodbye)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -315,9 +326,9 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueWindow::onSelectTopic(const std::string& topic, int id)
|
void DialogueWindow::onSelectListItem(const std::string& topic, int id)
|
||||||
{
|
{
|
||||||
if (!mEnabled || MWBase::Environment::get().getDialogueManager()->isInChoice())
|
if (mGoodbye || MWBase::Environment::get().getDialogueManager()->isInChoice())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int separatorPos = 0;
|
int separatorPos = 0;
|
||||||
|
@ -328,17 +339,18 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id >= separatorPos)
|
if (id >= separatorPos)
|
||||||
MWBase::Environment::get().getDialogueManager()->keywordSelected(topic);
|
onTopicActivated(topic);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
|
MWBase::DialogueManager::Response response;
|
||||||
if (topic == gmst.find("sPersuasion")->getString())
|
if (topic == gmst.find("sPersuasion")->getString())
|
||||||
mPersuasionDialog.setVisible(true);
|
mPersuasionDialog.setVisible(true);
|
||||||
else if (topic == gmst.find("sCompanionShare")->getString())
|
else if (topic == gmst.find("sCompanionShare")->getString())
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Companion, mPtr);
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Companion, mPtr);
|
||||||
else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused())
|
else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused(response))
|
||||||
{
|
{
|
||||||
if (topic == gmst.find("sBarter")->getString())
|
if (topic == gmst.find("sBarter")->getString())
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Barter, mPtr);
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Barter, mPtr);
|
||||||
|
@ -355,21 +367,30 @@ namespace MWGui
|
||||||
else if (topic == gmst.find("sRepair")->getString())
|
else if (topic == gmst.find("sRepair")->getString())
|
||||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_MerchantRepair, mPtr);
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_MerchantRepair, mPtr);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
addResponse(response.first, response.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueWindow::startDialogue(MWWorld::Ptr actor, std::string npcName)
|
void DialogueWindow::setPtr(const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
|
MWBase::DialogueManager::Response response;
|
||||||
|
if (!MWBase::Environment::get().getDialogueManager()->startDialogue(actor, response))
|
||||||
|
{
|
||||||
|
// No greetings found. The dialogue window should not be shown.
|
||||||
|
// If this is a companion, we must show the companion window directly (used by BM_bear_be_unique).
|
||||||
|
if (isCompanion())
|
||||||
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Companion, mPtr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mGoodbyeButton);
|
MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mGoodbyeButton);
|
||||||
|
|
||||||
mGoodbye = false;
|
mGoodbye = false;
|
||||||
mEnabled = true;
|
|
||||||
bool sameActor = (mPtr == actor);
|
bool sameActor = (mPtr == actor);
|
||||||
mPtr = actor;
|
mPtr = actor;
|
||||||
mTopicsList->setEnabled(true);
|
mTopicsList->setEnabled(true);
|
||||||
setTitle(npcName);
|
setTitle(mPtr.getClass().getName(mPtr));
|
||||||
|
|
||||||
clearChoices();
|
|
||||||
|
|
||||||
mTopicsList->clear();
|
mTopicsList->clear();
|
||||||
|
|
||||||
|
@ -381,12 +402,13 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::vector<Link*>::iterator it = mLinks.begin(); it != mLinks.end(); ++it)
|
for (std::vector<Link*>::iterator it = mLinks.begin(); it != mLinks.end(); ++it)
|
||||||
delete (*it);
|
mDeleteLater.push_back(*it); // Links are not deleted right away to prevent issues with event handlers
|
||||||
mLinks.clear();
|
mLinks.clear();
|
||||||
|
|
||||||
updateDisposition();
|
updateDisposition();
|
||||||
|
|
||||||
restock();
|
restock();
|
||||||
|
|
||||||
|
addResponse(response.first, response.second, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueWindow::restock()
|
void DialogueWindow::restock()
|
||||||
|
@ -403,11 +425,18 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::deleteLater()
|
||||||
|
{
|
||||||
|
for (Link* link : mDeleteLater)
|
||||||
|
delete link;
|
||||||
|
mDeleteLater.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
|
void DialogueWindow::setKeywords(std::list<std::string> keyWords)
|
||||||
{
|
{
|
||||||
mTopicsList->clear();
|
mTopicsList->clear();
|
||||||
for (std::map<std::string, Link*>::iterator it = mTopicLinks.begin(); it != mTopicLinks.end(); ++it)
|
for (std::map<std::string, Link*>::iterator it = mTopicLinks.begin(); it != mTopicLinks.end(); ++it)
|
||||||
delete it->second;
|
mDeleteLater.push_back(it->second);
|
||||||
mTopicLinks.clear();
|
mTopicLinks.clear();
|
||||||
mKeywordSearch.clear();
|
mKeywordSearch.clear();
|
||||||
|
|
||||||
|
@ -416,9 +445,6 @@ namespace MWGui
|
||||||
bool travel = (mPtr.getTypeName() == typeid(ESM::NPC).name() && !mPtr.get<ESM::NPC>()->mBase->getTransport().empty())
|
bool travel = (mPtr.getTypeName() == typeid(ESM::NPC).name() && !mPtr.get<ESM::NPC>()->mBase->getTransport().empty())
|
||||||
|| (mPtr.getTypeName() == typeid(ESM::Creature).name() && !mPtr.get<ESM::Creature>()->mBase->getTransport().empty());
|
|| (mPtr.getTypeName() == typeid(ESM::Creature).name() && !mPtr.get<ESM::Creature>()->mBase->getTransport().empty());
|
||||||
|
|
||||||
bool isCompanion = !mPtr.getClass().getScript(mPtr).empty()
|
|
||||||
&& mPtr.getRefData().getLocals().getIntVar(mPtr.getClass().getScript(mPtr), "companion");
|
|
||||||
|
|
||||||
const MWWorld::Store<ESM::GameSetting> &gmst =
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||||
|
|
||||||
|
@ -446,7 +472,7 @@ namespace MWGui
|
||||||
if (services & ESM::NPC::Repair)
|
if (services & ESM::NPC::Repair)
|
||||||
mTopicsList->addItem(gmst.find("sRepair")->getString());
|
mTopicsList->addItem(gmst.find("sRepair")->getString());
|
||||||
|
|
||||||
if (isCompanion)
|
if (isCompanion())
|
||||||
mTopicsList->addItem(gmst.find("sCompanionShare")->getString());
|
mTopicsList->addItem(gmst.find("sCompanionShare")->getString());
|
||||||
|
|
||||||
if (mTopicsList->getItemCount() > 0)
|
if (mTopicsList->getItemCount() > 0)
|
||||||
|
@ -458,6 +484,7 @@ namespace MWGui
|
||||||
mTopicsList->addItem(*it);
|
mTopicsList->addItem(*it);
|
||||||
|
|
||||||
Topic* t = new Topic(*it);
|
Topic* t = new Topic(*it);
|
||||||
|
t->eventTopicActivated += MyGUI::newDelegate(this, &DialogueWindow::onTopicActivated);
|
||||||
mTopicLinks[Misc::StringUtils::lowerCase(*it)] = t;
|
mTopicLinks[Misc::StringUtils::lowerCase(*it)] = t;
|
||||||
|
|
||||||
mKeywordSearch.seed(Misc::StringUtils::lowerCase(*it), intptr_t(t));
|
mKeywordSearch.seed(Misc::StringUtils::lowerCase(*it), intptr_t(t));
|
||||||
|
@ -491,9 +518,11 @@ namespace MWGui
|
||||||
typesetter->sectionBreak(9);
|
typesetter->sectionBreak(9);
|
||||||
// choices
|
// choices
|
||||||
const TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours();
|
const TextColours& textColours = MWBase::Environment::get().getWindowManager()->getTextColours();
|
||||||
for (std::vector<std::pair<std::string, int> >::iterator it = mChoices.begin(); it != mChoices.end(); ++it)
|
mChoices = MWBase::Environment::get().getDialogueManager()->getChoices();
|
||||||
|
for (std::vector<std::pair<std::string, int> >::const_iterator it = mChoices.begin(); it != mChoices.end(); ++it)
|
||||||
{
|
{
|
||||||
Choice* link = new Choice(it->second);
|
Choice* link = new Choice(it->second);
|
||||||
|
link->eventChoiceActivated += MyGUI::newDelegate(this, &DialogueWindow::onChoiceActivated);
|
||||||
mLinks.push_back(link);
|
mLinks.push_back(link);
|
||||||
|
|
||||||
typesetter->lineBreak();
|
typesetter->lineBreak();
|
||||||
|
@ -503,9 +532,11 @@ namespace MWGui
|
||||||
typesetter->write(questionStyle, to_utf8_span(it->first.c_str()));
|
typesetter->write(questionStyle, to_utf8_span(it->first.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mGoodbye = MWBase::Environment::get().getDialogueManager()->isGoodbye();
|
||||||
if (mGoodbye)
|
if (mGoodbye)
|
||||||
{
|
{
|
||||||
Goodbye* link = new Goodbye();
|
Goodbye* link = new Goodbye();
|
||||||
|
link->eventActivated += MyGUI::newDelegate(this, &DialogueWindow::onGoodbyeActivated);
|
||||||
mLinks.push_back(link);
|
mLinks.push_back(link);
|
||||||
std::string goodbye = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGoodbye")->getString();
|
std::string goodbye = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sGoodbye")->getString();
|
||||||
BookTypesetter::Style* questionStyle = typesetter->createHotStyle(body, textColours.answer, textColours.answerOver,
|
BookTypesetter::Style* questionStyle = typesetter->createHotStyle(body, textColours.answer, textColours.answerOver,
|
||||||
|
@ -550,15 +581,35 @@ namespace MWGui
|
||||||
reinterpret_cast<Link*>(link)->activated();
|
reinterpret_cast<Link*>(link)->activated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::onTopicActivated(const std::string &topicId)
|
||||||
|
{
|
||||||
|
MWBase::DialogueManager::Response response = MWBase::Environment::get().getDialogueManager()->keywordSelected(topicId);
|
||||||
|
addResponse(response.first, response.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::onChoiceActivated(int id)
|
||||||
|
{
|
||||||
|
MWBase::DialogueManager::Response response = MWBase::Environment::get().getDialogueManager()->questionAnswered(id);
|
||||||
|
addResponse(response.first, response.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::onGoodbyeActivated()
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
||||||
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue);
|
||||||
|
resetReference();
|
||||||
|
}
|
||||||
|
|
||||||
void DialogueWindow::onScrollbarMoved(MyGUI::ScrollBar *sender, size_t pos)
|
void DialogueWindow::onScrollbarMoved(MyGUI::ScrollBar *sender, size_t pos)
|
||||||
{
|
{
|
||||||
mHistory->setPosition(0, static_cast<int>(pos) * -1);
|
mHistory->setPosition(0, static_cast<int>(pos) * -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueWindow::addResponse(const std::string &text, const std::string &title, bool needMargin)
|
void DialogueWindow::addResponse(const std::string &title, const std::string &text, bool needMargin)
|
||||||
{
|
{
|
||||||
mHistoryContents.push_back(new Response(text, title, needMargin));
|
mHistoryContents.push_back(new Response(text, title, needMargin));
|
||||||
updateHistory();
|
updateHistory();
|
||||||
|
updateTopics();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueWindow::addMessageBox(const std::string& text)
|
void DialogueWindow::addMessageBox(const std::string& text)
|
||||||
|
@ -567,18 +618,6 @@ namespace MWGui
|
||||||
updateHistory();
|
updateHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueWindow::addChoice(const std::string& choice, int id)
|
|
||||||
{
|
|
||||||
mChoices.push_back(std::make_pair(choice, id));
|
|
||||||
updateHistory();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::clearChoices()
|
|
||||||
{
|
|
||||||
mChoices.clear();
|
|
||||||
updateHistory();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::updateDisposition()
|
void DialogueWindow::updateDisposition()
|
||||||
{
|
{
|
||||||
bool dispositionVisible = false;
|
bool dispositionVisible = false;
|
||||||
|
@ -608,13 +647,6 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogueWindow::goodbye()
|
|
||||||
{
|
|
||||||
mGoodbye = true;
|
|
||||||
mEnabled = false;
|
|
||||||
updateHistory();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogueWindow::onReferenceUnavailable()
|
void DialogueWindow::onReferenceUnavailable()
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
||||||
|
@ -623,6 +655,30 @@ namespace MWGui
|
||||||
void DialogueWindow::onFrame(float dt)
|
void DialogueWindow::onFrame(float dt)
|
||||||
{
|
{
|
||||||
checkReferenceAvailable();
|
checkReferenceAvailable();
|
||||||
|
if (mPtr.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
updateDisposition();
|
updateDisposition();
|
||||||
|
deleteLater();
|
||||||
|
|
||||||
|
if (mChoices != MWBase::Environment::get().getDialogueManager()->getChoices()
|
||||||
|
|| mGoodbye != MWBase::Environment::get().getDialogueManager()->isGoodbye())
|
||||||
|
updateHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::updateTopics()
|
||||||
|
{
|
||||||
|
setKeywords(MWBase::Environment::get().getDialogueManager()->getAvailableTopics());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DialogueWindow::isCompanion()
|
||||||
|
{
|
||||||
|
return !mPtr.getClass().getScript(mPtr).empty()
|
||||||
|
&& mPtr.getRefData().getLocals().getIntVar(mPtr.getClass().getScript(mPtr), "companion");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DialogueWindow::onPersuadeResult(const std::string &title, const std::string &text)
|
||||||
|
{
|
||||||
|
addResponse(title, text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
#include "../mwdialogue/keywordsearch.hpp"
|
#include "../mwdialogue/keywordsearch.hpp"
|
||||||
|
|
||||||
|
#include <MyGUI_Delegate.h>
|
||||||
|
|
||||||
namespace Gui
|
namespace Gui
|
||||||
{
|
{
|
||||||
class MWList;
|
class MWList;
|
||||||
|
@ -20,14 +22,14 @@ namespace MWGui
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
class DialogueHistoryViewModel;
|
|
||||||
class BookPage;
|
|
||||||
|
|
||||||
class PersuasionDialog : public WindowModal
|
class PersuasionDialog : public WindowModal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PersuasionDialog();
|
PersuasionDialog();
|
||||||
|
|
||||||
|
typedef MyGUI::delegates::CMultiDelegate2<const std::string&, const std::string&> EventHandle_Result;
|
||||||
|
EventHandle_Result eventPersuadeMsg;
|
||||||
|
|
||||||
virtual void onOpen();
|
virtual void onOpen();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -53,6 +55,8 @@ namespace MWGui
|
||||||
|
|
||||||
struct Topic : Link
|
struct Topic : Link
|
||||||
{
|
{
|
||||||
|
typedef MyGUI::delegates::CMultiDelegate1<const std::string&> EventHandle_TopicId;
|
||||||
|
EventHandle_TopicId eventTopicActivated;
|
||||||
Topic(const std::string& id) : mTopicId(id) {}
|
Topic(const std::string& id) : mTopicId(id) {}
|
||||||
std::string mTopicId;
|
std::string mTopicId;
|
||||||
virtual void activated ();
|
virtual void activated ();
|
||||||
|
@ -60,6 +64,8 @@ namespace MWGui
|
||||||
|
|
||||||
struct Choice : Link
|
struct Choice : Link
|
||||||
{
|
{
|
||||||
|
typedef MyGUI::delegates::CMultiDelegate1<int> EventHandle_ChoiceId;
|
||||||
|
EventHandle_ChoiceId eventChoiceActivated;
|
||||||
Choice(int id) : mChoiceId(id) {}
|
Choice(int id) : mChoiceId(id) {}
|
||||||
int mChoiceId;
|
int mChoiceId;
|
||||||
virtual void activated ();
|
virtual void activated ();
|
||||||
|
@ -67,6 +73,8 @@ namespace MWGui
|
||||||
|
|
||||||
struct Goodbye : Link
|
struct Goodbye : Link
|
||||||
{
|
{
|
||||||
|
typedef MyGUI::delegates::CMultiDelegate0 Event_Activated;
|
||||||
|
Event_Activated eventActivated;
|
||||||
virtual void activated ();
|
virtual void activated ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,6 +106,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DialogueWindow();
|
DialogueWindow();
|
||||||
|
~DialogueWindow();
|
||||||
|
|
||||||
void onTradeComplete();
|
void onTradeComplete();
|
||||||
|
|
||||||
|
@ -108,25 +117,29 @@ namespace MWGui
|
||||||
|
|
||||||
void notifyLinkClicked (TypesetBook::InteractiveId link);
|
void notifyLinkClicked (TypesetBook::InteractiveId link);
|
||||||
|
|
||||||
void startDialogue(MWWorld::Ptr actor, std::string npcName);
|
void setPtr(const MWWorld::Ptr& actor);
|
||||||
|
|
||||||
void setKeywords(std::list<std::string> keyWord);
|
void setKeywords(std::list<std::string> keyWord);
|
||||||
|
|
||||||
void addResponse (const std::string& text, const std::string& title="", bool needMargin = true);
|
void addResponse (const std::string& title, const std::string& text, bool needMargin = true);
|
||||||
|
|
||||||
void addMessageBox(const std::string& text);
|
void addMessageBox(const std::string& text);
|
||||||
|
|
||||||
void addChoice(const std::string& choice, int id);
|
|
||||||
void clearChoices();
|
|
||||||
|
|
||||||
void goodbye();
|
|
||||||
void onFrame(float dt);
|
void onFrame(float dt);
|
||||||
void clear() { resetReference(); }
|
void clear() { resetReference(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onSelectTopic(const std::string& topic, int id);
|
void updateTopics();
|
||||||
|
bool isCompanion();
|
||||||
|
|
||||||
|
void onPersuadeResult(const std::string& title, const std::string& text);
|
||||||
|
void onSelectListItem(const std::string& topic, int id);
|
||||||
void onByeClicked(MyGUI::Widget* _sender);
|
void onByeClicked(MyGUI::Widget* _sender);
|
||||||
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
void onMouseWheel(MyGUI::Widget* _sender, int _rel);
|
||||||
void onWindowResize(MyGUI::Window* _sender);
|
void onWindowResize(MyGUI::Window* _sender);
|
||||||
|
void onTopicActivated(const std::string& topicId);
|
||||||
|
void onChoiceActivated(int id);
|
||||||
|
void onGoodbyeActivated();
|
||||||
|
|
||||||
void onScrollbarMoved (MyGUI::ScrollBar* sender, size_t pos);
|
void onScrollbarMoved (MyGUI::ScrollBar* sender, size_t pos);
|
||||||
|
|
||||||
|
@ -137,17 +150,19 @@ namespace MWGui
|
||||||
private:
|
private:
|
||||||
void updateDisposition();
|
void updateDisposition();
|
||||||
void restock();
|
void restock();
|
||||||
|
void deleteLater();
|
||||||
|
|
||||||
bool mEnabled;
|
bool mEnabled;
|
||||||
|
|
||||||
bool mGoodbye;
|
|
||||||
|
|
||||||
std::vector<DialogueText*> mHistoryContents;
|
std::vector<DialogueText*> mHistoryContents;
|
||||||
std::vector<std::pair<std::string, int> > mChoices;
|
std::vector<std::pair<std::string, int> > mChoices;
|
||||||
|
bool mGoodbye;
|
||||||
|
|
||||||
std::vector<Link*> mLinks;
|
std::vector<Link*> mLinks;
|
||||||
std::map<std::string, Link*> mTopicLinks;
|
std::map<std::string, Link*> mTopicLinks;
|
||||||
|
|
||||||
|
std::vector<Link*> mDeleteLater;
|
||||||
|
|
||||||
KeywordSearchT mKeywordSearch;
|
KeywordSearchT mKeywordSearch;
|
||||||
|
|
||||||
BookPage* mHistory;
|
BookPage* mHistory;
|
||||||
|
|
|
@ -353,6 +353,7 @@ namespace MWGui
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Enchanting);
|
||||||
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
||||||
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,6 +323,7 @@ namespace MWGui
|
||||||
|
|
||||||
onCancelButtonClicked(mCancelButton);
|
onCancelButtonClicked(mCancelButton);
|
||||||
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
||||||
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,6 +197,7 @@ namespace MWGui
|
||||||
// go back to game mode
|
// go back to game mode
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Training);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Training);
|
||||||
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
||||||
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrainingWindow::onFrame(float dt)
|
void TrainingWindow::onFrame(float dt)
|
||||||
|
|
|
@ -178,6 +178,7 @@ namespace MWGui
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Travel);
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Travel);
|
||||||
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
|
||||||
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
|
||||||
|
|
||||||
// Teleports any followers, too.
|
// Teleports any followers, too.
|
||||||
MWWorld::ActionTeleport action(interior ? cellname : "", pos, true);
|
MWWorld::ActionTeleport action(interior ? cellname : "", pos, true);
|
||||||
|
|
|
@ -1288,7 +1288,6 @@ namespace MWGui
|
||||||
mConsole->executeFile (path);
|
mConsole->executeFile (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
MWGui::DialogueWindow* WindowManager::getDialogueWindow() { return mDialogueWindow; }
|
|
||||||
MWGui::InventoryWindow* WindowManager::getInventoryWindow() { return mInventoryWindow; }
|
MWGui::InventoryWindow* WindowManager::getInventoryWindow() { return mInventoryWindow; }
|
||||||
MWGui::CountDialog* WindowManager::getCountDialog() { return mCountDialog; }
|
MWGui::CountDialog* WindowManager::getCountDialog() { return mCountDialog; }
|
||||||
MWGui::ConfirmationDialog* WindowManager::getConfirmationDialog() { return mConfirmationDialog; }
|
MWGui::ConfirmationDialog* WindowManager::getConfirmationDialog() { return mConfirmationDialog; }
|
||||||
|
|
|
@ -179,7 +179,6 @@ namespace MWGui
|
||||||
virtual bool isAllowed(GuiWindow wnd) const;
|
virtual bool isAllowed(GuiWindow wnd) const;
|
||||||
|
|
||||||
/// \todo investigate, if we really need to expose every single lousy UI element to the outside world
|
/// \todo investigate, if we really need to expose every single lousy UI element to the outside world
|
||||||
virtual MWGui::DialogueWindow* getDialogueWindow();
|
|
||||||
virtual MWGui::InventoryWindow* getInventoryWindow();
|
virtual MWGui::InventoryWindow* getInventoryWindow();
|
||||||
virtual MWGui::CountDialog* getCountDialog();
|
virtual MWGui::CountDialog* getCountDialog();
|
||||||
virtual MWGui::ConfirmationDialog* getConfirmationDialog();
|
virtual MWGui::ConfirmationDialog* getConfirmationDialog();
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "../mwbase/dialoguemanager.hpp"
|
#include "../mwbase/dialoguemanager.hpp"
|
||||||
#include "../mwbase/journal.hpp"
|
#include "../mwbase/journal.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwmechanics/npcstats.hpp"
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
@ -116,7 +117,7 @@ namespace MWScript
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
arg0 = arg0 -1;
|
arg0 = arg0 -1;
|
||||||
}
|
}
|
||||||
dialogue->askQuestion(question,choice);
|
dialogue->addChoice(question,choice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -133,7 +134,7 @@ namespace MWScript
|
||||||
if (!ptr.getRefData().isEnabled())
|
if (!ptr.getRefData().isEnabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MWBase::Environment::get().getDialogueManager()->startDialogue (ptr);
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue, ptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "actiontalk.hpp"
|
#include "actiontalk.hpp"
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/dialoguemanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,6 @@ namespace MWWorld
|
||||||
|
|
||||||
void ActionTalk::executeImp (const Ptr& actor)
|
void ActionTalk::executeImp (const Ptr& actor)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getDialogueManager()->startDialogue (getTarget());
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Dialogue, getTarget());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue