예제 #1
0
파일: ScoreManager.cs 프로젝트: Wieku/osu
        public async Task <ScoreInfo[]> OrderByTotalScoreAsync(ScoreInfo[] scores, CancellationToken cancellationToken = default)
        {
            if (difficultyCache != null)
            {
                // Compute difficulties asynchronously first to prevent blocking via the GetTotalScore() call below.
                foreach (var s in scores)
                {
                    await difficultyCache.GetDifficultyAsync(s.BeatmapInfo, s.Ruleset, s.Mods, cancellationToken).ConfigureAwait(false);

                    cancellationToken.ThrowIfCancellationRequested();
                }
            }

            long[] totalScores = await Task.WhenAll(scores.Select(s => GetTotalScoreAsync(s, cancellationToken: cancellationToken))).ConfigureAwait(false);

            return(scores.Select((score, index) => (score, totalScore: totalScores[index]))
                   .OrderByDescending(g => g.totalScore)
                   .ThenBy(g => g.score.OnlineID)
                   .Select(g => g.score)
                   .ToArray());
        }
예제 #2
0
        private void load(BeatmapDifficultyCache beatmapDifficultyCache)
        {
            var beatmap  = score.Beatmap;
            var metadata = beatmap.BeatmapSet?.Metadata ?? beatmap.Metadata;
            var creator  = metadata.Author?.Username;

            var topStatistics = new List <StatisticDisplay>
            {
                new AccuracyStatistic(score.Accuracy),
                new ComboStatistic(score.MaxCombo, !score.Statistics.TryGetValue(HitResult.Miss, out var missCount) || missCount == 0),
                new PerformanceStatistic(score),
            };

            var bottomStatistics = new List <HitResultStatistic>();

            foreach (var result in score.GetStatisticsForDisplay())
            {
                bottomStatistics.Add(new HitResultStatistic(result));
            }

            statisticDisplays.AddRange(topStatistics);
            statisticDisplays.AddRange(bottomStatistics);

            var starDifficulty = beatmapDifficultyCache.GetDifficultyAsync(beatmap, score.Ruleset, score.Mods).Result;

            InternalChildren = new Drawable[]
            {
                new FillFlowContainer
                {
                    RelativeSizeAxes = Axes.Both,
                    Direction        = FillDirection.Vertical,
                    Spacing          = new Vector2(20),
                    Children         = new Drawable[]
                    {
                        new FillFlowContainer
                        {
                            Anchor           = Anchor.TopCentre,
                            Origin           = Anchor.TopCentre,
                            RelativeSizeAxes = Axes.X,
                            AutoSizeAxes     = Axes.Y,
                            Direction        = FillDirection.Vertical,
                            Children         = new Drawable[]
                            {
                                new OsuSpriteText
                                {
                                    Anchor   = Anchor.TopCentre,
                                    Origin   = Anchor.TopCentre,
                                    Text     = new LocalisedString((metadata.TitleUnicode, metadata.Title)),
                                    Font     = OsuFont.Torus.With(size: 20, weight: FontWeight.SemiBold),
                                    MaxWidth = ScorePanel.EXPANDED_WIDTH - padding * 2,
                                    Truncate = true,
                                },
예제 #3
0
        private Task <PerformanceAttributes> getPerfectPerformance(ScoreInfo score, CancellationToken cancellationToken = default)
        {
            return(Task.Run(async() =>
            {
                Ruleset ruleset = score.Ruleset.CreateInstance();
                ScoreInfo perfectPlay = score.DeepClone();
                perfectPlay.Accuracy = 1;
                perfectPlay.Passed = true;

                // calculate max combo
                // todo: Get max combo from difficulty calculator instead when diffcalc properly supports lazer-first scores
                perfectPlay.MaxCombo = calculateMaxCombo(playableBeatmap);

                // create statistics assuming all hit objects have perfect hit result
                var statistics = playableBeatmap.HitObjects
                                 .SelectMany(getPerfectHitResults)
                                 .GroupBy(hr => hr, (hr, list) => (hitResult: hr, count: list.Count()))
                                 .ToDictionary(pair => pair.hitResult, pair => pair.count);
                perfectPlay.Statistics = statistics;

                // calculate total score
                ScoreProcessor scoreProcessor = ruleset.CreateScoreProcessor();
                scoreProcessor.HighestCombo.Value = perfectPlay.MaxCombo;
                scoreProcessor.Mods.Value = perfectPlay.Mods;
                perfectPlay.TotalScore = (long)scoreProcessor.GetImmediateScore(ScoringMode.Standardised, perfectPlay.MaxCombo, statistics);

                // compute rank achieved
                // default to SS, then adjust the rank with mods
                perfectPlay.Rank = ScoreRank.X;

                foreach (IApplicableToScoreProcessor mod in perfectPlay.Mods.OfType <IApplicableToScoreProcessor>())
                {
                    perfectPlay.Rank = mod.AdjustRank(perfectPlay.Rank, 1);
                }

                // calculate performance for this perfect score
                var difficulty = await difficultyCache.GetDifficultyAsync(
                    playableBeatmap.BeatmapInfo,
                    score.Ruleset,
                    score.Mods,
                    cancellationToken
                    ).ConfigureAwait(false);

                // ScorePerformanceCache is not used to avoid caching multiple copies of essentially identical perfect performance attributes
                return difficulty == null ? null : ruleset.CreatePerformanceCalculator(difficulty.Value.Attributes, perfectPlay)?.Calculate();
            }, cancellationToken));
        }
예제 #4
0
        private void load(BeatmapDifficultyCache beatmapDifficultyCache)
        {
            var    beatmap  = score.BeatmapInfo;
            var    metadata = beatmap.BeatmapSet?.Metadata ?? beatmap.Metadata;
            string creator  = metadata.Author.Username;

            var topStatistics = new List <StatisticDisplay>
            {
                new AccuracyStatistic(score.Accuracy),
                new ComboStatistic(score.MaxCombo, !score.Statistics.TryGetValue(HitResult.Miss, out int missCount) || missCount == 0),
                new PerformanceStatistic(score),
            };

            var bottomStatistics = new List <HitResultStatistic>();

            foreach (var result in score.GetStatisticsForDisplay())
            {
                bottomStatistics.Add(new HitResultStatistic(result));
            }

            statisticDisplays.AddRange(topStatistics);
            statisticDisplays.AddRange(bottomStatistics);

            var starDifficulty = beatmapDifficultyCache.GetDifficultyAsync(beatmap, score.Ruleset, score.Mods).GetResultSafely();

            AddInternal(new FillFlowContainer
            {
                RelativeSizeAxes = Axes.Both,
                Direction        = FillDirection.Vertical,
                Spacing          = new Vector2(20),
                Children         = new Drawable[]
                {
                    new FillFlowContainer
                    {
                        Anchor           = Anchor.TopCentre,
                        Origin           = Anchor.TopCentre,
                        RelativeSizeAxes = Axes.X,
                        AutoSizeAxes     = Axes.Y,
                        Direction        = FillDirection.Vertical,
                        Children         = new Drawable[]
                        {
                            new OsuSpriteText
                            {
                                Anchor   = Anchor.TopCentre,
                                Origin   = Anchor.TopCentre,
                                Text     = new RomanisableString(metadata.TitleUnicode, metadata.Title),
                                Font     = OsuFont.Torus.With(size: 20, weight: FontWeight.SemiBold),
                                MaxWidth = ScorePanel.EXPANDED_WIDTH - padding * 2,
                                Truncate = true,
                            },
                            new OsuSpriteText
                            {
                                Anchor   = Anchor.TopCentre,
                                Origin   = Anchor.TopCentre,
                                Text     = new RomanisableString(metadata.ArtistUnicode, metadata.Artist),
                                Font     = OsuFont.Torus.With(size: 14, weight: FontWeight.SemiBold),
                                MaxWidth = ScorePanel.EXPANDED_WIDTH - padding * 2,
                                Truncate = true,
                            },
                            new Container
                            {
                                Anchor = Anchor.TopCentre,
                                Origin = Anchor.TopCentre,
                                Margin = new MarginPadding {
                                    Top = 40
                                },
                                RelativeSizeAxes = Axes.X,
                                Height           = 230,
                                Child            = new AccuracyCircle(score, withFlair)
                                {
                                    Anchor           = Anchor.Centre,
                                    Origin           = Anchor.Centre,
                                    RelativeSizeAxes = Axes.Both,
                                    FillMode         = FillMode.Fit,
                                }
                            },
                            scoreCounter = new TotalScoreCounter
                            {
                                Margin = new MarginPadding {
                                    Top = 0, Bottom = 5
                                },
                                Current       = { Value = 0 },
                                Alpha         = 0,
                                AlwaysPresent = true
                            },
                            starAndModDisplay = new FillFlowContainer
                            {
                                Anchor       = Anchor.TopCentre,
                                Origin       = Anchor.TopCentre,
                                AutoSizeAxes = Axes.Both,
                                Spacing      = new Vector2(5, 0),
                            },
                            new FillFlowContainer
                            {
                                Anchor       = Anchor.TopCentre,
                                Origin       = Anchor.TopCentre,
                                Direction    = FillDirection.Vertical,
                                AutoSizeAxes = Axes.Both,
                                Children     = new Drawable[]
                                {
                                    new OsuSpriteText
                                    {
                                        Anchor = Anchor.TopCentre,
                                        Origin = Anchor.TopCentre,
                                        Text   = beatmap.DifficultyName,
                                        Font   = OsuFont.Torus.With(size: 16, weight: FontWeight.SemiBold),
                                    },
                                    new OsuTextFlowContainer(s => s.Font = OsuFont.Torus.With(size: 12))
                                    {
                                        Anchor       = Anchor.TopCentre,
                                        Origin       = Anchor.TopCentre,
                                        AutoSizeAxes = Axes.Both,
                                        Direction    = FillDirection.Horizontal,
                                    }.With(t =>
                                    {
                                        if (!string.IsNullOrEmpty(creator))
                                        {
                                            t.AddText("mapped by ");
                                            t.AddText(creator, s => s.Font = s.Font.With(weight: FontWeight.SemiBold));
                                        }
                                    })
                                }
                            },
                        }
                    },
                    new FillFlowContainer
                    {
                        RelativeSizeAxes = Axes.X,
                        AutoSizeAxes     = Axes.Y,
                        Direction        = FillDirection.Vertical,
                        Spacing          = new Vector2(0, 5),
                        Children         = new Drawable[]
                        {
                            new GridContainer
                            {
                                RelativeSizeAxes = Axes.X,
                                AutoSizeAxes     = Axes.Y,
                                Content          = new[] { topStatistics.Cast <Drawable>().ToArray() },
                                RowDimensions    = new[]
                                {
                                    new Dimension(GridSizeMode.AutoSize),
                                }
                            },
                            new GridContainer
                            {
                                RelativeSizeAxes = Axes.X,
                                AutoSizeAxes     = Axes.Y,
                                Content          = new[] { bottomStatistics.Where(s => s.Result <= HitResult.Perfect).ToArray() },
                                RowDimensions    = new[]
                                {
                                    new Dimension(GridSizeMode.AutoSize),
                                }
                            },
                            new GridContainer
                            {
                                RelativeSizeAxes = Axes.X,
                                AutoSizeAxes     = Axes.Y,
                                Content          = new[] { bottomStatistics.Where(s => s.Result > HitResult.Perfect).ToArray() },
                                RowDimensions    = new[]
                                {
                                    new Dimension(GridSizeMode.AutoSize),
                                }
                            }
                        }
                    }
                }
            });

            if (score.Date != default)
            {
                AddInternal(new PlayedOnText(score.Date));
            }

            if (starDifficulty != null)
            {
                starAndModDisplay.Add(new StarRatingDisplay(starDifficulty.Value)
                {
                    Anchor = Anchor.CentreLeft,
                    Origin = Anchor.CentreLeft
                });
            }

            if (score.Mods.Any())
            {
                starAndModDisplay.Add(new ModDisplay
                {
                    Anchor        = Anchor.CentreLeft,
                    Origin        = Anchor.CentreLeft,
                    ExpansionMode = ExpansionMode.AlwaysExpanded,
                    Scale         = new Vector2(0.5f),
                    Current       = { Value = score.Mods }
                });
            }
        }