Implement continuous damage indication (Fixes #1970)

deque
MiroslavR 10 years ago
parent 4dc613a04b
commit 0ae604990e

@ -338,7 +338,7 @@ namespace MWBase
/// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading. /// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading.
virtual void setScreenFactor (float factor) = 0; 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 setWerewolfOverlay(bool set) = 0;
virtual void toggleDebugWindow() = 0; virtual void toggleDebugWindow() = 0;

@ -131,6 +131,11 @@ namespace MWGui
mQueue.push_back(FadeOp::Ptr(new FadeOp(this, time, targetAlpha))); mQueue.push_back(FadeOp::Ptr(new FadeOp(this, time, targetAlpha)));
} }
bool ScreenFader::isEmpty()
{
return mQueue.empty();
}
void ScreenFader::clearQueue() void ScreenFader::clearQueue()
{ {
mQueue.clear(); mQueue.clear();

@ -48,6 +48,7 @@ namespace MWGui
void setRepeat(bool repeat); void setRepeat(bool repeat);
void queue(float time, float targetAlpha); void queue(float time, float targetAlpha);
bool isEmpty();
void clearQueue(); void clearQueue();
void notifyAlphaChanged(float alpha); void notifyAlphaChanged(float alpha);

@ -1756,14 +1756,17 @@ namespace MWGui
mScreenFader->setFactor(factor); mScreenFader->setFactor(factor);
} }
void WindowManager::activateHitOverlay() void WindowManager::activateHitOverlay(bool interrupt)
{ {
if (!mHitFaderEnabled) if (!mHitFaderEnabled)
return; return;
if (!interrupt && !mHitFader->isEmpty())
return;
mHitFader->clearQueue(); mHitFader->clearQueue();
mHitFader->fadeTo(50, 0.2f); mHitFader->fadeTo(100, 0.0f);
mHitFader->fadeTo(0, 0.2f); mHitFader->fadeTo(0, 0.5f);
} }
void WindowManager::setWerewolfOverlay(bool set) void WindowManager::setWerewolfOverlay(bool set)

@ -333,7 +333,7 @@ namespace MWGui
/// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading. /// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading.
virtual void setScreenFactor (float factor); virtual void setScreenFactor (float factor);
virtual void activateHitOverlay(); virtual void activateHitOverlay(bool interrupt);
virtual void setWerewolfOverlay(bool set); virtual void setWerewolfOverlay(bool set);
virtual void toggleDebugWindow(); virtual void toggleDebugWindow();

@ -592,6 +592,7 @@ namespace MWMechanics
}; };
DynamicStat<float> health = creatureStats.getHealth(); DynamicStat<float> health = creatureStats.getHealth();
bool receivedMagicDamage = false;
for (unsigned int i=0; i<sizeof(damageEffects)/sizeof(int); ++i) for (unsigned int i=0; i<sizeof(damageEffects)/sizeof(int); ++i)
{ {
float magnitude = creatureStats.getMagicEffects().get(damageEffects[i]).getMagnitude(); float magnitude = creatureStats.getMagicEffects().get(damageEffects[i]).getMagnitude();
@ -612,11 +613,22 @@ namespace MWMechanics
if (weather > 1) if (weather > 1)
damageScale *= fMagicSunBlockedMult; damageScale *= fMagicSunBlockedMult;
health.setCurrent(health.getCurrent() - magnitude * duration * damageScale); health.setCurrent(health.getCurrent() - magnitude * duration * damageScale);
if (magnitude * damageScale > 0.0f)
receivedMagicDamage = true;
} }
else else
{
health.setCurrent(health.getCurrent() - magnitude * duration); 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); creatureStats.setHealth(health);
if (!wasDead && creatureStats.isDead()) if (!wasDead && creatureStats.isDead())
@ -875,13 +887,13 @@ namespace MWMechanics
static const float fSuffocationDamage = world->getStore().get<ESM::GameSetting>().find("fSuffocationDamage")->getFloat(); static const float fSuffocationDamage = world->getStore().get<ESM::GameSetting>().find("fSuffocationDamage")->getFloat();
ptr.getClass().setActorHealth(ptr, stats.getHealth().getCurrent() - fSuffocationDamage*duration); 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()) if(ptr == world->getPlayerPtr())
{ MWBase::Environment::get().getWindowManager()->activateHitOverlay(false);
MWBase::SoundManager *sndmgr = MWBase::Environment::get().getSoundManager();
if(!sndmgr->getSoundPlaying(MWWorld::Ptr(), "drown"))
sndmgr->playSound("drown", 1.0f, 1.0f);
}
} }
} }
else else

@ -2087,9 +2087,20 @@ namespace MWWorld
continue; continue;
MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor); MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
if (stats.isDead())
continue;
MWMechanics::DynamicStat<float> health = stats.getHealth(); MWMechanics::DynamicStat<float> health = stats.getHealth();
health.setCurrent(health.getCurrent()-healthPerSecond*MWBase::Environment::get().getFrameDuration()); health.setCurrent(health.getCurrent()-healthPerSecond*MWBase::Environment::get().getFrameDuration());
stats.setHealth(health); 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; continue;
MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor); MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
if (stats.isDead())
continue;
MWMechanics::DynamicStat<float> health = stats.getHealth(); MWMechanics::DynamicStat<float> health = stats.getHealth();
health.setCurrent(health.getCurrent()-healthPerSecond*MWBase::Environment::get().getFrameDuration()); health.setCurrent(health.getCurrent()-healthPerSecond*MWBase::Environment::get().getFrameDuration());
stats.setHealth(health); 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);
}
} }
} }

Loading…
Cancel
Save