Add training progress bar, implement jail screen, tweak wait dialog (Fixes #1714)

celladd
MiroslavR 10 years ago
parent 6c4920c58e
commit 1d9e973573

@ -41,7 +41,7 @@ add_openmw_dir (mwgui
itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
tradeitemmodel companionitemmodel pickpocketitemmodel controllers savegamedialog
recharge mode videowidget backgroundimage itemwidget screenfader debugwindow spellmodel spellview
draganddrop
draganddrop timeadvancer jailscreen
)
add_openmw_dir (mwdialogue

@ -63,6 +63,7 @@ namespace MWGui
class ContainerWindow;
class DialogueWindow;
class WindowModal;
class JailScreen;
enum ShowInDialogueMode {
ShowInDialogueMode_IfPossible,
@ -114,6 +115,8 @@ namespace MWBase
virtual void removeGuiMode (MWGui::GuiMode mode) = 0;
///< can be anywhere in the stack
virtual void goToJail(int days) = 0;
virtual void updatePlayer() = 0;
virtual MWGui::GuiMode getMode() const = 0;

@ -0,0 +1,136 @@
#include <MyGUI_RenderManager.h>
#include <MyGUI_ScrollBar.h>
#include <MyGUI_Gui.h>
#include <MyGUI_TextBox.h>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/store.hpp"
#include "../mwworld/class.hpp"
#include "jailscreen.hpp"
namespace MWGui
{
JailScreen::JailScreen()
: WindowBase("openmw_loading_screen.layout"),
mTimeAdvancer(0.0125),
mDays(1),
mFadeTimeRemaining(0)
{
getWidget(mLoadingText, "LoadingText");
getWidget(mProgressBar, "ProgressBar");
getWidget(mLoadingBox, "LoadingBox");
setVisible(false);
mTimeAdvancer.eventProgressChanged += MyGUI::newDelegate(this, &JailScreen::onJailProgressChanged);
mTimeAdvancer.eventFinished += MyGUI::newDelegate(this, &JailScreen::onJailFinished);
mLoadingText->setCaptionWithReplacing("#{sInPrisonTitle}");
center();
}
void JailScreen::goToJail(int days)
{
mDays = days;
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.5);
mFadeTimeRemaining = 0.5;
setVisible(false);
mProgressBar->setScrollRange(days*24+1);
mProgressBar->setScrollPosition(0);
mProgressBar->setTrackSize(0);
}
void JailScreen::onFrame(float dt)
{
mTimeAdvancer.onFrame(dt);
if (mFadeTimeRemaining <= 0)
return;
mFadeTimeRemaining -= dt;
if (mFadeTimeRemaining <= 0)
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
MWBase::Environment::get().getWorld()->teleportToClosestMarker(player, "prisonmarker");
setVisible(true);
mTimeAdvancer.run(mDays*24);
}
}
void JailScreen::onJailProgressChanged(int cur, int /*total*/)
{
mProgressBar->setScrollPosition(0);
mProgressBar->setTrackSize(cur / (float)(mProgressBar->getScrollRange()) * mProgressBar->getLineSize());
}
void JailScreen::onJailFinished()
{
MWBase::Environment::get().getWindowManager()->popGuiMode();
MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.5);
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
MWBase::Environment::get().getWorld()->advanceTime(mDays * 24);
for (int i=0; i<mDays*24; ++i)
MWBase::Environment::get().getMechanicsManager()->rest(true);
std::set<int> skills;
for (int day=0; day<mDays; ++day)
{
int skill = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * ESM::Skill::Length;
skills.insert(skill);
MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill);
if (skill == ESM::Skill::Security || skill == ESM::Skill::Sneak)
value.setBase(std::min(100, value.getBase()+1));
else
value.setBase(value.getBase()-1);
}
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
std::string message;
if (mDays == 1)
message = gmst.find("sNotifyMessage42")->getString();
else
message = gmst.find("sNotifyMessage43")->getString();
std::stringstream dayStr;
dayStr << mDays;
if (message.find("%d") != std::string::npos)
message.replace(message.find("%d"), 2, dayStr.str());
for (std::set<int>::iterator it = skills.begin(); it != skills.end(); ++it)
{
std::string skillName = gmst.find(ESM::Skill::sSkillNameIds[*it])->getString();
std::stringstream skillValue;
skillValue << player.getClass().getNpcStats(player).getSkill(*it).getBase();
std::string skillMsg = gmst.find("sNotifyMessage44")->getString();
if (*it == ESM::Skill::Sneak || *it == ESM::Skill::Security)
skillMsg = gmst.find("sNotifyMessage39")->getString();
if (skillMsg.find("%s") != std::string::npos)
skillMsg.replace(skillMsg.find("%s"), 2, skillName);
if (skillMsg.find("%d") != std::string::npos)
skillMsg.replace(skillMsg.find("%d"), 2, skillValue.str());
message += "\n" + skillMsg;
}
std::vector<std::string> buttons;
buttons.push_back("#{sOk}");
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons);
}
}

