From 07d8d654cd8b9192fc69946b5d0a26dcc4e9c516 Mon Sep 17 00:00:00 2001 From: gugus Date: Wed, 14 Mar 2012 18:47:29 +0100 Subject: [PATCH] one step toward function filters and end choices. --- apps/openmw/mwdialogue/dialoguemanager.cpp | 399 +++++++++++--------- apps/openmw/mwdialogue/dialoguemanager.hpp | 6 +- apps/openmw/mwgui/dialogue.cpp | 4 +- apps/openmw/mwscript/dialogueextensions.cpp | 5 +- 4 files changed, 234 insertions(+), 180 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index 498485b975..49da44477a 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -56,12 +56,12 @@ namespace { switch (comp) { - case '0': return value1==value2; - case '1': return value1!=value2; - case '2': return value1>value2; - case '3': return value1>=value2; - case '4': return value1value2; + case '3': return value1>=value2; + case '4': return value1::const_iterator iter (info.selects.begin()); + iter != info.selects.end(); ++iter) + { + ESM::DialInfo::SelectStruct select = *iter; + char type = select.selectRule[1]; + if(type == '1') + { + char comp = select.selectRule[4]; + std::string name = select.selectRule.substr (5); + std::string function = select.selectRule.substr(1,2); + std::cout << function; + + int ifunction; + std::istringstream iss(function); + iss >> ifunction; + + switch(ifunction) + { + case 4://choice + if(!selectCompare(comp,mChoice,select.i)) return false; + break; + + default: + break; + + } + } + } + return true; + } bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const @@ -152,168 +184,170 @@ namespace MWDialogue { char comp = select.selectRule[4]; std::string name = select.selectRule.substr (5); + std::string function = select.selectRule.substr(1,2); + std::cout << function; // TODO types 4, 5, 6, 7, 8, 9, A, B, C //new TOTO: 5,6,9 switch (type) { - case '1': // function + case '1': // function - return false; // TODO implement functions + return false; // TODO implement functions - case '2': // global + case '2': // global - if (select.type==ESM::VT_Short || select.type==ESM::VT_Int || - select.type==ESM::VT_Long) + if (select.type==ESM::VT_Short || select.type==ESM::VT_Int || + select.type==ESM::VT_Long) + { + if (!checkGlobal (comp, toLower (name), select.i, *mEnvironment.mWorld)) + return false; + } + else if (select.type==ESM::VT_Float) + { + if (!checkGlobal (comp, toLower (name), select.f, *mEnvironment.mWorld)) + return false; + } + else + throw std::runtime_error ( + "unsupported variable type in dialogue info select"); + + return true; + + case '3': // local + + if (select.type==ESM::VT_Short || select.type==ESM::VT_Int || + select.type==ESM::VT_Long) + { + if (!checkLocal (comp, toLower (name), select.i, actor, + mEnvironment.mWorld->getStore())) + return false; + } + else if (select.type==ESM::VT_Float) + { + if (!checkLocal (comp, toLower (name), select.f, actor, + mEnvironment.mWorld->getStore())) + return false; + } + else + throw std::runtime_error ( + "unsupported variable type in dialogue info select"); + + return true; + + case '4'://journal + if(select.type==ESM::VT_Int) + { + //std::cout << "vtint: " << select.i << std::endl; + bool isInJournal; + if(mEnvironment.mJournal->begin()!=mEnvironment.mJournal->end()) { - if (!checkGlobal (comp, toLower (name), select.i, *mEnvironment.mWorld)) - return false; - } - else if (select.type==ESM::VT_Float) - { - if (!checkGlobal (comp, toLower (name), select.f, *mEnvironment.mWorld)) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - - return true; - - case '3': // local - - if (select.type==ESM::VT_Short || select.type==ESM::VT_Int || - select.type==ESM::VT_Long) - { - if (!checkLocal (comp, toLower (name), select.i, actor, - mEnvironment.mWorld->getStore())) - return false; - } - else if (select.type==ESM::VT_Float) - { - if (!checkLocal (comp, toLower (name), select.f, actor, - mEnvironment.mWorld->getStore())) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - - return true; - - case '4'://journal - if(select.type==ESM::VT_Int) - { - //std::cout << "vtint: " << select.i << std::endl; - bool isInJournal; - if(mEnvironment.mJournal->begin()!=mEnvironment.mJournal->end()) + for(std::deque::const_iterator it = mEnvironment.mJournal->begin();it!=mEnvironment.mJournal->end();it++) { - for(std::deque::const_iterator it = mEnvironment.mJournal->begin();it!=mEnvironment.mJournal->end();it++) - { - if(it->mTopic == name) isInJournal = true; - } + if(it->mTopic == name) isInJournal = true; } - else - isInJournal = false; - if(!selectCompare(comp,int(isInJournal),select.i)) return false; } else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); + isInJournal = false; + if(!selectCompare(comp,int(isInJournal),select.i)) return false; + } + else + throw std::runtime_error ( + "unsupported variable type in dialogue info select"); - return true; + return true; - case '7':// not ID - if(select.type==ESM::VT_String ||select.type==ESM::VT_Int)//bug in morrowind here? it's not a short, it's a string - { - int isID = int(toLower(name)==toLower(MWWorld::Class::get (actor).getId (actor))); - if (selectCompare(comp,!isID,select.i)) return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); + case '7':// not ID + if(select.type==ESM::VT_String ||select.type==ESM::VT_Int)//bug in morrowind here? it's not a short, it's a string + { + int isID = int(toLower(name)==toLower(MWWorld::Class::get (actor).getId (actor))); + if (selectCompare(comp,!isID,select.i)) return false; + } + else + throw std::runtime_error ( + "unsupported variable type in dialogue info select"); - return true; + return true; - case '8':// not faction - if(select.type==ESM::VT_Int) - { - ESMS::LiveCellRef* npc = actor.get(); - int isFaction = int(toLower(npc->base->faction) == toLower(name)); - if(selectCompare(comp,!isFaction,select.i)) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); + case '8':// not faction + if(select.type==ESM::VT_Int) + { + ESMS::LiveCellRef* npc = actor.get(); + int isFaction = int(toLower(npc->base->faction) == toLower(name)); + if(selectCompare(comp,!isFaction,select.i)) + return false; + } + else + throw std::runtime_error ( + "unsupported variable type in dialogue info select"); - return true; + return true; - case '9':// not class - if(select.type==ESM::VT_Int) - { - ESMS::LiveCellRef* npc = actor.get(); - int isClass = int(toLower(npc->base->cls) == toLower(name)); - if(selectCompare(comp,!isClass,select.i)) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); + case '9':// not class + if(select.type==ESM::VT_Int) + { + ESMS::LiveCellRef* npc = actor.get(); + int isClass = int(toLower(npc->base->cls) == toLower(name)); + if(selectCompare(comp,!isClass,select.i)) + return false; + } + else + throw std::runtime_error ( + "unsupported variable type in dialogue info select"); - return true; + return true; - case 'A'://not Race - if(select.type==ESM::VT_Int) - { - ESMS::LiveCellRef* npc = actor.get(); - int isRace = int(toLower(npc->base->race) == toLower(name)); - //std::cout << "isRace"<(comp,!isRace,select.i)) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); + case 'A'://not Race + if(select.type==ESM::VT_Int) + { + ESMS::LiveCellRef* npc = actor.get(); + int isRace = int(toLower(npc->base->race) == toLower(name)); + //std::cout << "isRace"<(comp,!isRace,select.i)) + return false; + } + else + throw std::runtime_error ( + "unsupported variable type in dialogue info select"); - return true; + return true; - case 'B'://not Cell - if(select.type==ESM::VT_Int) - { - int isCell = int(toLower(actor.getCell()->cell->name) == toLower(name)); - if(selectCompare(comp,!isCell,select.i)) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - return true; + case 'B'://not Cell + if(select.type==ESM::VT_Int) + { + int isCell = int(toLower(actor.getCell()->cell->name) == toLower(name)); + if(selectCompare(comp,!isCell,select.i)) + return false; + } + else + throw std::runtime_error ( + "unsupported variable type in dialogue info select"); + return true; - case 'C'://not local - if (select.type==ESM::VT_Short || select.type==ESM::VT_Int || - select.type==ESM::VT_Long) - { - if (checkLocal (comp, toLower (name), select.i, actor, - mEnvironment.mWorld->getStore())) - return false; - } - else if (select.type==ESM::VT_Float) - { - if (checkLocal (comp, toLower (name), select.f, actor, - mEnvironment.mWorld->getStore())) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - return true; + case 'C'://not local + if (select.type==ESM::VT_Short || select.type==ESM::VT_Int || + select.type==ESM::VT_Long) + { + if (checkLocal (comp, toLower (name), select.i, actor, + mEnvironment.mWorld->getStore())) + return false; + } + else if (select.type==ESM::VT_Float) + { + if (checkLocal (comp, toLower (name), select.f, actor, + mEnvironment.mWorld->getStore())) + return false; + } + else + throw std::runtime_error ( + "unsupported variable type in dialogue info select"); + return true; - default: + default: - std::cout << "unchecked select: " << type << " " << comp << " " << name << std::endl; + std::cout << "unchecked select: " << type << " " << comp << " " << name << std::endl; } } @@ -401,12 +435,12 @@ namespace MWDialogue return false; /*std::cout - << "unchecked entries:" << std::endl - << " player faction: " << info.pcFaction << std::endl - << " disposition: " << info.data.disposition << std::endl - << " NPC rank: " << static_cast (info.data.rank) << std::endl - << " gender: " << static_cast (info.data.gender) << std::endl - << " PC rank: " << static_cast (info.data.PCrank) << std::endl;*/ + << "unchecked entries:" << std::endl + << " player faction: " << info.pcFaction << std::endl + << " disposition: " << info.data.disposition << std::endl + << " NPC rank: " << static_cast (info.data.rank) << std::endl + << " gender: " << static_cast (info.data.gender) << std::endl + << " PC rank: " << static_cast (info.data.PCrank) << std::endl;*/ return true; } @@ -415,6 +449,7 @@ namespace MWDialogue mEnvironment (environment),mCompilerContext (MWScript::CompilerContext::Type_Dialgoue, environment), mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream) { + mChoice = -1; mCompilerContext.setExtensions (&extensions); } @@ -425,24 +460,27 @@ namespace MWDialogue void DialogueManager::parseText(std::string text) { - std::map::iterator it; + 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) + if(!it->second.empty()) { - //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); + if(pos==0) + { + //std::cout << "fouuuuuuuuuuund"; + knownTopics[it->first] = true; + win->addKeyword(it->first,it->second.front().response); + } + else if(text.substr(pos -1,1) == " ") + { + //std::cout << "fouuuuuuuuuuund"; + knownTopics[it->first] = true; + win->addKeyword(it->first,it->second.front().response); + } } } @@ -472,14 +510,14 @@ namespace MWDialogue { if (isMatching (actor, *iter)) { - actorKnownTopics[it->first] = *iter; + actorKnownTopics[it->first].push_back(*iter); if(knownTopics.find(toLower(it->first)) != knownTopics.end()) { MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); win->addKeyword(it->first,iter->response); //std::cout << it->first; //std::cout << "match found!!"; - break; + //break; } } } @@ -585,10 +623,21 @@ namespace MWDialogue void DialogueManager::keywordSelected(std::string keyword) { - std::string text = actorKnownTopics[keyword].response; - std::string script = actorKnownTopics[keyword].resultScript; - parseText(text); - executeScript(script); + if(!actorKnownTopics[keyword].empty()) + { + for(std::list::iterator it = actorKnownTopics[keyword].begin(); it != actorKnownTopics[keyword].end();it++) + { + ESM::DialInfo dial = *it; + if(functionFilter(mActor,dial)) + { + std::string text = actorKnownTopics[keyword].front().response; + std::string script = actorKnownTopics[keyword].front().resultScript; + parseText(text); + executeScript(script); + break; + } + } + } } void DialogueManager::goodbyeSelected() @@ -598,7 +647,7 @@ namespace MWDialogue void DialogueManager::questionAnswered(std::string answere) { - std::cout << "and the ansere is..."<< answere; + std::cout << "and the ansere is..."<< answere; } void DialogueManager::printError(std::string error) diff --git a/apps/openmw/mwdialogue/dialoguemanager.hpp b/apps/openmw/mwdialogue/dialoguemanager.hpp index 83d4832ba0..85e89573ff 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.hpp +++ b/apps/openmw/mwdialogue/dialoguemanager.hpp @@ -26,10 +26,12 @@ namespace MWDialogue bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const; + bool functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info); + 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; @@ -42,6 +44,8 @@ namespace MWDialogue void printError(std::string error); + int mChoice; + public: DialogueManager (MWWorld::Environment& environment,const Compiler::Extensions& extensions); diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 01466a7dc8..25653d9fcd 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -84,8 +84,8 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender) //std::cout << "Clicked on key: " << key << std::endl; if(color == "#686EBA") { - mEnvironment.mDialogueManager->keywordSelected(lower_string(key)); displayTopicText(lower_string(key)); + mEnvironment.mDialogueManager->keywordSelected(lower_string(key)); } if(color == "#572D21") { @@ -117,8 +117,8 @@ void DialogueWindow::onSelectTopic(MyGUI::List* _sender, size_t _index) if (_index == MyGUI::ITEM_NONE) return; std::string topic = _sender->getItem(_index); - mEnvironment.mDialogueManager->keywordSelected(lower_string(topic)); displayTopicText(topic); + mEnvironment.mDialogueManager->keywordSelected(lower_string(topic)); //const std::string* theTopic = topicsList->getItemDataAt(_index); //std::cout << "Selected: "<< theTopic << std::endl; diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp index 09adc0060f..331cb0a341 100644 --- a/apps/openmw/mwscript/dialogueextensions.cpp +++ b/apps/openmw/mwscript/dialogueextensions.cpp @@ -95,7 +95,8 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { - std::cout << "CHOICECHOICEHOCQSCHQSHD"; + std::cout << "CHOICE" << arg0; + arg0 = 4; MWScript::InterpreterContext& context = static_cast (runtime.getContext()); MWDialogue::DialogueManager* dialogue = context.getEnvironment().mDialogueManager; @@ -130,7 +131,7 @@ namespace MWScript extensions.registerInstruction ("setjournalindex", "cl", opcodeSetJournalIndex); extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex); extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic); - extensions.registerInstruction ("choice", "clcl", opcodeChoice); + extensions.registerInstruction ("choice", "/SlSl", opcodeChoice); } void installOpcodes (Interpreter::Interpreter& interpreter)