From f9227beedd787e2386ce85310b11c663b07c6770 Mon Sep 17 00:00:00 2001 From: scrawl <scrawl@baseoftrash.de> Date: Sat, 10 Jan 2015 23:58:55 +0100 Subject: [PATCH] Add warning when loading a savegame that depends on non-existing content files (Fixes #2261) --- apps/openmw/mwgui/messagebox.cpp | 5 +-- apps/openmw/mwgui/messagebox.hpp | 3 +- apps/openmw/mwgui/windowmanagerimp.cpp | 5 +-- apps/openmw/mwstate/statemanagerimp.cpp | 33 +++++++++++++++++++ apps/openmw/mwstate/statemanagerimp.hpp | 2 ++ .../openmw_interactive_messagebox.layout | 2 +- files/mygui/openmw_layers.xml | 1 + 7 files changed, 45 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index c45136eb38..9cb778ea2d 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -146,10 +146,11 @@ namespace MWGui return false; } - int MessageBoxManager::readPressedButton () + int MessageBoxManager::readPressedButton (bool reset) { int pressed = mLastButtonPressed; - mLastButtonPressed = -1; + if (reset) + mLastButtonPressed = -1; return pressed; } diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index 59804e097c..48a92c844b 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -33,7 +33,8 @@ namespace MWGui bool removeMessageBox (MessageBox *msgbox); - int readPressedButton (); + /// @param reset Reset the pressed button to -1 after reading it. + int readPressedButton (bool reset=true); typedef MyGUI::delegates::CMultiDelegate1<int> EventHandle_Int; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 7d9e10d8fd..077ca4fe33 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -607,7 +607,7 @@ namespace MWGui // GM_Loading uses a texture of the last rendered frame so everything previously visible will be rendered. mHud->setVisible(false); mToolTips->setVisible(false); - setCursorVisible(false); + setCursorVisible(mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox()); break; default: // Unsupported mode, switch back to game @@ -813,9 +813,10 @@ namespace MWGui if (block) { - while (mMessageBoxManager->readPressedButton() == -1 + while (mMessageBoxManager->readPressedButton(false) == -1 && !MWBase::Environment::get().getStateManager()->hasQuitRequest()) { + mMessageBoxManager->onFrame(0.f); MWBase::Environment::get().getInputManager()->update(0, true, false); mRendering->getWindow()->update(); diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 8ae7fb3554..f756ee42ae 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -353,6 +353,12 @@ void MWState::StateManager::loadGame (const Character *character, const std::str { ESM::SavedGame profile; profile.load(reader); + if (!verifyProfile(profile)) + { + cleanup (true); + MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + return; + } mTimePlayed = profile.mTimePlayed; } break; @@ -517,3 +523,30 @@ void MWState::StateManager::update (float duration) } } } + +bool MWState::StateManager::verifyProfile(const ESM::SavedGame& profile) const +{ + const std::vector<std::string>& selectedContentFiles = MWBase::Environment::get().getWorld()->getContentFiles(); + bool notFound = false; + for (std::vector<std::string>::const_iterator it = profile.mContentFiles.begin(); + it != profile.mContentFiles.end(); ++it) + { + if (std::find(selectedContentFiles.begin(), selectedContentFiles.end(), *it) + == selectedContentFiles.end()) + { + notFound = true; + break; + } + } + if (notFound) + { + std::vector<std::string> buttons; + buttons.push_back("#{sYes}"); + buttons.push_back("#{sNo}"); + MWBase::Environment::get().getWindowManager()->interactiveMessageBox("#{sMissingMastersMsg}", buttons, true); + int selectedButton = MWBase::Environment::get().getWindowManager()->readPressedButton(); + if (selectedButton == 1 || selectedButton == -1) + return false; + } + return true; +} diff --git a/apps/openmw/mwstate/statemanagerimp.hpp b/apps/openmw/mwstate/statemanagerimp.hpp index 956a2d73c4..37f38f8df7 100644 --- a/apps/openmw/mwstate/statemanagerimp.hpp +++ b/apps/openmw/mwstate/statemanagerimp.hpp @@ -23,6 +23,8 @@ namespace MWState void cleanup (bool force = false); + bool verifyProfile (const ESM::SavedGame& profile) const; + std::map<int, int> buildContentFileIndexMap (const ESM::ESMReader& reader) const; public: diff --git a/files/mygui/openmw_interactive_messagebox.layout b/files/mygui/openmw_interactive_messagebox.layout index a1dbc5aa83..a72bebf3a9 100644 --- a/files/mygui/openmw_interactive_messagebox.layout +++ b/files/mygui/openmw_interactive_messagebox.layout @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <MyGUI type="Layout"> - <Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 500 400" name="_Main"> + <Widget type="Window" skin="MW_Dialog" layer="MessageBox" position="0 0 500 400" name="_Main"> <Widget type="EditBox" skin="MW_TextEditClient" position="10 10 490 20" align="Left Top Stretch" name="message"> <Property key="FontName" value="Default"/> <Property key="TextAlign" value="Center"/> diff --git a/files/mygui/openmw_layers.xml b/files/mygui/openmw_layers.xml index 38a98d133f..50f83aaa2c 100644 --- a/files/mygui/openmw_layers.xml +++ b/files/mygui/openmw_layers.xml @@ -11,6 +11,7 @@ <Layer name="Popup" overlapped="true" peek="true"/> <Layer name="DragAndDrop" overlapped="false" peek="false"/> <Layer name="LoadingScreen" overlapped="false" peek="true"/> + <Layer name="MessageBox" overlapped="false" peek="true"/> <Layer name="Overlay" overlapped="false" peek="true"/> <Layer name="Pointer" overlapped="false" peek="false"/> </MyGUI>