@ -0,0 +1,33 @@
#ifndef MWGUI_JAILSCREEN_H
#define MWGUI_JAILSCREEN_H
#include "windowbase.hpp"
#include "timeadvancer.hpp"
namespace MWGui
{
class JailScreen : public WindowBase
{
public:
JailScreen();
void goToJail(int days);
void onFrame(float dt);
private:
int mDays;
float mFadeTimeRemaining;
MyGUI::Widget* mLoadingBox;
MyGUI::TextBox* mLoadingText;
MyGUI::ScrollBar* mProgressBar;
void onJailProgressChanged(int cur, int total);
void onJailFinished();
TimeAdvancer mTimeAdvancer;
};
}
#endif

@ -46,6 +46,7 @@ namespace MWGui
GM_Loading,
GM_LoadingWallpaper,
GM_Jail,
GM_QuickKeysMenu
};

@ -0,0 +1,73 @@
#include "timeadvancer.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
namespace MWGui
{
TimeAdvancer::TimeAdvancer(float delay)
: mRunning(false),
mCurHour(0),
mHours(1),
mInterruptAt(-1),
mDelay(delay),
mRemainingTime(delay)
{
}
void TimeAdvancer::run(int hours, int interruptAt)
{
mHours = hours;
mCurHour = 0;
mInterruptAt = interruptAt;
mRemainingTime = mDelay;
mRunning = true;
}
void TimeAdvancer::stop()
{
mRunning = false;
}
void TimeAdvancer::onFrame(float dt)
{
if (!mRunning)
return;
if (mCurHour == mInterruptAt)
{
stop();
eventInterrupted();
return;
}
mRemainingTime -= dt;
while (mRemainingTime <= 0)
{
mRemainingTime += mDelay;
++mCurHour;
if (mCurHour <= mHours)
eventProgressChanged(mCurHour, mHours);
else
{
stop();
eventFinished();
return;
}
}
}
int TimeAdvancer::getHours()
{
return mHours;
}
bool TimeAdvancer::isRunning()
{
return mRunning;
}
}

@ -0,0 +1,40 @@
#ifndef MWGUI_TIMEADVANCER_H
#define MWGUI_TIMEADVANCER_H
#include <MyGUI_Widget.h>
namespace MWGui
{
class TimeAdvancer
{
public:
TimeAdvancer(float delay);
void run(int hours, int interruptAt=-1);
void stop();
void onFrame(float dt);
int getHours();
bool isRunning();
// signals
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
typedef MyGUI::delegates::CMultiDelegate2<int, int> EventHandle_IntInt;
EventHandle_IntInt eventProgressChanged;
EventHandle_Void eventInterrupted;
EventHandle_Void eventFinished;
private:
bool mRunning;
int mCurHour;
int mHours;
int mInterruptAt;
float mDelay;
float mRemainingTime;
};
}
#endif

