1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 06:52:55 +08:00

Merge pull request #14929 from peppy/gameplay-state

Replace `GameplayBeatmap` with `GameplayState`
This commit is contained in:
Dan Balasescu 2021-10-04 15:56:44 +09:00 committed by GitHub
commit aa1bfc16d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 130 additions and 124 deletions

View File

@ -4,13 +4,11 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Play;
using osuTK;
namespace osu.Game.Rulesets.Osu.Tests.Mods
@ -122,7 +120,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
private bool checkSomeHit() => Player.ScoreProcessor.JudgedHits >= 4;
private bool objectWithIncreasedVisibilityHasIndex(int index)
=> Player.Mods.Value.OfType<TestOsuModHidden>().Single().FirstObject == Player.ChildrenOfType<GameplayBeatmap>().Single().HitObjects[index];
=> Player.Mods.Value.OfType<TestOsuModHidden>().Single().FirstObject == Player.GameplayState.Beatmap.HitObjects[index];
private class TestOsuModHidden : OsuModHidden
{

View File

@ -17,6 +17,7 @@ using osu.Framework.Testing.Input;
using osu.Framework.Utils;
using osu.Game.Audio;
using osu.Game.Configuration;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Skinning;
using osu.Game.Rulesets.Osu.UI.Cursor;
using osu.Game.Screens.Play;
@ -29,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Tests
public class TestSceneGameplayCursor : OsuSkinnableTestScene
{
[Cached]
private GameplayBeatmap gameplayBeatmap;
private GameplayState gameplayState;
private OsuCursorContainer lastContainer;
@ -40,7 +41,8 @@ namespace osu.Game.Rulesets.Osu.Tests
public TestSceneGameplayCursor()
{
gameplayBeatmap = new GameplayBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo));
var ruleset = new OsuRuleset();
gameplayState = new GameplayState(CreateBeatmap(ruleset.RulesetInfo), ruleset, Array.Empty<Mod>());
AddStep("change background colour", () =>
{
@ -57,7 +59,7 @@ namespace osu.Game.Rulesets.Osu.Tests
AddSliderStep("circle size", 0f, 10f, 0f, val =>
{
config.SetValue(OsuSetting.AutoCursorSize, true);
gameplayBeatmap.BeatmapInfo.BaseDifficulty.CircleSize = val;
gameplayState.Beatmap.BeatmapInfo.BaseDifficulty.CircleSize = val;
Scheduler.AddOnce(() => loadContent(false));
});
@ -73,7 +75,7 @@ namespace osu.Game.Rulesets.Osu.Tests
public void TestSizing(int circleSize, float userScale)
{
AddStep($"set user scale to {userScale}", () => config.SetValue(OsuSetting.GameplayCursorSize, userScale));
AddStep($"adjust cs to {circleSize}", () => gameplayBeatmap.BeatmapInfo.BaseDifficulty.CircleSize = circleSize);
AddStep($"adjust cs to {circleSize}", () => gameplayState.Beatmap.BeatmapInfo.BaseDifficulty.CircleSize = circleSize);
AddStep("turn on autosizing", () => config.SetValue(OsuSetting.AutoCursorSize, true));
AddStep("load content", () => loadContent());

View File

@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
private OsuPlayfield playfield { get; set; }
[Resolved(canBeNull: true)]
private GameplayBeatmap gameplayBeatmap { get; set; }
private GameplayState gameplayState { get; set; }
[BackgroundDependencyLoader]
private void load(ISkinSource skin, OsuColour colours)
@ -75,12 +75,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
protected override void Update()
{
if (playfield == null || gameplayBeatmap == null) return;
if (playfield == null || gameplayState == null) return;
DrawableHitObject kiaiHitObject = null;
// Check whether currently in a kiai section first. This is only done as an optimisation to avoid enumerating AliveObjects when not necessary.
if (gameplayBeatmap.ControlPointInfo.EffectPointAt(Time.Current).KiaiMode)
if (gameplayState.Beatmap.ControlPointInfo.EffectPointAt(Time.Current).KiaiMode)
kiaiHitObject = playfield.HitObjectContainer.AliveObjects.FirstOrDefault(isTracking);
kiaiSpewer.Active.Value = kiaiHitObject != null;

View File

@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
}
[Resolved(canBeNull: true)]
private GameplayBeatmap beatmap { get; set; }
private GameplayState state { get; set; }
[Resolved]
private OsuConfigManager config { get; set; }
@ -96,10 +96,10 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
{
float scale = userCursorScale.Value;
if (autoCursorScale.Value && beatmap != null)
if (autoCursorScale.Value && state != null)
{
// if we have a beatmap available, let's get its circle size to figure out an automatic cursor scale modifier.
scale *= GetScaleForCircleSize(beatmap.BeatmapInfo.BaseDifficulty.CircleSize);
scale *= GetScaleForCircleSize(state.Beatmap.BeatmapInfo.BaseDifficulty.CircleSize);
}
cursorScale.Value = scale;

View File

@ -25,10 +25,10 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
}
[BackgroundDependencyLoader(true)]
private void load(GameplayBeatmap gameplayBeatmap)
private void load(GameplayState gameplayState)
{
if (gameplayBeatmap != null)
((IBindable<JudgementResult>)LastResult).BindTo(gameplayBeatmap.LastJudgementResult);
if (gameplayState != null)
((IBindable<JudgementResult>)LastResult).BindTo(gameplayState.LastJudgementResult);
}
private bool passing;

View File

@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Taiko.UI
}
[BackgroundDependencyLoader(true)]
private void load(TextureStore textures, GameplayBeatmap gameplayBeatmap)
private void load(TextureStore textures, GameplayState gameplayState)
{
InternalChildren = new[]
{
@ -49,8 +49,8 @@ namespace osu.Game.Rulesets.Taiko.UI
animations[TaikoMascotAnimationState.Fail] = new TaikoMascotAnimation(TaikoMascotAnimationState.Fail),
};
if (gameplayBeatmap != null)
((IBindable<JudgementResult>)LastResult).BindTo(gameplayBeatmap.LastJudgementResult);
if (gameplayState != null)
((IBindable<JudgementResult>)LastResult).BindTo(gameplayState.LastJudgementResult);
}
protected override void LoadComplete()

View File

@ -1,6 +1,7 @@
// 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.
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@ -17,6 +18,8 @@ using osu.Game.Beatmaps;
using osu.Game.Graphics.Sprites;
using osu.Game.Replays;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.UI;
using osu.Game.Scoring;
@ -38,7 +41,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private TestReplayRecorder recorder;
[Cached]
private GameplayBeatmap gameplayBeatmap = new GameplayBeatmap(new Beatmap());
private GameplayState gameplayState = new GameplayState(new Beatmap(), new OsuRuleset(), Array.Empty<Mod>());
[SetUp]
public void SetUp() => Schedule(() =>
@ -57,7 +60,7 @@ namespace osu.Game.Tests.Visual.Gameplay
Recorder = recorder = new TestReplayRecorder(new Score
{
Replay = replay,
ScoreInfo = { Beatmap = gameplayBeatmap.BeatmapInfo }
ScoreInfo = { Beatmap = gameplayState.Beatmap.BeatmapInfo }
})
{
ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos),

View File

@ -1,6 +1,7 @@
// 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.
using System;
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@ -13,6 +14,8 @@ using osu.Game.Beatmaps;
using osu.Game.Graphics.Sprites;
using osu.Game.Replays;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.UI;
using osu.Game.Scoring;
@ -30,7 +33,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private readonly TestRulesetInputManager recordingManager;
[Cached]
private GameplayBeatmap gameplayBeatmap = new GameplayBeatmap(new Beatmap());
private GameplayState gameplayState = new GameplayState(new Beatmap(), new OsuRuleset(), Array.Empty<Mod>());
public TestSceneReplayRecording()
{
@ -48,7 +51,7 @@ namespace osu.Game.Tests.Visual.Gameplay
Recorder = new TestReplayRecorder(new Score
{
Replay = replay,
ScoreInfo = { Beatmap = gameplayBeatmap.BeatmapInfo }
ScoreInfo = { Beatmap = gameplayState.Beatmap.BeatmapInfo }
})
{
ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos)

View File

@ -25,6 +25,8 @@ using osu.Game.Online.Spectator;
using osu.Game.Replays;
using osu.Game.Replays.Legacy;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Replays.Types;
using osu.Game.Rulesets.UI;
@ -62,7 +64,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private SpectatorClient spectatorClient { get; set; }
[Cached]
private GameplayBeatmap gameplayBeatmap = new GameplayBeatmap(new Beatmap());
private GameplayState gameplayState = new GameplayState(new Beatmap(), new OsuRuleset(), Array.Empty<Mod>());
[SetUp]
public void SetUp() => Schedule(() =>

View File

@ -134,7 +134,7 @@ namespace osu.Game.Online.Spectator
return Task.CompletedTask;
}
public void BeginPlaying(GameplayBeatmap beatmap, Score score)
public void BeginPlaying(GameplayState state, Score score)
{
Debug.Assert(ThreadSafety.IsUpdateThread);
@ -148,7 +148,7 @@ namespace osu.Game.Online.Spectator
currentState.RulesetID = score.ScoreInfo.RulesetID;
currentState.Mods = score.ScoreInfo.Mods.Select(m => new APIMod(m)).ToArray();
currentBeatmap = beatmap.PlayableBeatmap;
currentBeatmap = state.Beatmap;
currentScore = score;
BeginPlayingInternal(currentState);

View File

@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.UI
private SpectatorClient spectatorClient { get; set; }
[Resolved]
private GameplayBeatmap gameplayBeatmap { get; set; }
private GameplayState gameplayState { get; set; }
protected ReplayRecorder(Score target)
{
@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.UI
inputManager = GetContainingInputManager();
spectatorClient?.BeginPlaying(gameplayBeatmap, target);
spectatorClient?.BeginPlaying(gameplayState, target);
}
protected override void Dispose(bool isDisposing)

View File

@ -213,8 +213,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate
{
}
protected override void StartGameplay(int userId, GameplayState gameplayState)
=> instances.Single(i => i.UserId == userId).LoadScore(gameplayState.Score);
protected override void StartGameplay(int userId, SpectatorGameplayState spectatorGameplayState)
=> instances.Single(i => i.UserId == userId).LoadScore(spectatorGameplayState.Score);
protected override void EndGameplay(int userId)
{

View File

@ -1,56 +0,0 @@
// 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.
using System.Collections.Generic;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Timing;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Screens.Play
{
public class GameplayBeatmap : Component, IBeatmap
{
public readonly IBeatmap PlayableBeatmap;
public GameplayBeatmap(IBeatmap playableBeatmap)
{
PlayableBeatmap = playableBeatmap;
}
public BeatmapInfo BeatmapInfo
{
get => PlayableBeatmap.BeatmapInfo;
set => PlayableBeatmap.BeatmapInfo = value;
}
public BeatmapMetadata Metadata => PlayableBeatmap.Metadata;
public ControlPointInfo ControlPointInfo
{
get => PlayableBeatmap.ControlPointInfo;
set => PlayableBeatmap.ControlPointInfo = value;
}
public List<BreakPeriod> Breaks => PlayableBeatmap.Breaks;
public double TotalBreakTime => PlayableBeatmap.TotalBreakTime;
public IReadOnlyList<HitObject> HitObjects => PlayableBeatmap.HitObjects;
public IEnumerable<BeatmapStatistic> GetStatistics() => PlayableBeatmap.GetStatistics();
public double GetMostCommonBeatLength() => PlayableBeatmap.GetMostCommonBeatLength();
public IBeatmap Clone() => PlayableBeatmap.Clone();
private readonly Bindable<JudgementResult> lastJudgementResult = new Bindable<JudgementResult>();
public IBindable<JudgementResult> LastJudgementResult => lastJudgementResult;
public void ApplyResult(JudgementResult result) => lastJudgementResult.Value = result;
}
}

View File

@ -0,0 +1,55 @@
// 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.
using System.Collections.Generic;
using osu.Framework.Bindables;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mods;
#nullable enable
namespace osu.Game.Screens.Play
{
/// <summary>
/// The state of an active gameplay session, generally constructed and exposed by <see cref="Player"/>.
/// </summary>
public class GameplayState
{
/// <summary>
/// The final post-convert post-mod-application beatmap.
/// </summary>
public readonly IBeatmap Beatmap;
/// <summary>
/// The ruleset used in gameplay.
/// </summary>
public readonly Ruleset Ruleset;
/// <summary>
/// The mods applied to the gameplay.
/// </summary>
public IReadOnlyList<Mod> Mods;
/// <summary>
/// A bindable tracking the last judgement result applied to any hit object.
/// </summary>
public IBindable<JudgementResult> LastJudgementResult => lastJudgementResult;
private readonly Bindable<JudgementResult> lastJudgementResult = new Bindable<JudgementResult>();
public GameplayState(IBeatmap beatmap, Ruleset ruleset, IReadOnlyList<Mod> mods)
{
Beatmap = beatmap;
Ruleset = ruleset;
Mods = mods;
}
/// <summary>
/// Applies the score change of a <see cref="JudgementResult"/> to this <see cref="GameplayState"/>.
/// </summary>
/// <param name="result">The <see cref="JudgementResult"/> to apply.</param>
public void ApplyResult(JudgementResult result) => lastJudgementResult.Value = result;
}
}

View File

@ -93,9 +93,9 @@ namespace osu.Game.Screens.Play
[Resolved]
private SpectatorClient spectatorClient { get; set; }
protected Ruleset GameplayRuleset { get; private set; }
public GameplayState GameplayState { get; private set; }
protected GameplayBeatmap GameplayBeatmap { get; private set; }
private Ruleset ruleset;
private Sample sampleRestart;
@ -165,7 +165,7 @@ namespace osu.Game.Screens.Play
// ensure the score is in a consistent state with the current player.
Score.ScoreInfo.Beatmap = Beatmap.Value.BeatmapInfo;
Score.ScoreInfo.Ruleset = GameplayRuleset.RulesetInfo;
Score.ScoreInfo.Ruleset = ruleset.RulesetInfo;
Score.ScoreInfo.Mods = Mods.Value.ToArray();
PrepareReplay();
@ -206,16 +206,16 @@ namespace osu.Game.Screens.Play
if (game is OsuGame osuGame)
LocalUserPlaying.BindTo(osuGame.LocalUserPlaying);
DrawableRuleset = GameplayRuleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value);
DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value);
dependencies.CacheAs(DrawableRuleset);
ScoreProcessor = GameplayRuleset.CreateScoreProcessor();
ScoreProcessor = ruleset.CreateScoreProcessor();
ScoreProcessor.ApplyBeatmap(playableBeatmap);
ScoreProcessor.Mods.BindTo(Mods);
dependencies.CacheAs(ScoreProcessor);
HealthProcessor = GameplayRuleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime);
HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime);
HealthProcessor.ApplyBeatmap(playableBeatmap);
dependencies.CacheAs(HealthProcessor);
@ -225,12 +225,11 @@ namespace osu.Game.Screens.Play
InternalChild = GameplayClockContainer = CreateGameplayClockContainer(Beatmap.Value, DrawableRuleset.GameplayStartTime);
AddInternal(GameplayBeatmap = new GameplayBeatmap(playableBeatmap));
dependencies.CacheAs(GameplayState = new GameplayState(playableBeatmap, ruleset, Mods.Value));
AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer));
dependencies.CacheAs(GameplayBeatmap);
var rulesetSkinProvider = new RulesetSkinProvidingContainer(GameplayRuleset, playableBeatmap, Beatmap.Value.Skin);
var rulesetSkinProvider = new RulesetSkinProvidingContainer(ruleset, playableBeatmap, Beatmap.Value.Skin);
// load the skinning hierarchy first.
// this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources.
@ -280,7 +279,7 @@ namespace osu.Game.Screens.Play
{
HealthProcessor.ApplyResult(r);
ScoreProcessor.ApplyResult(r);
GameplayBeatmap.ApplyResult(r);
GameplayState.ApplyResult(r);
};
DrawableRuleset.RevertResult += r =>
@ -478,17 +477,17 @@ namespace osu.Game.Screens.Play
throw new InvalidOperationException("Beatmap was not loaded");
var rulesetInfo = Ruleset.Value ?? Beatmap.Value.BeatmapInfo.Ruleset;
GameplayRuleset = rulesetInfo.CreateInstance();
ruleset = rulesetInfo.CreateInstance();
try
{
playable = Beatmap.Value.GetPlayableBeatmap(GameplayRuleset.RulesetInfo, Mods.Value);
playable = Beatmap.Value.GetPlayableBeatmap(ruleset.RulesetInfo, Mods.Value);
}
catch (BeatmapInvalidForRulesetException)
{
// A playable beatmap may not be creatable with the user's preferred ruleset, so try using the beatmap's default ruleset
rulesetInfo = Beatmap.Value.BeatmapInfo.Ruleset;
GameplayRuleset = rulesetInfo.CreateInstance();
ruleset = rulesetInfo.CreateInstance();
playable = Beatmap.Value.GetPlayableBeatmap(rulesetInfo, Mods.Value);
}
@ -1010,7 +1009,7 @@ namespace osu.Game.Screens.Play
using (var stream = new MemoryStream())
{
new LegacyScoreEncoder(score, GameplayBeatmap.PlayableBeatmap).Encode(stream);
new LegacyScoreEncoder(score, GameplayState.Beatmap).Encode(stream);
replayReader = new LegacyByteArrayReader(stream.ToArray(), "replay.osr");
}

View File

@ -41,7 +41,7 @@ namespace osu.Game.Screens.Play
DrawableRuleset?.SetReplayScore(Score);
}
protected override Score CreateScore() => createScore(GameplayBeatmap.PlayableBeatmap, Mods.Value);
protected override Score CreateScore() => createScore(GameplayState.Beatmap, Mods.Value);
// Don't re-import replay scores as they're already present in the database.
protected override Task ImportScore(Score score) => Task.CompletedTask;
@ -78,7 +78,7 @@ namespace osu.Game.Screens.Play
void keyboardSeek(int direction)
{
double target = Math.Clamp(GameplayClockContainer.CurrentTime + direction * keyboard_seek_amount, 0, GameplayBeatmap.HitObjects.Last().GetEndTime());
double target = Math.Clamp(GameplayClockContainer.CurrentTime + direction * keyboard_seek_amount, 0, GameplayState.Beatmap.HitObjects.Last().GetEndTime());
Seek(target);
}

