Feature #1697: Queue fade operations, implement hit fader & werewolf overlay

deque
MiroslavR 10 years ago
parent cd7cc4bec9
commit de2cb8926a

@ -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;
};
}

@ -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
{

@ -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;
}
}

@ -1,15 +1,42 @@
#ifndef OPENMW_MWGUI_SCREENFADER_H
#define OPENMW_MWGUI_SCREENFADER_H
#include <deque>
#include <boost/shared_ptr.hpp>
#include "windowbase.hpp"
namespace MWGui
{
class ScreenFader;
class FadeOp
{
public:
typedef boost::shared_ptr<FadeOp> 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<FadeOp::Ptr> mQueue;
};
}
#endif

@ -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<MyGUI::Widget>("",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")

@ -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;

@ -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<MWWorld::Ptr> closeActors;
MWBase::Environment::get().getMechanicsManager()->getActorsInRange(Ogre::Vector3(actor.getRefData().getPosition().pos),

@ -41,6 +41,9 @@ tooltip delay = 0
subtitles = false
hit fader = true
werewolf overlay = true
[General]
# Camera field of view
field of view = 55

Loading…
Cancel
Save