mirror of
https://github.com/ppy/osu
synced 2024-12-23 23:33:36 +00:00
Move storyboard outro logic to DrawableStoryboard
This commit is contained in:
parent
0e545e1ed9
commit
b15838b220
@ -6,12 +6,14 @@ using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osu.Game.Storyboards;
|
||||
using osuTK;
|
||||
@ -36,6 +38,16 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
storyboard.GetLayer("Background").Add(sprite);
|
||||
}
|
||||
|
||||
[SetUpSteps]
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
AddStep("ignore user settings", () =>
|
||||
{
|
||||
Player.DimmableStoryboard.IgnoreUserSettings.Value = true;
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStoryboardSkipOutro()
|
||||
{
|
||||
@ -50,8 +62,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
AddUntilStep("storyboard loaded", () => Player.Beatmap.Value.StoryboardLoaded);
|
||||
AddUntilStep("storyboard ends", () => Player.HUDOverlay.Progress.ReferenceClock.CurrentTime >= storyboard_duration);
|
||||
AddWaitStep("wait for score", 10);
|
||||
AddAssert("score shown", () => Player.IsScoreShown);
|
||||
AddUntilStep("wait for score shown", () => Player.IsScoreShown);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -85,6 +96,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
public bool IsScoreShown => !this.IsCurrentScreen() && this.GetChildScreen() is ResultsScreen;
|
||||
|
||||
public new DimmableStoryboard DimmableStoryboard => base.DimmableStoryboard;
|
||||
|
||||
public OutroPlayer()
|
||||
: base(false)
|
||||
{
|
||||
|
@ -48,8 +48,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
{
|
||||
AllowPause = false,
|
||||
AllowRestart = false,
|
||||
AllowSkippingIntro = false,
|
||||
AllowSkippingOutro = false,
|
||||
AllowSkipping = false,
|
||||
})
|
||||
{
|
||||
this.userIds = userIds;
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Storyboards;
|
||||
@ -61,5 +62,7 @@ namespace osu.Game.Screens.Play
|
||||
Add(storyboard);
|
||||
OverlayLayerContainer.Add(storyboard.OverlayLayer.CreateProxy());
|
||||
}
|
||||
|
||||
public IBindable<bool> HasStoryboardEnded => drawableStoryboard?.HasStoryboardEnded;
|
||||
}
|
||||
}
|
||||
|
@ -240,8 +240,6 @@ namespace osu.Game.Screens.Play
|
||||
userOffsetClock.ProcessFrame();
|
||||
}
|
||||
|
||||
updateHasStoryboardEnded();
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
@ -303,23 +301,5 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
# region Storyboard outro logic
|
||||
|
||||
public IBindable<bool> HasStoryboardEnded => hasStoryboardEnded;
|
||||
|
||||
public bool HasTimeLeftInStoryboard => GameplayClock.CurrentTime <= StoryboardEndTime;
|
||||
|
||||
private readonly BindableBool hasStoryboardEnded = new BindableBool(true);
|
||||
|
||||
private void updateHasStoryboardEnded()
|
||||
{
|
||||
if (StoryboardEndTime == 0)
|
||||
return;
|
||||
|
||||
hasStoryboardEnded.Value = GameplayClock.CurrentTime >= StoryboardEndTime;
|
||||
}
|
||||
|
||||
# endregion
|
||||
}
|
||||
}
|
||||
|
@ -74,8 +74,6 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private Bindable<bool> mouseWheelDisabled;
|
||||
|
||||
private Bindable<bool> storyboardEnabled;
|
||||
|
||||
private readonly Bindable<bool> storyboardReplacesBackground = new Bindable<bool>();
|
||||
|
||||
protected readonly Bindable<bool> LocalUserPlaying = new Bindable<bool>();
|
||||
@ -106,7 +104,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private BreakTracker breakTracker;
|
||||
|
||||
private SkipOverlay skipOverlay;
|
||||
private SkipOverlay skipIntroOverlay;
|
||||
|
||||
private SkipOverlay skipOutroOverlay;
|
||||
|
||||
@ -194,8 +192,6 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
mouseWheelDisabled = config.GetBindable<bool>(OsuSetting.MouseDisableWheel);
|
||||
|
||||
storyboardEnabled = config.GetBindable<bool>(OsuSetting.ShowStoryboard);
|
||||
|
||||
if (game != null)
|
||||
gameActive.BindTo(game.IsActive);
|
||||
|
||||
@ -250,7 +246,7 @@ namespace osu.Game.Screens.Play
|
||||
HUDOverlay.ShowHud.Value = false;
|
||||
HUDOverlay.ShowHud.Disabled = true;
|
||||
BreakOverlay.Hide();
|
||||
skipOverlay.Hide();
|
||||
skipIntroOverlay.Hide();
|
||||
}
|
||||
|
||||
DrawableRuleset.FrameStableClock.WaitingOnFrames.BindValueChanged(waiting =>
|
||||
@ -292,7 +288,8 @@ namespace osu.Game.Screens.Play
|
||||
HealthProcessor.Failed += onFail;
|
||||
|
||||
// Keep track of whether the storyboard ended after the playable portion
|
||||
GameplayClockContainer.HasStoryboardEnded.ValueChanged += updateCompletionState;
|
||||
if (DimmableStoryboard.HasStoryboardEnded != null)
|
||||
DimmableStoryboard.HasStoryboardEnded.ValueChanged += updateCompletionState;
|
||||
|
||||
foreach (var mod in Mods.Value.OfType<IApplicableToScoreProcessor>())
|
||||
mod.ApplyToScoreProcessor(ScoreProcessor);
|
||||
@ -365,7 +362,7 @@ namespace osu.Game.Screens.Play
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
},
|
||||
skipOverlay = new SkipOverlay(DrawableRuleset.GameplayStartTime)
|
||||
skipIntroOverlay = new SkipOverlay(DrawableRuleset.GameplayStartTime)
|
||||
{
|
||||
RequestSkip = performUserRequestedSkip
|
||||
},
|
||||
@ -399,11 +396,8 @@ namespace osu.Game.Screens.Play
|
||||
}
|
||||
};
|
||||
|
||||
if (!Configuration.AllowSkippingIntro)
|
||||
skipOverlay.Expire();
|
||||
|
||||
if (!Configuration.AllowSkippingOutro)
|
||||
skipOutroOverlay.Expire();
|
||||
if (!Configuration.AllowSkipping)
|
||||
skipIntroOverlay.Expire();
|
||||
|
||||
if (Configuration.AllowRestart)
|
||||
{
|
||||
@ -637,8 +631,9 @@ namespace osu.Game.Screens.Play
|
||||
return score.ScoreInfo;
|
||||
});
|
||||
|
||||
// show skip overlay if storyboard is enabled and has an outro
|
||||
if (storyboardEnabled.Value && GameplayClockContainer.HasTimeLeftInStoryboard)
|
||||
var storyboardHasOutro = DimmableStoryboard.ContentDisplayed && (!DimmableStoryboard.HasStoryboardEnded?.Value ?? false);
|
||||
|
||||
if (storyboardHasOutro)
|
||||
{
|
||||
skipOutroOverlay.Show();
|
||||
completionProgressDelegate = null;
|
||||
|
@ -21,13 +21,8 @@ namespace osu.Game.Screens.Play
|
||||
public bool AllowRestart { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player should be allowed to skip the intro, advancing to the start of gameplay.
|
||||
/// Whether the player should be allowed to skip intros/outros, advancing to the start of gameplay or the end of a storyboard.
|
||||
/// </summary>
|
||||
public bool AllowSkippingIntro { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player should be allowed to skip the outro, advancing to the end of a storyboard.
|
||||
/// </summary>
|
||||
public bool AllowSkippingOutro { get; set; } = true;
|
||||
public bool AllowSkipping { get; set; } = true;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using osuTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
@ -82,5 +83,27 @@ namespace osu.Game.Storyboards.Drawables
|
||||
foreach (var layer in Children)
|
||||
layer.Enabled = passing ? layer.Layer.VisibleWhenPassing : layer.Layer.VisibleWhenFailing;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
updateHasStoryboardEnded();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether the storyboard has ended after the gameplay portion of the beatmap.
|
||||
/// </summary>
|
||||
public IBindable<bool> HasStoryboardEnded => hasStoryboardEnded;
|
||||
|
||||
private readonly BindableBool hasStoryboardEnded = new BindableBool(true);
|
||||
|
||||
private void updateHasStoryboardEnded()
|
||||
{
|
||||
if (Storyboard.LatestEventTime == null)
|
||||
return;
|
||||
|
||||
var time = Clock.CurrentTime;
|
||||
hasStoryboardEnded.Value = time >= Storyboard.LatestEventTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
namespace osu.Game.Storyboards
|
||||
{
|
||||
public interface IHasDuration
|
||||
public interface IStoryboardElementHasDuration
|
||||
{
|
||||
double EndTime { get; }
|
||||
}
|
@ -40,7 +40,7 @@ namespace osu.Game.Storyboards
|
||||
/// Across all layers, find the latest point in time that a storyboard element ends at.
|
||||
/// Will return null if there are no elements.
|
||||
/// </summary>
|
||||
public double? LatestEventTime => Layers.SelectMany(l => l.Elements.OfType<IHasDuration>()).OrderByDescending(e => e.EndTime).FirstOrDefault()?.EndTime;
|
||||
public double? LatestEventTime => Layers.SelectMany(l => l.Elements.OfType<IStoryboardElementHasDuration>()).OrderByDescending(e => e.EndTime).FirstOrDefault()?.EndTime;
|
||||
|
||||
/// <summary>
|
||||
/// Depth of the currently front-most storyboard layer, excluding the overlay layer.
|
||||
|
@ -11,7 +11,7 @@ using JetBrains.Annotations;
|
||||
|
||||
namespace osu.Game.Storyboards
|
||||
{
|
||||
public class StoryboardSprite : IStoryboardElement, IHasDuration
|
||||
public class StoryboardSprite : IStoryboardElement, IStoryboardElementHasDuration
|
||||
{
|
||||
private readonly List<CommandLoop> loops = new List<CommandLoop>();
|
||||
private readonly List<CommandTrigger> triggers = new List<CommandTrigger>();
|
||||
|
Loading…
Reference in New Issue
Block a user