diff --git a/CHANGELOG.md b/CHANGELOG.md index 36ea55a65c..421d01ebcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -168,6 +168,7 @@ Feature #5036: Allow scripted faction leaving Feature #5046: Gamepad thumbstick cursor speed Feature #5051: Provide a separate textures for scrollbars + Feature #5091: Human-readable light source duration Feature #5094: Unix like console hotkeys Feature #5098: Allow user controller bindings Feature #5121: Handle NiTriStrips and NiTriStripsData diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 36440076bf..f31df3aed2 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -156,13 +156,9 @@ namespace MWClass std::string text; - if (Settings::Manager::getBool("show effect duration","Game")) - { - // -1 is infinite light source, so duration makes no sense here. Other negative values are treated as 0. - float remainingTime = ptr.getClass().getRemainingUsageTime(ptr); - if (remainingTime != -1.0f) - text += "\n#{sDuration}: " + MWGui::ToolTips::toString(std::max(0.f, remainingTime)); - } + // Don't show duration for infinite light sources. + if (Settings::Manager::getBool("show effect duration","Game") && ptr.getClass().getRemainingUsageTime(ptr) != -1) + text += MWGui::ToolTips::getDurationString(ptr.getClass().getRemainingUsageTime(ptr), "\n#{sDuration}"); text += MWGui::ToolTips::getWeightString(ref->mBase->mData.mWeight, "#{sWeight}"); text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 51508cd06b..8a501e5989 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -137,27 +137,8 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", "") ); } } - if (effectInfo.mRemainingTime > -1 && - Settings::Manager::getBool("show effect duration","Game")) { - sourcesDescription += " #{sDuration}: "; - float duration = effectInfo.mRemainingTime; - if (duration > 3600) - { - int hour = duration / 3600; - duration -= hour*3600; - sourcesDescription += MWGui::ToolTips::toString(hour) + "h"; - } - if (duration > 60) - { - int minute = duration / 60; - duration -= minute*60; - sourcesDescription += MWGui::ToolTips::toString(minute) + "m"; - } - if (duration > 0.1) - { - sourcesDescription += MWGui::ToolTips::toString(duration) + "s"; - } - } + if (effectInfo.mRemainingTime > -1 && Settings::Manager::getBool("show effect duration","Game")) + sourcesDescription += MWGui::ToolTips::getDurationString(effectInfo.mRemainingTime, " #{sDuration}"); addNewLine = true; } diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index dc7a9668d1..7d8a07c219 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -667,6 +667,60 @@ namespace MWGui return ret; } + std::string ToolTips::getDurationString(float duration, const std::string& prefix) + { + std::string ret; + ret = prefix + ": "; + + if (duration < 1.f) + { + ret += "0 s"; + return ret; + } + + constexpr int secondsPerMinute = 60; // 60 seconds + constexpr int secondsPerHour = secondsPerMinute * 60; // 60 minutes + constexpr int secondsPerDay = secondsPerHour * 24; // 24 hours + constexpr int secondsPerMonth = secondsPerDay * 30; // 30 days + constexpr int secondsPerYear = secondsPerDay * 365; + int fullDuration = static_cast(duration); + int units = 0; + int years = fullDuration / secondsPerYear; + int months = fullDuration % secondsPerYear / secondsPerMonth; + int days = fullDuration % secondsPerYear % secondsPerMonth / secondsPerDay; // Because a year is not exactly 12 "months" + int hours = fullDuration % secondsPerDay / secondsPerHour; + int minutes = fullDuration % secondsPerHour / secondsPerMinute; + int seconds = fullDuration % secondsPerMinute; + if (years) + { + units++; + ret += toString(years) + " y "; + } + if (months) + { + units++; + ret += toString(months) + " mo "; + } + if (units < 2 && days) + { + units++; + ret += toString(days) + " d "; + } + if (units < 2 && hours) + { + units++; + ret += toString(hours) + " h "; + } + if (units >= 2) + return ret; + if (minutes) + ret += toString(minutes) + " min "; + if (seconds) + ret += toString(seconds) + " s "; + + return ret; + } + bool ToolTips::toggleFullHelp() { mFullHelp = !mFullHelp; diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp index 43187dc5c8..afdc7dec0a 100644 --- a/apps/openmw/mwgui/tooltips.hpp +++ b/apps/openmw/mwgui/tooltips.hpp @@ -84,6 +84,9 @@ namespace MWGui static std::string getCellRefString(const MWWorld::CellRef& cellref); ///< Returns a string containing debug tooltip information about the given cellref. + static std::string getDurationString (float duration, const std::string& prefix); + ///< Returns duration as two largest time units, rounded down. Note: not localized; no line break. + // these do not create an actual tooltip, but they fill in the data that is required so the tooltip // system knows what to show in case this widget is hovered static void createSkillToolTip(MyGUI::Widget* widget, int skillId);