1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:27:29 +08:00

Add visualisation of when a spectated player fails

Create a new stack each time for isolation and safety
This commit is contained in:
Dean Herbert 2023-11-22 17:53:35 +09:00
parent 51e2ce500d
commit ca93fdc94b
No known key found for this signature in database
5 changed files with 56 additions and 4 deletions

View File

@ -244,6 +244,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
playerArea.LoadScore(spectatorGameplayState.Score);
});
protected override void FailGameplay(int userId)
{
// We probably want to visualise this in the future.
}
protected override void QuitGameplay(int userId) => Schedule(() =>
{
RemoveUser(userId);

View File

@ -17,8 +17,8 @@ namespace osu.Game.Screens.Play
protected override UserActivity InitialActivity => new UserActivity.SpectatingUser(Score.ScoreInfo);
public SoloSpectatorPlayer(Score score, PlayerConfiguration configuration = null)
: base(score, configuration)
public SoloSpectatorPlayer(Score score)
: base(score, new PlayerConfiguration { AllowUserInteraction = false })
{
this.score = score;
}

View File

@ -178,6 +178,19 @@ namespace osu.Game.Screens.Play
scheduleStart(spectatorGameplayState);
});
protected override void FailGameplay(int userId)
{
if (this.GetChildScreen() is SpectatorPlayer player)
player.AllowFail();
Schedule(() =>
{
scheduledStart?.Cancel();
immediateSpectatorGameplayState = null;
clearDisplay();
});
}
protected override void QuitGameplay(int userId)
{
// Importantly, don't schedule this call, as a child screen may be present (and will cause the schedule to not be run as expected).
@ -187,7 +200,6 @@ namespace osu.Game.Screens.Play
{
scheduledStart?.Cancel();
immediateSpectatorGameplayState = null;
watchButton.Enabled.Value = false;
clearDisplay();
});

View File

@ -25,7 +25,15 @@ namespace osu.Game.Screens.Play
private readonly Score score;
protected override bool CheckModsAllowFailure() => false; // todo: better support starting mid-way through beatmap
protected override bool CheckModsAllowFailure()
{
if (!allowFail)
return false;
return base.CheckModsAllowFailure();
}
private bool allowFail;
protected SpectatorPlayer(Score score, PlayerConfiguration configuration = null)
: base(configuration)
@ -123,5 +131,7 @@ namespace osu.Game.Screens.Play
if (SpectatorClient != null)
SpectatorClient.OnNewFrames -= userSentFrames;
}
public void AllowFail() => allowFail = true;
}
}

View File

@ -137,6 +137,10 @@ namespace osu.Game.Screens.Spectate
markReceivedAllFrames(userId);
break;
case SpectatedUserState.Failed:
failGameplay(userId);
break;
case SpectatedUserState.Quit:
quitGameplay(userId);
break;
@ -185,6 +189,20 @@ namespace osu.Game.Screens.Spectate
gameplayState.Score.Replay.HasReceivedAllFrames = true;
}
private void failGameplay(int userId)
{
if (!userMap.ContainsKey(userId))
return;
if (!gameplayStates.ContainsKey(userId))
return;
markReceivedAllFrames(userId);
gameplayStates.Remove(userId);
FailGameplay(userId);
}
private void quitGameplay(int userId)
{
if (!userMap.ContainsKey(userId))
@ -222,6 +240,13 @@ namespace osu.Game.Screens.Spectate
/// <param name="userId">The user to quit gameplay for.</param>
protected abstract void QuitGameplay(int userId);
/// <summary>
/// Fails gameplay for a user.
/// Thread safety is not guaranteed should be scheduled as required.
/// </summary>
/// <param name="userId">The user to fail gameplay for.</param>
protected abstract void FailGameplay(int userId);
/// <summary>
/// Stops spectating a user.
/// </summary>