Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorporate break bonus into actual scoring #626

Merged
merged 9 commits into from
Oct 20, 2024
10 changes: 0 additions & 10 deletions osu.Game.Rulesets.Sentakki/Judgements/SentakkiBonusJudgement.cs

This file was deleted.

4 changes: 2 additions & 2 deletions osu.Game.Rulesets.Sentakki/Objects/Drawables/DrawableHold.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ protected override void CheckForResult(bool userTriggered, double timeOffset)
{
if (timeOffset >= 0 && Auto)
ApplyResult(HitResult.Perfect);
else if (timeOffset >= 0 && isHolding)
ApplyResult(applyDeductionTo(HitResult.Perfect));
else if (timeOffset > HitObject.HitWindows.WindowFor(HitResult.Perfect) && isHolding)
ApplyResult(applyDeductionTo(HitResult.Great));
else if (!HitObject.HitWindows.CanBeHit(timeOffset: timeOffset))
ApplyResult(Result.Judgement.MinResult);

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private void load(SentakkiRulesetConfigManager sentakkiConfigs)

public DrawableSentakkiJudgement Apply(JudgementResult result, DrawableHitObject hitObject)
{
if (result.Type == HitResult.Perfect)
if (result.Type == HitResult.Perfect && detailedJudgements.Value)
judgementPiece.JudgementText.Text = HitResult.Great.GetDisplayNameForSentakkiResult().ToUpperInvariant();
else
judgementPiece.JudgementText.Text = result.Type.GetDisplayNameForSentakkiResult().ToUpperInvariant();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ public partial class DrawableSentakkiLanedHitObject : DrawableSentakkiHitObject

private Container<DrawableScorePaddingObject> scorePaddingObjects = null!;

private Container<DrawableScoreBonusObject> scoreBonusObjects = null!;

public DrawableSentakkiLanedHitObject(SentakkiLanedHitObject? hitObject)
: base(hitObject)
{
Expand All @@ -33,7 +31,6 @@ private void load()
AddRangeInternal(new Drawable[]
{
scorePaddingObjects = new Container<DrawableScorePaddingObject>(),
scoreBonusObjects = new Container<DrawableScoreBonusObject>(),
breakSample = new PausableSkinnableSound(),
});

Expand Down Expand Up @@ -62,9 +59,6 @@ protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
{
case ScorePaddingObject p:
return new DrawableScorePaddingObject(p);

case ScoreBonusObject b:
return new DrawableScoreBonusObject(b);
}

return base.CreateNestedHitObject(hitObject);
Expand All @@ -78,9 +72,6 @@ protected override void AddNestedHitObject(DrawableHitObject hitObject)
scorePaddingObjects.Add(p);
break;

case DrawableScoreBonusObject b:
scoreBonusObjects.Add(b);
break;

default:
base.AddNestedHitObject(hitObject);
Expand All @@ -92,7 +83,6 @@ protected override void ClearNestedHitObjects()
{
base.ClearNestedHitObjects();
scorePaddingObjects.Clear(false);
scoreBonusObjects.Clear(false);
}

protected override void OnFree()
Expand All @@ -103,10 +93,6 @@ protected override void OnFree()

protected new void ApplyResult(HitResult hitResult)
{
// Judge the scoreBonus
foreach (var bonusObject in scoreBonusObjects)
bonusObject.TriggerResult(hitResult == HitResult.Perfect);

// Also give Break note score padding a judgement
for (int i = 0; i < scorePaddingObjects.Count; ++i)
scorePaddingObjects[^(i + 1)].ApplyResult(hitResult);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ protected override void CheckForResult(bool userTriggered, double timeOffset)
if (!userTriggered)
{
if (Auto && timeOffset > 0)
ApplyResult(HitResult.Perfect);
ApplyResult(Result.Judgement.MaxResult);
else if (!HitObject.HitWindows.CanBeHit(timeOffset))
ApplyResult(Result.Judgement.MinResult);

Expand Down
4 changes: 2 additions & 2 deletions osu.Game.Rulesets.Sentakki/Objects/Hold.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ public double EndTime

protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
// We intentionally not call the base method to avoid break notes being added

AddNested(new HoldHead
{
Break = Break,
Expand All @@ -47,6 +45,8 @@ protected override void CreateNestedHitObjects(CancellationToken cancellationTok
ColourBindable = ColourBindable.GetBoundCopy(),
Ex = Ex
});

base.CreateNestedHitObjects(cancellationToken);
}

protected override HitWindows CreateHitWindows() => new SentakkiTapHitWindows();
Expand Down
14 changes: 0 additions & 14 deletions osu.Game.Rulesets.Sentakki/Objects/ScoreBonusObject.cs

This file was deleted.

7 changes: 0 additions & 7 deletions osu.Game.Rulesets.Sentakki/Objects/SentakkiLanedHitObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,6 @@ protected override void CreateNestedHitObjects(CancellationToken cancellationTok

for (int i = 1; i < ScoreWeighting; ++i)
AddNested(new ScorePaddingObject { StartTime = this.GetEndTime() });

if (Break)
AddNested(new ScoreBonusObject
{
StartTime = this.GetEndTime(),
HitWindows = HitWindows
});
}

public override IList<HitSampleInfo> AuxiliarySamples => new HitSampleInfo[] { new BreakSample(CreateHitSampleInfo()) };
Expand Down
28 changes: 25 additions & 3 deletions osu.Game.Rulesets.Sentakki/Scoring/SentakkiScoreProcessor.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
namespace osu.Game.Rulesets.Sentakki.Scoring
{
public partial class SentakkiScoreProcessor : ScoreProcessor
Expand All @@ -11,9 +14,28 @@ public SentakkiScoreProcessor(SentakkiRuleset ruleset)

protected override double ComputeTotalScore(double comboProgress, double accuracyProgress, double bonusPortion)
{
return (10000 * comboProgress)
+ (990000 * Math.Pow(Accuracy.Value, 2 + (2 * Accuracy.Value)) * accuracyProgress)
+ bonusPortion;
return (150000 * comboProgress)
+ (850000 * Math.Pow(Accuracy.Value, 2 + (2 * Accuracy.Value)) * accuracyProgress)
+ bonusPortion;
}

public override int GetBaseScoreForResult(HitResult result)
{
if (result == HitResult.Perfect)
return 305;

return base.GetBaseScoreForResult(result);
}

public override ScoreRank RankFromScore(double accuracy, IReadOnlyDictionary<HitResult, int> results)
{
bool anyImperfect =
results.GetValueOrDefault(HitResult.Good) > 0
|| results.GetValueOrDefault(HitResult.Ok) > 0
|| results.GetValueOrDefault(HitResult.Meh) > 0
|| results.GetValueOrDefault(HitResult.Miss) > 0;

return !anyImperfect ? ScoreRank.X : base.RankFromScore(accuracy, results);
}
}
}
3 changes: 0 additions & 3 deletions osu.Game.Rulesets.Sentakki/SentakkiExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,6 @@ public static string GetDisplayNameForSentakkiResult(this HitResult result)
{
switch (result)
{
case HitResult.LargeBonus:
return "Critical Break Bonus";

case HitResult.Perfect:
return "Critical";

Expand Down
1 change: 0 additions & 1 deletion osu.Game.Rulesets.Sentakki/SentakkiRuleset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ protected override IEnumerable<HitResult> GetValidHitResults()
{
return new[]
{
HitResult.LargeBonus,
HitResult.Perfect,
HitResult.Great,
HitResult.Good,
Expand Down
6 changes: 3 additions & 3 deletions osu.Game.Rulesets.Sentakki/Statistics/JudgementChart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ public partial class JudgementChart : TableContainer
private static readonly (string, Func<HitEvent, bool>)[] hitObjectTypes =
{
("Tap", e => e.HitObject is Tap x && !x.Break),
("Hold", e => ((e.HitObject is Hold.HoldHead) && !((SentakkiLanedHitObject)e.HitObject).Break) || e.HitObject is Hold),
("Slide", e => e.HitObject is SlideBody x),
("Hold", e => (e.HitObject is Hold.HoldHead || e.HitObject is Hold) && !((SentakkiLanedHitObject)e.HitObject).Break),
("Slide", e => e.HitObject is SlideBody x && !x.Break),
("Touch", e => e.HitObject is Touch),
("Touch Hold", e => e.HitObject is TouchHold),
// Note Hold and Slide breaks are applied to child objects, not itself.
("Break", e => e.HitObject is SentakkiLanedHitObject x && (x is not Hold) && (x is not Slide) && x.Break),
("Break", e => e.HitObject is SentakkiLanedHitObject x && (x is not Slide) && x.Break),
};

private static readonly HitResult[] valid_results = new HitResult[]{
Expand Down
52 changes: 23 additions & 29 deletions osu.Game.Rulesets.Sentakki/Statistics/MaimaiDXAccuracy.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Sentakki.Objects;
using osu.Game.Screens.Ranking.Statistics;

namespace osu.Game.Rulesets.Sentakki.Statistics;
Expand All @@ -17,40 +18,24 @@ private static double calculateDXAcc(IEnumerable<HitEvent> hitEvents)
double actual = 0;

int maxBonus = 0;
int actualBonuses = 0;
float actualBonuses = 0;

foreach (HitEvent hitEvent in hitEvents)
{
switch (hitEvent.HitObject.Judgement.MaxResult)
{
case HitResult.Perfect:
case HitResult.Great:
maximum += 1;
break;
if (hitEvent.Result == HitResult.IgnoreMiss || hitEvent.Result == HitResult.IgnoreHit)
continue;

case HitResult.LargeBonus:
maxBonus += 1;
break;
}
maximum += ratioForHit(hitEvent.HitObject.Judgement.MaxResult);
actual += ratioForHit(hitEvent.Result);

switch (hitEvent.Result)
if (hitEvent.HitObject is SentakkiLanedHitObject sho)
{
case HitResult.Perfect:
case HitResult.Great:
actual += 1;
break;

case HitResult.Good:
actual += 0.8;
break;

case HitResult.Ok:
actual += 0.5;
break;

case HitResult.LargeBonus:
actualBonuses += 1;
break;
if (sho.Break)
{
maxBonus += 1 * sho.ScoreWeighting;
if (hitEvent.Result == HitResult.Perfect)
actualBonuses += 1 * sho.ScoreWeighting;
}
}
}

Expand All @@ -62,8 +47,17 @@ private static double calculateDXAcc(IEnumerable<HitEvent> hitEvents)
if (maxBonus == 0)
actualBonuses = maxBonus = 1;

return ((actual / maximum) * 100) + (actualBonuses / (float)maxBonus);
return ((actual / maximum) * 100) + (actualBonuses / maxBonus);
}

private static float ratioForHit(HitResult result) => result switch
{
HitResult.Perfect => 1,
HitResult.Great => 1,
HitResult.Good => 0.8f,
HitResult.Ok => 0.5f,
_ => 0
};

protected override string DisplayValue(double value) => $"{value:N4}%";
}
2 changes: 0 additions & 2 deletions osu.Game.Rulesets.Sentakki/UI/Lane.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using osu.Framework.Input.Events;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Sentakki.Configuration;
using osu.Game.Rulesets.Sentakki.Objects;
using osu.Game.Rulesets.Sentakki.Objects.Drawables;
using osu.Game.Rulesets.UI;
Expand Down Expand Up @@ -56,7 +55,6 @@ private void load()
RegisterPool<SlideCheckpoint.CheckpointNode, DrawableSlideCheckpointNode>(18);

RegisterPool<ScorePaddingObject, DrawableScorePaddingObject>(20);
RegisterPool<ScoreBonusObject, DrawableScoreBonusObject>(5);
}

protected override void OnNewDrawableHitObject(DrawableHitObject d) => OnLoaded?.Invoke(d);
Expand Down
Loading