diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 58fa221e6..c2b02452a 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -338,6 +338,9 @@ namespace MWBase /// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading. virtual void setScreenFactor (float factor) = 0; + virtual void activateHitOverlay() = 0; + virtual void setWerewolfOverlay(bool set) = 0; + virtual void toggleDebugWindow() = 0; }; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 5d5b8a689..b4c1ad13a 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -778,6 +778,9 @@ namespace MWClass sndMgr->playSound3D(ptr, "Health Damage", 1.0f, 1.0f); float health = getCreatureStats(ptr).getHealth().getCurrent() - damage; setActorHealth(ptr, health, attacker); + + if (ptr.getRefData().getHandle() == "player") + MWBase::Environment::get().getWindowManager()->activateHitOverlay(); } else { diff --git a/apps/openmw/mwgui/screenfader.cpp b/apps/openmw/mwgui/screenfader.cpp index c27737285..1adfdef05 100644 --- a/apps/openmw/mwgui/screenfader.cpp +++ b/apps/openmw/mwgui/screenfader.cpp @@ -3,43 +3,86 @@ namespace MWGui { - ScreenFader::ScreenFader() + FadeOp::FadeOp(ScreenFader * fader, float time, float targetAlpha) + : mFader(fader), + mRemainingTime(time), + mTargetTime(time), + mTargetAlpha(targetAlpha), + mStartAlpha(0.f), + mRunning(false) + { + } + + bool FadeOp::isRunning() + { + return mRunning; + } + + void FadeOp::start() + { + if (mRunning) + return; + + mRemainingTime = mTargetTime; + mStartAlpha = mFader->getCurrentAlpha(); + mRunning = true; + } + + void FadeOp::update(float dt) + { + if (!mRunning) + return; + + if (mRemainingTime <= 0 || mStartAlpha == mTargetAlpha) + { + finish(); + return; + } + + float currentAlpha = mFader->getCurrentAlpha(); + if (mStartAlpha > mTargetAlpha) + { + currentAlpha -= dt/mTargetTime * (mStartAlpha-mTargetAlpha); + if (currentAlpha < mTargetAlpha) + currentAlpha = mTargetAlpha; + } + else + { + currentAlpha += dt/mTargetTime * (mTargetAlpha-mStartAlpha); + if (currentAlpha > mTargetAlpha) + currentAlpha = mTargetAlpha; + } + + mFader->notifyAlphaChanged(currentAlpha); + + mRemainingTime -= dt; + } + + void FadeOp::finish() + { + mRunning = false; + mFader->notifyOperationFinished(); + } + + ScreenFader::ScreenFader(const std::string & texturePath) : WindowBase("openmw_screen_fader.layout") - , mMode(FadingMode_In) - , mRemainingTime(0.f) - , mTargetTime(0.f) - , mTargetAlpha(0.f) , mCurrentAlpha(0.f) - , mStartAlpha(0.f) , mFactor(1.f) + , mRepeat(false) { mMainWidget->setSize(MyGUI::RenderManager::getInstance().getViewSize()); - + mMainWidget->setProperty("ImageTexture", texturePath); setVisible(false); } void ScreenFader::update(float dt) { - if (mRemainingTime > 0) + if (!mQueue.empty()) { - if (mMode == FadingMode_In) - { - mCurrentAlpha -= dt/mTargetTime * (mStartAlpha-mTargetAlpha); - if (mCurrentAlpha < mTargetAlpha) mCurrentAlpha = mTargetAlpha; - } - else if (mMode == FadingMode_Out) - { - mCurrentAlpha += dt/mTargetTime * (mTargetAlpha-mStartAlpha); - if (mCurrentAlpha > mTargetAlpha) mCurrentAlpha = mTargetAlpha; - } - - mRemainingTime -= dt; + if (!mQueue.front()->isRunning()) + mQueue.front()->start(); + mQueue.front()->update(dt); } - - if (1.f-((1.f-mCurrentAlpha) * mFactor) == 0.f) - mMainWidget->setVisible(false); - else - applyAlpha(); } void ScreenFader::applyAlpha() @@ -50,62 +93,73 @@ namespace MWGui void ScreenFader::fadeIn(float time) { - if (time<0.f) return; - if (time==0.f) - { - mCurrentAlpha = 0.f; - applyAlpha(); - return; - } - - mStartAlpha = mCurrentAlpha; - mTargetAlpha = 0.f; - mMode = FadingMode_In; - mTargetTime = time; - mRemainingTime = time; + queue(time, 0.f); } void ScreenFader::fadeOut(const float time) { - if (time<0.f) return; - if (time==0.f) - { - mCurrentAlpha = 1.f; - applyAlpha(); - return; - } - - mStartAlpha = mCurrentAlpha; - mTargetAlpha = 1.f; - mMode = FadingMode_Out; - mTargetTime = time; - mRemainingTime = time; + queue(time, 1.f); } void ScreenFader::fadeTo(const int percent, const float time) { - if (time<0.f) return; - if (time==0.f) + queue(time, percent/100.f); + } + + void ScreenFader::setFactor(float factor) + { + mFactor = factor; + } + + void ScreenFader::setRepeat(bool repeat) + { + mRepeat = repeat; + } + + void ScreenFader::queue(float time, float targetAlpha) + { + if (time < 0.f) + return; + + if (time == 0.f) { - mCurrentAlpha = percent/100.f; + mCurrentAlpha = targetAlpha; applyAlpha(); return; } - mStartAlpha = mCurrentAlpha; - mTargetAlpha = percent/100.f; + mQueue.push_back(FadeOp::Ptr(new FadeOp(this, time, targetAlpha))); + } + + void ScreenFader::clearQueue() + { + mQueue.clear(); + } + + void ScreenFader::notifyAlphaChanged(float alpha) + { + if (mCurrentAlpha == alpha) + return; - if (mTargetAlpha == mStartAlpha) return; - else if (mTargetAlpha > mStartAlpha) mMode = FadingMode_Out; - else mMode = FadingMode_In; + mCurrentAlpha = alpha; - mTargetTime = time; - mRemainingTime = time; + if (1.f-((1.f-mCurrentAlpha) * mFactor) == 0.f) + mMainWidget->setVisible(false); + else + applyAlpha(); } - void ScreenFader::setFactor(float factor) + void ScreenFader::notifyOperationFinished() { - mFactor = factor; + FadeOp::Ptr op = mQueue.front(); + mQueue.pop_front(); + + if (mRepeat) + mQueue.push_back(op); } + float ScreenFader::getCurrentAlpha() + { + return mCurrentAlpha; + } } diff --git a/apps/openmw/mwgui/screenfader.hpp b/apps/openmw/mwgui/screenfader.hpp index 975006a85..07b6992ba 100644 --- a/apps/openmw/mwgui/screenfader.hpp +++ b/apps/openmw/mwgui/screenfader.hpp @@ -1,15 +1,42 @@ #ifndef OPENMW_MWGUI_SCREENFADER_H #define OPENMW_MWGUI_SCREENFADER_H +#include + +#include + #include "windowbase.hpp" namespace MWGui { + class ScreenFader; + + class FadeOp + { + public: + typedef boost::shared_ptr Ptr; + + FadeOp(ScreenFader * fader, float time, float targetAlpha); + + bool isRunning(); + + void start(); + void update(float dt); + void finish(); + + private: + ScreenFader * mFader; + float mRemainingTime; + float mTargetTime; + float mTargetAlpha; + float mStartAlpha; + bool mRunning; + }; class ScreenFader : public WindowBase { public: - ScreenFader(); + ScreenFader(const std::string & texturePath); void update(float dt); @@ -18,27 +45,24 @@ namespace MWGui void fadeTo(const int percent, const float time); void setFactor (float factor); + void setRepeat(bool repeat); - private: - enum FadingMode - { - FadingMode_In, - FadingMode_Out - }; + void queue(float time, float targetAlpha); + void clearQueue(); - void applyAlpha(); + void notifyAlphaChanged(float alpha); + void notifyOperationFinished(); + float getCurrentAlpha(); - FadingMode mMode; + private: + void applyAlpha(); - float mRemainingTime; - float mTargetTime; - float mTargetAlpha; float mCurrentAlpha; - float mStartAlpha; - float mFactor; - }; + bool mRepeat; // repeat queued operations without removing them + std::deque mQueue; + }; } #endif diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 16295d3a5..ba880ddc9 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -120,6 +120,8 @@ namespace MWGui , mCompanionWindow(NULL) , mVideoBackground(NULL) , mVideoWidget(NULL) + , mHitFader(NULL) + , mWerewolfFader(NULL) , mScreenFader(NULL) , mDebugWindow(NULL) , mTranslationDataStorage (translationDataStorage) @@ -127,6 +129,8 @@ namespace MWGui , mInputBlocker(NULL) , mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD")) , mSubtitlesEnabled(Settings::Manager::getBool ("subtitles", "GUI")) + , mHitFaderEnabled(Settings::Manager::getBool ("hit fader", "GUI")) + , mWerewolfOverlayEnabled(Settings::Manager::getBool ("werewolf overlay", "GUI")) , mHudEnabled(true) , mGuiEnabled(true) , mCursorVisible(true) @@ -267,7 +271,11 @@ namespace MWGui mSoulgemDialog = new SoulgemDialog(mMessageBoxManager); mCompanionWindow = new CompanionWindow(mDragAndDrop, mMessageBoxManager); trackWindow(mCompanionWindow, "companion"); - mScreenFader = new ScreenFader(); + + mWerewolfFader = new ScreenFader("textures\\werewolfoverlay.dds"); + mHitFader = new ScreenFader("textures\\player_hit_01.dds"); + mScreenFader = new ScreenFader("black.png"); + mDebugWindow = new DebugWindow(); mInputBlocker = MyGUI::Gui::getInstance().createWidget("",0,0,w,h,MyGUI::Align::Stretch,"Overlay"); @@ -359,6 +367,8 @@ namespace MWGui delete mCursorManager; delete mRecharge; delete mCompanionWindow; + delete mHitFader; + delete mWerewolfFader; delete mScreenFader; delete mDebugWindow; @@ -862,6 +872,8 @@ namespace MWGui mConsole->checkReferenceAvailable(); mCompanionWindow->onFrame(); + mHitFader->update(frameDuration); + mWerewolfFader->update(frameDuration); mScreenFader->update(frameDuration); mDebugWindow->onFrame(frameDuration); @@ -1450,7 +1462,10 @@ namespace MWGui const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if (player.getClass().getNpcStats(player).isWerewolf()) + { + setWerewolfOverlay(true); forceHide((GuiWindow)(MWGui::GW_Inventory | MWGui::GW_Magic)); + } } // Remove this method for MyGUI 3.2.2 @@ -1718,16 +1733,19 @@ namespace MWGui void WindowManager::fadeScreenIn(const float time) { + mScreenFader->clearQueue(); mScreenFader->fadeIn(time); } void WindowManager::fadeScreenOut(const float time) { + mScreenFader->clearQueue(); mScreenFader->fadeOut(time); } void WindowManager::fadeScreenTo(const int percent, const float time) { + mScreenFader->clearQueue(); mScreenFader->fadeTo(percent, time); } @@ -1736,6 +1754,27 @@ namespace MWGui mScreenFader->setFactor(factor); } + void WindowManager::activateHitOverlay() + { + if (!mHitFaderEnabled) + return; + + mHitFader->clearQueue(); + mHitFader->fadeTo(50, 0.2f); + mHitFader->fadeTo(0, 0.2f); + } + + void WindowManager::setWerewolfOverlay(bool set) + { + if (mWerewolfOverlayEnabled) + return; + + if (set) + mWerewolfFader->fadeOut(1.0f); + else + mWerewolfFader->fadeIn(1.0f); + } + void WindowManager::onClipboardChanged(const std::string &_type, const std::string &_data) { if (_type == "Text") diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 1dae77641..7be0c1165 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -334,6 +334,9 @@ namespace MWGui /// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading. virtual void setScreenFactor (float factor); + virtual void activateHitOverlay(); + virtual void setWerewolfOverlay(bool set); + virtual void toggleDebugWindow(); private: @@ -388,6 +391,8 @@ namespace MWGui CompanionWindow* mCompanionWindow; MyGUI::ImageBox* mVideoBackground; VideoWidget* mVideoWidget; + ScreenFader* mWerewolfFader; + ScreenFader* mHitFader; ScreenFader* mScreenFader; DebugWindow* mDebugWindow; @@ -400,6 +405,8 @@ namespace MWGui bool mCrosshairEnabled; bool mSubtitlesEnabled; + bool mHitFaderEnabled; + bool mWerewolfOverlayEnabled; bool mHudEnabled; bool mGuiEnabled; bool mCursorVisible; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 28a44d3ba..a905820f8 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2352,6 +2352,8 @@ namespace MWWorld windowManager->unsetForceHide(MWGui::GW_Magic); } + windowManager->setWerewolfOverlay(werewolf); + // Witnesses of the player's transformation will make them a globally known werewolf std::vector closeActors; MWBase::Environment::get().getMechanicsManager()->getActorsInRange(Ogre::Vector3(actor.getRefData().getPosition().pos), diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 06d999189..12b52d3db 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -41,6 +41,9 @@ tooltip delay = 0 subtitles = false +hit fader = true +werewolf overlay = true + [General] # Camera field of view field of view = 55