From fe0cf5be05bba1037b9d1191c1bd7c59077b8492 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 6 Feb 2017 02:40:35 +0100 Subject: [PATCH] StatsWindow: don't rebuild all skill widgets when one skill changes --- apps/openmw/mwgui/statswindow.cpp | 70 +++++++++++++------ apps/openmw/mwgui/statswindow.hpp | 4 +- .../mwmechanics/mechanicsmanagerimp.cpp | 6 -- 3 files changed, 49 insertions(+), 31 deletions(-) diff --git a/apps/openmw/mwgui/statswindow.cpp b/apps/openmw/mwgui/statswindow.cpp index 6c9fd0f52..cee015da0 100644 --- a/apps/openmw/mwgui/statswindow.cpp +++ b/apps/openmw/mwgui/statswindow.cpp @@ -68,12 +68,14 @@ namespace MWGui for (int i = 0; i < ESM::Skill::Length; ++i) { - mSkillValues.insert(std::pair(i, MWMechanics::SkillValue())); - mSkillWidgetMap.insert(std::pair(i, (MyGUI::TextBox*)NULL)); + mSkillValues.insert(std::make_pair(i, MWMechanics::SkillValue())); + mSkillWidgetMap.insert(std::make_pair(i, std::make_pair((MyGUI::TextBox*)NULL, (MyGUI::TextBox*)NULL))); } MyGUI::Window* t = mMainWidget->castType(); t->eventWindowChangeCoord += MyGUI::newDelegate(this, &StatsWindow::onWindowResize); + + onWindowResize(t); } void StatsWindow::onMouseWheel(MyGUI::Widget* _sender, int _rel) @@ -188,11 +190,32 @@ namespace MWGui } } + void setSkillProgress(MyGUI::Widget* w, float progress, int skillId) + { + MWWorld::Ptr player = MWMechanics::getPlayer(); + const MWWorld::ESMStore &esmStore = + MWBase::Environment::get().getWorld()->getStore(); + + float progressRequirement = player.getClass().getNpcStats(player).getSkillProgressRequirement(skillId, + *esmStore.get().find(player.get()->mBase->mClass)); + + // This is how vanilla MW displays the progress bar (I think). Note it's slightly inaccurate, + // due to the int casting in the skill levelup logic. Also the progress label could in rare cases + // reach 100% without the skill levelling up. + // Leaving the original display logic for now, for consistency with ess-imported savegames. + int progressPercent = int(float(progress) / float(progressRequirement) * 100.f + 0.5f); + + w->setUserString("Caption_SkillProgressText", MyGUI::utility::toString(progressPercent)+"/100"); + w->setUserString("RangePosition_SkillProgress", MyGUI::utility::toString(progressPercent)); + } + void StatsWindow::setValue(const ESM::Skill::SkillEnum parSkill, const MWMechanics::SkillValue& value) { mSkillValues[parSkill] = value; - MyGUI::TextBox* widget = mSkillWidgetMap[(int)parSkill]; - if (widget) + std::pair widgets = mSkillWidgetMap[(int)parSkill]; + MyGUI::TextBox* valueWidget = widgets.second; + MyGUI::TextBox* nameWidget = widgets.first; + if (valueWidget && nameWidget) { int modified = value.getModified(), base = value.getBase(); std::string text = MyGUI::utility::toString(modified); @@ -202,8 +225,20 @@ namespace MWGui else if (modified < base) state = "decreased"; - widget->setCaption(text); - widget->_setWidgetState(state); + int widthBefore = valueWidget->getTextSize().width; + + valueWidget->setCaption(text); + valueWidget->_setWidgetState(state); + + int widthAfter = valueWidget->getTextSize().width; + if (widthBefore != widthAfter) + { + valueWidget->setCoord(valueWidget->getLeft() - (widthAfter-widthBefore), valueWidget->getTop(), valueWidget->getWidth() + (widthAfter-widthBefore), valueWidget->getHeight()); + nameWidget->setSize(nameWidget->getWidth() - (widthAfter-widthBefore), nameWidget->getHeight()); + } + + if (value.getBase() < 100) + setSkillProgress(valueWidget, value.getProgress(), parSkill); } } @@ -316,7 +351,7 @@ namespace MWGui coord2.top += sLineHeight; } - MyGUI::TextBox* StatsWindow::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) + std::pair StatsWindow::addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) { MyGUI::TextBox *skillNameWidget, *skillValueWidget; @@ -340,7 +375,7 @@ namespace MWGui coord1.top += sLineHeight; coord2.top += sLineHeight; - return skillValueWidget; + return std::make_pair(skillNameWidget, skillValueWidget); } MyGUI::Widget* StatsWindow::addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2) @@ -384,19 +419,9 @@ namespace MWGui int base = stat.getBase(); int modified = stat.getModified(); - MWWorld::Ptr player = MWMechanics::getPlayer(); const MWWorld::ESMStore &esmStore = MWBase::Environment::get().getWorld()->getStore(); - float progressRequirement = player.getClass().getNpcStats(player).getSkillProgressRequirement(skillId, - *esmStore.get().find(player.get()->mBase->mClass)); - - // This is how vanilla MW displays the progress bar (I think). Note it's slightly inaccurate, - // due to the int casting in the skill levelup logic. Also the progress label could in rare cases - // reach 100% without the skill levelling up. - // Leaving the original display logic for now, for consistency with ess-imported savegames. - int progressPercent = int(float(stat.getProgress()) / float(progressRequirement) * 100.f + 0.5f); - const ESM::Skill* skill = esmStore.get().find(skillId); std::string icon = "icons\\k\\" + ESM::Skill::sIconNames[skillId]; @@ -409,7 +434,7 @@ namespace MWGui state = "increased"; else if (modified < base) state = "decreased"; - MyGUI::TextBox* widget = addValueItem(MWBase::Environment::get().getWindowManager()->getGameSettingString(skillNameId, skillNameId), + std::pair widgets = addValueItem(MWBase::Environment::get().getWindowManager()->getGameSettingString(skillNameId, skillNameId), MyGUI::utility::toString(static_cast(modified)), state, coord1, coord2); for (int i=0; i<2; ++i) @@ -420,6 +445,7 @@ namespace MWGui mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_SkillDescription", skill->mDescription); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_SkillAttribute", "#{sGoverningAttribute}: #{" + attr->mName + "}"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("ImageTexture_SkillImage", icon); + mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Range_SkillProgress", "100"); if (base < 100) { mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Visible_SkillMaxed", "false"); @@ -428,9 +454,7 @@ namespace MWGui mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Visible_SkillProgressVBox", "true"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("UserData^Hidden_SkillProgressVBox", "false"); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Caption_SkillProgressText", MyGUI::utility::toString(progressPercent)+"/100"); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Range_SkillProgress", "100"); - mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("RangePosition_SkillProgress", MyGUI::utility::toString(progressPercent)); + setSkillProgress(mSkillWidgets[mSkillWidgets.size()-1-i], stat.getProgress(), skillId); } else { mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("Visible_SkillMaxed", "true"); mSkillWidgets[mSkillWidgets.size()-1-i]->setUserString("UserData^Hidden_SkillMaxed", "false"); @@ -440,7 +464,7 @@ namespace MWGui } } - mSkillWidgetMap[skillId] = widget; + mSkillWidgetMap[skillId] = widgets; } } diff --git a/apps/openmw/mwgui/statswindow.hpp b/apps/openmw/mwgui/statswindow.hpp index 2cf4ca819..1fe3cb68d 100644 --- a/apps/openmw/mwgui/statswindow.hpp +++ b/apps/openmw/mwgui/statswindow.hpp @@ -43,7 +43,7 @@ namespace MWGui void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); - MyGUI::TextBox* addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); + std::pair addValueItem(const std::string& text, const std::string &value, const std::string& state, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); MyGUI::Widget* addItem(const std::string& text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2); void setFactions (const FactionList& factions); @@ -62,7 +62,7 @@ namespace MWGui SkillList mMajorSkills, mMinorSkills, mMiscSkills; std::map mSkillValues; - std::map mSkillWidgetMap; + std::map > mSkillWidgetMap; std::map mFactionWidgetMap; FactionList mFactions; ///< Stores a list of factions and the current rank std::string mBirthSignId; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index e552f4683..ad1ca9bb9 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -338,22 +338,16 @@ namespace MWMechanics } } - bool update = false; - //Loop over ESM::Skill::SkillEnum for(int i = 0; i < ESM::Skill::Length; ++i) { if(stats.getSkill(i) != mWatchedSkills[i] || mWatchedStatsEmpty) { - update = true; mWatchedSkills[i] = stats.getSkill(i); winMgr->setValue((ESM::Skill::SkillEnum)i, stats.getSkill(i)); } } - if(update) - winMgr->updateSkillArea(); - winMgr->setValue("level", stats.getLevel()); mWatchedStatsEmpty = false;