diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index 339755c358..9c099f7dbc 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -24,6 +24,18 @@ #include +#include "../mwscript/extensions.hpp" +#include +#include +#include +#include +#include +#include + +#include "../mwscript/compilercontext.hpp" +#include "../mwscript/interpretercontext.hpp" +#include + namespace { std::string toLower (const std::string& name) @@ -397,17 +409,49 @@ namespace MWDialogue return true; } - DialogueManager::DialogueManager (MWWorld::Environment& environment) : mEnvironment (environment) {} + DialogueManager::DialogueManager (MWWorld::Environment& environment) : + mEnvironment (environment),mCompilerContext (MWScript::CompilerContext::Type_Dialgoue, environment), + mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream) + { + } void DialogueManager::addTopic(std::string topic) { knownTopics[toLower(topic)] = true; } + void DialogueManager::parseText(std::string text) + { + std::map::iterator it; + for(it = actorKnownTopics.begin();it != actorKnownTopics.end();it++) + { + MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); + size_t pos = find_str_ci(text,it->first,0); + if(pos !=std::string::npos) + { + if(pos==0) + { + //std::cout << "fouuuuuuuuuuund"; + knownTopics[it->first] = true; + win->addKeyword(it->first,it->second.response); + } + else if(text.substr(pos -1,1) == " ") + { + //std::cout << "fouuuuuuuuuuund"; + knownTopics[it->first] = true; + win->addKeyword(it->first,it->second.response); + } + } + + } + } + void DialogueManager::startDialogue (const MWWorld::Ptr& actor) { std::cout << "talking with " << MWWorld::Class::get (actor).getName (actor) << std::endl; + mActor = actor; + //initialise the GUI mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue); MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); @@ -425,7 +469,7 @@ namespace MWDialogue { if (isMatching (actor, *iter)) { - actorKnownTopics[it->first] = iter->response; + actorKnownTopics[it->first] = *iter; if(knownTopics.find(toLower(it->first)) != knownTopics.end()) { MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); @@ -463,18 +507,9 @@ namespace MWDialogue // TODO execute script } std::string text = iter->response; - std::map::iterator it; - for(it = actorKnownTopics.begin();it != actorKnownTopics.end();it++) - { - if(find_str_ci(text,it->first,0) !=std::string::npos) - { - //std::cout << "fouuuuuuuuuuund"; - knownTopics[it->first] = true; - MWGui::DialogueWindow* win2 = mEnvironment.mWindowManager->getDialogueWindow(); - win2->addKeyword(it->first,it->second); - } - } + parseText(text); win->addText(iter->response); + executeScript(iter->resultScript); greetingFound = true; break; } @@ -483,21 +518,66 @@ namespace MWDialogue } } - void DialogueManager::keywordSelected(std::string keyword) + bool DialogueManager::compile (const std::string& cmd,std::vector& code) { - std::string text = actorKnownTopics[keyword]; - std::map::iterator it; - for(it = actorKnownTopics.begin();it != actorKnownTopics.end();it++) + try { - if(find_str_ci(text,it->first,0) !=std::string::npos) + mErrorHandler.reset(); + + std::istringstream input (cmd); + + Compiler::Scanner scanner (mErrorHandler, input, mCompilerContext.getExtensions()); + + Compiler::ScriptParser parser(mErrorHandler,mCompilerContext,Compiler::Locals());//??????&mActor.getRefData().getLocals()); + + scanner.scan (parser); + + if(mErrorHandler.isGood()) { - knownTopics[it->first] = true; - MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); - win->addKeyword(it->first,it->second); + parser.getCode(code); + return true; + } + return false; + } + catch (const Compiler::SourceException& error) + { + // error has already been reported via error handler + } + catch (const std::exception& error) + { + printError (std::string ("An exception has been thrown: ") + error.what()); + } + + return false; + } + + void DialogueManager::executeScript(std::string script) + { + std::vector code; + if(compile(script,code)) + { + try + { + MWScript::InterpreterContext interpreterContext(mEnvironment,&mActor.getRefData().getLocals(),mActor); + Interpreter::Interpreter interpreter; + MWScript::installOpcodes (interpreter); + interpreter.run (&code[0], code.size(), interpreterContext); + } + catch (const std::exception& error) + { + printError (std::string ("An exception has been thrown: ") + error.what()); } } } + void DialogueManager::keywordSelected(std::string keyword) + { + std::string text = actorKnownTopics[keyword].response; + std::string script = actorKnownTopics[keyword].resultScript; + parseText(text); + executeScript(script); + } + void DialogueManager::goodbyeSelected() { mEnvironment.mInputManager->setGuiMode(MWGui::GM_Game); @@ -508,4 +588,10 @@ namespace MWDialogue std::cout << "and the ansere is..."<< answere; } + void DialogueManager::printError(std::string error) + { + MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); + win->addText(error); + } + } diff --git a/apps/openmw/mwdialogue/dialoguemanager.hpp b/apps/openmw/mwdialogue/dialoguemanager.hpp index 88ae9e35c7..600171d331 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.hpp +++ b/apps/openmw/mwdialogue/dialoguemanager.hpp @@ -3,6 +3,11 @@ #include +#include +#include "../mwscript/compilercontext.hpp" +#include "../mwscript/interpretercontext.hpp" +#include + #include "../mwworld/ptr.hpp" #include @@ -21,8 +26,21 @@ namespace MWDialogue bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const; + void parseText(std::string text); + std::map knownTopics;// Those are the topics the player knows. - std::map actorKnownTopics; + std::map actorKnownTopics; + + MWScript::CompilerContext mCompilerContext; + std::ostream mErrorStream; + Compiler::StreamErrorHandler mErrorHandler; + + + bool compile (const std::string& cmd,std::vector& code); + void executeScript(std::string script); + MWWorld::Ptr mActor; + + void printError(std::string error); public: diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 5754d1d7e6..f336d8a38d 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -154,12 +154,23 @@ void addColorInString(std::string& str, const std::string& keyword,std::string c size_t pos = 0; while((pos = find_str_ci(str,keyword, pos)) != std::string::npos) { + if(pos==0) + { + str.insert(pos,color1); + pos += color1.length(); + pos += keyword.length(); + str.insert(pos,color2); + pos+= color2.length(); + } + else if(str.substr(pos -1,1) == " ") + { + str.insert(pos,color1); + pos += color1.length(); + pos += keyword.length(); + str.insert(pos,color2); + pos+= color2.length(); + } //str.replace(pos, oldStr.length(), "#686EBA"+str.get); - str.insert(pos,color1); - pos += color1.length(); - pos += keyword.length(); - str.insert(pos,color2); - pos+= color2.length(); } } @@ -190,7 +201,7 @@ void DialogueWindow::displayTopicText(std::string topic) void DialogueWindow::addText(std::string text) { - history->addDialogText(parseText(text)); + history->addDialogText("#B29154"+parseText(text)+"#B29154"); } void DialogueWindow::askQuestion(std::string question,std::list answers)