#include "trainingwindow.hpp" #include #include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/dialoguemanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/esmstore.hpp" #include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" #include "tooltips.hpp" namespace { // Sorts a container descending by skill value. If skill value is equal, sorts ascending by skill ID. // pair bool sortSkills (const std::pair& left, const std::pair& right) { if (left == right) return false; if (left.second > right.second) return true; else if (left.second < right.second) return false; return left.first < right.first; } } namespace MWGui { TrainingWindow::TrainingWindow() : WindowBase("openmw_trainingwindow.layout") , mFadeTimeRemaining(0) , mTimeAdvancer(0.05f) { 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() { center(); } void TrainingWindow::exit() { MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Training); } void TrainingWindow::startTraining (MWWorld::Ptr actor) { mPtr = actor; MWWorld::Ptr player = MWMechanics::getPlayer(); int playerGold = player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId); mPlayerGold->setCaptionWithReplacing("#{sGold}: " + MyGUI::utility::toString(playerGold)); MWMechanics::NpcStats& npcStats = actor.getClass().getNpcStats (actor); // NPC can train you in his best 3 skills std::vector< std::pair > skills; for (int i=0; igetEnumerator (); MyGUI::Gui::getInstance ().destroyWidgets (widgets); MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats (player); const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); for (int i=0; i<3; ++i) { int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer (mPtr,pcStats.getSkill (skills[i].first).getBase() * gmst.find("iTrainingMod")->getInt (),true); MyGUI::Button* button = mTrainingOptions->createWidget(price <= playerGold ? "SandTextButton" : "SandTextButtonDisabled", // can't use setEnabled since that removes tooltip MyGUI::IntCoord(5, 5+i*18, mTrainingOptions->getWidth()-10, 18), MyGUI::Align::Default); button->setUserData(skills[i].first); button->eventMouseButtonClick += MyGUI::newDelegate(this, &TrainingWindow::onTrainingSelected); button->setCaptionWithReplacing("#{" + ESM::Skill::sSkillNameIds[skills[i].first] + "} - " + MyGUI::utility::toString(price)); button->setSize(button->getTextSize ().width+12, button->getSize().height); ToolTips::createSkillToolTip (button, skills[i].first); } center(); } void TrainingWindow::onReferenceUnavailable () { MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Training); } void TrainingWindow::onCancelButtonClicked (MyGUI::Widget *sender) { exit(); } void TrainingWindow::onTrainingSelected (MyGUI::Widget *sender) { int skillId = *sender->getUserData(); MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWMechanics::NpcStats& pcStats = player.getClass().getNpcStats (player); const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); int price = pcStats.getSkill (skillId).getBase() * store.get().find("iTrainingMod")->getInt (); price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr,price,true); if (price > player.getClass().getContainerStore(player).count(MWWorld::ContainerStore::sGoldId)) return; MWMechanics::NpcStats& npcStats = mPtr.getClass().getNpcStats (mPtr); if (npcStats.getSkill (skillId).getBase () <= pcStats.getSkill (skillId).getBase ()) { MWBase::Environment::get().getWindowManager()->messageBox ("#{sServiceTrainingWords}"); return; } // You can not train a skill above its governing attribute const ESM::Skill* skill = MWBase::Environment::get().getWorld()->getStore().get().find(skillId); if (pcStats.getSkill(skillId).getBase() >= pcStats.getAttribute(skill->mData.mAttribute).getBase()) { MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage17}"); return; } // increase skill MWWorld::LiveCellRef *playerRef = player.get(); const ESM::Class *class_ = store.get().find(playerRef->mBase->mClass); pcStats.increaseSkill (skillId, *class_, true); // remove gold player.getClass().getContainerStore(player).remove(MWWorld::ContainerStore::sGoldId, price, player); // add gold to NPC trading gold pool npcStats.setGoldPool(npcStats.getGoldPool() + price); // go back to game mode MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Training); MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); // advance time MWBase::Environment::get().getWorld ()->advanceTime (2); 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; mFadeTimeRemaining -= dt; if (mFadeTimeRemaining <= 0) MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.25); } }