From fd9f8c34f6065d2645db9bd1443df00939fa020a Mon Sep 17 00:00:00 2001 From: mrcheko Date: Sun, 15 Dec 2013 18:50:25 +0200 Subject: [PATCH 1/3] bug fix http://bugs.openmw.org/issues/428 --- apps/openmw/mwbase/world.hpp | 3 +++ apps/openmw/mwinput/inputmanagerimp.cpp | 7 +++-- apps/openmw/mwmechanics/actors.cpp | 16 +++++------- apps/openmw/mwmechanics/character.cpp | 32 ++++++++++++++++++++--- apps/openmw/mwmechanics/character.hpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 5 ++++ apps/openmw/mwrender/renderingmanager.hpp | 2 ++ apps/openmw/mwworld/worldimp.cpp | 5 ++++ apps/openmw/mwworld/worldimp.hpp | 2 ++ 9 files changed, 58 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 740114aff..ea8619b3a 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -43,6 +43,7 @@ namespace MWRender { class ExternalRendering; class Animation; + class Camera; } namespace MWMechanics @@ -112,6 +113,8 @@ namespace MWBase virtual MWWorld::CellStore *getInterior (const std::string& name) = 0; + virtual MWRender::Camera* getCamera() const = 0; + virtual void setWaterHeight(const float height) = 0; virtual void toggleWater() = 0; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 850a62bec..47fb979d7 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -181,7 +181,8 @@ namespace MWInput switch (action) { case A_GameMenu: - toggleMainMenu (); + if(MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_Running) + toggleMainMenu (); break; case A_Screenshot: screenshot(); @@ -301,7 +302,9 @@ namespace MWInput return; // Disable movement in Gui mode - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; + if (MWBase::Environment::get().getWindowManager()->isGuiMode() + || MWWorld::Class::get(mPlayer->getPlayer()).getCreatureStats(mPlayer->getPlayer()).isDead() ) + return; // Configure player movement according to keyboard input. Actual movement will diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 19c2dac0c..c7ab0322d 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -571,19 +571,15 @@ namespace MWMechanics stats.resurrect(); continue; } - - MWBase::Environment::get().getStateManager()->endGame(); } - if(iter->second->isDead()) - continue; + if (iter->second->kill()) + { + ++mDeathCount[cls.getId(iter->first)]; - iter->second->kill(); - - ++mDeathCount[cls.getId(iter->first)]; - - if(cls.isEssential(iter->first)) - MWBase::Environment::get().getWindowManager()->messageBox("#{sKilledEssential}"); + if(cls.isEssential(iter->first)) + MWBase::Environment::get().getWindowManager()->messageBox("#{sKilledEssential}"); + } } } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 68f87ef4c..7c7f40e97 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -26,12 +26,14 @@ #include "creaturestats.hpp" #include "security.hpp" +#include "../mwrender/camera.hpp" #include "../mwrender/animation.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/statemanager.hpp" #include "../mwworld/player.hpp" #include "../mwworld/class.hpp" @@ -1052,10 +1054,20 @@ void CharacterController::forceStateUpdate() } } -void CharacterController::kill() +bool CharacterController::kill() { - if(mDeathState != CharState_None) - return; + if( isDead() ) + { + //state=end game only when player's death animation is over + if( mPtr.getRefData().getHandle()=="player" && !isAnimPlaying(mCurrentDeath) + && MWBase::Environment::get().getWindowManager()->getMode () != MWGui::GM_MainMenu ) + { + MWBase::Environment::get().getStateManager()->endGame(); + MWWorld::Class::get(mPtr).getCreatureStats(mPtr).setHealth(0); + MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + } + return false; + } if(mPtr.getTypeName() == typeid(ESM::NPC).name()) { @@ -1093,6 +1105,18 @@ void CharacterController::kill() if(mAnimation) { + //switch to 3rd person before player's death animation + if (mPtr.getRefData().getHandle()=="player") + { + if(MWBase::Environment::get().getWorld()->getCamera()->isVanityOrPreviewModeEnabled() ) + { + MWBase::Environment::get().getWorld()->getCamera()->togglePreviewMode(false); + MWBase::Environment::get().getWorld()->getCamera()->toggleVanityMode(false); + } + if(MWBase::Environment::get().getWorld()->getCamera()->isFirstPerson()) + MWBase::Environment::get().getWorld()->togglePOV(); + } + mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); mAnimation->disable(mCurrentIdle); @@ -1100,6 +1124,8 @@ void CharacterController::kill() mIdleState = CharState_None; mCurrentIdle.clear(); + + return true; } void CharacterController::resurrect() diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 0b55534a6..5e7a7c6d4 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -188,7 +188,7 @@ public: void skipAnim(); bool isAnimPlaying(const std::string &groupName); - void kill(); + bool kill(); void resurrect(); bool isDead() const { return mDeathState != CharState_None; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 2eb2b1523..8aca3b489 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -221,6 +221,11 @@ OEngine::Render::Fader* RenderingManager::getFader() return mRendering.getFader(); } + MWRender::Camera* RenderingManager::getCamera() const +{ + return mCamera; +} + void RenderingManager::removeCell (MWWorld::CellStore *store) { mObjects.removeCell(store); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 2d0813912..5bbc3055d 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -98,6 +98,8 @@ public: SkyManager* getSkyManager(); Compositors* getCompositors(); + MWRender::Camera* getCamera() const; + void toggleLight(); bool toggleRenderMode(int mode); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index c4e63fad0..2676be4b7 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -400,6 +400,11 @@ namespace MWWorld return mCells.getInterior (name); } + MWRender::Camera* World::getCamera() const + { + return mRendering->getCamera(); + } + MWWorld::Player& World::getPlayer() { return *mPlayer; diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 845668449..7c24adfa8 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -185,6 +185,8 @@ namespace MWWorld virtual CellStore *getInterior (const std::string& name); + virtual MWRender::Camera* getCamera() const; + virtual void setWaterHeight(const float height); virtual void toggleWater(); From f50ff0b1c4df394bc451e1fbd137e846cf81e39c Mon Sep 17 00:00:00 2001 From: mrcheko Date: Mon, 16 Dec 2013 15:40:47 +0200 Subject: [PATCH 2/3] reworked http://bugs.openmw.org/issues/428 --- apps/openmw/engine.cpp | 54 +++++++++++++------------ apps/openmw/mwbase/world.hpp | 3 +- apps/openmw/mwinput/inputmanagerimp.cpp | 9 +++-- apps/openmw/mwmechanics/actors.cpp | 1 - apps/openmw/mwmechanics/character.cpp | 19 +-------- apps/openmw/mwstate/statemanagerimp.cpp | 1 + apps/openmw/mwworld/worldimp.cpp | 10 ++++- apps/openmw/mwworld/worldimp.hpp | 4 +- 8 files changed, 49 insertions(+), 52 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 8fc36a5d5..97c2844eb 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -94,35 +94,39 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) MWBase::Environment::get().getSoundManager()->update(frametime); // global scripts + MWBase::Environment::get().getScriptManager()->getGlobalScripts().run(); + + bool changed = MWBase::Environment::get().getWorld()->hasCellChanged(); + + // local scripts + executeLocalScripts(); // This does not handle the case where a global script causes a + // cell change, followed by a cell change in a local script during + // the same frame. + + if (changed) // keep change flag for another frame, if cell changed happened in local script + MWBase::Environment::get().getWorld()->markCellAsUnchanged(); + + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) + MWBase::Environment::get().getWorld()->advanceTime( + frametime*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600); + + // update actors + MWBase::Environment::get().getMechanicsManager()->update(frametime, + MWBase::Environment::get().getWindowManager()->isGuiMode()); + if (MWBase::Environment::get().getStateManager()->getState()== MWBase::StateManager::State_Running) { - MWBase::Environment::get().getScriptManager()->getGlobalScripts().run(); - - bool changed = MWBase::Environment::get().getWorld()->hasCellChanged(); - - // local scripts - executeLocalScripts(); // This does not handle the case where a global script causes a - // cell change, followed by a cell change in a local script during - // the same frame. - - if (changed) // keep change flag for another frame, if cell changed happened in local script - MWBase::Environment::get().getWorld()->markCellAsUnchanged(); - - if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) - MWBase::Environment::get().getWorld()->advanceTime( - frametime*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600); - - // update actors - MWBase::Environment::get().getMechanicsManager()->update(frametime, - MWBase::Environment::get().getWindowManager()->isGuiMode()); - - // update world - MWBase::Environment::get().getWorld()->update(frametime, MWBase::Environment::get().getWindowManager()->isGuiMode()); - - // update game state - MWBase::Environment::get().getStateManager()->update (frametime); + MWWorld::Ptr player = mEnvironment.getWorld()->getPlayer().getPlayer(); + if(MWWorld::Class::get(player).getCreatureStats(player).isDead()) + MWBase::Environment::get().getStateManager()->endGame(); } + + // update world + MWBase::Environment::get().getWorld()->update(frametime, MWBase::Environment::get().getWindowManager()->isGuiMode()); + + // update game state + MWBase::Environment::get().getStateManager()->update (frametime); // update GUI Ogre::RenderWindow* window = mOgre->getWindow(); diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index ea8619b3a..f7041a47b 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -43,7 +43,6 @@ namespace MWRender { class ExternalRendering; class Animation; - class Camera; } namespace MWMechanics @@ -113,7 +112,7 @@ namespace MWBase virtual MWWorld::CellStore *getInterior (const std::string& name) = 0; - virtual MWRender::Camera* getCamera() const = 0; + virtual void useDeathCamera() = 0; virtual void setWaterHeight(const float height) = 0; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 47fb979d7..e6e349c4d 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -181,8 +181,9 @@ namespace MWInput switch (action) { case A_GameMenu: - if(MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_Running) - toggleMainMenu (); + if(!(MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running + && MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_MainMenu)) + toggleMainMenu (); break; case A_Screenshot: screenshot(); @@ -303,8 +304,8 @@ namespace MWInput // Disable movement in Gui mode if (MWBase::Environment::get().getWindowManager()->isGuiMode() - || MWWorld::Class::get(mPlayer->getPlayer()).getCreatureStats(mPlayer->getPlayer()).isDead() ) - return; + || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running) + return; // Configure player movement according to keyboard input. Actual movement will diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index c7ab0322d..7180eb883 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -19,7 +19,6 @@ #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" - #include "../mwbase/statemanager.hpp" #include "npcstats.hpp" #include "creaturestats.hpp" diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 7c7f40e97..9a19ac7fa 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -26,14 +26,12 @@ #include "creaturestats.hpp" #include "security.hpp" -#include "../mwrender/camera.hpp" #include "../mwrender/animation.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwbase/statemanager.hpp" #include "../mwworld/player.hpp" #include "../mwworld/class.hpp" @@ -1058,11 +1056,10 @@ bool CharacterController::kill() { if( isDead() ) { - //state=end game only when player's death animation is over + //player's death animation is over if( mPtr.getRefData().getHandle()=="player" && !isAnimPlaying(mCurrentDeath) - && MWBase::Environment::get().getWindowManager()->getMode () != MWGui::GM_MainMenu ) + && MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_MainMenu ) { - MWBase::Environment::get().getStateManager()->endGame(); MWWorld::Class::get(mPtr).getCreatureStats(mPtr).setHealth(0); MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); } @@ -1105,18 +1102,6 @@ bool CharacterController::kill() if(mAnimation) { - //switch to 3rd person before player's death animation - if (mPtr.getRefData().getHandle()=="player") - { - if(MWBase::Environment::get().getWorld()->getCamera()->isVanityOrPreviewModeEnabled() ) - { - MWBase::Environment::get().getWorld()->getCamera()->togglePreviewMode(false); - MWBase::Environment::get().getWorld()->getCamera()->toggleVanityMode(false); - } - if(MWBase::Environment::get().getWorld()->getCamera()->isFirstPerson()) - MWBase::Environment::get().getWorld()->togglePOV(); - } - mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); mAnimation->disable(mCurrentIdle); diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index 94219b8fc..bad4de03d 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -70,6 +70,7 @@ void MWState::StateManager::newGame (bool bypass) void MWState::StateManager::endGame() { mState = State_Ended; + MWBase::Environment::get().getWorld()->useDeathCamera(); } void MWState::StateManager::saveGame (const std::string& description, const Slot *slot) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 2676be4b7..357101e45 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -400,9 +400,15 @@ namespace MWWorld return mCells.getInterior (name); } - MWRender::Camera* World::getCamera() const + void World::useDeathCamera() { - return mRendering->getCamera(); + if(mRendering->getCamera()->isVanityOrPreviewModeEnabled() ) + { + mRendering->getCamera()->togglePreviewMode(false); + mRendering->getCamera()->toggleVanityMode(false); + } + if(mRendering->getCamera()->isFirstPerson()) + togglePOV(); } MWWorld::Player& World::getPlayer() diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 7c24adfa8..fb9c4cb68 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -42,6 +42,7 @@ namespace MWRender class SkyManager; class CellRender; class Animation; + class Camera; } struct ContentLoader; @@ -185,7 +186,8 @@ namespace MWWorld virtual CellStore *getInterior (const std::string& name); - virtual MWRender::Camera* getCamera() const; + //switch to POV before showing player's death animation + virtual void useDeathCamera(); virtual void setWaterHeight(const float height); From a854eb73db8e0629cf5c707b69ccbb7b2a1d4943 Mon Sep 17 00:00:00 2001 From: mrcheko Date: Mon, 16 Dec 2013 21:02:21 +0200 Subject: [PATCH 3/3] StateRunning check returns --- apps/openmw/engine.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 97c2844eb..5b8872b0f 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -93,22 +93,30 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) if (mUseSound) MWBase::Environment::get().getSoundManager()->update(frametime); - // global scripts - MWBase::Environment::get().getScriptManager()->getGlobalScripts().run(); + if (MWBase::Environment::get().getStateManager()->getState()== + MWBase::StateManager::State_Running) + { + // global scripts + MWBase::Environment::get().getScriptManager()->getGlobalScripts().run(); - bool changed = MWBase::Environment::get().getWorld()->hasCellChanged(); + bool changed = MWBase::Environment::get().getWorld()->hasCellChanged(); - // local scripts - executeLocalScripts(); // This does not handle the case where a global script causes a - // cell change, followed by a cell change in a local script during - // the same frame. + // local scripts + executeLocalScripts(); // This does not handle the case where a global script causes a + // cell change, followed by a cell change in a local script during + // the same frame. - if (changed) // keep change flag for another frame, if cell changed happened in local script - MWBase::Environment::get().getWorld()->markCellAsUnchanged(); + if (changed) // keep change flag for another frame, if cell changed happened in local script + MWBase::Environment::get().getWorld()->markCellAsUnchanged(); + + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) + MWBase::Environment::get().getWorld()->advanceTime( + frametime*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600); + + // update game state + MWBase::Environment::get().getStateManager()->update (frametime); + } - if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) - MWBase::Environment::get().getWorld()->advanceTime( - frametime*MWBase::Environment::get().getWorld()->getTimeScaleFactor()/3600); // update actors MWBase::Environment::get().getMechanicsManager()->update(frametime, @@ -125,9 +133,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) // update world MWBase::Environment::get().getWorld()->update(frametime, MWBase::Environment::get().getWindowManager()->isGuiMode()); - // update game state - MWBase::Environment::get().getStateManager()->update (frametime); - // update GUI Ogre::RenderWindow* window = mOgre->getWindow(); unsigned int tri, batch;