Skip to content

Commit

Permalink
Initial implemention of the No Release mod
Browse files Browse the repository at this point in the history
This commit adds a new osu!mania mod No Release that relaxes tail
judgements. The current implementation automatically awards Perfect
(or Meh if the hold note is broken midway) for a hold note tail at
the end of its Perfect window, as long as it is held by then.

Tests are pending for the next commit.
  • Loading branch information
mcendu committed Jun 28, 2024
1 parent 007bd39 commit 960d552
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
1 change: 1 addition & 0 deletions osu.Game.Rulesets.Mania/ManiaRuleset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ public override IEnumerable<Mod> GetModsFor(ModType type)
new ManiaModEasy(),
new ManiaModNoFail(),
new MultiMod(new ManiaModHalfTime(), new ManiaModDaycore()),
new ManiaModNoRelease(),
};

case ModType.DifficultyIncrease:
Expand Down
35 changes: 35 additions & 0 deletions osu.Game.Rulesets.Mania/Mods/ManiaModNoRelease.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Localisation;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Mania.Mods
{
public class ManiaModNoRelease : Mod, IApplicableToDrawableHitObject
{
public override string Name => "No Release";

public override string Acronym => "NR";

public override LocalisableString Description => "No more timing the end of hold notes.";

public override double ScoreMultiplier => 0.9;

public override ModType Type => ModType.DifficultyReduction;

public void ApplyToDrawableHitObject(DrawableHitObject drawable)
{
if (drawable is DrawableHoldNote hold)
{
hold.HitObjectApplied += dho =>
{
((DrawableHoldNote)dho).Tail.LateReleaseResult = HitResult.Perfect;
};
}
}
}
}
24 changes: 22 additions & 2 deletions osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#nullable disable

using System.Diagnostics;
using osu.Framework.Graphics;
using osu.Framework.Input.Events;
using osu.Game.Rulesets.Scoring;
Expand All @@ -18,6 +19,11 @@ public partial class DrawableHoldNoteTail : DrawableNote

protected internal DrawableHoldNote HoldNote => (DrawableHoldNote)ParentHitObject;

/// <summary>
/// The minimum uncapped result for a late release.
/// </summary>
public HitResult LateReleaseResult { get; set; } = HitResult.Miss;

public DrawableHoldNoteTail()
: this(null)
{
Expand All @@ -32,9 +38,23 @@ public DrawableHoldNoteTail(TailNote tailNote)

public void UpdateResult() => base.UpdateResult(true);

protected override void CheckForResult(bool userTriggered, double timeOffset) =>
protected override void CheckForResult(bool userTriggered, double timeOffset)
{
Debug.Assert(HitObject.HitWindows != null);

// Factor in the release lenience
base.CheckForResult(userTriggered, timeOffset / TailNote.RELEASE_WINDOW_LENIENCE);
double scaledTimeOffset = timeOffset / TailNote.RELEASE_WINDOW_LENIENCE;

// Check for late release
if (HoldNote.HoldStartTime != null && scaledTimeOffset > HitObject.HitWindows.WindowFor(LateReleaseResult))
{
ApplyResult(GetCappedResult(LateReleaseResult));
}
else
{
base.CheckForResult(userTriggered, scaledTimeOffset);
}
}

protected override HitResult GetCappedResult(HitResult result)
{
Expand Down

0 comments on commit 960d552

Please sign in to comment.