@ -40,12 +40,18 @@ namespace MWGui
TrainingWindow::TrainingWindow()
: WindowBase("openmw_trainingwindow.layout")
, mFadeTimeRemaining(0)
, mTimeAdvancer(0.05)
{
getWidget(mTrainingOptions, "TrainingOptions");
getWidget(mCancelButton, "CancelButton");
getWidget(mPlayerGold, "PlayerGold");
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onCancelButtonClicked);
mTimeAdvancer.eventProgressChanged += MyGUI::newDelegate(this, &TrainingWindow::onTrainingProgressChanged);
mTimeAdvancer.eventFinished += MyGUI::newDelegate(this, &TrainingWindow::onTrainingFinished);
mProgressBar.setVisible(false);
}
void TrainingWindow::open()
@ -173,12 +179,28 @@ namespace MWGui
MWBase::Environment::get().getMechanicsManager()->rest(false);
MWBase::Environment::get().getMechanicsManager()->rest(false);
mProgressBar.setVisible(true);
mProgressBar.setProgress(0, 2);
mTimeAdvancer.run(2);
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.25);
mFadeTimeRemaining = 0.5;
}
void TrainingWindow::onTrainingProgressChanged(int cur, int total)
{
mProgressBar.setProgress(cur, total);
}
void TrainingWindow::onTrainingFinished()
{
mProgressBar.setVisible(false);
}
void TrainingWindow::onFrame(float dt)
{
mTimeAdvancer.onFrame(dt);
if (mFadeTimeRemaining <= 0)
return;

@ -3,6 +3,8 @@
#include "windowbase.hpp"
#include "referenceinterface.hpp"
#include "timeadvancer.hpp"
#include "waitdialog.hpp"
namespace MWGui
{
@ -26,11 +28,17 @@ namespace MWGui
void onCancelButtonClicked (MyGUI::Widget* sender);
void onTrainingSelected(MyGUI::Widget* sender);
void onTrainingProgressChanged(int cur, int total);
void onTrainingFinished();
MyGUI::Widget* mTrainingOptions;
MyGUI::Button* mCancelButton;
MyGUI::TextBox* mPlayerGold;
float mFadeTimeRemaining;
WaitDialogProgressBar mProgressBar;
TimeAdvancer mTimeAdvancer;
};
}

@ -49,12 +49,11 @@ namespace MWGui
WaitDialog::WaitDialog()
: WindowBase("openmw_wait_dialog.layout")
, mProgressBar()
, mWaiting(false)
, mTimeAdvancer(0.05)
, mSleeping(false)
, mHours(1)
, mRemainingTime(0.05)
, mCurHour(0)
, mManualHours(1)
, mFadeTimeRemaining(0)
, mInterruptAt(-1)
{
getWidget(mDateTimeText, "DateTimeText");
@ -70,6 +69,10 @@ namespace MWGui
mWaitButton->eventMouseButtonClick += MyGUI::newDelegate(this, &WaitDialog::onWaitButtonClicked);
mHourSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &WaitDialog::onHourSliderChangedPosition);
mTimeAdvancer.eventProgressChanged += MyGUI::newDelegate(this, &WaitDialog::onWaitingProgressChanged);
mTimeAdvancer.eventInterrupted += MyGUI::newDelegate(this, &WaitDialog::onWaitingInterrupted);
mTimeAdvancer.eventFinished += MyGUI::newDelegate(this, &WaitDialog::onWaitingFinished);
mProgressBar.setVisible (false);
}
@ -133,11 +136,9 @@ namespace MWGui
MWBase::World* world = MWBase::Environment::get().getWorld();
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.2);
mFadeTimeRemaining = 0.4;
setVisible(false);
mProgressBar.setVisible (true);
mWaiting = true;
mCurHour = 0;
mHours = hoursToWait;
// FIXME: move this somewhere else?
@ -164,8 +165,7 @@ namespace MWGui
}
}
mRemainingTime = 0.05;
mProgressBar.setProgress (0, mHours);
mProgressBar.setProgress (0, hoursToWait);
}
void WaitDialog::onCancelButtonClicked(MyGUI::Widget* sender)
@ -179,6 +179,36 @@ namespace MWGui
mManualHours = position+1;
}
void WaitDialog::onWaitingProgressChanged(int cur, int total)
{
mProgressBar.setProgress(cur, total);
MWBase::Environment::get().getWorld()->advanceTime(1);
MWBase::Environment::get().getMechanicsManager()->rest(mSleeping);
}
void WaitDialog::onWaitingInterrupted()
{
MWBase::Environment::get().getWindowManager()->messageBox("#{sSleepInterrupt}");
MWBase::Environment::get().getWorld()->spawnRandomCreature(mInterruptCreatureList);
stopWaiting();
}
void WaitDialog::onWaitingFinished()
{
stopWaiting();
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
const MWMechanics::NpcStats &pcstats = player.getClass().getNpcStats(player);
// trigger levelup if possible
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
if (mSleeping && pcstats.getLevelProgress () >= gmst.find("iLevelUpTotal")->getInt())
{
MWBase::Environment::get().getWindowManager()->pushGuiMode (GM_Levelup);
}
}
void WaitDialog::setCanRest (bool canRest)
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
@ -205,45 +235,17 @@ namespace MWGui
void WaitDialog::onFrame(float dt)
{
if (!mWaiting)
return;
mTimeAdvancer.onFrame(dt);
if (mCurHour == mInterruptAt)
{
MWBase::Environment::get().getWindowManager()->messageBox("#{sSleepInterrupt}");
MWBase::Environment::get().getWorld()->spawnRandomCreature(mInterruptCreatureList);
stopWaiting();
}
if (mFadeTimeRemaining <= 0)
return;
mRemainingTime -= dt;
mFadeTimeRemaining -= dt;
while (mRemainingTime < 0)
if (mFadeTimeRemaining <= 0)
{
mRemainingTime += 0.05;
++mCurHour;
mProgressBar.setProgress (mCurHour, mHours);
if (mCurHour <= mHours)
{
MWBase::Environment::get().getWorld ()->advanceTime (1);
MWBase::Environment::get().getMechanicsManager ()->rest (mSleeping);
}
}
if (mCurHour > mHours)
{
stopWaiting();
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
const MWMechanics::NpcStats &pcstats = player.getClass().getNpcStats(player);
// trigger levelup if possible
const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
if (mSleeping && pcstats.getLevelProgress () >= gmst.find("iLevelUpTotal")->getInt())
{
MWBase::Environment::get().getWindowManager()->pushGuiMode (GM_Levelup);
}
mProgressBar.setVisible(true);
mTimeAdvancer.run(mHours, mInterruptAt);
}
}
@ -253,14 +255,14 @@ namespace MWGui
mProgressBar.setVisible (false);
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Rest);
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_RestBed);
mWaiting = false;
mTimeAdvancer.stop();
}
void WaitDialog::wakeUp ()
{
mSleeping = false;
mWaiting = false;
mTimeAdvancer.stop();
stopWaiting();
}

