mirror of
https://github.com/osukey/osukey.git
synced 2025-08-06 16:13:57 +09:00
Merge pull request #11253 from peppy/realtime-leaderboard
This commit is contained in:
@ -233,7 +233,7 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Given a minimal set of inputs, return the computed score and accuracy for the tracked beatmap / mods combination.
|
/// Given a minimal set of inputs, return the computed score and accuracy for the tracked beatmap / mods combination, at the current point in time.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="mode">The <see cref="ScoringMode"/> to compute the total score in.</param>
|
/// <param name="mode">The <see cref="ScoringMode"/> to compute the total score in.</param>
|
||||||
/// <param name="maxCombo">The maximum combo achievable in the beatmap.</param>
|
/// <param name="maxCombo">The maximum combo achievable in the beatmap.</param>
|
||||||
@ -252,15 +252,28 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
computedBaseScore += Judgement.ToNumericResult(pair.Key) * pair.Value;
|
computedBaseScore += Judgement.ToNumericResult(pair.Key) * pair.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
double accuracy = calculateAccuracyRatio(computedBaseScore);
|
double pointInTimeAccuracy = calculateAccuracyRatio(computedBaseScore, true);
|
||||||
double comboRatio = calculateComboRatio(maxCombo);
|
double comboRatio = calculateComboRatio(maxCombo);
|
||||||
|
|
||||||
double score = GetScore(mode, maxAchievableCombo, accuracy, comboRatio, scoreResultCounts);
|
double score = GetScore(mode, maxAchievableCombo, calculateAccuracyRatio(computedBaseScore), comboRatio, scoreResultCounts);
|
||||||
|
|
||||||
return (score, accuracy);
|
return (score, pointInTimeAccuracy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the accuracy fraction for the provided base score.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="baseScore">The score to be used for accuracy calculation.</param>
|
||||||
|
/// <param name="preferRolling">Whether the rolling base score should be used (ie. for the current point in time based on Apply/Reverted results).</param>
|
||||||
|
/// <returns>The computed accuracy.</returns>
|
||||||
|
private double calculateAccuracyRatio(double baseScore, bool preferRolling = false)
|
||||||
|
{
|
||||||
|
if (preferRolling && rollingMaxBaseScore != 0)
|
||||||
|
return baseScore / rollingMaxBaseScore;
|
||||||
|
|
||||||
|
return maxBaseScore > 0 ? baseScore / maxBaseScore : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double calculateAccuracyRatio(double baseScore) => maxBaseScore > 0 ? baseScore / maxBaseScore : 0;
|
|
||||||
private double calculateComboRatio(int maxCombo) => maxAchievableCombo > 0 ? (double)maxCombo / maxAchievableCombo : 1;
|
private double calculateComboRatio(int maxCombo) => maxAchievableCombo > 0 ? (double)maxCombo / maxAchievableCombo : 1;
|
||||||
|
|
||||||
private double getBonusScore(Dictionary<HitResult, int> statistics)
|
private double getBonusScore(Dictionary<HitResult, int> statistics)
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
@ -12,7 +14,9 @@ using osu.Game.Online.Multiplayer;
|
|||||||
using osu.Game.Online.RealtimeMultiplayer;
|
using osu.Game.Online.RealtimeMultiplayer;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Multi.Play;
|
using osu.Game.Screens.Multi.Play;
|
||||||
|
using osu.Game.Screens.Play.HUD;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Multi.RealtimeMultiplayer
|
namespace osu.Game.Screens.Multi.RealtimeMultiplayer
|
||||||
{
|
{
|
||||||
@ -30,6 +34,9 @@ namespace osu.Game.Screens.Multi.RealtimeMultiplayer
|
|||||||
private readonly TaskCompletionSource<bool> resultsReady = new TaskCompletionSource<bool>();
|
private readonly TaskCompletionSource<bool> resultsReady = new TaskCompletionSource<bool>();
|
||||||
private readonly ManualResetEventSlim startedEvent = new ManualResetEventSlim();
|
private readonly ManualResetEventSlim startedEvent = new ManualResetEventSlim();
|
||||||
|
|
||||||
|
[CanBeNull]
|
||||||
|
private MultiplayerGameplayLeaderboard leaderboard;
|
||||||
|
|
||||||
public RealtimePlayer(PlaylistItem playlistItem)
|
public RealtimePlayer(PlaylistItem playlistItem)
|
||||||
: base(playlistItem, false)
|
: base(playlistItem, false)
|
||||||
{
|
{
|
||||||
@ -55,6 +62,31 @@ namespace osu.Game.Screens.Multi.RealtimeMultiplayer
|
|||||||
this.Exit();
|
this.Exit();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug.Assert(client.Room != null);
|
||||||
|
|
||||||
|
int[] userIds = client.Room.Users.Where(u => u.State >= MultiplayerUserState.WaitingForLoad).Select(u => u.UserID).ToArray();
|
||||||
|
|
||||||
|
// todo: this should be implemented via a custom HUD implementation, and correctly masked to the main content area.
|
||||||
|
LoadComponentAsync(leaderboard = new MultiplayerGameplayLeaderboard(ScoreProcessor, userIds), HUDOverlay.Add);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
adjustLeaderboardPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void adjustLeaderboardPosition()
|
||||||
|
{
|
||||||
|
if (leaderboard == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const float padding = 44; // enough margin to avoid the hit error display.
|
||||||
|
|
||||||
|
leaderboard.Position = new Vector2(
|
||||||
|
padding,
|
||||||
|
padding + HUDOverlay.TopScoringElementsHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onMatchStarted() => startedEvent.Set();
|
private void onMatchStarted() => startedEvent.Set();
|
||||||
|
@ -28,6 +28,11 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
public const Easing FADE_EASING = Easing.Out;
|
public const Easing FADE_EASING = Easing.Out;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total height of all the top of screen scoring elements.
|
||||||
|
/// </summary>
|
||||||
|
public float TopScoringElementsHeight { get; private set; }
|
||||||
|
|
||||||
public readonly KeyCounterDisplay KeyCounter;
|
public readonly KeyCounterDisplay KeyCounter;
|
||||||
public readonly SkinnableComboCounter ComboCounter;
|
public readonly SkinnableComboCounter ComboCounter;
|
||||||
public readonly SkinnableScoreCounter ScoreCounter;
|
public readonly SkinnableScoreCounter ScoreCounter;
|
||||||
@ -209,7 +214,7 @@ namespace osu.Game.Screens.Play
|
|||||||
// HACK: for now align with the accuracy counter.
|
// HACK: for now align with the accuracy counter.
|
||||||
// this is done for the sake of hacky legacy skins which extend the health bar to take up the full screen area.
|
// this is done for the sake of hacky legacy skins which extend the health bar to take up the full screen area.
|
||||||
// it only works with the default skin due to padding offsetting it *just enough* to coexist.
|
// it only works with the default skin due to padding offsetting it *just enough* to coexist.
|
||||||
topRightElements.Y = ToLocalSpace(AccuracyCounter.Drawable.ScreenSpaceDrawQuad.BottomRight).Y;
|
topRightElements.Y = TopScoringElementsHeight = ToLocalSpace(AccuracyCounter.Drawable.ScreenSpaceDrawQuad.BottomRight).Y;
|
||||||
|
|
||||||
bottomRightElements.Y = -Progress.Height;
|
bottomRightElements.Y = -Progress.Height;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user