From 0ae604990e9a446ce852828363276915f4941f70 Mon Sep 17 00:00:00 2001 From: MiroslavR Date: Sat, 11 Oct 2014 22:21:48 +0200 Subject: [PATCH] Implement continuous damage indication (Fixes #1970) --- apps/openmw/mwbase/windowmanager.hpp | 2 +- apps/openmw/mwgui/screenfader.cpp | 5 +++++ apps/openmw/mwgui/screenfader.hpp | 1 + apps/openmw/mwgui/windowmanagerimp.cpp | 9 ++++++--- apps/openmw/mwgui/windowmanagerimp.hpp | 2 +- apps/openmw/mwmechanics/actors.cpp | 24 ++++++++++++++++++------ apps/openmw/mwworld/worldimp.cpp | 22 ++++++++++++++++++++++ 7 files changed, 54 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index c2b02452a..adffa9903 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -338,7 +338,7 @@ 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 activateHitOverlay(bool interrupt=true) = 0; virtual void setWerewolfOverlay(bool set) = 0; virtual void toggleDebugWindow() = 0; diff --git a/apps/openmw/mwgui/screenfader.cpp b/apps/openmw/mwgui/screenfader.cpp index 1adfdef05..c616a8338 100644 --- a/apps/openmw/mwgui/screenfader.cpp +++ b/apps/openmw/mwgui/screenfader.cpp @@ -131,6 +131,11 @@ namespace MWGui mQueue.push_back(FadeOp::Ptr(new FadeOp(this, time, targetAlpha))); } + bool ScreenFader::isEmpty() + { + return mQueue.empty(); + } + void ScreenFader::clearQueue() { mQueue.clear(); diff --git a/apps/openmw/mwgui/screenfader.hpp b/apps/openmw/mwgui/screenfader.hpp index 07b6992ba..8c393bf92 100644 --- a/apps/openmw/mwgui/screenfader.hpp +++ b/apps/openmw/mwgui/screenfader.hpp @@ -48,6 +48,7 @@ namespace MWGui void setRepeat(bool repeat); void queue(float time, float targetAlpha); + bool isEmpty(); void clearQueue(); void notifyAlphaChanged(float alpha); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 2479f699b..0bc36cf4f 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1756,14 +1756,17 @@ namespace MWGui mScreenFader->setFactor(factor); } - void WindowManager::activateHitOverlay() + void WindowManager::activateHitOverlay(bool interrupt) { if (!mHitFaderEnabled) return; + if (!interrupt && !mHitFader->isEmpty()) + return; + mHitFader->clearQueue(); - mHitFader->fadeTo(50, 0.2f); - mHitFader->fadeTo(0, 0.2f); + mHitFader->fadeTo(100, 0.0f); + mHitFader->fadeTo(0, 0.5f); } void WindowManager::setWerewolfOverlay(bool set) diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index e3bc7781f..088f6c6e9 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -333,7 +333,7 @@ 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 activateHitOverlay(bool interrupt); virtual void setWerewolfOverlay(bool set); virtual void toggleDebugWindow(); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index da6aec0be..71f9edfde 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -592,6 +592,7 @@ namespace MWMechanics }; DynamicStat health = creatureStats.getHealth(); + bool receivedMagicDamage = false; for (unsigned int i=0; i 1) damageScale *= fMagicSunBlockedMult; health.setCurrent(health.getCurrent() - magnitude * duration * damageScale); + + if (magnitude * damageScale > 0.0f) + receivedMagicDamage = true; } else + { health.setCurrent(health.getCurrent() - magnitude * duration); + if (magnitude > 0.0f) + receivedMagicDamage = true; + } } + + if (receivedMagicDamage && ptr.getRefData().getHandle() == "player") + MWBase::Environment::get().getWindowManager()->activateHitOverlay(false); + creatureStats.setHealth(health); if (!wasDead && creatureStats.isDead()) @@ -875,13 +887,13 @@ namespace MWMechanics static const float fSuffocationDamage = world->getStore().get().find("fSuffocationDamage")->getFloat(); ptr.getClass().setActorHealth(ptr, stats.getHealth().getCurrent() - fSuffocationDamage*duration); - // Play a drowning sound as necessary for the player + // Play a drowning sound + MWBase::SoundManager *sndmgr = MWBase::Environment::get().getSoundManager(); + if(!sndmgr->getSoundPlaying(ptr, "drown")) + sndmgr->playSound3D(ptr, "drown", 1.0f, 1.0f); + if(ptr == world->getPlayerPtr()) - { - MWBase::SoundManager *sndmgr = MWBase::Environment::get().getSoundManager(); - if(!sndmgr->getSoundPlaying(MWWorld::Ptr(), "drown")) - sndmgr->playSound("drown", 1.0f, 1.0f); - } + MWBase::Environment::get().getWindowManager()->activateHitOverlay(false); } } else diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index b112c812a..92e240d7a 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2087,9 +2087,20 @@ namespace MWWorld continue; MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor); + if (stats.isDead()) + continue; MWMechanics::DynamicStat health = stats.getHealth(); health.setCurrent(health.getCurrent()-healthPerSecond*MWBase::Environment::get().getFrameDuration()); stats.setHealth(health); + + if (healthPerSecond > 0.0f) + { + if (actor.getRefData().getHandle() == "player") + MWBase::Environment::get().getWindowManager()->activateHitOverlay(false); + + if (!MWBase::Environment::get().getSoundManager()->getSoundPlaying(actor, "Health Damage")) + MWBase::Environment::get().getSoundManager()->playSound3D(actor, "Health Damage", 1.0f, 1.0f); + } } } @@ -2104,9 +2115,20 @@ namespace MWWorld continue; MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor); + if (stats.isDead()) + continue; MWMechanics::DynamicStat health = stats.getHealth(); health.setCurrent(health.getCurrent()-healthPerSecond*MWBase::Environment::get().getFrameDuration()); stats.setHealth(health); + + if (healthPerSecond > 0.0f) + { + if (actor.getRefData().getHandle() == "player") + MWBase::Environment::get().getWindowManager()->activateHitOverlay(false); + + if (!MWBase::Environment::get().getSoundManager()->getSoundPlaying(actor, "Health Damage")) + MWBase::Environment::get().getSoundManager()->playSound3D(actor, "Health Damage", 1.0f, 1.0f); + } } }