diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanager.cpp index f78160cd7..d4b2234d6 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanager.cpp @@ -9,6 +9,7 @@ #include + #include "../mwworld/class.hpp" #include "../mwworld/environment.hpp" #include "../mwworld/world.hpp" @@ -16,6 +17,10 @@ #include "../mwworld/player.hpp" #include "../mwinput/inputmanager.hpp" +#include "../mwgui/dialogue.hpp" +#include "../mwgui/window_manager.hpp" + +#include "journal.hpp" #include @@ -31,6 +36,7 @@ namespace return lowerCase; } + template bool selectCompare (char comp, T1 value1, T2 value2) { @@ -115,6 +121,14 @@ namespace namespace MWDialogue { + + //helper function + std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos) + { + return toLower(str).find(toLower(substr),pos); + } + + bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const { @@ -126,7 +140,7 @@ namespace MWDialogue std::string name = select.selectRule.substr (5); // TODO types 4, 5, 6, 7, 8, 9, A, B, C - + //new TOTO: 5,6,9 switch (type) { case '1': // function @@ -167,12 +181,122 @@ namespace MWDialogue 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++) + { + + 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"); 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"); + + 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"); + + 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"); + + 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"); + + 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; + + default: std::cout << "unchecked select: " << type << " " << comp << " " << name << std::endl; @@ -184,11 +308,13 @@ namespace MWDialogue bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const { + //bool return true;//does the actor knows the topic? // actor id if (!info.actor.empty()) if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor)) return false; + //NPC race if (!info.race.empty()) { ESMS::LiveCellRef *cellRef = actor.get(); @@ -200,6 +326,7 @@ namespace MWDialogue return false; } + //NPC class if (!info.clas.empty()) { ESMS::LiveCellRef *cellRef = actor.get(); @@ -211,6 +338,7 @@ namespace MWDialogue return false; } + //NPC faction if (!info.npcFaction.empty()) { ESMS::LiveCellRef *cellRef = actor.get(); @@ -220,10 +348,32 @@ namespace MWDialogue if (toLower (info.npcFaction)!=toLower (cellRef->base->faction)) return false; + + //check NPC rank + if(cellRef->base->npdt52.gold != -10) + { + if(cellRef->base->npdt52.rank < info.data.rank) return false; + } + else + { + if(cellRef->base->npdt12.rank < info.data.rank) return false; + } } // TODO check player faction + //check gender + ESMS::LiveCellRef* npc = actor.get(); + if(npc->base->flags&npc->base->Female) + { + if(static_cast (info.data.gender)==0) return false; + } + else + { + if(static_cast (info.data.gender)==1) return false; + } + + // check cell if (!info.cell.empty()) if (mEnvironment.mWorld->getPlayer().getPlayer().getCell()->cell->name != info.cell) @@ -236,50 +386,126 @@ namespace MWDialogue if (!isMatching (actor, *iter)) return false; - std::cout + /*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; + << " PC rank: " << static_cast (info.data.PCrank) << std::endl;*/ return true; } DialogueManager::DialogueManager (MWWorld::Environment& environment) : mEnvironment (environment) {} + void DialogueManager::addTopic(std::string topic) + { + knownTopics[toLower(topic)] = true; + } + void DialogueManager::startDialogue (const MWWorld::Ptr& actor) { std::cout << "talking with " << MWWorld::Class::get (actor).getName (actor) << std::endl; - const ESM::Dialogue *dialogue = mEnvironment.mWorld->getStore().dialogs.find ("hello"); + //initialise the GUI + mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue); + MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); + win->startDialogue(MWWorld::Class::get (actor).getName (actor)); - for (std::vector::const_iterator iter (dialogue->mInfo.begin()); - iter!=dialogue->mInfo.end(); ++iter) + actorKnownTopics.clear(); + ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; + for(ESMS::RecListT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) { - if (isMatching (actor, *iter)) + ESM::Dialogue ndialogue = it->second; + if(ndialogue.type == ESM::Dialogue::Type::Topic) { - // start dialogue - std::cout << "found matching info record" << std::endl; - - std::cout << "response: " << iter->response << std::endl; - - if (!iter->sound.empty()) + for (std::vector::const_iterator iter (it->second.mInfo.begin()); + iter!=it->second.mInfo.end(); ++iter) { - // TODO play sound + if (isMatching (actor, *iter)) + { + actorKnownTopics[it->first] = iter->response; + 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; + } + } } + } + } + //ESMS::RecListT::MapType dialogueList = mEnvironment.mWorld->getStore().dialogs.list; - if (!iter->resultScript.empty()) + bool greetingFound = false; + for(ESMS::RecListT::MapType::iterator it = dialogueList.begin(); it!=dialogueList.end();it++) + { + ESM::Dialogue ndialogue = it->second; + if(ndialogue.type == ESM::Dialogue::Type::Greeting) + { + if (greetingFound) break; + for (std::vector::const_iterator iter (it->second.mInfo.begin()); + iter!=it->second.mInfo.end(); ++iter) { - std::cout << "script: " << iter->resultScript << std::endl; - // TODO execute script - } + if (isMatching (actor, *iter)) + { + if (!iter->sound.empty()) + { + // TODO play sound + } - mEnvironment.mInputManager->setGuiMode(MWGui::GM_Dialogue); - break; + if (!iter->resultScript.empty()) + { + //std::cout << "script: " << iter->resultScript << std::endl; + // 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); + } + } + win->addText(iter->response); + greetingFound = true; + break; + } + } } } } + void DialogueManager::keywordSelected(std::string keyword) + { + std::string text = actorKnownTopics[keyword]; + std::map::iterator it; + for(it = actorKnownTopics.begin();it != actorKnownTopics.end();it++) + { + if(find_str_ci(text,it->first,0) !=std::string::npos) + { + knownTopics[it->first] = true; + MWGui::DialogueWindow* win = mEnvironment.mWindowManager->getDialogueWindow(); + win->addKeyword(it->first,it->second); + } + } + } + + void DialogueManager::goodbyeSelected() + { + mEnvironment.mInputManager->setGuiMode(MWGui::GM_Game); + } + + void DialogueManager::questionAnswered(std::string answere) + { + std::cout << "and the ansere is..."<< answere; + } + } diff --git a/apps/openmw/mwdialogue/dialoguemanager.hpp b/apps/openmw/mwdialogue/dialoguemanager.hpp index 5b6b26240..88ae9e35c 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.hpp +++ b/apps/openmw/mwdialogue/dialoguemanager.hpp @@ -4,6 +4,7 @@ #include #include "../mwworld/ptr.hpp" +#include namespace MWWorld { @@ -20,12 +21,22 @@ namespace MWDialogue bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const; + std::map knownTopics;// Those are the topics the player knows. + std::map actorKnownTopics; + public: DialogueManager (MWWorld::Environment& environment); void startDialogue (const MWWorld::Ptr& actor); + void addTopic(std::string topic); + + //calbacks for the GUI + void keywordSelected(std::string keyword); + void goodbyeSelected(); + void questionAnswered(std::string answere); + }; } diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index e48c142aa..5754d1d7e 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -3,6 +3,8 @@ #include "window_manager.hpp" #include "widgets.hpp" #include "components/esm_store/store.hpp" +#include "../mwworld/environment.hpp" +#include "../mwdialogue/dialoguemanager.hpp" #include #include @@ -14,32 +16,55 @@ using namespace MWGui; using namespace Widgets; -DialogueWindow::DialogueWindow(WindowManager& parWindowManager) - : WindowBase("openmw_dialogue_window_layout.xml", parWindowManager) +/** +*Copied from the internet. +*/ + +std::string lower_string(const std::string& str) +{ + std::string lowerCase; + + std::transform (str.begin(), str.end(), std::back_inserter (lowerCase), + (int(*)(int)) std::tolower); + + return lowerCase; +} + +std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos) +{ + return lower_string(str).find(lower_string(substr),pos); +} + + +DialogueWindow::DialogueWindow(WindowManager& parWindowManager,MWWorld::Environment& environment) + : WindowBase("openmw_dialogue_window_layout.xml", parWindowManager), + mEnvironment(environment) { // Centre dialog center(); //WindowManager *wm = environment.mWindowManager; setText("NpcName", "Name of character"); - + //History view getWidget(history, "History"); history->setOverflowToTheLeft(true); history->getClient()->eventMouseButtonClick = MyGUI::newDelegate(this, &DialogueWindow::onHistoryClicked); - + history->setMaxTextLength(1000000); //Topics list getWidget(topicsList, "TopicsList"); topicsList->setScrollVisible(true); - topicsList->eventListSelectAccept = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); + //topicsList->eventListSelectAccept = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); topicsList->eventListMouseItemActivate = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); - topicsList->eventListChangePosition = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); + //topicsList->eventListChangePosition = MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); MyGUI::ButtonPtr byeButton; getWidget(byeButton, "ByeButton"); byeButton->eventMouseButtonClick = MyGUI::newDelegate(this, &DialogueWindow::onByeClicked); - updateOptions(); + getWidget(pDispositionBar, "Disposition"); + getWidget(pDispositionText,"DispositionText"); + std::cout << "creation dialogue"; } void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender) @@ -51,50 +76,160 @@ void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender) const IntPoint& lastPressed = InputManager::getInstance().getLastLeftPressed(); size_t cursorPosition = t->getCursorPosition(lastPressed); - if(history->getColorAtPos(cursorPosition) != "#FFFFFF") + MyGUI::UString color = history->getColorAtPos(cursorPosition); + if(color != "#B29154") { UString key = history->getColorTextAt(cursorPosition); - std::cout << "Clicked on key: " << key << std::endl; - //eventTopicSelected(key); + + //std::cout << "Clicked on key: " << key << std::endl; + if(color == "#686EBA") + { + mEnvironment.mDialogueManager->keywordSelected(lower_string(key)); + displayTopicText(lower_string(key)); + } + if(color == "#572D21") + { + //TODO: send back the answere to the question! + mEnvironment.mDialogueManager->questionAnswered(key); + //std::cout << "and the ansere is..."<< key; + } } } void DialogueWindow::open() { + //updateOptions(); + topicsList->removeAllItems(); + pTopicsText.clear(); + history->eraseText(0,history->getTextLength()); updateOptions(); setVisible(true); } void DialogueWindow::onByeClicked(MyGUI::Widget* _sender) { - eventBye(); + //eventBye(); + mEnvironment.mDialogueManager->goodbyeSelected(); } 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); //const std::string* theTopic = topicsList->getItemDataAt(_index); //std::cout << "Selected: "<< theTopic << std::endl; //eventTopicSelected(key); } +void DialogueWindow::startDialogue(std::string npcName) +{ + setText("NpcName", npcName); +} + +void DialogueWindow::addKeyword(std::string keyWord,std::string topicText) +{ + if(topicsList->findItemIndexWith(keyWord) == MyGUI::ITEM_NONE) + { + topicsList->addItem(keyWord); + pTopicsText[keyWord] = topicText; + } +} + +void DialogueWindow::removeKeyword(std::string keyWord) +{ + if(topicsList->findItemIndexWith(keyWord) != MyGUI::ITEM_NONE) + { + std::cout << topicsList->findItem(keyWord); + topicsList->removeItemAt(topicsList->findItem(keyWord)); + pTopicsText.erase(keyWord); + } +} + +void addColorInString(std::string& str, const std::string& keyword,std::string color1, std::string color2) +{ + size_t pos = 0; + while((pos = find_str_ci(str,keyword, pos)) != std::string::npos) + { + //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(); + } +} + +std::string DialogueWindow::parseText(std::string text) +{ + //topicsList->geti + for(int i = 0;igetItemCount();i++) + { + std::string keyWord = topicsList->getItem(i); + //std::string newKeyWord = "#686EBA"+keyWord+"#B29154"; + addColorInString(text,keyWord,"#686EBA","#B29154"); + } + return text; +} + +void DialogueWindow::displayTopicText(std::string topic) +{ + if(topicsList->findItemIndexWith(topic) != MyGUI::ITEM_NONE) + { + history->addDialogHeading(topic); + history->addDialogText(parseText(pTopicsText[topic])); + } + else + { + std::cout << "topic not found!"; + } +} + +void DialogueWindow::addText(std::string text) +{ + history->addDialogText(parseText(text)); +} + +void DialogueWindow::askQuestion(std::string question,std::list answers) +{ + history->addDialogText(parseText(question)); + for(std::list::iterator it = answers.begin();it!=answers.end();it++) + { + history->addDialogText("#572D21"+(*it)+"#B29154"+" "); + } +} void DialogueWindow::updateOptions() { //FIXME Add this properly - history->addDialogText("Through the translucent surface of the orb, you see shifting images of distant locations..."); + /*history->addDialogText("Through the translucent surface of the orb, you see shifting images of distant locations..."); for(int z = 0; z < 10; z++) { - history->addDialogHeading("Fort Frostmoth"); - history->addDialogText("The image in the orb flickers, and you see.... The cold courtyard of #FF0000Fort Frostmoth#FFFFFF, battered bu werewolf attack, but still standing, still projecting Imperial might even to this distant and cold corner of the world."); - } + history->addDialogHeading("Fort Frostmoth"); + history->addDialogText("The image in the orb flickers, and you see.... The cold courtyard of #FF0000Fort Frostmoth#FFFFFF, battered bu werewolf attack, but still standing, still projecting Imperial might even to this distant and cold corner of the world."); + }*/ //Clear the list of topics topicsList->removeAllItems(); - int i = 0; - topicsList->addItem("Ald'ruhn", i++); + pTopicsText.clear(); + history->eraseText(0,history->getTextLength()); + + /*addKeyword("gus","gus is working on the dialogue system"); + displayTopicText("gus");*/ + + pDispositionBar->setProgressRange(100); + pDispositionBar->setProgressPosition(40); + pDispositionText->eraseText(0,pDispositionText->getTextLength()); + pDispositionText->addText("#B29154"+std::string("40/100")+"#B29154"); + + /*std::list test; + test.push_back("option 1"); + test.push_back("option 2"); + askQuestion("is gus cooking?",test);*/ + /*topicsList->addItem("Ald'ruhn", i++); topicsList->addItem("Balmora", i++); topicsList->addItem("Sadrith Mora", i++); topicsList->addItem("Vivec", i++); @@ -115,6 +250,6 @@ void DialogueWindow::updateOptions() topicsList->addItem("Tel Fyr", i++); topicsList->addItem("Tel Mora", i++); topicsList->addItem("Tel Vos", i++); - topicsList->addItem("Vos", i++); + topicsList->addItem("Vos", i++);*/ } diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index ddb6f8a4c..232721f0a 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -9,6 +9,11 @@ namespace MWGui class WindowManager; } +namespace MWWorld +{ + class Environment; +} + /* This file contains the dialouge window Layout is defined by resources/mygui/openmw_dialogue_window_layout.xml. @@ -23,7 +28,7 @@ namespace MWGui class DialogueWindow: public WindowBase { public: - DialogueWindow(WindowManager& parWindowManager); + DialogueWindow(WindowManager& parWindowManager,MWWorld::Environment& environment); void open(); @@ -35,6 +40,13 @@ namespace MWGui */ EventHandle_Void eventBye; + void startDialogue(std::string npcName); + void stopDialogue(); + void addKeyword(std::string keyWord,std::string topicText); + void removeKeyword(std::string keyWord); + void addText(std::string text); + void askQuestion(std::string question,std::list answers); + protected: void onSelectTopic(MyGUI::List* _sender, size_t _index); void onByeClicked(MyGUI::Widget* _sender); @@ -42,9 +54,19 @@ namespace MWGui private: void updateOptions(); + /** + *Helper function that add topic keyword in blue in a text. + */ + std::string parseText(std::string text); + void displayTopicText(std::string topic); DialogeHistory* history; MyGUI::ListPtr topicsList; + MyGUI::ProgressPtr pDispositionBar; + MyGUI::EditPtr pDispositionText; + std::map pTopicsText;// this map links keyword and "real" text. + + MWWorld::Environment& mEnvironment; }; } #endif diff --git a/apps/openmw/mwgui/dialogue_history.cpp b/apps/openmw/mwgui/dialogue_history.cpp index aaa559d24..ceb904528 100644 --- a/apps/openmw/mwgui/dialogue_history.cpp +++ b/apps/openmw/mwgui/dialogue_history.cpp @@ -61,9 +61,9 @@ UString DialogeHistory::getColorTextAt(size_t _pos) void DialogeHistory::addDialogHeading(const UString& parText) { - UString head("\n#00FF00"); + UString head("\n#D8C09A"); head.append(parText); - head.append("#FFFFFF\n"); + head.append("#B29154\n"); addText(head); } diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index aca9fbd9a..baf854814 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -51,6 +51,7 @@ WindowManager::WindowManager(MWWorld::Environment& environment, console = new Console(w,h, environment, extensions); mJournal = new JournalWindow(*this); mMessageBoxManager = new MessageBoxManager(this); + dialogueWindow = new DialogueWindow(*this,environment); // The HUD is always on hud->setVisible(true); @@ -149,6 +150,7 @@ void WindowManager::updateVisible() stats->setVisible(false); console->disable(); mJournal->setVisible(false); + dialogueWindow->setVisible(false); // Mouse is visible whenever we're not in game mode gui->setVisiblePointer(isGuiMode()); @@ -195,11 +197,6 @@ void WindowManager::updateVisible() if (mode == GM_Dialogue) { - if (!dialogueWindow) - { - dialogueWindow = new DialogueWindow(*this); - dialogueWindow->eventBye = MyGUI::newDelegate(this, &WindowManager::onDialogueWindowBye); - } dialogueWindow->open(); return; } @@ -349,6 +346,7 @@ void WindowManager::updateSkillArea() void WindowManager::removeDialog(OEngine::GUI::Layout*dialog) { + std::cout << "dialogue a la poubelle"; assert(dialog); if (!dialog) return; @@ -387,7 +385,8 @@ void WindowManager::onDialogueWindowBye() if (dialogueWindow) { //FIXME set some state and stuff? - removeDialog(dialogueWindow); + //removeDialog(dialogueWindow); + dialogueWindow->setVisible(false); } setGuiMode(GM_Game); } diff --git a/apps/openmw/mwgui/window_manager.hpp b/apps/openmw/mwgui/window_manager.hpp index 89ff4b9bb..0124c9239 100644 --- a/apps/openmw/mwgui/window_manager.hpp +++ b/apps/openmw/mwgui/window_manager.hpp @@ -124,6 +124,8 @@ namespace MWGui updateVisible(); } + MWGui::DialogueWindow* getDialogueWindow() {return dialogueWindow;} + MyGUI::Gui* getGui() const { return gui; } void wmUpdateFps(float fps, size_t triangleCount, size_t batchCount) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 3b495dd3c..2a75c2445 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -52,10 +52,12 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const cameraPitchNode->attachObject(mRendering.getCamera()); mPlayer = new MWRender::Player (mRendering.getCamera(), playerNode); + mSun = 0; } RenderingManager::~RenderingManager () { + //TODO: destroy mSun? delete mPlayer; delete mSkyManager; } @@ -202,12 +204,15 @@ void RenderingManager::configureAmbient(ESMS::CellStore &mCell // Create a "sun" that shines light downwards. It doesn't look // completely right, but leave it for now. - Ogre::Light *light = mRendering.getScene()->createLight(); + if(!mSun) + { + mSun = mRendering.getScene()->createLight(); + } Ogre::ColourValue colour; colour.setAsABGR (mCell.cell->ambi.sunlight); - light->setDiffuseColour (colour); - light->setType(Ogre::Light::LT_DIRECTIONAL); - light->setDirection(0,-1,0); + mSun->setDiffuseColour (colour); + mSun->setType(Ogre::Light::LT_DIRECTIONAL); + mSun->setDirection(0,-1,0); } // Switch through lighting modes. diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 084f89cb0..ca5d95a3f 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -118,6 +118,7 @@ class RenderingManager: private RenderingInterface { int mAmbientMode; Ogre::ColourValue mAmbientColor; + Ogre::Light* mSun; /// Root node for all objects added to the scene. This is rotated so /// that the OGRE coordinate system matches that used internally in diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp index c2ff9ed8b..26fb6d9be 100644 --- a/apps/openmw/mwscript/dialogueextensions.cpp +++ b/apps/openmw/mwscript/dialogueextensions.cpp @@ -8,6 +8,7 @@ #include #include "../mwdialogue/journal.hpp" +#include "../mwdialogue/dialoguemanager.hpp" #include "interpretercontext.hpp" @@ -72,15 +73,33 @@ namespace MWScript } }; + class OpAddTopic : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string topic = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + context.getEnvironment().mDialogueManager->addTopic(topic); + } + }; + const int opcodeJournal = 0x2000133; const int opcodeSetJournalIndex = 0x2000134; const int opcodeGetJournalIndex = 0x2000135; + const int opcodeAddTopic = 0x200013a; void registerExtensions (Compiler::Extensions& extensions) { extensions.registerInstruction ("journal", "cl", opcodeJournal); extensions.registerInstruction ("setjournalindex", "cl", opcodeSetJournalIndex); extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex); + extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -88,6 +107,7 @@ namespace MWScript interpreter.installSegment5 (opcodeJournal, new OpJournal); interpreter.installSegment5 (opcodeSetJournalIndex, new OpSetJournalIndex); interpreter.installSegment5 (opcodeGetJournalIndex, new OpGetJournalIndex); + interpreter.installSegment5 (opcodeAddTopic, new OpAddTopic); } } diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 183605328..1f033c8db 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -115,4 +115,5 @@ op 0x2000136: GetPCCell op 0x2000137: GetButtonPressed op 0x2000138: SkipAnim op 0x2000139: SkipAnim, expplicit reference -opcodes 0x200013a-0x3ffffff unused +op 0x200013a: AddTopic +opcodes 0x200013b-0x3ffffff unused diff --git a/extern/mygui_3.0.1/CMakeLists.txt b/extern/mygui_3.0.1/CMakeLists.txt index 2cbe8aabe..6a96bd367 100644 --- a/extern/mygui_3.0.1/CMakeLists.txt +++ b/extern/mygui_3.0.1/CMakeLists.txt @@ -54,6 +54,7 @@ configure_file("${SDIR}/openmw_chargen_class_description_layout.xml" "${DDIR}/op configure_file("${SDIR}/openmw_chargen_birth_layout.xml" "${DDIR}/openmw_chargen_birth_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_chargen_review_layout.xml" "${DDIR}/openmw_chargen_review_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_dialogue_window_layout.xml" "${DDIR}/openmw_dialogue_window_layout.xml" COPYONLY) +configure_file("${SDIR}/openmw_dialogue_window_skin.xml" "${DDIR}/openmw_dialogue_window_skin.xml" COPYONLY) configure_file("${SDIR}/openmw_inventory_window_layout.xml" "${DDIR}/openmw_inventory_window_layout.xml" COPYONLY) configure_file("${SDIR}/openmw_layers.xml" "${DDIR}/openmw_layers.xml" COPYONLY) configure_file("${SDIR}/openmw_mainmenu_layout.xml" "${DDIR}/openmw_mainmenu_layout.xml" COPYONLY) diff --git a/extern/mygui_3.0.1/openmw_resources/core.xml b/extern/mygui_3.0.1/openmw_resources/core.xml index 31d409a35..e98b20d3a 100644 --- a/extern/mygui_3.0.1/openmw_resources/core.xml +++ b/extern/mygui_3.0.1/openmw_resources/core.xml @@ -20,6 +20,7 @@ + diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_dialogue_window_layout.xml b/extern/mygui_3.0.1/openmw_resources/openmw_dialogue_window_layout.xml index 2987e82be..44642167b 100644 --- a/extern/mygui_3.0.1/openmw_resources/openmw_dialogue_window_layout.xml +++ b/extern/mygui_3.0.1/openmw_resources/openmw_dialogue_window_layout.xml @@ -17,8 +17,13 @@ + + + + - + diff --git a/extern/mygui_3.0.1/openmw_resources/openmw_dialogue_window_skin.xml b/extern/mygui_3.0.1/openmw_resources/openmw_dialogue_window_skin.xml new file mode 100644 index 000000000..25e0b8659 --- /dev/null +++ b/extern/mygui_3.0.1/openmw_resources/openmw_dialogue_window_skin.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file