From ca69a2a9b28f7127e6926ab048353de0148e1b43 Mon Sep 17 00:00:00 2001
From: Derrick Timmermans <derrick.timmermans@outlook.com>
Date: Wed, 14 Aug 2024 13:18:29 +0200
Subject: [PATCH 1/2] Add approximated maimaiDX accuracy in detailed statistics
 screen

---
 osu.Game.Rulesets.Sentakki/SentakkiRuleset.cs |  1 +
 .../Statistics/MaimaiDXAccuracy.cs            | 67 +++++++++++++++++++
 2 files changed, 68 insertions(+)
 create mode 100644 osu.Game.Rulesets.Sentakki/Statistics/MaimaiDXAccuracy.cs

diff --git a/osu.Game.Rulesets.Sentakki/SentakkiRuleset.cs b/osu.Game.Rulesets.Sentakki/SentakkiRuleset.cs
index f1f2cfb63..77b3e75a7 100644
--- a/osu.Game.Rulesets.Sentakki/SentakkiRuleset.cs
+++ b/osu.Game.Rulesets.Sentakki/SentakkiRuleset.cs
@@ -163,6 +163,7 @@ public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatm
 
             new StatisticItem(string.Empty, () => new SimpleStatisticTable(3, new SimpleStatisticItem[]
             {
+                new MaimaiDXAccuracy(score.HitEvents),
                 new UnstableRate(score.HitEvents)
             }), true)
         };
diff --git a/osu.Game.Rulesets.Sentakki/Statistics/MaimaiDXAccuracy.cs b/osu.Game.Rulesets.Sentakki/Statistics/MaimaiDXAccuracy.cs
new file mode 100644
index 000000000..83883efa9
--- /dev/null
+++ b/osu.Game.Rulesets.Sentakki/Statistics/MaimaiDXAccuracy.cs
@@ -0,0 +1,67 @@
+using System.Collections.Generic;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Screens.Ranking.Statistics;
+
+namespace osu.Game.Rulesets.Sentakki.Statistics;
+
+public partial class MaimaiDXAccuracy : SimpleStatisticItem<double>
+{
+    public MaimaiDXAccuracy(IEnumerable<HitEvent> hitEvents) : base("MaimaiDX accuracy (approximated)")
+    {
+        Value = calculateDXAcc(hitEvents);
+    }
+
+    private static double calculateDXAcc(IEnumerable<HitEvent> hitEvents)
+    {
+        double maximum = 0;
+        double actual = 0;
+
+        int maxBonus = 0;
+        int actualBonuses = 0;
+
+        foreach (HitEvent hitEvent in hitEvents)
+        {
+            switch (hitEvent.HitObject.Judgement.MaxResult)
+            {
+                case HitResult.Great:
+                    maximum += 1;
+                    break;
+
+                case HitResult.LargeBonus:
+                    maxBonus += 1;
+                    break;
+            }
+
+            switch (hitEvent.Result)
+            {
+                case HitResult.Great:
+                    actual += 1;
+                    break;
+
+                case HitResult.Good:
+                    actual += 0.75;
+                    break;
+
+                case HitResult.Ok:
+                    actual += 0.5;
+                    break;
+
+                case HitResult.LargeBonus:
+                    actualBonuses += 1;
+                    break;
+            }
+        }
+
+        // If there are no regular notes, then a perfect play is vacuosly true
+        if (maximum == 0)
+            actual = maximum = 1;
+
+        // If there are no break notes, then the player vacuosly hit all the breaks perfectly
+        if (maxBonus == 0)
+            actualBonuses = maxBonus = 1;
+
+        return ((actual / maximum) * 100) + (actualBonuses / (float)maxBonus);
+    }
+
+    protected override string DisplayValue(double value) => $"{value:N4}%";
+}

From 9c465c2554311ea101cbea6fcd15e8baffaf8ff0 Mon Sep 17 00:00:00 2001
From: Derrick Timmermans <derrick.timmermans@outlook.com>
Date: Mon, 19 Aug 2024 11:46:10 +0200
Subject: [PATCH 2/2] Slghtly adjust Great acc values for DX acc

---
 osu.Game.Rulesets.Sentakki/Statistics/MaimaiDXAccuracy.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/osu.Game.Rulesets.Sentakki/Statistics/MaimaiDXAccuracy.cs b/osu.Game.Rulesets.Sentakki/Statistics/MaimaiDXAccuracy.cs
index 83883efa9..4eea55348 100644
--- a/osu.Game.Rulesets.Sentakki/Statistics/MaimaiDXAccuracy.cs
+++ b/osu.Game.Rulesets.Sentakki/Statistics/MaimaiDXAccuracy.cs
@@ -39,7 +39,7 @@ private static double calculateDXAcc(IEnumerable<HitEvent> hitEvents)
                     break;
 
                 case HitResult.Good:
-                    actual += 0.75;
+                    actual += 0.8;
                     break;
 
                 case HitResult.Ok: