Skip to content

Commit 79e8564

Browse files
committed
feat(Draw): Add score checker status detection and display function
- Add the ProberRootPath constant for the score checker status icon path - Implement score checker status detection logic in ListDrawer and BestsDrawer - Display warning status and description when score mismatch or mask is enabled - Adjust positions of some UI elements and the score calculation logic
1 parent 444714a commit 79e8564

File tree

3 files changed

+128
-35
lines changed

3 files changed

+128
-35
lines changed

src/Draw/BestsDrawer.cs

Lines changed: 88 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class BestsDrawer : DrawerBase
2424
public const string FrameLinePath = "./Static/Maimai/Bests/frame.png";
2525
public const string NamebasePath = "./Static/Maimai/Bests/namebase.png";
2626
public const string ScorebasePath = "./Static/Maimai/Bests/scorebase.png";
27+
public const string ProberStateDescbasePath = "./Static/Maimai/Bests/descbase.png";
2728
public const string BackgroundPath = "./Static/Maimai/Bests/background.png";
2829
public const string BackgroundAnimationPath = "./Static/Maimai/Bests/background_animation.png";
2930
public const string LevelSugBackgroundPath = "./Static/Maimai/Bests/rating_base.png";
@@ -40,6 +41,7 @@ public class BestsDrawer : DrawerBase
4041
public const string FrameLinePath = "./Resources/Background/frame.png";
4142
public const string NamebasePath = "./Resources/Background/namebase.png";
4243
public const string ScorebasePath = "./Resources/Background/scorebase.png";
44+
public const string ProberStateDescbasePath = "./Resources/Prober/descbase.png";
4345
public const string BackgroundPath = "./Resources/Background/bests.png";
4446
public const string BackgroundAnimationPath = "./Resources/Background/bests_animation.png";
4547
public const string LevelSugBackgroundPath = "./Resources/Background/level_seg.png";
@@ -69,6 +71,26 @@ public Image Draw(CommonUser user, IReadOnlyList<CommonRecord> ever, IReadOnlyLi
6971
using Image namebase = AssetManager.Shared.Load(NamebasePath);
7072
using Image ratingbase = AssetManager.Shared.Load(Path.Combine(RatingRootPath, $"{user.RatingLevel}.png"));
7173
using Image proberLogo = AssetManager.Shared.Load(Path.Combine(ProberLogoRootPath, $"{prober}.png"));
74+
string proberState;
75+
string? proberStateDesc = null;
76+
int realRating = everTotal + currentTotal;
77+
if (user.Rating != realRating)
78+
{
79+
proberState = "off";
80+
proberStateDesc = "DX评分与最佳成绩不匹配";
81+
}
82+
else if (ever.Any(r => r.DXScore is 0 && (r.DXStar > 0 || r.Rank < Ranks.C)) ||
83+
current.Any(r => r.DXScore is 0 && (r.DXStar > 0 || r.Rank < Ranks.C)))
84+
{
85+
proberState = "warning";
86+
proberStateDesc = "查分器可能启用了掩码";
87+
}
88+
else
89+
{
90+
proberState = "on";
91+
}
92+
93+
using Image proberbase = AssetManager.Shared.Load(Path.Combine(ProberRootPath, $"{proberState}.png"));
7294

7395
frameImage.Resize(0.95, KnownResamplers.Lanczos3);
7496
plate.Resize(0.951, KnownResamplers.Lanczos3);
@@ -99,7 +121,8 @@ public Image Draw(CommonUser user, IReadOnlyList<CommonRecord> ever, IReadOnlyLi
99121
});
100122

101123
string shougou = user.TrophyText;
102-
FontRectangle shougouSize = LatinHeavyFont.GetSize(14, shougou, [JpHeavyFont, ScHeavyFont, SymbolsFont, Symbols2Font]);
124+
FontRectangle shougouSize =
125+
LatinHeavyFont.GetSize(14, shougou, [JpHeavyFont, ScHeavyFont, SymbolsFont, Symbols2Font]);
103126
Point shougoubasePos = new(180, 143);
104127
PointF shougouPos = new(shougoubasePos.X + ((shougoubase.Width - shougouSize.Width) / 2), 151);
105128
using Image shougouImage = LatinHeavyFont.DrawImage(14, shougou, Brushes.Solid(new Rgb24(255, 255, 255)),
@@ -112,19 +135,24 @@ public Image Draw(CommonUser user, IReadOnlyList<CommonRecord> ever, IReadOnlyLi
112135
string scorePart2 = "B35";
113136
string scorePart3 = $"+{currentTotal}";
114137
string scorePart4 = "B15";
115-
string scorePart5 = $"={everTotal + currentTotal}";
116-
FontRectangle scorePart1Size = LatinBoldFont.GetSize(27, scorePart1, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
117-
FontRectangle scorePart2Size = LatinBoldFont.GetSize(19, scorePart2, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
118-
FontRectangle scorePart3Size = LatinBoldFont.GetSize(27, scorePart3, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
119-
FontRectangle scorePart4Size = LatinBoldFont.GetSize(19, scorePart4, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
120-
FontRectangle scorePart5Size = LatinBoldFont.GetSize(27, scorePart5, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
138+
string scorePart5 = $"={realRating}";
139+
FontRectangle scorePart1Size =
140+
LatinBoldFont.GetSize(27, scorePart1, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
141+
FontRectangle scorePart2Size =
142+
LatinBoldFont.GetSize(19, scorePart2, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
143+
FontRectangle scorePart3Size =
144+
LatinBoldFont.GetSize(27, scorePart3, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
145+
FontRectangle scorePart4Size =
146+
LatinBoldFont.GetSize(19, scorePart4, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
147+
FontRectangle scorePart5Size =
148+
LatinBoldFont.GetSize(27, scorePart5, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
121149
float scoreWidth = scorePart1Size.Width + scorePart2Size.Width + scorePart3Size.Width + scorePart4Size.Width +
122150
scorePart5Size.Width;
123-
PointF scorePart1Pos = new(285 - (scoreWidth / 2), 532);
124-
PointF scorePart2Pos = new(scorePart1Pos.X + scorePart1Size.Width, 543);
125-
PointF scorePart3Pos = new(scorePart2Pos.X + scorePart2Size.Width, 532);
126-
PointF scorePart4Pos = new(scorePart3Pos.X + scorePart3Size.Width, 543);
127-
PointF scorePart5Pos = new(scorePart4Pos.X + scorePart4Size.Width, 532);
151+
PointF scorePart1Pos = new(285 - (scoreWidth / 2), 530);
152+
PointF scorePart2Pos = new(scorePart1Pos.X + scorePart1Size.Width, 542);
153+
PointF scorePart3Pos = new(scorePart2Pos.X + scorePart2Size.Width, 530);
154+
PointF scorePart4Pos = new(scorePart3Pos.X + scorePart3Size.Width, 542);
155+
PointF scorePart5Pos = new(scorePart4Pos.X + scorePart4Size.Width, 530);
128156
Rgb24 scoreColorValue = new(75, 77, 138);
129157
Color scoreColor = new(scoreColorValue);
130158
using Image scorePart1Image = LatinBoldFont.DrawImage(27, scorePart1, scoreColor,
@@ -138,15 +166,31 @@ public Image Draw(CommonUser user, IReadOnlyList<CommonRecord> ever, IReadOnlyLi
138166
using Image scorePart5Image = LatinBoldFont.DrawImage(27, scorePart5, scoreColor,
139167
[JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
140168

141-
FontRectangle typeSize = LatinBoldFont.GetSize(32, typename, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
169+
FontRectangle typeSize =
170+
LatinBoldFont.GetSize(32, typename, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
142171
PointF typePos = new(720 - (typeSize.Width / 2), 725);
143172
using Image typeImage = LatinBoldFont.DrawImage(32, typename, new(new Rgb24(0, 109, 103)),
144173
[JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
145174

175+
if (proberStateDesc is not null)
176+
{
177+
using Image proberStateDescbase = AssetManager.Shared.Load(ProberStateDescbasePath);
178+
FontRectangle proberStateDescSize = LatinBoldFont.GetSize(27, proberStateDesc,
179+
[JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
180+
PointF proberStateDescPos = new(828 - (proberStateDescSize.Width / 2), 528);
181+
using Image proberStateDescImage = LatinBoldFont.DrawImage(27, proberStateDesc, scoreColor,
182+
[JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
183+
bg.Mutate(ctx =>
184+
{
185+
ctx.DrawImage(proberStateDescbase, new Point(574, 492), 1);
186+
ctx.DrawImage(proberStateDescImage, (Point)proberStateDescPos, 1);
187+
});
188+
}
189+
146190
if (isAnime)
147191
{
148192
using Image scorebase = AssetManager.Shared.Load(ScorebasePath);
149-
bg.Mutate(ctx => ctx.DrawImage(scorebase, new Point(25, 492), 1));
193+
bg.Mutate(ctx => ctx.DrawImage(scorebase, new Point(27, 492), 1));
150194
}
151195

152196
bg.Mutate(ctx =>
@@ -169,7 +213,8 @@ public Image Draw(CommonUser user, IReadOnlyList<CommonRecord> ever, IReadOnlyLi
169213
ctx.DrawImage(scorePart4Image, (Point)scorePart4Pos, 1);
170214
ctx.DrawImage(scorePart5Image, (Point)scorePart5Pos, 1);
171215
ctx.DrawImage(typeImage, (Point)typePos, 1);
172-
ctx.DrawImage(proberLogo, new Point(1011, 67), 1);
216+
ctx.DrawImage(proberbase, new Point(1011, 67), 1);
217+
ctx.DrawImage(proberLogo, new Point(1016, 72), 1);
173218
foreach ((Point point, Image scoreImage) in sdBests)
174219
{
175220
using (scoreImage)
@@ -213,7 +258,7 @@ public Image Draw(CommonUser user, IReadOnlyList<CommonRecord> ever, IReadOnlyLi
213258
if (drawLevelSeg)
214259
{
215260
using Image levelSegImage = DrawLevelSug(ever, current);
216-
bg.Mutate(ctx => ctx.DrawImage(levelSegImage, new Point(60, 197), 1));
261+
bg.Mutate(ctx => ctx.DrawImage(levelSegImage, new Point(76, 200), 1));
217262
}
218263

219264
return bg;
@@ -295,7 +340,8 @@ public Image DrawScore(CommonRecord score, int index, bool isMax = false)
295340
drawName = $"{title}…";
296341
}
297342

298-
using Image titleImage = LatinBoldFont.DrawImage(40, drawName, color, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
343+
using Image titleImage =
344+
LatinBoldFont.DrawImage(40, drawName, color, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
299345

300346
#endregion
301347

@@ -307,9 +353,12 @@ public Image DrawScore(CommonRecord score, int index, bool isMax = false)
307353
string achiPart3 = achievements.Length > 1 ? achievements[1].PadRight(4, '0') : "0000";
308354
string achiPart4 = "%";
309355

310-
FontRectangle achiPart1Size = LatinHeavyFont.GetSize(76, achiPart1, [JpHeavyFont, ScHeavyFont, SymbolsFont, Symbols2Font]);
311-
FontRectangle achiPart2Size = LatinBoldFont.GetSize(76, achiPart2, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
312-
FontRectangle achiPart3Size = LatinHeavyFont.GetSize(54, achiPart3, [JpHeavyFont, ScHeavyFont, SymbolsFont, Symbols2Font]);
356+
FontRectangle achiPart1Size =
357+
LatinHeavyFont.GetSize(76, achiPart1, [JpHeavyFont, ScHeavyFont, SymbolsFont, Symbols2Font]);
358+
FontRectangle achiPart2Size =
359+
LatinBoldFont.GetSize(76, achiPart2, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
360+
FontRectangle achiPart3Size =
361+
LatinHeavyFont.GetSize(54, achiPart3, [JpHeavyFont, ScHeavyFont, SymbolsFont, Symbols2Font]);
313362

314363
Point achiPart1Pos = new(371, 90);
315364
PointF achiPart2Pos = new(achiPart1Pos.X + achiPart1Size.Width, 90);
@@ -331,8 +380,10 @@ public Image DrawScore(CommonRecord score, int index, bool isMax = false)
331380

332381
string indexPart1 = "#";
333382
string indexPart2 = index.ToString();
334-
FontRectangle indexPart1Size = LatinBoldFont.GetSize(24, indexPart1, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
335-
FontRectangle indexPart2Size = LatinBoldFont.GetSize(30, indexPart2, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
383+
FontRectangle indexPart1Size =
384+
LatinBoldFont.GetSize(24, indexPart1, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
385+
FontRectangle indexPart2Size =
386+
LatinBoldFont.GetSize(30, indexPart2, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
336387
float indexWidth = indexPart1Size.Width + indexPart2Size.Width;
337388
PointF indexPart1Pos = new(335 - (indexWidth / 2), 250);
338389
PointF indexPart2Pos = new(indexPart1Pos.X + indexPart1Size.Width, 245);
@@ -350,7 +401,8 @@ public Image DrawScore(CommonRecord score, int index, bool isMax = false)
350401
string[] level = score.LevelValue.ToString().Split('.');
351402
string levelPart1 = $"{level[0]}.";
352403
string levelPart2 = level.Length > 1 ? level[1] : "0";
353-
FontRectangle levelPart1Size = LatinBoldFont.GetSize(34, levelPart1, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
404+
FontRectangle levelPart1Size =
405+
LatinBoldFont.GetSize(34, levelPart1, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
354406

355407
Point levelPart1Pos = new(375, 182);
356408
PointF levelPart2Pos = new(levelPart1Pos.X + levelPart1Size.Width, 187);
@@ -364,10 +416,12 @@ public Image DrawScore(CommonRecord score, int index, bool isMax = false)
364416
#region Rating
365417

366418
string rating = score.DXRating.ToString();
367-
FontRectangle ratingSize = LatinBoldFont.GetSize(34, rating, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
419+
FontRectangle ratingSize =
420+
LatinBoldFont.GetSize(34, rating, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
368421

369422
PointF ratingPos = new(548 - ratingSize.Width, 182);
370-
using Image ratingImage = LatinBoldFont.DrawImage(34, rating, color, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
423+
using Image ratingImage =
424+
LatinBoldFont.DrawImage(34, rating, color, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
371425

372426
#endregion
373427

@@ -376,7 +430,8 @@ public Image DrawScore(CommonRecord score, int index, bool isMax = false)
376430
string numeroPart1 = "No.";
377431
string numeroPart2 = score.Id.ToString();
378432

379-
FontRectangle numeroPart1Size = LatinBoldFont.GetSize(24, numeroPart1, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
433+
FontRectangle numeroPart1Size =
434+
LatinBoldFont.GetSize(24, numeroPart1, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
380435

381436
Point numeroPart1Pos = new(386, 250);
382437
PointF numeroPart2Pos = new(numeroPart1Pos.X + numeroPart1Size.Width, 245);
@@ -395,8 +450,10 @@ public Image DrawScore(CommonRecord score, int index, bool isMax = false)
395450
string dxScorePart1 = $"{score.DXScore}/";
396451
string dxScorePart2 = score.TotalDXScore.ToString();
397452

398-
FontRectangle dxScorePart1Size = LatinBoldFont.GetSize(30, dxScorePart1, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
399-
FontRectangle dxScorePart2Size = LatinBoldFont.GetSize(24, dxScorePart2, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
453+
FontRectangle dxScorePart1Size =
454+
LatinBoldFont.GetSize(30, dxScorePart1, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
455+
FontRectangle dxScorePart2Size =
456+
LatinBoldFont.GetSize(24, dxScorePart2, [JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
400457

401458
PointF dxScorePart2Pos = new(734 - dxScorePart2Size.Width, 250);
402459
PointF dxScorePart1Pos = new(dxScorePart2Pos.X - dxScorePart1Size.Width, 245);
@@ -587,15 +644,15 @@ public Image DrawLevelSug(IReadOnlyList<CommonRecord> ever, IReadOnlyList<Common
587644
{
588645
ReadOnlySpan<int> posY = [73, 113, 179, 219];
589646
ReadOnlySpan<int> diffs = [b35maxDiff, b35minDiff, b15maxDiff, b15minDiff];
590-
Point pos = new(140, posY[i % 4]);
647+
Point pos = new(148, posY[i % 4]);
591648
Image levelImage = LatinBoldFont.DrawImage(30, $"{$"+{diffs[i]}",4}", new(new Rgb24(255, 255, 255)),
592649
[JpBoldFont, ScBoldFont, SymbolsFont, Symbols2Font]);
593650
images[i] = (pos, levelImage);
594651
});
595652
Parallel.For(0, 16, i =>
596653
{
597-
ReadOnlySpan<int> posX = [270, 390, 510, 630];
598-
ReadOnlySpan<int> posY = [73, 113, 179, 219];
654+
ReadOnlySpan<int> posX = [273, 393, 513, 633];
655+
ReadOnlySpan<int> posY = [73, 113, 178, 218];
599656
ReadOnlySpan<Ranks> ranks = [Ranks.SSSPlus, Ranks.SSS, Ranks.SSPlus, Ranks.SS];
600657
ReadOnlySpan<int> ratings = [b35max, b35min, b15max, b15min];
601658
int indexX = i % 4;

src/Draw/DrawerBase.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public abstract class DrawerBase
1111
public const string ComboRootPath = "./Static/Maimai/Bests/Combo/";
1212
public const string SyncRootPath = "./Static/Maimai/Bests/Sync/";
1313
public const string SongTypeRootPath = "./Static/maimai/MusicType/";
14+
public const string ProberRootPath = "./Static/Maimai/Prober/";
1415
public const string ProberLogoRootPath = "./Static/Maimai/ProberLogo/";
1516
#elif DEBUG
1617
public const string FontRootPath = "./Resources/Font/";
@@ -19,6 +20,7 @@ public abstract class DrawerBase
1920
public const string ComboRootPath = "./Resources/Combo/";
2021
public const string SyncRootPath = "./Resources/Sync/";
2122
public const string SongTypeRootPath = "./Resources/SongType/";
23+
public const string ProberRootPath = "./Resources/Prober/";
2224
public const string ProberLogoRootPath = "./Resources/ProberLogo/";
2325
#endif
2426

0 commit comments

Comments
 (0)