From c41f119ba6d4734a8cea85ee4bbada750fa2d386 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 May 2013 17:54:18 +0200 Subject: [PATCH 1/2] Added new game button --- apps/openmw/engine.cpp | 10 +- apps/openmw/main.cpp | 4 - apps/openmw/mwbase/dialoguemanager.hpp | 2 + apps/openmw/mwbase/journal.hpp | 2 + apps/openmw/mwbase/scriptmanager.hpp | 2 + apps/openmw/mwbase/windowmanager.hpp | 4 + apps/openmw/mwbase/world.hpp | 2 + apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 11 ++- apps/openmw/mwdialogue/dialoguemanagerimp.hpp | 2 + apps/openmw/mwdialogue/journalimp.cpp | 7 ++ apps/openmw/mwdialogue/journalimp.hpp | 2 + apps/openmw/mwgui/alchemywindow.cpp | 11 ++- apps/openmw/mwgui/inventorywindow.cpp | 17 +++- apps/openmw/mwgui/inventorywindow.hpp | 2 + apps/openmw/mwgui/mainmenu.cpp | 12 ++- apps/openmw/mwgui/windowmanagerimp.cpp | 29 ++++-- apps/openmw/mwgui/windowmanagerimp.hpp | 6 +- apps/openmw/mwinput/inputmanagerimp.cpp | 2 +- apps/openmw/mwinput/inputmanagerimp.hpp | 2 +- .../mwmechanics/mechanicsmanagerimp.cpp | 12 +-- apps/openmw/mwscript/globalscripts.cpp | 10 +- apps/openmw/mwscript/globalscripts.hpp | 2 + apps/openmw/mwscript/scriptmanagerimp.cpp | 5 + apps/openmw/mwscript/scriptmanagerimp.hpp | 2 + apps/openmw/mwsound/openal_output.cpp | 10 +- apps/openmw/mwworld/cells.cpp | 11 +++ apps/openmw/mwworld/cells.hpp | 2 + apps/openmw/mwworld/esmstore.cpp | 9 -- apps/openmw/mwworld/esmstore.hpp | 17 ++++ apps/openmw/mwworld/physicssystem.cpp | 2 +- apps/openmw/mwworld/player.cpp | 8 ++ apps/openmw/mwworld/player.hpp | 2 + apps/openmw/mwworld/ptr.hpp | 2 +- apps/openmw/mwworld/scene.cpp | 9 ++ apps/openmw/mwworld/scene.hpp | 5 +- apps/openmw/mwworld/store.hpp | 8 ++ apps/openmw/mwworld/worldimp.cpp | 96 ++++++++++++++----- apps/openmw/mwworld/worldimp.hpp | 11 +-- 38 files changed, 263 insertions(+), 89 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 125ef8803..372378f31 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -131,7 +131,6 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) , mFpsLevel(0) , mDebug (false) , mVerboseScripts (false) - , mNewGame (false) , mUseSound (true) , mCompileAll (false) , mScriptContext (0) @@ -278,11 +277,6 @@ void OMW::Engine::setScriptsVerbosity(bool scriptsVerbosity) mVerboseScripts = scriptsVerbosity; } -void OMW::Engine::setNewGame(bool newGame) -{ - mNewGame = newGame; -} - std::string OMW::Engine::loadSettings (Settings::Manager & settings) { // Create the settings manager and load default settings file @@ -366,7 +360,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) // Create the world mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mMaster, mPlugins, - mResDir, mCfgMgr.getCachePath(), mNewGame, mEncoder, mFallbackMap, + mResDir, mCfgMgr.getCachePath(), mEncoder, mFallbackMap, mActivationDistanceOverride)); MWBase::Environment::get().getWorld()->setupPlayer(); @@ -379,7 +373,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) MWScript::registerExtensions (mExtensions); mEnvironment.setWindowManager (new MWGui::WindowManager( - mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"), + mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"), mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage)); // Create sound system diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 1fa461c2f..6742372d8 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -136,9 +136,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("script-run", bpo::value()->default_value(""), "select a file containing a list of console commands that is executed on startup") - ("new-game", bpo::value()->implicit_value(true) - ->default_value(false), "activate char gen/new game mechanics") - ("fs-strict", bpo::value()->implicit_value(true) ->default_value(false), "strict file system handling (no case folding)") @@ -240,7 +237,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat // startup-settings engine.setCell(variables["start"].as()); - engine.setNewGame(variables["new-game"].as()); // other settings engine.setDebugMode(variables["debug"].as()); diff --git a/apps/openmw/mwbase/dialoguemanager.hpp b/apps/openmw/mwbase/dialoguemanager.hpp index aafc0a12f..12996cc30 100644 --- a/apps/openmw/mwbase/dialoguemanager.hpp +++ b/apps/openmw/mwbase/dialoguemanager.hpp @@ -23,6 +23,8 @@ namespace MWBase DialogueManager() {} + virtual void clear() = 0; + virtual ~DialogueManager() {} virtual bool isInChoice() const = 0; diff --git a/apps/openmw/mwbase/journal.hpp b/apps/openmw/mwbase/journal.hpp index b3dfea45b..51e51edda 100644 --- a/apps/openmw/mwbase/journal.hpp +++ b/apps/openmw/mwbase/journal.hpp @@ -33,6 +33,8 @@ namespace MWBase Journal() {} + virtual void clear() = 0; + virtual ~Journal() {} virtual void addEntry (const std::string& id, int index) = 0; diff --git a/apps/openmw/mwbase/scriptmanager.hpp b/apps/openmw/mwbase/scriptmanager.hpp index ae146e064..32df2bfa3 100644 --- a/apps/openmw/mwbase/scriptmanager.hpp +++ b/apps/openmw/mwbase/scriptmanager.hpp @@ -35,6 +35,8 @@ namespace MWBase virtual ~ScriptManager() {} + virtual void resetGlobalScripts() = 0; + virtual void run (const std::string& name, Interpreter::Context& interpreterContext) = 0; ///< Run the script with the given name (compile first, if not compiled yet) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index dca81ac1d..c5ca5d000 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -81,12 +81,16 @@ namespace MWBase */ virtual void update() = 0; + virtual void setNewGame(bool newgame) = 0; + virtual void pushGuiMode (MWGui::GuiMode mode) = 0; virtual void popGuiMode() = 0; virtual void removeGuiMode (MWGui::GuiMode mode) = 0; ///< can be anywhere in the stack + virtual void updatePlayer() = 0; + virtual MWGui::GuiMode getMode() const = 0; virtual bool isGuiMode() const = 0; diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index ebbeff851..de1a34792 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -94,6 +94,8 @@ namespace MWBase virtual ~World() {} + virtual void startNewGame() = 0; + virtual OEngine::Render::Fader* getFader() = 0; ///< \ŧodo remove this function. Rendering details should not be exposed. diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index e66cfa6e2..7093ff91e 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -50,12 +50,11 @@ namespace MWDialogue , mTemporaryDispositionChange(0.f) , mPermanentDispositionChange(0.f), mScriptVerbose (scriptVerbose) , mTranslationDataStorage(translationDataStorage) + , mTalkedTo(false) { mChoice = -1; mIsInChoice = false; mCompilerContext.setExtensions (&extensions); - mDialogueMap.clear(); - mActorKnownTopics.clear(); const MWWorld::Store &dialogs = MWBase::Environment::get().getWorld()->getStore().get(); @@ -67,6 +66,14 @@ namespace MWDialogue } } + void DialogueManager::clear() + { + mKnownTopics.clear(); + mTalkedTo = false; + mTemporaryDispositionChange = 0; + mPermanentDispositionChange = 0; + } + void DialogueManager::addTopic (const std::string& topic) { mKnownTopics[Misc::StringUtils::lowerCase(topic)] = true; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index 13f7cb098..de1ac77c6 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -51,6 +51,8 @@ namespace MWDialogue DialogueManager (const Compiler::Extensions& extensions, bool scriptVerbose, Translation::Storage& translationDataStorage); + virtual void clear(); + virtual bool isInChoice() const; virtual void startDialogue (const MWWorld::Ptr& actor); diff --git a/apps/openmw/mwdialogue/journalimp.cpp b/apps/openmw/mwdialogue/journalimp.cpp index 5e2bc6bc0..23cfb5fdd 100644 --- a/apps/openmw/mwdialogue/journalimp.cpp +++ b/apps/openmw/mwdialogue/journalimp.cpp @@ -29,6 +29,13 @@ namespace MWDialogue Journal::Journal() {} + void Journal::clear() + { + mJournal.clear(); + mQuests.clear(); + mTopics.clear(); + } + void Journal::addEntry (const std::string& id, int index) { // bail out of we already have heard this... diff --git a/apps/openmw/mwdialogue/journalimp.hpp b/apps/openmw/mwdialogue/journalimp.hpp index 7d71fd7d0..f4f8eb1c2 100644 --- a/apps/openmw/mwdialogue/journalimp.hpp +++ b/apps/openmw/mwdialogue/journalimp.hpp @@ -21,6 +21,8 @@ namespace MWDialogue Journal(); + virtual void clear(); + virtual void addEntry (const std::string& id, int index); ///< Add a journal entry. diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 3b6146a24..136cb7c98 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -45,6 +45,7 @@ namespace MWGui : WindowBase("openmw_alchemy_window.layout") , mApparatus (4) , mIngredients (4) + , mSortModel(NULL) { getWidget(mCreateButton, "CreateButton"); getWidget(mCancelButton, "CancelButton"); @@ -60,10 +61,7 @@ namespace MWGui getWidget(mNameEdit, "NameEdit"); getWidget(mItemView, "ItemView"); - InventoryItemModel* model = new InventoryItemModel(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); - mSortModel = new SortFilterItemModel(model); - mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients); - mItemView->setModel (mSortModel); + mItemView->eventItemClicked += MyGUI::newDelegate(this, &AlchemyWindow::onSelectedItem); mIngredients[0]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); @@ -145,6 +143,11 @@ namespace MWGui void AlchemyWindow::open() { + InventoryItemModel* model = new InventoryItemModel(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + mSortModel = new SortFilterItemModel(model); + mSortModel->setFilter(SortFilterItemModel::Filter_OnlyIngredients); + mItemView->setModel (mSortModel); + mNameEdit->setCaption(""); mAlchemy.setAlchemist (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index ea963f393..9fa87c4b8 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -53,15 +53,12 @@ namespace MWGui mAvatar->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onAvatarClicked); - mPtr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); - getWidget(mItemView, "ItemView"); - mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr()); - mSortModel = new SortFilterItemModel(mTradeModel); - mItemView->setModel(mSortModel); mItemView->eventItemClicked += MyGUI::newDelegate(this, &InventoryWindow::onItemSelected); mItemView->eventBackgroundClicked += MyGUI::newDelegate(this, &InventoryWindow::onBackgroundSelected); + updatePlayer(); + mFilterAll->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged); mFilterWeapon->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged); mFilterApparel->eventMouseButtonClick += MyGUI::newDelegate(this, &InventoryWindow::onFilterChanged); @@ -76,6 +73,16 @@ namespace MWGui mPreview.setup(); } + void InventoryWindow::updatePlayer() + { + mPtr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); + mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr()); + mSortModel = new SortFilterItemModel(mTradeModel); + mItemView->setModel(mSortModel); + mPreview = MWRender::InventoryPreview(mPtr); + mPreview.setup(); + } + TradeItemModel* InventoryWindow::getTradeModel() { return mTradeModel; diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index 4bd1ef501..13c118913 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -45,6 +45,8 @@ namespace MWGui void updateItemView(); + void updatePlayer(); + private: DragAndDrop* mDragAndDrop; diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index ebd31d92c..88227c751 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -5,6 +5,9 @@ #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/journal.hpp" +#include "../mwbase/dialoguemanager.hpp" namespace MWGui { @@ -29,7 +32,7 @@ namespace MWGui std::vector buttons; buttons.push_back("return"); - //buttons.push_back("newgame"); + buttons.push_back("newgame"); //buttons.push_back("loadgame"); //buttons.push_back("savegame"); buttons.push_back("options"); @@ -72,6 +75,13 @@ namespace MWGui MWBase::Environment::get().getWindowManager ()->pushGuiMode (GM_Settings); else if (sender == mButtons["exitgame"]) Ogre::Root::getSingleton ().queueEndRendering (); + else if (sender == mButtons["newgame"]) + { + MWBase::Environment::get().getWorld()->startNewGame(); + MWBase::Environment::get().getWindowManager()->setNewGame(true); + MWBase::Environment::get().getDialogueManager()->clear(); + MWBase::Environment::get().getJournal()->clear(); + } } } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 4ce1d93dc..48c5aba6b 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -47,7 +47,7 @@ namespace MWGui { WindowManager::WindowManager( - const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *ogre, + const Compiler::Extensions& extensions, int fpsLevel, OEngine::Render::OgreRenderer *ogre, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage) : mGuiManager(NULL) @@ -94,8 +94,8 @@ namespace MWGui , mGui(NULL) , mGarbageDialogs() , mShown(GW_ALL) - , mAllowed(newGame ? GW_None : GW_ALL) - , mRestAllowed(newGame ? false : true) + , mAllowed(GW_ALL) + , mRestAllowed(true) , mShowFPSLevel(fpsLevel) , mFPS(0.0f) , mTriangleCount(0) @@ -203,13 +203,25 @@ namespace MWGui unsetSelectedSpell(); unsetSelectedWeapon(); - if (newGame) - disallowAll (); - // Set up visibility updateVisible(); } + void WindowManager::setNewGame(bool newgame) + { + if (newgame) + { + disallowAll(); + delete mCharGen; + mCharGen = new CharacterCreation(); + mGuiModes.clear(); + } + else + allow(GW_ALL); + + mRestAllowed = !newgame; + } + WindowManager::~WindowManager() { delete mConsole; @@ -1200,4 +1212,9 @@ namespace MWGui mInventoryWindow->doRenderUpdate (); } + void WindowManager::updatePlayer() + { + mInventoryWindow->updatePlayer(); + } + } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index a3d856535..4bcc581f0 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -80,7 +80,7 @@ namespace MWGui typedef std::pair Faction; typedef std::vector FactionList; - WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, + WindowManager(const Compiler::Extensions& extensions, int fpsLevel, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage); @@ -93,6 +93,8 @@ namespace MWGui */ virtual void update(); + virtual void setNewGame(bool newgame); + virtual void pushGuiMode(GuiMode mode); virtual void popGuiMode(); virtual void removeGuiMode(GuiMode mode); ///< can be anywhere in the stack @@ -227,6 +229,8 @@ namespace MWGui virtual bool getPlayerSleeping(); virtual void wakeUpPlayer(); + virtual void updatePlayer(); + virtual void showCompanionWindow(MWWorld::Ptr actor); virtual void startSpellMaking(MWWorld::Ptr actor); virtual void startEnchanting(MWWorld::Ptr actor); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index a7ec4d4d2..30221416d 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -29,7 +29,7 @@ namespace MWInput { InputManager::InputManager(OEngine::Render::OgreRenderer &ogre, - MWWorld::Player &player, + MWWorld::Player& player, MWBase::WindowManager &windows, bool debug, OMW::Engine& engine, diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index e181fb351..8aa0d32ad 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -119,7 +119,7 @@ namespace MWInput private: OEngine::Render::OgreRenderer &mOgre; - MWWorld::Player &mPlayer; + MWWorld::Player& mPlayer; MWBase::WindowManager &mWindows; OMW::Engine& mEngine; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 969a233bc..b83cfb365 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -156,17 +156,11 @@ namespace MWMechanics creatureStats.setDynamic (i, stat); } - // unequip any items that may not be equipped. we need this for when the race is changed to a beast race + // auto-equip again. we need this for when the race is changed to a beast race MWWorld::InventoryStore& invStore = MWWorld::Class::get(ptr).getInventoryStore(ptr); for (int i=0; i::iterator iter = - store.get().begin(); + mStore.get().begin(); - for (; iter != store.get().end(); ++iter) { + for (; iter != mStore.get().end(); ++iter) { addScript (iter->mScript); } } diff --git a/apps/openmw/mwscript/globalscripts.hpp b/apps/openmw/mwscript/globalscripts.hpp index f9f9b7ae3..628919d1d 100644 --- a/apps/openmw/mwscript/globalscripts.hpp +++ b/apps/openmw/mwscript/globalscripts.hpp @@ -22,6 +22,8 @@ namespace MWScript GlobalScripts (const MWWorld::ESMStore& store); + void reset(); + void addScript (const std::string& name); void removeScript (const std::string& name); diff --git a/apps/openmw/mwscript/scriptmanagerimp.cpp b/apps/openmw/mwscript/scriptmanagerimp.cpp index 933a6e0d3..b3e5f8ff6 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.cpp +++ b/apps/openmw/mwscript/scriptmanagerimp.cpp @@ -221,4 +221,9 @@ namespace MWScript throw std::runtime_error ("unable to access local variable " + variable + " of " + scriptId); } + + void ScriptManager::resetGlobalScripts() + { + mGlobalScripts.reset(); + } } diff --git a/apps/openmw/mwscript/scriptmanagerimp.hpp b/apps/openmw/mwscript/scriptmanagerimp.hpp index 1a856e0c5..7bb98ffbd 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.hpp +++ b/apps/openmw/mwscript/scriptmanagerimp.hpp @@ -61,6 +61,8 @@ namespace MWScript ///< Compile script with the given namen /// \return Success? + virtual void resetGlobalScripts(); + virtual std::pair compileAll(); ///< Compile all scripts /// \return count, success diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 1dc5f9974..690b07331 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -586,7 +586,7 @@ void OpenAL_Sound::update() alSourcef(mSource, AL_GAIN, gain); alSourcef(mSource, AL_PITCH, pitch); - alSource3f(mSource, AL_POSITION, mPos[0], mPos[2], -mPos[1]); + alSource3f(mSource, AL_POSITION, mPos[0], mPos[1], mPos[2]); alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f); alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f); throwALerror(); @@ -606,7 +606,7 @@ void OpenAL_Sound3D::update() alSourcef(mSource, AL_GAIN, gain); alSourcef(mSource, AL_PITCH, pitch); - alSource3f(mSource, AL_POSITION, mPos[0], mPos[2], -mPos[1]); + alSource3f(mSource, AL_POSITION, mPos[0], mPos[1], mPos[2]); alSource3f(mSource, AL_DIRECTION, 0.0f, 0.0f, 0.0f); alSource3f(mSource, AL_VELOCITY, 0.0f, 0.0f, 0.0f); throwALerror(); @@ -923,10 +923,10 @@ void OpenAL_Output::updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 if(mContext) { ALfloat orient[6] = { - atdir.x, atdir.z, -atdir.y, - updir.x, updir.z, -updir.y + atdir.x, atdir.y, atdir.z, + updir.x, updir.y, updir.z }; - alListener3f(AL_POSITION, mPos.x, mPos.z, -mPos.y); + alListener3f(AL_POSITION, mPos.x, mPos.y, mPos.z); alListenerfv(AL_ORIENTATION, orient); throwALerror(); } diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index efabe2f63..564f62c8f 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -36,6 +36,17 @@ MWWorld::Ptr::CellStore *MWWorld::Cells::getCellStore (const ESM::Cell *cell) } } +void MWWorld::Cells::clear() +{ + mInteriors.clear(); + mExteriors.clear(); + + mIdCache = std::vector >( + 40, std::pair ("", (MWWorld::Ptr::CellStore*)0)), /// \todo make cache size configurable + + mIdCacheIndex = 0; +} + void MWWorld::Cells::fillContainers (Ptr::CellStore& cellStore) { for (CellRefList::List::iterator iter ( diff --git a/apps/openmw/mwworld/cells.hpp b/apps/openmw/mwworld/cells.hpp index f999fedde..53c72bb75 100644 --- a/apps/openmw/mwworld/cells.hpp +++ b/apps/openmw/mwworld/cells.hpp @@ -37,6 +37,8 @@ namespace MWWorld public: + void clear(); + Cells (const MWWorld::ESMStore& store, std::vector& reader); ///< \todo pass the dynamic part of the ESMStore isntead (once it is written) of the whole /// world diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 09a39ff8b..5a4f1db54 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -134,15 +134,6 @@ void ESMStore::setUp() mSkills.setUp(); mMagicEffects.setUp(); mAttributes.setUp(); - - ESM::NPC item; - item.mId = "player"; - - const ESM::NPC *pIt = mNpcs.find("player"); - assert(pIt != NULL); - - mNpcs.insert(*pIt); - mNpcs.eraseStatic(pIt->mId); } } // end namespace diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index cde9e2425..49458c9b9 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -141,6 +141,23 @@ namespace MWWorld mStores[ESM::REC_WEAP] = &mWeapons; } + void clearDynamic () + { + ESM::NPC playerNpc = *mNpcs.find("player"); + + for (std::map::iterator it = mStores.begin(); it != mStores.end(); ++it) + it->second->clearDynamic(); + + mNpcs.insert(playerNpc); + } + + void movePlayerRecord () + { + ESM::NPC playerNpc = *mNpcs.find("player"); + mNpcs.eraseStatic(playerNpc.mId); + mNpcs.insert(playerNpc); + } + void load(ESM::ESMReader &esm); template diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index c4120f8ff..7d63a2362 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -121,7 +121,7 @@ namespace MWWorld physicActor->enableCollisions(wasCollisionMode); if (hit) - return newPosition; + return newPosition+Ogre::Vector3(0,0,4); else return position; } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 3338f08ed..08d908e62 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -24,6 +24,14 @@ namespace MWWorld playerPos[0] = playerPos[1] = playerPos[2] = 0; } + void Player::set(const ESM::NPC *player) + { + mPlayer.mBase = player; + + float* playerPos = mPlayer.mData.getPosition().pos; + playerPos[0] = playerPos[1] = playerPos[2] = 0; + } + void Player::setCell (MWWorld::CellStore *cellStore) { mCellStore = cellStore; diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index dfaddf66a..f51d8f890 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -35,6 +35,8 @@ namespace MWWorld Player(const ESM::NPC *player, const MWBase::World& world); + void set (const ESM::NPC *player); + void setCell (MWWorld::CellStore *cellStore); MWWorld::Ptr getPlayer(); diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index d97ebcc6e..14e2c76a4 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -68,7 +68,7 @@ namespace MWWorld Ptr::CellStore *getCell() const { - assert (mCell); + assert(mCell); return mCell; } diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index da808a9a8..aec00a8c6 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -186,6 +186,15 @@ namespace MWWorld MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell); } + void Scene::changeToVoid() + { + CellStoreCollection::iterator active = mActiveCells.begin(); + while (active!=mActiveCells.end()) + unloadCell (active++); + assert(mActiveCells.empty()); + mCurrentCell = NULL; + } + void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) { Nif::NIFFile::CacheLock cachelock; diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index dc08d6f9b..3dfbd1045 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -47,7 +47,7 @@ namespace MWWorld private: //OEngine::Render::OgreRenderer& mRenderer; - CellStore* mCurrentCell; // the cell, the player is in + CellStore* mCurrentCell; // the cell the player is in CellStoreCollection mActiveCells; bool mCellChanged; PhysicsSystem *mPhysics; @@ -85,6 +85,9 @@ namespace MWWorld void changeToExteriorCell (const ESM::Position& position); ///< Move to exterior cell. + void changeToVoid(); + ///< Change into a void + void markCellAsUnchanged(); void update (float duration, bool paused); diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 65041e662..b49569f24 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -21,6 +21,7 @@ namespace MWWorld virtual void load(ESM::ESMReader &esm, const std::string &id) = 0; virtual bool eraseStatic(const std::string &id) {return false;} + virtual void clearDynamic() {} }; template @@ -106,6 +107,13 @@ namespace MWWorld typedef SharedIterator iterator; + // setUp needs to be called again after + virtual void clearDynamic() + { + mDynamic.clear(); + mShared.clear(); + } + const T *search(const std::string &id) const { T item; item.mId = Misc::StringUtils::lowerCase(id); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 9814ce53c..e8b68d266 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -160,12 +160,12 @@ namespace MWWorld World::World (OEngine::Render::OgreRenderer& renderer, const Files::Collections& fileCollections, const std::vector& master, const std::vector& plugins, - const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame, + const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, ToUTF8::Utf8Encoder* encoder, const std::map& fallbackMap, int mActivationDistanceOverride) : mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0), mSky (true), mCells (mStore, mEsm), mNumFacing(0), mActivationDistanceOverride (mActivationDistanceOverride), - mFallback(fallbackMap), mNewGame(newGame) + mFallback(fallbackMap), mPlayIntro(0) { mPhysics = new PhysicsSystem(renderer); mPhysEngine = mPhysics->getEngine(); @@ -215,22 +215,71 @@ namespace MWWorld if (mEsm[0].getFormat() == 0) ensureNeededRecords(); + mStore.movePlayerRecord(); mStore.setUp(); - // global variables mGlobalVariables = new Globals (mStore); - if (mNewGame) - { - // set new game mark - mGlobalVariables->setInt ("chargenstate", 1); - } + mWorldScene = new Scene(*mRendering, mPhysics); + } + void World::startNewGame() + { + + mWorldScene->changeToVoid(); + + mStore.clearDynamic(); + mStore.setUp(); + + mCells.clear(); + + // Rebuild player + setupPlayer(); + const ESM::NPC* playerNpc = mStore.get().find("player"); + MWWorld::Ptr player = mPlayer->getPlayer(); + + // removes NpcStats, ContainerStore etc + player.getRefData().setCustomData(NULL); + + // make sure to do this so that local scripts from items that were in the players inventory are removed + mLocalScripts.clear(); + + MWWorld::Class::get(player).getContainerStore(player).fill(playerNpc->mInventory, "", mStore); + MWWorld::Class::get(player).getInventoryStore(player).autoEquip(player); + + MWBase::Environment::get().getWindowManager()->updatePlayer(); + + ESM::Position pos; + const int cellSize = 8192; + pos.pos[0] = cellSize/2; + pos.pos[1] = cellSize/2; + pos.pos[2] = 0; + pos.rot[0] = 0; + pos.rot[1] = 0; + pos.rot[2] = 0; + mWorldScene->changeToExteriorCell(pos); + + + // enable collision + if(!mPhysics->toggleCollisionMode()) + mPhysics->toggleCollisionMode(); + + // FIXME: should be set to 1, but the sound manager won't pause newly started sounds + mPlayIntro = 2; + + // global variables + delete mGlobalVariables; + mGlobalVariables = new Globals (mStore); + + // set new game mark + mGlobalVariables->setInt ("chargenstate", 1); mGlobalVariables->setInt ("pcrace", 3); - mWorldScene = new Scene(*mRendering, mPhysics); + // we don't want old weather to persist on a new game + delete mWeatherManager; + mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback); - lastTick = mTimer.getMilliseconds(); + MWBase::Environment::get().getScriptManager()->resetGlobalScripts(); } @@ -754,7 +803,7 @@ namespace MWWorld CellStore *currCell = ptr.getCell(); bool isPlayer = ptr == mPlayer->getPlayer(); - bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer; + bool haveToMove = isPlayer || mWorldScene->isCellActive(*currCell); if (*currCell != newCell) { @@ -950,9 +999,9 @@ namespace MWWorld float terrainHeight = mRendering->getTerrainHeightAt(pos); if (pos.z < terrainHeight) - pos.z = terrainHeight+5; // place slightly above. will snap down to ground with code below + pos.z = terrainHeight; - ptr.getRefData().getPosition().pos[2] = pos.z; + ptr.getRefData().getPosition().pos[2] = pos.z + 20; // place slightly above. will snap down to ground with code below if (!isFlying(ptr)) { @@ -961,7 +1010,7 @@ namespace MWWorld pos.z = traced.z; } - moveObject(ptr, pos.x, pos.y, pos.z); + moveObject(ptr, *ptr.getCell(), pos.x, pos.y, pos.z); } void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust) @@ -1193,6 +1242,13 @@ namespace MWWorld void World::update (float duration, bool paused) { + if (mPlayIntro) + { + --mPlayIntro; + if (mPlayIntro == 0) + mRendering->playVideo("mw_intro.bik", true); + } + mWeatherManager->update (duration); mWorldScene->update (duration, paused); @@ -1547,23 +1603,19 @@ namespace MWWorld void World::setupPlayer() { const ESM::NPC *player = mStore.get().find("player"); - mPlayer = new MWWorld::Player(player, *this); + if (!mPlayer) + mPlayer = new MWWorld::Player(player, *this); + else + mPlayer->set(player); Ptr ptr = mPlayer->getPlayer(); mRendering->setupPlayer(ptr); - if (mNewGame) - { - MWWorld::Class::get(ptr).getContainerStore(ptr).fill(player->mInventory, "", mStore); - MWWorld::Class::get(ptr).getInventoryStore(ptr).autoEquip(ptr); - } } void World::renderPlayer() { mRendering->renderPlayer(mPlayer->getPlayer()); mPhysics->addActor(mPlayer->getPlayer()); - if (mNewGame) - toggleCollisionMode(); } void World::setupExternalRendering (MWRender::ExternalRendering& rendering) diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 124f473e7..205361ef3 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -85,14 +85,9 @@ namespace MWWorld float mFaced2Distance; int mNumFacing; - bool mNewGame; - std::map mDoorStates; ///< only holds doors that are currently moving. 0 means closing, 1 opening - unsigned long lastTick; - Ogre::Timer mTimer; - int getDaysPerMonth (int month) const; void rotateObjectImp (const Ptr& ptr, Ogre::Vector3 rot, bool adjust); @@ -120,16 +115,20 @@ namespace MWWorld void ensureNeededRecords(); + int mPlayIntro; + public: World (OEngine::Render::OgreRenderer& renderer, const Files::Collections& fileCollections, const std::vector& master, const std::vector& plugins, - const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, bool newGame, + const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, ToUTF8::Utf8Encoder* encoder, const std::map& fallbackMap, int mActivationDistanceOverride); virtual ~World(); + virtual void startNewGame(); + virtual OEngine::Render::Fader* getFader(); ///< \ŧodo remove this function. Rendering details should not be exposed. From aaa9aba99983d15738e2fdacb89c58f5c2fbd70a Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 15 May 2013 22:38:53 +0200 Subject: [PATCH 2/2] Some fixes --- apps/openmw/engine.cpp | 39 +++++++++++++++++++++----------- apps/openmw/main.cpp | 4 ++++ apps/openmw/mwworld/cells.cpp | 5 +--- apps/openmw/mwworld/esmstore.hpp | 12 +++++----- apps/openmw/mwworld/worldimp.cpp | 1 - apps/openmw/mwworld/worldimp.hpp | 2 +- 6 files changed, 38 insertions(+), 25 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 372378f31..abc951726 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -131,6 +131,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) , mFpsLevel(0) , mDebug (false) , mVerboseScripts (false) + , mNewGame (false) , mUseSound (true) , mCompileAll (false) , mScriptContext (0) @@ -277,6 +278,11 @@ void OMW::Engine::setScriptsVerbosity(bool scriptsVerbosity) mVerboseScripts = scriptsVerbosity; } +void OMW::Engine::setNewGame(bool newGame) +{ + mNewGame = newGame; +} + std::string OMW::Engine::loadSettings (Settings::Manager & settings) { // Create the settings manager and load default settings file @@ -375,6 +381,8 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mEnvironment.setWindowManager (new MWGui::WindowManager( mExtensions, mFpsLevel, mOgre, mCfgMgr.getLogPath().string() + std::string("/"), mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage)); + if (mNewGame) + mEnvironment.getWindowManager()->setNewGame(true); // Create sound system mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound)); @@ -403,24 +411,29 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) MWBase::Environment::get().getWorld()->getPlayer(), *MWBase::Environment::get().getWindowManager(), mDebug, *this, keybinderUser, keybinderUserExists)); - // load cell - ESM::Position pos; - pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; - pos.pos[2] = 0; - mEnvironment.getWorld()->renderPlayer(); - if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName)) + if (!mNewGame) { - MWBase::Environment::get().getWorld()->indexToPosition (exterior->mData.mX, exterior->mData.mY, - pos.pos[0], pos.pos[1], true); - MWBase::Environment::get().getWorld()->changeToExteriorCell (pos); + // load cell + ESM::Position pos; + pos.rot[0] = pos.rot[1] = pos.rot[2] = 0; + pos.pos[2] = 0; + + if (const ESM::Cell *exterior = MWBase::Environment::get().getWorld()->getExterior (mCellName)) + { + MWBase::Environment::get().getWorld()->indexToPosition (exterior->mData.mX, exterior->mData.mY, + pos.pos[0], pos.pos[1], true); + MWBase::Environment::get().getWorld()->changeToExteriorCell (pos); + } + else + { + pos.pos[0] = pos.pos[1] = 0; + MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, pos); + } } else - { - pos.pos[0] = pos.pos[1] = 0; - MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, pos); - } + mEnvironment.getWorld()->startNewGame(); Ogre::FrameEvent event; event.timeSinceLastEvent = 0; diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 6742372d8..1fa461c2f 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -136,6 +136,9 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat ("script-run", bpo::value()->default_value(""), "select a file containing a list of console commands that is executed on startup") + ("new-game", bpo::value()->implicit_value(true) + ->default_value(false), "activate char gen/new game mechanics") + ("fs-strict", bpo::value()->implicit_value(true) ->default_value(false), "strict file system handling (no case folding)") @@ -237,6 +240,7 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat // startup-settings engine.setCell(variables["start"].as()); + engine.setNewGame(variables["new-game"].as()); // other settings engine.setDebugMode(variables["debug"].as()); diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index 564f62c8f..cb2e49ca0 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -40,10 +40,7 @@ void MWWorld::Cells::clear() { mInteriors.clear(); mExteriors.clear(); - - mIdCache = std::vector >( - 40, std::pair ("", (MWWorld::Ptr::CellStore*)0)), /// \todo make cache size configurable - + std::fill(mIdCache.begin(), mIdCache.end(), std::make_pair("", (MWWorld::Ptr::CellStore*)0)); mIdCacheIndex = 0; } diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index 49458c9b9..d86faf766 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -67,6 +67,8 @@ namespace MWWorld std::map mIds; std::map mStores; + ESM::NPC mPlayerTemplate; + unsigned int mDynamicCount; public: @@ -143,19 +145,17 @@ namespace MWWorld void clearDynamic () { - ESM::NPC playerNpc = *mNpcs.find("player"); - for (std::map::iterator it = mStores.begin(); it != mStores.end(); ++it) it->second->clearDynamic(); - mNpcs.insert(playerNpc); + mNpcs.insert(mPlayerTemplate); } void movePlayerRecord () { - ESM::NPC playerNpc = *mNpcs.find("player"); - mNpcs.eraseStatic(playerNpc.mId); - mNpcs.insert(playerNpc); + mPlayerTemplate = *mNpcs.find("player"); + mNpcs.eraseStatic(mPlayerTemplate.mId); + mNpcs.insert(mPlayerTemplate); } void load(ESM::ESMReader &esm); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index e8b68d266..d7304f2b0 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -225,7 +225,6 @@ namespace MWWorld void World::startNewGame() { - mWorldScene->changeToVoid(); mStore.clearDynamic(); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 205361ef3..1baf3d4ba 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -122,7 +122,7 @@ namespace MWWorld World (OEngine::Render::OgreRenderer& renderer, const Files::Collections& fileCollections, const std::vector& master, const std::vector& plugins, - const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, + const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, ToUTF8::Utf8Encoder* encoder, const std::map& fallbackMap, int mActivationDistanceOverride); virtual ~World();