Skip to content

Commit

Permalink
Merge pull request #24636 from smoogipoo/mania-hitwindow-audio-rate-2
Browse files Browse the repository at this point in the history
Adjust mania hit windows with DT/NC/HT/DC gameplay rate
  • Loading branch information
bdach authored Sep 4, 2023
2 parents 0da37e4 + 8df63ee commit ffcc00c
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 4 deletions.
63 changes: 63 additions & 0 deletions osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModDoubleTime.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Replays;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Replays;
using osu.Game.Tests.Visual;

namespace osu.Game.Rulesets.Mania.Tests.Mods
{
public partial class TestSceneManiaModDoubleTime : ModTestScene
{
private const double offset = 18;

protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset();

[Test]
public void TestHitWindowWithoutDoubleTime() => CreateModTest(new ModTestData
{
PassCondition = () => Player.ScoreProcessor.JudgedHits > 0 && Player.ScoreProcessor.Accuracy.Value != 1,
Autoplay = false,
Beatmap = new Beatmap
{
BeatmapInfo = { Ruleset = new ManiaRuleset().RulesetInfo },
Difficulty = { OverallDifficulty = 10 },
HitObjects = new List<HitObject>
{
new Note { StartTime = 1000 }
},
},
ReplayFrames = new List<ReplayFrame>
{
new ManiaReplayFrame(1000 + offset, ManiaAction.Key1)
}
});

[Test]
public void TestHitWindowWithDoubleTime() => CreateModTest(new ModTestData
{
Mod = new ManiaModDoubleTime(),
PassCondition = () => Player.ScoreProcessor.JudgedHits > 0 && Player.ScoreProcessor.Accuracy.Value == 1,
Autoplay = false,
Beatmap = new Beatmap
{
BeatmapInfo = { Ruleset = new ManiaRuleset().RulesetInfo },
Difficulty = { OverallDifficulty = 10 },
HitObjects = new List<HitObject>
{
new Note { StartTime = 1000 }
},
},
ReplayFrames = new List<ReplayFrame>
{
new ManiaReplayFrame(1000 + offset, ManiaAction.Key1)
}
});
}
}
47 changes: 47 additions & 0 deletions osu.Game.Rulesets.Mania/Mods/IManiaRateAdjustmentMod.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Bindables;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Mania.Mods
{
/// <summary>
/// May be attached to rate-adjustment mods to adjust hit windows adjust relative to gameplay rate.
/// </summary>
/// <remarks>
/// Historically, in osu!mania, hit windows are expected to adjust relative to the gameplay rate such that the real-world hit window remains the same.
/// </remarks>
public interface IManiaRateAdjustmentMod : IApplicableToDifficulty, IApplicableToHitObject
{
BindableNumber<double> SpeedChange { get; }

HitWindows HitWindows { get; set; }

void IApplicableToDifficulty.ApplyToDifficulty(BeatmapDifficulty difficulty)
{
HitWindows = new ManiaHitWindows(SpeedChange.Value);
HitWindows.SetDifficulty(difficulty.OverallDifficulty);
}

void IApplicableToHitObject.ApplyToHitObject(HitObject hitObject)
{
switch (hitObject)
{
case Note:
hitObject.HitWindows = HitWindows;
break;

case HoldNote hold:
hold.Head.HitWindows = HitWindows;
hold.Tail.HitWindows = HitWindows;
break;
}
}
}
}
5 changes: 4 additions & 1 deletion osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Mania.Mods
{
public class ManiaModDaycore : ModDaycore
public class ManiaModDaycore : ModDaycore, IManiaRateAdjustmentMod
{
public HitWindows HitWindows { get; set; } = new ManiaHitWindows();
}
}
5 changes: 4 additions & 1 deletion osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Mania.Mods
{
public class ManiaModDoubleTime : ModDoubleTime
public class ManiaModDoubleTime : ModDoubleTime, IManiaRateAdjustmentMod
{
public HitWindows HitWindows { get; set; } = new ManiaHitWindows();
}
}
5 changes: 4 additions & 1 deletion osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Mania.Mods
{
public class ManiaModHalfTime : ModHalfTime
public class ManiaModHalfTime : ModHalfTime, IManiaRateAdjustmentMod
{
public HitWindows HitWindows { get; set; } = new ManiaHitWindows();
}
}
5 changes: 4 additions & 1 deletion osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
// See the LICENCE file in the repository root for full licence text.

using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Mania.Mods
{
public class ManiaModNightcore : ModNightcore<ManiaHitObject>
public class ManiaModNightcore : ModNightcore<ManiaHitObject>, IManiaRateAdjustmentMod
{
public HitWindows HitWindows { get; set; } = new ManiaHitWindows();
}
}
20 changes: 20 additions & 0 deletions osu.Game.Rulesets.Mania/Scoring/ManiaHitWindows.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Linq;
using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Mania.Scoring
{
public class ManiaHitWindows : HitWindows
{
private readonly double multiplier;

public ManiaHitWindows()
: this(1)
{
}

public ManiaHitWindows(double multiplier)
{
this.multiplier = multiplier;
}

public override bool IsHitResultAllowed(HitResult result)
{
switch (result)
Expand All @@ -22,5 +35,12 @@ public override bool IsHitResultAllowed(HitResult result)

return false;
}

protected override DifficultyRange[] GetRanges() => base.GetRanges().Select(r =>
new DifficultyRange(
r.Result,
r.Min * multiplier,
r.Average * multiplier,
r.Max * multiplier)).ToArray();
}
}

0 comments on commit ffcc00c

Please sign in to comment.