Skip to content

Commit

Permalink
Merge pull request #26140 from CaffeeLake/multiplier1x
Browse files Browse the repository at this point in the history
Fix mod score multiplier rounding to 1.00x with specific mod combinations
  • Loading branch information
peppy authored Jan 4, 2024
2 parents 085f5ac + fc1a2c5 commit 35b9940
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 7 deletions.
30 changes: 30 additions & 0 deletions osu.Game.Tests/Mods/ModUtilsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,26 @@ public void TestInvalidFreeModScenarios(Mod[] inputMods, Type[] expectedInvalid)
Assert.That(invalid?.Select(t => t.GetType()), Is.EquivalentTo(expectedInvalid));
}

[Test]
public void TestFormatScoreMultiplier()
{
Assert.AreEqual(ModUtils.FormatScoreMultiplier(0.9999).ToString(), "0.99x");
Assert.AreEqual(ModUtils.FormatScoreMultiplier(1.0).ToString(), "1.00x");
Assert.AreEqual(ModUtils.FormatScoreMultiplier(1.0001).ToString(), "1.01x");

Assert.AreEqual(ModUtils.FormatScoreMultiplier(0.899999999999999).ToString(), "0.90x");
Assert.AreEqual(ModUtils.FormatScoreMultiplier(0.9).ToString(), "0.90x");
Assert.AreEqual(ModUtils.FormatScoreMultiplier(0.900000000000001).ToString(), "0.90x");

Assert.AreEqual(ModUtils.FormatScoreMultiplier(1.099999999999999).ToString(), "1.10x");
Assert.AreEqual(ModUtils.FormatScoreMultiplier(1.1).ToString(), "1.10x");
Assert.AreEqual(ModUtils.FormatScoreMultiplier(1.100000000000001).ToString(), "1.10x");

Assert.AreEqual(ModUtils.FormatScoreMultiplier(1.045).ToString(), "1.05x");
Assert.AreEqual(ModUtils.FormatScoreMultiplier(1.05).ToString(), "1.05x");
Assert.AreEqual(ModUtils.FormatScoreMultiplier(1.055).ToString(), "1.06x");
}

public abstract class CustomMod1 : Mod, IModCompatibilitySpecification
{
}
Expand Down Expand Up @@ -339,6 +359,16 @@ private class InvalidMultiplayerFreeMod : Mod
public override bool ValidForMultiplayerAsFreeMod => false;
}

public class EditableMod : Mod
{
public override string Name => string.Empty;
public override LocalisableString Description => string.Empty;
public override string Acronym => string.Empty;
public override double ScoreMultiplier => Multiplier;

public double Multiplier = 1;
}

public interface IModCompatibilitySpecification
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.Select;
using osu.Game.Utils;

namespace osu.Game.Tests.Visual.UserInterface
{
Expand Down Expand Up @@ -74,7 +75,7 @@ private void changeMods(IReadOnlyList<Mod> mods)
private bool assertModsMultiplier(IEnumerable<Mod> mods)
{
double multiplier = mods.Aggregate(1.0, (current, mod) => current * mod.ScoreMultiplier);
string expectedValue = multiplier.Equals(1.0) ? string.Empty : $"{multiplier:N2}x";
string expectedValue = multiplier == 1 ? string.Empty : ModUtils.FormatScoreMultiplier(multiplier).ToString();

return expectedValue == footerButtonMods.MultiplierText.Current.Value;
}
Expand Down
4 changes: 2 additions & 2 deletions osu.Game/Overlays/Mods/ScoreMultiplierDisplay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
Expand All @@ -15,6 +14,7 @@
using osu.Game.Graphics.UserInterface;
using osu.Game.Localisation;
using osu.Game.Rulesets.Mods;
using osu.Game.Utils;
using osuTK;

namespace osu.Game.Overlays.Mods
Expand Down Expand Up @@ -147,7 +147,7 @@ private partial class EffectCounter : RollingCounter<double>
{
protected override double RollingDuration => 500;

protected override LocalisableString FormatCount(double count) => count.ToLocalisableString(@"0.00x");
protected override LocalisableString FormatCount(double count) => ModUtils.FormatScoreMultiplier(count);

protected override OsuSpriteText CreateSpriteText() => new OsuSpriteText
{
Expand Down
8 changes: 4 additions & 4 deletions osu.Game/Screens/Select/FooterButtonMods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using osuTK;
using osuTK.Graphics;
using osu.Game.Input.Bindings;
using osu.Game.Utils;

namespace osu.Game.Screens.Select
{
Expand Down Expand Up @@ -87,12 +88,11 @@ protected override void LoadComplete()
private void updateMultiplierText() => Schedule(() =>
{
double multiplier = Current.Value?.Aggregate(1.0, (current, mod) => current * mod.ScoreMultiplier) ?? 1;
MultiplierText.Text = multiplier == 1 ? string.Empty : ModUtils.FormatScoreMultiplier(multiplier);
MultiplierText.Text = multiplier.Equals(1.0) ? string.Empty : $"{multiplier:N2}x";
if (multiplier > 1.0)
if (multiplier > 1)
MultiplierText.FadeColour(highMultiplierColour, 200);
else if (multiplier < 1.0)
else if (multiplier < 1)
MultiplierText.FadeColour(lowMultiplierColour, 200);
else
MultiplierText.FadeColour(Color4.White, 200);
Expand Down
18 changes: 18 additions & 0 deletions osu.Game/Utils/ModUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Localisation;
using osu.Game.Online.API;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
Expand Down Expand Up @@ -226,5 +228,21 @@ public static bool InstantiateValidModsForRuleset(Ruleset ruleset, IEnumerable<A

return proposedWereValid;
}

/// <summary>
/// Given a value of a score multiplier, returns a string version with special handling for a value near 1.00x.
/// </summary>
/// <param name="scoreMultiplier">The value of the score multiplier.</param>
/// <returns>A formatted score multiplier with a trailing "x" symbol</returns>
public static LocalisableString FormatScoreMultiplier(double scoreMultiplier)
{
// Round multiplier values away from 1.00x to two significant digits.
if (scoreMultiplier > 1)
scoreMultiplier = Math.Ceiling(Math.Round(scoreMultiplier * 100, 12)) / 100;
else
scoreMultiplier = Math.Floor(Math.Round(scoreMultiplier * 100, 12)) / 100;

return scoreMultiplier.ToLocalisableString("0.00x");
}
}
}

0 comments on commit 35b9940

Please sign in to comment.