1 #include <MyGUI_ScrollBar.h>
2 
3 #include <components/misc/rng.hpp>
4 
5 #include "../mwbase/windowmanager.hpp"
6 #include "../mwbase/mechanicsmanager.hpp"
7 #include "../mwbase/world.hpp"
8 #include "../mwbase/environment.hpp"
9 
10 #include "../mwmechanics/npcstats.hpp"
11 #include "../mwmechanics/actorutil.hpp"
12 
13 #include "../mwworld/esmstore.hpp"
14 #include "../mwworld/store.hpp"
15 #include "../mwworld/class.hpp"
16 
17 #include "jailscreen.hpp"
18 
19 namespace MWGui
20 {
JailScreen()21     JailScreen::JailScreen()
22         : WindowBase("openmw_jail_screen.layout"),
23           mDays(1),
24           mFadeTimeRemaining(0),
25           mTimeAdvancer(0.01f)
26     {
27         getWidget(mProgressBar, "ProgressBar");
28 
29         mTimeAdvancer.eventProgressChanged += MyGUI::newDelegate(this, &JailScreen::onJailProgressChanged);
30         mTimeAdvancer.eventFinished += MyGUI::newDelegate(this, &JailScreen::onJailFinished);
31 
32         center();
33     }
34 
goToJail(int days)35     void JailScreen::goToJail(int days)
36     {
37         mDays = days;
38 
39         MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.5);
40         mFadeTimeRemaining = 0.5;
41 
42         setVisible(false);
43         mProgressBar->setScrollRange(100+1);
44         mProgressBar->setScrollPosition(0);
45         mProgressBar->setTrackSize(0);
46     }
47 
onFrame(float dt)48     void JailScreen::onFrame(float dt)
49     {
50         mTimeAdvancer.onFrame(dt);
51 
52         if (mFadeTimeRemaining <= 0)
53             return;
54 
55         mFadeTimeRemaining -= dt;
56 
57         if (mFadeTimeRemaining <= 0)
58         {
59             MWWorld::Ptr player = MWMechanics::getPlayer();
60             MWBase::Environment::get().getWorld()->teleportToClosestMarker(player, "prisonmarker");
61             MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.f); // override fade-in caused by cell transition
62 
63             setVisible(true);
64             mTimeAdvancer.run(100);
65         }
66     }
67 
onJailProgressChanged(int cur,int)68     void JailScreen::onJailProgressChanged(int cur, int /*total*/)
69     {
70         mProgressBar->setScrollPosition(0);
71         mProgressBar->setTrackSize(static_cast<int>(cur / (float)(mProgressBar->getScrollRange()) * mProgressBar->getLineSize()));
72     }
73 
onJailFinished()74     void JailScreen::onJailFinished()
75     {
76         MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Jail);
77         MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.5);
78 
79         MWWorld::Ptr player = MWMechanics::getPlayer();
80 
81         MWBase::Environment::get().getMechanicsManager()->rest(mDays * 24, true);
82         MWBase::Environment::get().getWorld()->advanceTime(mDays * 24);
83 
84         // We should not worsen corprus when in prison
85         for (auto& spell : player.getClass().getCreatureStats(player).getCorprusSpells())
86         {
87             spell.second.mNextWorsening += mDays * 24;
88         }
89 
90         std::set<int> skills;
91         for (int day=0; day<mDays; ++day)
92         {
93             int skill = Misc::Rng::rollDice(ESM::Skill::Length);
94             skills.insert(skill);
95 
96             MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill);
97             if (skill == ESM::Skill::Security || skill == ESM::Skill::Sneak)
98                 value.setBase(std::min(100.f, value.getBase()+1));
99             else
100                 value.setBase(std::max(0.f, value.getBase()-1));
101         }
102 
103         const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
104 
105         std::string message;
106         if (mDays == 1)
107             message = gmst.find("sNotifyMessage42")->mValue.getString();
108         else
109             message = gmst.find("sNotifyMessage43")->mValue.getString();
110 
111         message = Misc::StringUtils::format(message, mDays);
112 
113         for (const int& skill : skills)
114         {
115             std::string skillName = gmst.find(ESM::Skill::sSkillNameIds[skill])->mValue.getString();
116             int skillValue = player.getClass().getNpcStats(player).getSkill(skill).getBase();
117             std::string skillMsg = gmst.find("sNotifyMessage44")->mValue.getString();
118             if (skill == ESM::Skill::Sneak || skill == ESM::Skill::Security)
119                 skillMsg = gmst.find("sNotifyMessage39")->mValue.getString();
120 
121             skillMsg = Misc::StringUtils::format(skillMsg, skillName, skillValue);
122             message += "\n" + skillMsg;
123         }
124 
125         std::vector<std::string> buttons;
126         buttons.emplace_back("#{sOk}");
127         MWBase::Environment::get().getWindowManager()->interactiveMessageBox(message, buttons);
128     }
129 }
130