mirror of
https://github.com/ppy/osu.git
synced 2025-03-25 11:47:19 +08:00
Send ScoreProcessor statistics in SpectatorState
This commit is contained in:
parent
c97b477485
commit
a052e09ac3
@ -172,6 +172,9 @@ namespace osu.Game.Online.Spectator
|
||||
currentState.RulesetID = score.ScoreInfo.RulesetID;
|
||||
currentState.Mods = score.ScoreInfo.Mods.Select(m => new APIMod(m)).ToArray();
|
||||
currentState.State = SpectatedUserState.Playing;
|
||||
currentState.MaxAchievableCombo = state.ScoreProcessor.MaxAchievableCombo;
|
||||
currentState.MaxAchievableBaseScore = state.ScoreProcessor.MaxAchievableBaseScore;
|
||||
currentState.TotalBasicHitObjects = state.ScoreProcessor.TotalBasicHitObjects;
|
||||
|
||||
currentBeatmap = state.Beatmap;
|
||||
currentScore = score;
|
||||
|
@ -27,6 +27,24 @@ namespace osu.Game.Online.Spectator
|
||||
[Key(3)]
|
||||
public SpectatedUserState State { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The maximum achievable combo, if everything is hit perfectly.
|
||||
/// </summary>
|
||||
[Key(4)]
|
||||
public int MaxAchievableCombo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The maximum achievable base score, if everything is hit perfectly.
|
||||
/// </summary>
|
||||
[Key(5)]
|
||||
public double MaxAchievableBaseScore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The total number of basic (non-tick and non-bonus) hitobjects that can be hit.
|
||||
/// </summary>
|
||||
[Key(6)]
|
||||
public int TotalBasicHitObjects { get; set; }
|
||||
|
||||
public bool Equals(SpectatorState other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
|
@ -88,17 +88,20 @@ namespace osu.Game.Rulesets.Scoring
|
||||
private readonly double accuracyPortion;
|
||||
private readonly double comboPortion;
|
||||
|
||||
private int maxAchievableCombo;
|
||||
/// <summary>
|
||||
/// The maximum achievable combo, if everything is hit perfectly.
|
||||
/// </summary>
|
||||
internal int MaxAchievableCombo;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum achievable base score.
|
||||
/// The maximum achievable base score, if everything is hit perfectly.
|
||||
/// </summary>
|
||||
private double maxBaseScore;
|
||||
internal double MaxAchievableBaseScore;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of basic (non-tick and non-bonus) hitobjects.
|
||||
/// The total number of basic (non-tick and non-bonus) hitobjects that can be hit.
|
||||
/// </summary>
|
||||
private int maxBasicHitObjects;
|
||||
internal int TotalBasicHitObjects;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum <see cref="HitResult"/> of a basic (non-tick and non-bonus) hitobject.
|
||||
@ -106,9 +109,9 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// </summary>
|
||||
private HitResult? maxBasicResult;
|
||||
|
||||
private double rollingMaxBaseScore;
|
||||
private double baseScore;
|
||||
private int basicHitObjects;
|
||||
private double rollingMaxAchievableBaseScore;
|
||||
private double rollingBaseScore;
|
||||
private int rollingBasicHitObjects;
|
||||
private bool beatmapApplied;
|
||||
|
||||
private readonly Dictionary<HitResult, int> scoreResultCounts = new Dictionary<HitResult, int>();
|
||||
@ -175,12 +178,12 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
if (!result.Type.IsBonus())
|
||||
{
|
||||
baseScore += scoreIncrease;
|
||||
rollingMaxBaseScore += result.Judgement.MaxNumericResult;
|
||||
rollingBaseScore += scoreIncrease;
|
||||
rollingMaxAchievableBaseScore += result.Judgement.MaxNumericResult;
|
||||
}
|
||||
|
||||
if (result.Type.IsBasic())
|
||||
basicHitObjects++;
|
||||
rollingBasicHitObjects++;
|
||||
|
||||
hitEvents.Add(CreateHitEvent(result));
|
||||
lastHitObject = result.HitObject;
|
||||
@ -213,12 +216,12 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
if (!result.Type.IsBonus())
|
||||
{
|
||||
baseScore -= scoreIncrease;
|
||||
rollingMaxBaseScore -= result.Judgement.MaxNumericResult;
|
||||
rollingBaseScore -= scoreIncrease;
|
||||
rollingMaxAchievableBaseScore -= result.Judgement.MaxNumericResult;
|
||||
}
|
||||
|
||||
if (result.Type.IsBasic())
|
||||
basicHitObjects--;
|
||||
rollingBasicHitObjects--;
|
||||
|
||||
Debug.Assert(hitEvents.Count > 0);
|
||||
lastHitObject = hitEvents[^1].LastHitObject;
|
||||
@ -229,12 +232,12 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
private void updateScore()
|
||||
{
|
||||
double rollingAccuracyRatio = rollingMaxBaseScore > 0 ? baseScore / rollingMaxBaseScore : 1;
|
||||
double accuracyRatio = maxBaseScore > 0 ? baseScore / maxBaseScore : 1;
|
||||
double comboRatio = maxAchievableCombo > 0 ? (double)HighestCombo.Value / maxAchievableCombo : 1;
|
||||
double rollingAccuracyRatio = rollingMaxAchievableBaseScore > 0 ? rollingBaseScore / rollingMaxAchievableBaseScore : 1;
|
||||
double accuracyRatio = MaxAchievableBaseScore > 0 ? rollingBaseScore / MaxAchievableBaseScore : 1;
|
||||
double comboRatio = MaxAchievableCombo > 0 ? (double)HighestCombo.Value / MaxAchievableCombo : 1;
|
||||
|
||||
Accuracy.Value = rollingAccuracyRatio;
|
||||
TotalScore.Value = ComputeScore(Mode.Value, accuracyRatio, comboRatio, getBonusScore(scoreResultCounts), maxBasicHitObjects);
|
||||
TotalScore.Value = ComputeScore(Mode.Value, accuracyRatio, comboRatio, getBonusScore(scoreResultCounts), TotalBasicHitObjects);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -288,10 +291,10 @@ namespace osu.Game.Rulesets.Scoring
|
||||
out _,
|
||||
out _);
|
||||
|
||||
double accuracyRatio = maxBaseScore > 0 ? extractedBaseScore / maxBaseScore : 1;
|
||||
double comboRatio = maxAchievableCombo > 0 ? (double)scoreInfo.MaxCombo / maxAchievableCombo : 1;
|
||||
double accuracyRatio = MaxAchievableBaseScore > 0 ? extractedBaseScore / MaxAchievableBaseScore : 1;
|
||||
double comboRatio = MaxAchievableCombo > 0 ? (double)scoreInfo.MaxCombo / MaxAchievableCombo : 1;
|
||||
|
||||
return ComputeScore(mode, accuracyRatio, comboRatio, getBonusScore(scoreInfo.Statistics), maxBasicHitObjects);
|
||||
return ComputeScore(mode, accuracyRatio, comboRatio, getBonusScore(scoreInfo.Statistics), TotalBasicHitObjects);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -403,14 +406,14 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
if (storeResults)
|
||||
{
|
||||
maxAchievableCombo = HighestCombo.Value;
|
||||
maxBaseScore = baseScore;
|
||||
maxBasicHitObjects = basicHitObjects;
|
||||
MaxAchievableCombo = HighestCombo.Value;
|
||||
MaxAchievableBaseScore = rollingBaseScore;
|
||||
TotalBasicHitObjects = rollingBasicHitObjects;
|
||||
}
|
||||
|
||||
baseScore = 0;
|
||||
rollingMaxBaseScore = 0;
|
||||
basicHitObjects = 0;
|
||||
rollingBaseScore = 0;
|
||||
rollingMaxAchievableBaseScore = 0;
|
||||
rollingBasicHitObjects = 0;
|
||||
|
||||
TotalScore.Value = 0;
|
||||
Accuracy.Value = 1;
|
||||
@ -444,7 +447,7 @@ namespace osu.Game.Rulesets.Scoring
|
||||
if (frame.Header == null)
|
||||
return;
|
||||
|
||||
extractFromStatistics(ruleset, frame.Header.Statistics, out baseScore, out rollingMaxBaseScore, out _, out _);
|
||||
extractFromStatistics(ruleset, frame.Header.Statistics, out rollingBaseScore, out rollingMaxAchievableBaseScore, out _, out _);
|
||||
HighestCombo.Value = frame.Header.MaxCombo;
|
||||
|
||||
scoreResultCounts.Clear();
|
||||
|
@ -1,6 +1,8 @@
|
||||
// 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.
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Bindables;
|
||||
@ -8,10 +10,9 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
{
|
||||
/// <summary>
|
||||
@ -39,6 +40,8 @@ namespace osu.Game.Screens.Play
|
||||
/// </summary>
|
||||
public readonly Score Score;
|
||||
|
||||
public readonly ScoreProcessor ScoreProcessor;
|
||||
|
||||
/// <summary>
|
||||
/// Whether gameplay completed without the user failing.
|
||||
/// </summary>
|
||||
@ -61,7 +64,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private readonly Bindable<JudgementResult> lastJudgementResult = new Bindable<JudgementResult>();
|
||||
|
||||
public GameplayState(IBeatmap beatmap, Ruleset ruleset, IReadOnlyList<Mod>? mods = null, Score? score = null)
|
||||
public GameplayState(IBeatmap beatmap, Ruleset ruleset, IReadOnlyList<Mod>? mods = null, Score? score = null, ScoreProcessor? scoreProcessor = null)
|
||||
{
|
||||
Beatmap = beatmap;
|
||||
Ruleset = ruleset;
|
||||
@ -72,7 +75,8 @@ namespace osu.Game.Screens.Play
|
||||
Ruleset = ruleset.RulesetInfo
|
||||
}
|
||||
};
|
||||
Mods = mods ?? ArraySegment<Mod>.Empty;
|
||||
Mods = mods ?? Array.Empty<Mod>();
|
||||
ScoreProcessor = scoreProcessor ?? ruleset.CreateScoreProcessor();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -237,7 +237,7 @@ namespace osu.Game.Screens.Play
|
||||
Score.ScoreInfo.Ruleset = ruleset.RulesetInfo;
|
||||
Score.ScoreInfo.Mods = gameplayMods;
|
||||
|
||||
dependencies.CacheAs(GameplayState = new GameplayState(playableBeatmap, ruleset, gameplayMods, Score));
|
||||
dependencies.CacheAs(GameplayState = new GameplayState(playableBeatmap, ruleset, gameplayMods, Score, ScoreProcessor));
|
||||
|
||||
var rulesetSkinProvider = new RulesetSkinProvidingContainer(ruleset, playableBeatmap, Beatmap.Value.Skin);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user