@ -1,6 +1,8 @@
#ifndef MWGUI_WAIT_DIALOG_H
#define MWGUI_WAIT_DIALOG_H
#include "timeadvancer.hpp"
#include "windowbase.hpp"
namespace MWGui
@ -38,7 +40,7 @@ namespace MWGui
void bedActivated() { setCanRest(true); }
bool getSleeping() { return mWaiting && mSleeping; }
bool getSleeping() { return mTimeAdvancer.isRunning() && mSleeping; }
void wakeUp();
void autosave();
@ -51,12 +53,11 @@ namespace MWGui
MyGUI::Button* mCancelButton;
MWGui::Widgets::MWScrollBar* mHourSlider;
bool mWaiting;
TimeAdvancer mTimeAdvancer;
bool mSleeping;
int mCurHour;
int mHours;
int mManualHours; // stores the hours to rest selected via slider
float mRemainingTime;
float mFadeTimeRemaining;
int mInterruptAt;
std::string mInterruptCreatureList;
@ -68,6 +69,10 @@ namespace MWGui
void onCancelButtonClicked(MyGUI::Widget* sender);
void onHourSliderChangedPosition(MyGUI::ScrollBar* sender, size_t position);
void onWaitingProgressChanged(int cur, int total);
void onWaitingInterrupted();
void onWaitingFinished();
void setCanRest(bool canRest);
void startWaiting(int hoursToWait);