View File

@ -56,7 +56,7 @@ namespace osu.Game.Screens.Play
/// The player's immediate online gameplay state.
/// This doesn't always reflect the gameplay state being watched.
/// </summary>
private GameplayState immediateGameplayState;
private SpectatorGameplayState immediateSpectatorGameplayState;
private GetBeatmapSetRequest onlineBeatmapRequest;
@ -146,7 +146,7 @@ namespace osu.Game.Screens.Play
Width = 250,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Action = () => scheduleStart(immediateGameplayState),
Action = () => scheduleStart(immediateSpectatorGameplayState),
Enabled = { Value = false }
}
}
@ -167,18 +167,18 @@ namespace osu.Game.Screens.Play
showBeatmapPanel(spectatorState);
}
protected override void StartGameplay(int userId, GameplayState gameplayState)
protected override void StartGameplay(int userId, SpectatorGameplayState spectatorGameplayState)
{
immediateGameplayState = gameplayState;
immediateSpectatorGameplayState = spectatorGameplayState;
watchButton.Enabled.Value = true;
scheduleStart(gameplayState);
scheduleStart(spectatorGameplayState);
}
protected override void EndGameplay(int userId)
{
scheduledStart?.Cancel();
immediateGameplayState = null;
immediateSpectatorGameplayState = null;
watchButton.Enabled.Value = false;
clearDisplay();
@ -194,7 +194,7 @@ namespace osu.Game.Screens.Play
private ScheduledDelegate scheduledStart;
private void scheduleStart(GameplayState gameplayState)
private void scheduleStart(SpectatorGameplayState spectatorGameplayState)
{
// This function may be called multiple times in quick succession once the screen becomes current again.
scheduledStart?.Cancel();
@ -203,15 +203,15 @@ namespace osu.Game.Screens.Play
if (this.IsCurrentScreen())
start();
else
scheduleStart(gameplayState);
scheduleStart(spectatorGameplayState);
});
void start()
{
Beatmap.Value = gameplayState.Beatmap;
Ruleset.Value = gameplayState.Ruleset.RulesetInfo;
Beatmap.Value = spectatorGameplayState.Beatmap;
Ruleset.Value = spectatorGameplayState.Ruleset.RulesetInfo;
this.Push(new SpectatorPlayerLoader(gameplayState.Score, () => new SoloSpectatorPlayer(gameplayState.Score)));
this.Push(new SpectatorPlayerLoader(spectatorGameplayState.Score, () => new SoloSpectatorPlayer(spectatorGameplayState.Score)));
}
}

