Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion include/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ namespace Qounters::Utils {
std::tuple<std::string, std::string, int> GetBeatmapDetails(GlobalNamespace::BeatmapKey beatmap);
std::string GetBeatmapIdentifier(GlobalNamespace::BeatmapKey beatmap);
std::vector<std::string> GetSimplifiedRequirements(GlobalNamespace::BeatmapKey beatmap);
std::string FormatNumber(int value, int separator);
double GetScoreRatio(bool includeModifiers = true, int saber = (int) Types::Sabers::Both);
double GetBestScoreRatio();

template <class U, class T>
U* ptr_cast(T* inst) {
Expand Down Expand Up @@ -46,4 +49,4 @@ namespace Qounters::Utils {
void RebuildWithScrollPosition(UnityEngine::GameObject* scrollView);

UnityEngine::RectTransform* GetScrollViewTop(UnityEngine::GameObject* scrollView);
}
}
1 change: 1 addition & 0 deletions shared/options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace Qounters::Options {
extern std::vector<std::string_view> const FillStrings;
extern std::vector<std::string_view> const TypeStrings;
extern std::vector<std::string_view> const AnchorStrings;
extern std::vector<std::string_view> const SeparatorStrings;
extern std::vector<std::string_view> const BaseGameObjectStrings;

DECLARE_JSON_STRUCT(Gradient) {
Expand Down
9 changes: 9 additions & 0 deletions shared/sources.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ namespace Qounters::Sources {
}

extern std::vector<std::string_view> const AverageCutPartStrings;
extern std::vector<std::string_view> const PBDisplayStrings;
extern std::vector<std::string_view> const NotesDisplayStrings;
extern std::vector<std::string_view> const PPLeaderboardStrings;
extern std::vector<std::string_view> const SaberSpeedModeStrings;
Expand Down Expand Up @@ -89,17 +90,25 @@ namespace Qounters::Sources {
VALUE_DEFAULT(int, Saber, (int) Types::Sabers::Both);
VALUE_DEFAULT(int, Decimals, 1);
VALUE_DEFAULT(bool, Percentage, true);
VALUE_DEFAULT(int, Separator, (int) Types::Separators::Gap);
};
DECLARE_JSON_STRUCT(Rank) {
VALUE_DEFAULT(int, Saber, (int) Types::Sabers::Both);
VALUE_DEFAULT(bool, PositiveModifiers, false);
VALUE_DEFAULT(bool, NegativeModifiers, true);
};
DECLARE_JSON_STRUCT(PersonalBest) {
enum class Displays {
PersonalBest,
PBGap,
};
VALUE_DEFAULT(int, Decimals, 1);
VALUE_DEFAULT(bool, Percentage, true);
VALUE_DEFAULT(bool, HideFirstScore, true);
VALUE_DEFAULT(bool, Label, true);
VALUE_DEFAULT(int, Separator, (int) Types::Separators::None);
VALUE_DEFAULT(int, Display, (int) Displays::PersonalBest);
VALUE_DEFAULT(bool, Sign, true);
};
DECLARE_JSON_STRUCT(Combo) {
VALUE_DEFAULT(int, Saber, (int) Types::Sabers::Both);
Expand Down
7 changes: 7 additions & 0 deletions shared/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ namespace Qounters::Types {
Enable,
};

enum class Separators {
None,
Gap,
Comma,
Period,
};

template <class T>
using SourceFn = std::function<T(UnparsedJSON)>;
using SourceUIFn = std::function<void(UnityEngine::GameObject*, UnparsedJSON)>;
Expand Down
6 changes: 6 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ std::vector<std::string_view> const Options::AnchorStrings = {
"Bottom",
"Center",
};
std::vector<std::string_view> const Options::SeparatorStrings = {
"None",
"Gap",
"Comma",
"Period",
};
std::vector<std::string_view> const Options::BaseGameObjectStrings = {
"Multiplier Ring", "Song Time Panel",
// "Health Bar",
Expand Down
1 change: 1 addition & 0 deletions src/events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ static std::map<int, std::vector<std::pair<Types::Sources, std::string>>> eventS
{Types::Sources::Shape, Sources::Shape::ScoreName},
{Types::Sources::Color, Sources::Color::RankName},
{Types::Sources::Color, Sources::Color::PersonalBestName},
{Types::Sources::Text, Sources::Text::PersonalBestName},
{Types::Sources::Enable, Sources::Enable::PercentageName},
}},
{(int) MetaCore::Events::NoteCut,
Expand Down
85 changes: 45 additions & 40 deletions src/sources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ Sources::PremadeInfo* Sources::GetPremadeInfo(std::string const& mod, std::strin
}
return nullptr;
}
std::vector<std::string_view> const Sources::PBDisplayStrings = {
"Best Score",
"PB Gap",

};
std::vector<std::string_view> const Sources::AverageCutPartStrings = {
"Preswing",
"Postswing",
Expand Down Expand Up @@ -183,21 +187,13 @@ std::string Sources::Text::GetScore(UnparsedJSON unparsed) {

int score = Stats::GetScore(opts.Saber);
if (opts.Percentage) {
int max = Stats::GetMaxScore(opts.Saber);
double ratio = max > 0 ? score / (double) max : 1;
double ratio = Utils::GetScoreRatio(false, opts.Saber);
ratio *= 100;
return Strings::FormatDecimals(ratio, opts.Decimals) + "%";
} else {
// spaces between every three digits, and pad zeroes if below 100
auto number = fmt::format("{:03}", score);
if (score < 1000)
return number;
size_t len = number.size();
for (int i = 1; i <= (len - 1) / 3; i++) {
size_t split = len - 3 * i;
number = number.substr(0, split) + " " + number.substr(split);
}
return number;
return fmt::format("{:03}", score);
return Utils::FormatNumber(score, opts.Separator);
}
}
std::string Sources::Text::GetRank(UnparsedJSON unparsed) {
Expand Down Expand Up @@ -235,26 +231,47 @@ std::string Sources::Text::GetRank(UnparsedJSON unparsed) {
}
std::string Sources::Text::GetPersonalBest(UnparsedJSON unparsed) {
auto opts = unparsed.Parse<PersonalBest>();

bool pbGap = opts.Display == (int) PersonalBest::Displays::PBGap;
int best = Stats::GetBestScore();
if (best == -1) {
if (opts.HideFirstScore)
if (opts.HideFirstScore && !pbGap)
return opts.Label ? "PB: --" : "--";
else
best = 0;
}
int max = Stats::GetSongMaxScore();
int songMax = Stats::GetSongMaxScore();
std::string text;
if (opts.Percentage) {
double ratio;
if (Environment::InSettings())
ratio = Playtest::GetOverridePBRatio();
else
ratio = max > 0 ? best / (Stats::GetModifierMultiplier(true, true) * max) : 1;
text = Strings::FormatDecimals(ratio * 100, opts.Decimals) + "%";
} else
text = Environment::InSettings() && max == 1 ? "0" : std::to_string(best);
return opts.Label ? "PB: " + text : text;
int maxScore = Stats::GetMaxScore((int) Types::Sabers::Both);
double ratio = Utils::GetScoreRatio();
double bestRatio;
if (Environment::InSettings())
bestRatio = Playtest::GetOverridePBRatio();
else
bestRatio = songMax > 0 ? (!pbGap ? (double) best / (Stats::GetModifierMultiplier(true, true) * songMax) : Utils::GetBestScoreRatio()) : 1;
if (pbGap) {
if (opts.Percentage) {
double percentDiff = (maxScore > 0) ? ((ratio - bestRatio) * 100.0) : 0.0;
if (opts.Sign) {
text = (percentDiff >= 0 ? "+" : "") + Strings::FormatDecimals(percentDiff, opts.Decimals) + "%";
} else {
text = Strings::FormatDecimals(std::abs(percentDiff), opts.Decimals) + "%";
}
} else {
int difference = static_cast<int>(std::round((ratio - bestRatio) * maxScore));
if (opts.Sign) {
text = (difference >= 0 ? "+" : "") + Utils::FormatNumber(difference, opts.Separator);
} else {
text = Utils::FormatNumber(std::abs(difference), opts.Separator);
}
}
} else {
if (opts.Percentage) {
text = Strings::FormatDecimals(bestRatio * 100, opts.Decimals) + "%";
} else {
text = Environment::InSettings() && songMax == 1 ? "0" : Utils::FormatNumber(best, opts.Separator);
}
}
return opts.Label ? (pbGap ? "PB Gap: " : "PB: ") + text : text;
}
std::string Sources::Text::GetCombo(UnparsedJSON unparsed) {
auto opts = unparsed.Parse<Combo>();
Expand Down Expand Up @@ -387,9 +404,7 @@ float Sources::Shape::GetStatic(UnparsedJSON unparsed) {
float Sources::Shape::GetScore(UnparsedJSON unparsed) {
auto opts = unparsed.Parse<Score>();

int score = Stats::GetScore(opts.Saber);
int max = Stats::GetMaxScore(opts.Saber);
return max > 0 ? score / (double) max : 1;
return Utils::GetScoreRatio(false, opts.Saber);
}
float Sources::Shape::GetMultiplier(UnparsedJSON unparsed) {
auto opts = unparsed.Parse<Multiplier>();
Expand Down Expand Up @@ -471,15 +486,8 @@ UnityEngine::Color Sources::Color::GetRank(UnparsedJSON unparsed) {
}
UnityEngine::Color Sources::Color::GetPersonalBest(UnparsedJSON unparsed) {
auto opts = unparsed.Parse<PersonalBest>();

double best = Stats::GetBestScore();
int songMax = Stats::GetSongMaxScore();
double current = Stats::GetScore((int) Types::Sabers::Both);
// PB modifiers would be applied to best score
current *= Stats::GetModifierMultiplier(true, true);
int max = Stats::GetMaxScore((int) Types::Sabers::Both);
double bestRatio = songMax > 0 ? best / songMax : 1;
double ratio = max > 0 ? current / max : 1;
double bestRatio = Utils::GetBestScoreRatio();
double ratio = Utils::GetScoreRatio();

return ratio >= bestRatio ? opts.Better : opts.Worse;
}
Expand Down Expand Up @@ -530,10 +538,7 @@ bool Sources::Enable::GetFullCombo(UnparsedJSON unparsed) {
}
bool Sources::Enable::GetPercentage(UnparsedJSON unparsed) {
auto opts = unparsed.Parse<Percentage>();

int score = Stats::GetScore(opts.Saber);
int max = Stats::GetMaxScore(opts.Saber);
float percent = max > 0 ? score / (double) max : 1;
float percent = Utils::GetScoreRatio(false, opts.Saber);
return percent * 100 >= opts.Percent;
}
bool Sources::Enable::GetFailed(UnparsedJSON unparsed) {
Expand Down
Loading
Loading