@ -91,6 +91,7 @@
#include "draganddrop.hpp"
#include "container.hpp"
#include "controllers.hpp"
#include "jailscreen.hpp"
namespace MWGui
{
@ -143,6 +144,7 @@ namespace MWGui
, mHitFader(NULL)
, mScreenFader(NULL)
, mDebugWindow(NULL)
, mJailScreen(NULL)
, mTranslationDataStorage (translationDataStorage)
, mCharGen(NULL)
, mInputBlocker(NULL)
@ -290,6 +292,7 @@ namespace MWGui
mSoulgemDialog = new SoulgemDialog(mMessageBoxManager);
mCompanionWindow = new CompanionWindow(mDragAndDrop, mMessageBoxManager);
trackWindow(mCompanionWindow, "companion");
mJailScreen = new JailScreen();
mWerewolfFader = new ScreenFader("textures\\werewolfoverlay.dds");
mBlindnessFader = new ScreenFader("black.png");
@ -402,6 +405,7 @@ namespace MWGui
delete mScreenFader;
delete mBlindnessFader;
delete mDebugWindow;
delete mJailScreen;
delete mCursorManager;
@ -467,6 +471,7 @@ namespace MWGui
mInventoryWindow->setTrading(false);
mRecharge->setVisible(false);
mVideoBackground->setVisible(false);
mJailScreen->setVisible(false);
mHud->setVisible(mHudEnabled && mGuiEnabled);
mToolTips->setVisible(mGuiEnabled);
@ -612,6 +617,9 @@ namespace MWGui
case GM_Journal:
mJournal->setVisible(true);
break;
case GM_Jail:
mJailScreen->setVisible(true);
break;
case GM_LoadingWallpaper:
case GM_Loading:
// Don't need to show anything here - GM_LoadingWallpaper covers everything else anyway,
@ -912,6 +920,7 @@ namespace MWGui
mCompanionWindow->checkReferenceAvailable();
mConsole->checkReferenceAvailable();
mCompanionWindow->onFrame();
mJailScreen->onFrame(frameDuration);
mWerewolfFader->update(frameDuration);
mBlindnessFader->update(frameDuration);
@ -1187,6 +1196,12 @@ namespace MWGui
updateVisible();
}
void WindowManager::goToJail(int days)
{
pushGuiMode(MWGui::GM_Jail);
mJailScreen->goToJail(days);
}
void WindowManager::setSelectedSpell(const std::string& spellId, int successChancePercent)
{
mSelectedSpell = spellId;

@ -90,6 +90,7 @@ namespace MWGui
class WindowModal;
class ScreenFader;
class DebugWindow;
class JailScreen;
class WindowManager : public MWBase::WindowManager
{
@ -128,6 +129,8 @@ namespace MWGui
virtual void popGuiMode();
virtual void removeGuiMode(GuiMode mode); ///< can be anywhere in the stack
virtual void goToJail(int days);
virtual GuiMode getMode() const;
virtual bool containsMode(GuiMode mode) const;
@ -404,6 +407,7 @@ namespace MWGui
ScreenFader* mHitFader;
ScreenFader* mScreenFader;
DebugWindow* mDebugWindow;
JailScreen* mJailScreen;
Translation::Storage& mTranslationDataStorage;

@ -1008,7 +1008,7 @@ namespace MWScript
virtual void execute (Interpreter::Runtime &runtime)
{
/// \todo implement jail check
runtime.push (0);
runtime.push (MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Jail);
}
};

@ -3019,59 +3019,7 @@ namespace MWWorld
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue);
MWWorld::Ptr player = getPlayerPtr();
teleportToClosestMarker(player, "prisonmarker");
int days = mDaysInPrison;
advanceTime(days * 24);
for (int i=0; i<days*24; ++i)
MWBase::Environment::get().getMechanicsManager ()->rest (true);
std::set<int> skills;
for (int day=0; day<days; ++day)
{
int skill = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * ESM::Skill::Length;
skills.insert(skill);
MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill);
if (skill == ESM::Skill::Security || skill == ESM::Skill::Sneak)
value.setBase(std::min(100, value.getBase()+1));
else
value.setBase(value.getBase()-1);
}
const Store<ESM::GameSetting>& gmst = getStore().get<ESM::GameSetting>();
std::string message;
if (days == 1)
message = gmst.find("sNotifyMessage42")->getString();
else
message = gmst.find("sNotifyMessage43")->getString();
std::stringstream dayStr;
dayStr << days;
if (message.find("%d") != std::string::npos)
message.replace(message.find("%d"), 2, dayStr.str());
for (std::set<int>::iterator it = skills.begin(); it != skills.end(); ++it)
{
std::string skillName = gmst.find(ESM::Skill::sSkillNameIds[*it])->getString();
std::stringstream skillValue;
skillValue << player.getClass().getNpcStats(player).getSkill(*it).getBase();
std::string skillMsg = gmst.find("sNotifyMessage44")->getString();
if (*it == ESM::Skill::Sneak || *it == ESM::Skill::Security)
skillMsg = gmst.find("sNotifyMessage39")->getString();
if (skillMsg.find("%s") != std::string::npos)
skillMsg.replace(skillMsg.find("%s"), 2, skillName);
if (skillMsg.find("%d") != std::string::npos)
skillMsg.replace(skillMsg.find("%d"), 2, skillValue.str());
message += "\n" + skillMsg;
}
std::vector<std::string> buttons;
buttons.push_back("#{sOk}");
MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons);
MWBase::Environment::get().getWindowManager()->goToJail(mDaysInPrison);
}
}

Loading…
Cancel
Save