View File

@ -66,8 +66,8 @@ namespace osu.Game.Screens.Play
foreach (var frame in bundle.Frames)
{
IConvertibleReplayFrame convertibleFrame = GameplayRuleset.CreateConvertibleReplayFrame();
convertibleFrame.FromLegacy(frame, GameplayBeatmap.PlayableBeatmap);
IConvertibleReplayFrame convertibleFrame = GameplayState.Ruleset.CreateConvertibleReplayFrame();
convertibleFrame.FromLegacy(frame, GameplayState.Beatmap);
var convertedFrame = (ReplayFrame)convertibleFrame;
convertedFrame.Time = frame.Time;

View File

@ -8,9 +8,9 @@ using osu.Game.Scoring;
namespace osu.Game.Screens.Spectate
{
/// <summary>
/// The gameplay state of a spectated user. This class is immutable.
/// An immutable spectator gameplay state.
/// </summary>
public class GameplayState
public class SpectatorGameplayState
{
/// <summary>
/// The score which the user is playing.
@ -27,7 +27,7 @@ namespace osu.Game.Screens.Spectate
/// </summary>
public readonly WorkingBeatmap Beatmap;
public GameplayState(Score score, Ruleset ruleset, WorkingBeatmap beatmap)
public SpectatorGameplayState(Score score, Ruleset ruleset, WorkingBeatmap beatmap)
{
Score = score;
Ruleset = ruleset;

View File

@ -43,7 +43,7 @@ namespace osu.Game.Screens.Spectate
private readonly IBindableDictionary<int, SpectatorState> playingUserStates = new BindableDictionary<int, SpectatorState>();
private readonly Dictionary<int, User> userMap = new Dictionary<int, User>();
private readonly Dictionary<int, GameplayState> gameplayStates = new Dictionary<int, GameplayState>();
private readonly Dictionary<int, SpectatorGameplayState> gameplayStates = new Dictionary<int, SpectatorGameplayState>();
private IBindable<WeakReference<BeatmapSetInfo>> managerUpdated;
@ -173,7 +173,7 @@ namespace osu.Game.Screens.Spectate
Replay = new Replay { HasReceivedAllFrames = false },
};
var gameplayState = new GameplayState(score, resolvedRuleset, beatmaps.GetWorkingBeatmap(resolvedBeatmap));
var gameplayState = new SpectatorGameplayState(score, resolvedRuleset, beatmaps.GetWorkingBeatmap(resolvedBeatmap));
gameplayStates[userId] = gameplayState;
Schedule(() => StartGameplay(userId, gameplayState));
@ -190,8 +190,8 @@ namespace osu.Game.Screens.Spectate
/// Starts gameplay for a user.
/// </summary>
/// <param name="userId">The user to start gameplay for.</param>
/// <param name="gameplayState">The gameplay state.</param>
protected abstract void StartGameplay(int userId, [NotNull] GameplayState gameplayState);
/// <param name="spectatorGameplayState">The gameplay state.</param>
protected abstract void StartGameplay(int userId, [NotNull] SpectatorGameplayState spectatorGameplayState);
/// <summary>
/// Ends gameplay for a user.

View File

@ -84,7 +84,7 @@ namespace osu.Game.Tests.Visual
if (autoplayMod != null)
{
DrawableRuleset?.SetReplayScore(autoplayMod.CreateReplayScore(GameplayBeatmap.PlayableBeatmap, Mods.Value));
DrawableRuleset?.SetReplayScore(autoplayMod.CreateReplayScore(GameplayState.Beatmap, Mods.Value));
return;
}