diff --git a/osu.Android.props b/osu.Android.props
index 1c4a6ffe75..97f7a7edb1 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,6 +52,6 @@
-
+
diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs
new file mode 100644
index 0000000000..dcf19ad993
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs
@@ -0,0 +1,35 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Framework.Utils;
+using osu.Game.Rulesets.Osu.Mods;
+using osu.Game.Tests.Visual;
+
+namespace osu.Game.Rulesets.Osu.Tests.Mods
+{
+ public class TestSceneOsuModDoubleTime : ModTestScene
+ {
+ public TestSceneOsuModDoubleTime()
+ : base(new OsuRuleset())
+ {
+ }
+
+ [TestCase(0.5)]
+ [TestCase(1.01)]
+ [TestCase(1.5)]
+ [TestCase(2)]
+ [TestCase(5)]
+ public void TestSpeedChangeCustomisation(double rate)
+ {
+ var mod = new OsuModDoubleTime { SpeedChange = { Value = rate } };
+
+ CreateModTest(new ModTestData
+ {
+ Mod = mod,
+ PassCondition = () => Player.ScoreProcessor.JudgedHits >= 2 &&
+ Precision.AlmostEquals(Player.GameplayClockContainer.GameplayClock.Rate, mod.SpeedChange.Value)
+ });
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs
new file mode 100644
index 0000000000..67b6dac787
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs
@@ -0,0 +1,108 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using NUnit.Framework;
+using osu.Framework.Graphics;
+using osu.Framework.Testing;
+using osu.Game.Beatmaps;
+using osu.Game.Beatmaps.ControlPoints;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Skinning;
+using osuTK;
+
+namespace osu.Game.Rulesets.Osu.Tests
+{
+ public class TestSceneHitCircleArea : ManualInputManagerTestScene
+ {
+ private HitCircle hitCircle;
+ private DrawableHitCircle drawableHitCircle;
+ private DrawableHitCircle.HitReceptor hitAreaReceptor => drawableHitCircle.HitArea;
+
+ [SetUp]
+ public new void SetUp()
+ {
+ base.SetUp();
+
+ Schedule(() =>
+ {
+ hitCircle = new HitCircle
+ {
+ Position = new Vector2(100, 100),
+ StartTime = Time.Current + 500
+ };
+
+ hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
+
+ Child = new SkinProvidingContainer(new DefaultSkin())
+ {
+ RelativeSizeAxes = Axes.Both,
+ Child = drawableHitCircle = new DrawableHitCircle(hitCircle)
+ {
+ Size = new Vector2(100)
+ }
+ };
+ });
+ }
+
+ [Test]
+ public void TestCircleHitCentre()
+ {
+ AddStep("move mouse to centre", () => InputManager.MoveMouseTo(hitAreaReceptor.ScreenSpaceDrawQuad.Centre));
+ scheduleHit();
+
+ AddAssert("hit registered", () => hitAreaReceptor.HitAction == OsuAction.LeftButton);
+ }
+
+ [Test]
+ public void TestCircleHitLeftEdge()
+ {
+ AddStep("move mouse to left edge", () =>
+ {
+ var drawQuad = hitAreaReceptor.ScreenSpaceDrawQuad;
+ var mousePosition = new Vector2(drawQuad.TopLeft.X, drawQuad.Centre.Y);
+
+ InputManager.MoveMouseTo(mousePosition);
+ });
+ scheduleHit();
+
+ AddAssert("hit registered", () => hitAreaReceptor.HitAction == OsuAction.LeftButton);
+ }
+
+ [TestCase(0.95f, OsuAction.LeftButton)]
+ [TestCase(1.05f, null)]
+ public void TestHitsCloseToEdge(float relativeDistanceFromCentre, OsuAction? expectedAction)
+ {
+ AddStep("move mouse to top left circle edge", () =>
+ {
+ var drawQuad = hitAreaReceptor.ScreenSpaceDrawQuad;
+ // sqrt(2) / 2 = sin(45deg) = cos(45deg)
+ // draw width halved to get radius
+ float correction = relativeDistanceFromCentre * (float)Math.Sqrt(2) / 2 * (drawQuad.Width / 2);
+ var mousePosition = new Vector2(drawQuad.Centre.X - correction, drawQuad.Centre.Y - correction);
+
+ InputManager.MoveMouseTo(mousePosition);
+ });
+ scheduleHit();
+
+ AddAssert($"hit {(expectedAction == null ? "not " : string.Empty)}registered", () => hitAreaReceptor.HitAction == expectedAction);
+ }
+
+ [Test]
+ public void TestCircleMissBoundingBoxCorner()
+ {
+ AddStep("move mouse to top left corner of bounding box", () => InputManager.MoveMouseTo(hitAreaReceptor.ScreenSpaceDrawQuad.TopLeft));
+ scheduleHit();
+
+ AddAssert("hit not registered", () => hitAreaReceptor.HitAction == null);
+ }
+
+ private void scheduleHit() => AddStep("schedule action", () =>
+ {
+ var delay = hitCircle.StartTime - hitCircle.HitWindows.WindowFor(HitResult.Great) - Time.Current;
+ Scheduler.AddDelayed(() => hitAreaReceptor.OnPressed(OsuAction.LeftButton), delay);
+ });
+ }
+}
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs
index 4ef63bb2a0..da1e666aba 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs
@@ -170,7 +170,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public Drawable ProxiedLayer => ApproachCircle;
- public class HitReceptor : Drawable, IKeyBindingHandler
+ public class HitReceptor : CompositeDrawable, IKeyBindingHandler
{
// IsHovered is used
public override bool HandlePositionalInput => true;
@@ -185,6 +185,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
+
+ CornerRadius = OsuHitObject.OBJECT_RADIUS;
+ CornerExponent = 2;
}
public bool OnPressed(OsuAction action)
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs
index 756f31e0bf..afeda5fb7c 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs
@@ -3,10 +3,8 @@
using System.ComponentModel;
using System.Linq;
-using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Screens.Play;
-using osu.Game.Storyboards;
namespace osu.Game.Tests.Visual.Gameplay
{
@@ -15,8 +13,6 @@ namespace osu.Game.Tests.Visual.Gameplay
{
protected new TestPlayer Player => (TestPlayer)base.Player;
- private ClockBackedTestWorkingBeatmap.TrackVirtualManual track;
-
protected override Player CreatePlayer(Ruleset ruleset)
{
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
@@ -27,17 +23,12 @@ namespace osu.Game.Tests.Visual.Gameplay
{
AddUntilStep("score above zero", () => Player.ScoreProcessor.TotalScore.Value > 0);
AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2));
- AddStep("rewind", () => track.Seek(-10000));
+ AddStep("seek to break time", () => Player.GameplayClockContainer.Seek(Player.BreakOverlay.Breaks.First().StartTime));
+ AddUntilStep("wait for seek to complete", () =>
+ Player.HUDOverlay.Progress.ReferenceClock.CurrentTime >= Player.BreakOverlay.Breaks.First().StartTime);
+ AddAssert("test keys not counting", () => !Player.HUDOverlay.KeyCounter.IsCounting);
+ AddStep("rewind", () => Player.GameplayClockContainer.Seek(-80000));
AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
}
-
- protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
- {
- var working = base.CreateWorkingBeatmap(beatmap, storyboard);
-
- track = (ClockBackedTestWorkingBeatmap.TrackVirtualManual)working.Track;
-
- return working;
- }
}
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
index e7b3e007fc..227ada70fe 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
@@ -47,21 +47,22 @@ namespace osu.Game.Tests.Visual.Gameplay
Key testKey = ((KeyCounterKeyboard)kc.Children.First()).Key;
- AddStep($"Press {testKey} key", () =>
+ void addPressKeyStep()
{
- InputManager.PressKey(testKey);
- InputManager.ReleaseKey(testKey);
- });
+ AddStep($"Press {testKey} key", () =>
+ {
+ InputManager.PressKey(testKey);
+ InputManager.ReleaseKey(testKey);
+ });
+ }
+ addPressKeyStep();
AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses == 1);
-
- AddStep($"Press {testKey} key", () =>
- {
- InputManager.PressKey(testKey);
- InputManager.ReleaseKey(testKey);
- });
-
+ addPressKeyStep();
AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses == 2);
+ AddStep("Disable counting", () => testCounter.IsCounting = false);
+ addPressKeyStep();
+ AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses == 2);
Add(kc);
}
diff --git a/osu.Game.Tournament/Components/TourneyVideo.cs b/osu.Game.Tournament/Components/TourneyVideo.cs
index 206689ca1a..7d2eaff515 100644
--- a/osu.Game.Tournament/Components/TourneyVideo.cs
+++ b/osu.Game.Tournament/Components/TourneyVideo.cs
@@ -1,12 +1,13 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using System.IO;
+using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Video;
+using osu.Framework.Platform;
using osu.Framework.Timing;
using osu.Game.Graphics;
@@ -14,21 +15,24 @@ namespace osu.Game.Tournament.Components
{
public class TourneyVideo : CompositeDrawable
{
- private readonly VideoSprite video;
+ private readonly string filename;
+ private readonly bool drawFallbackGradient;
+ private VideoSprite video;
- private readonly ManualClock manualClock;
+ private ManualClock manualClock;
- public TourneyVideo(Stream stream)
+ public TourneyVideo(string filename, bool drawFallbackGradient = false)
{
- if (stream == null)
- {
- InternalChild = new Box
- {
- Colour = ColourInfo.GradientVertical(OsuColour.Gray(0.3f), OsuColour.Gray(0.6f)),
- RelativeSizeAxes = Axes.Both,
- };
- }
- else
+ this.filename = filename;
+ this.drawFallbackGradient = drawFallbackGradient;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(Storage storage)
+ {
+ var stream = storage.GetStream($@"videos/{filename}.m4v");
+
+ if (stream != null)
{
InternalChild = video = new VideoSprite(stream)
{
@@ -37,6 +41,14 @@ namespace osu.Game.Tournament.Components
Clock = new FramedClock(manualClock = new ManualClock())
};
}
+ else if (drawFallbackGradient)
+ {
+ InternalChild = new Box
+ {
+ Colour = ColourInfo.GradientVertical(OsuColour.Gray(0.3f), OsuColour.Gray(0.6f)),
+ RelativeSizeAxes = Axes.Both,
+ };
+ }
}
public bool Loop
diff --git a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs
index 7119533743..8b8078e119 100644
--- a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs
@@ -129,8 +129,6 @@ namespace osu.Game.Tournament.Screens.Editors
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
- LayoutDuration = 200,
- LayoutEasing = Easing.OutQuint,
ChildrenEnumerable = round.Beatmaps.Select(p => new RoundBeatmapRow(round, p))
};
}
diff --git a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs
index e68946aaf2..46bb7b83e3 100644
--- a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs
@@ -124,8 +124,6 @@ namespace osu.Game.Tournament.Screens.Editors
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
- LayoutDuration = 200,
- LayoutEasing = Easing.OutQuint,
ChildrenEnumerable = round.Beatmaps.Select(p => new SeedingBeatmapRow(round, p))
};
}
diff --git a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs
index ca8bce1cca..631393c6f4 100644
--- a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs
@@ -202,8 +202,6 @@ namespace osu.Game.Tournament.Screens.Editors
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
- LayoutDuration = 200,
- LayoutEasing = Easing.OutQuint,
ChildrenEnumerable = team.Players.Select(p => new PlayerRow(team, p))
};
}
diff --git a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs
index 5598910824..e4256e727d 100644
--- a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs
@@ -48,8 +48,6 @@ namespace osu.Game.Tournament.Screens.Editors
Direction = FillDirection.Vertical,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
- LayoutDuration = 200,
- LayoutEasing = Easing.OutQuint,
Spacing = new Vector2(20)
},
},
diff --git a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs
index 6a3095d42d..d632e7c5f3 100644
--- a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs
+++ b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs
@@ -6,6 +6,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
+using osu.Framework.Platform;
using osu.Framework.Threading;
using osu.Game.Graphics.UserInterface;
using osu.Game.Tournament.Components;
@@ -19,7 +20,7 @@ using osuTK.Graphics;
namespace osu.Game.Tournament.Screens.Gameplay
{
- public class GameplayScreen : BeatmapInfoScreen
+ public class GameplayScreen : BeatmapInfoScreen, IProvideVideo
{
private readonly BindableBool warmup = new BindableBool();
@@ -39,12 +40,17 @@ namespace osu.Game.Tournament.Screens.Gameplay
private TournamentMatchChatDisplay chat { get; set; }
[BackgroundDependencyLoader]
- private void load(LadderInfo ladder, MatchIPCInfo ipc)
+ private void load(LadderInfo ladder, MatchIPCInfo ipc, Storage storage)
{
this.ipc = ipc;
AddRangeInternal(new Drawable[]
{
+ new TourneyVideo("gameplay")
+ {
+ Loop = true,
+ RelativeSizeAxes = Axes.Both,
+ },
new MatchHeader(),
new Container
{
diff --git a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs
index 293f6e0068..7b265ded32 100644
--- a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs
+++ b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs
@@ -42,7 +42,7 @@ namespace osu.Game.Tournament.Screens.Ladder
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
- new TourneyVideo(storage.GetStream(@"videos/ladder.m4v"))
+ new TourneyVideo("ladder")
{
RelativeSizeAxes = Axes.Both,
Loop = true,
diff --git a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs
index 080570eac4..4c93c04fcf 100644
--- a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs
+++ b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs
@@ -18,7 +18,7 @@ using osuTK.Graphics;
namespace osu.Game.Tournament.Screens.Schedule
{
- public class ScheduleScreen : TournamentScreen, IProvideVideo
+ public class ScheduleScreen : TournamentScreen
{
private readonly Bindable currentMatch = new Bindable();
private Container mainContainer;
@@ -33,7 +33,7 @@ namespace osu.Game.Tournament.Screens.Schedule
InternalChildren = new Drawable[]
{
- new TourneyVideo(storage.GetStream(@"videos/schedule.m4v"))
+ new TourneyVideo("schedule")
{
RelativeSizeAxes = Axes.Both,
Loop = true,
diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
index db5363c155..513d84b594 100644
--- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
+++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
@@ -34,7 +34,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
InternalChildren = new Drawable[]
{
- new TourneyVideo(storage.GetStream(@"videos/seeding.m4v"))
+ new TourneyVideo("seeding")
{
RelativeSizeAxes = Axes.Both,
Loop = true,
diff --git a/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs
index 6559113f55..d584c21058 100644
--- a/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs
+++ b/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs
@@ -26,7 +26,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
InternalChildren = new Drawable[]
{
- new TourneyVideo(storage.GetStream(@"videos/teamintro.m4v"))
+ new TourneyVideo("teamintro")
{
RelativeSizeAxes = Axes.Both,
Loop = true,
diff --git a/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs b/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs
index 30b86f8421..1765ab7ba2 100644
--- a/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs
+++ b/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs
@@ -31,13 +31,13 @@ namespace osu.Game.Tournament.Screens.TeamWin
InternalChildren = new Drawable[]
{
- blueWinVideo = new TourneyVideo(storage.GetStream(@"videos/teamwin-blue.m4v"))
+ blueWinVideo = new TourneyVideo("teamwin-blue")
{
Alpha = 1,
RelativeSizeAxes = Axes.Both,
Loop = true,
},
- redWinVideo = new TourneyVideo(storage.GetStream(@"videos/teamwin-red.m4v"))
+ redWinVideo = new TourneyVideo("teamwin-red")
{
Alpha = 0,
RelativeSizeAxes = Axes.Both,
diff --git a/osu.Game.Tournament/Screens/TournamentScreen.cs b/osu.Game.Tournament/Screens/TournamentScreen.cs
index 0b5b3e728b..5da7c7a5d2 100644
--- a/osu.Game.Tournament/Screens/TournamentScreen.cs
+++ b/osu.Game.Tournament/Screens/TournamentScreen.cs
@@ -18,6 +18,9 @@ namespace osu.Game.Tournament.Screens
protected TournamentScreen()
{
RelativeSizeAxes = Axes.Both;
+
+ FillMode = FillMode.Fit;
+ FillAspectRatio = 16 / 9f;
}
public override void Hide() => this.FadeOut(FADE_DELAY);
diff --git a/osu.Game.Tournament/TournamentSceneManager.cs b/osu.Game.Tournament/TournamentSceneManager.cs
index 9f5f2b6827..287e25b1fb 100644
--- a/osu.Game.Tournament/TournamentSceneManager.cs
+++ b/osu.Game.Tournament/TournamentSceneManager.cs
@@ -61,7 +61,7 @@ namespace osu.Game.Tournament
//Masking = true,
Children = new Drawable[]
{
- video = new TourneyVideo(storage.GetStream("videos/main.m4v"))
+ video = new TourneyVideo("main", true)
{
Loop = true,
RelativeSizeAxes = Axes.Both,
diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs
index 11ca36e25f..bcadba14af 100644
--- a/osu.Game/Screens/Play/Player.cs
+++ b/osu.Game/Screens/Play/Player.cs
@@ -184,7 +184,7 @@ namespace osu.Game.Screens.Play
foreach (var mod in Mods.Value.OfType())
mod.ApplyToHealthProcessor(HealthProcessor);
- BreakOverlay.IsBreakTime.ValueChanged += _ => updatePauseOnFocusLostState();
+ BreakOverlay.IsBreakTime.BindValueChanged(onBreakTimeChanged, true);
}
private void addUnderlayComponents(Container target)
@@ -229,7 +229,11 @@ namespace osu.Game.Screens.Play
IsPaused = { BindTarget = GameplayClockContainer.IsPaused }
},
PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = GameplayClockContainer.UserPlaybackRate } } },
- KeyCounter = { AlwaysVisible = { BindTarget = DrawableRuleset.HasReplayLoaded } },
+ KeyCounter =
+ {
+ AlwaysVisible = { BindTarget = DrawableRuleset.HasReplayLoaded },
+ IsCounting = false
+ },
RequestSeek = GameplayClockContainer.Seek,
Anchor = Anchor.Centre,
Origin = Anchor.Centre
@@ -286,6 +290,12 @@ namespace osu.Game.Screens.Play
HealthProcessor.IsBreakTime.BindTo(BreakOverlay.IsBreakTime);
}
+ private void onBreakTimeChanged(ValueChangedEvent isBreakTime)
+ {
+ updatePauseOnFocusLostState();
+ HUDOverlay.KeyCounter.IsCounting = !isBreakTime.NewValue;
+ }
+
private void updatePauseOnFocusLostState() =>
HUDOverlay.HoldToQuit.PauseOnFocusLost = PauseOnFocusLost
&& !DrawableRuleset.HasReplayLoaded.Value
diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs
index 3daf5b1ff1..ac7e509c2c 100644
--- a/osu.Game/Screens/Play/SkipOverlay.cs
+++ b/osu.Game/Screens/Play/SkipOverlay.cs
@@ -116,7 +116,7 @@ namespace osu.Game.Screens.Play
{
base.Update();
- var progress = Math.Max(0, 1 - (gameplayClock.CurrentTime - displayTime) / (fadeOutBeginTime - displayTime));
+ var progress = fadeOutBeginTime <= displayTime ? 1 : Math.Max(0, 1 - (gameplayClock.CurrentTime - displayTime) / (fadeOutBeginTime - displayTime));
remainingTimeBox.Width = (float)Interpolation.Lerp(remainingTimeBox.Width, progress, Math.Clamp(Time.Elapsed / 40, 0, 1));
diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs
index f102e2ece3..d1d8059cb1 100644
--- a/osu.Game/Tests/Visual/OsuTestScene.cs
+++ b/osu.Game/Tests/Visual/OsuTestScene.cs
@@ -231,15 +231,8 @@ namespace osu.Game.Tests.Visual
{
private readonly IFrameBasedClock referenceClock;
- private readonly ManualClock clock = new ManualClock();
-
private bool running;
- ///
- /// Local offset added to the reference clock to resolve correct time.
- ///
- private double offset;
-
public TrackVirtualManual(IFrameBasedClock referenceClock)
{
this.referenceClock = referenceClock;
@@ -248,10 +241,10 @@ namespace osu.Game.Tests.Visual
public override bool Seek(double seek)
{
- offset = Math.Clamp(seek, 0, Length);
+ accumulated = Math.Clamp(seek, 0, Length);
lastReferenceTime = null;
- return offset == seek;
+ return accumulated == seek;
}
public override void Start()
@@ -270,9 +263,6 @@ namespace osu.Game.Tests.Visual
if (running)
{
running = false;
- // on stopping, the current value should be transferred out of the clock, as we can no longer rely on
- // the referenceClock (which will still be counting time).
- offset = clock.CurrentTime;
lastReferenceTime = null;
}
}
@@ -281,7 +271,9 @@ namespace osu.Game.Tests.Visual
private double? lastReferenceTime;
- public override double CurrentTime => clock.CurrentTime;
+ private double accumulated;
+
+ public override double CurrentTime => Math.Min(accumulated, Length);
protected override void UpdateState()
{
@@ -291,18 +283,12 @@ namespace osu.Game.Tests.Visual
{
double refTime = referenceClock.CurrentTime;
- if (!lastReferenceTime.HasValue)
- {
- // if the clock just started running, the current value should be transferred to the offset
- // (to zero the progression of time).
- offset -= refTime;
- }
+ if (lastReferenceTime.HasValue)
+ accumulated += (refTime - lastReferenceTime.Value) * Rate;
lastReferenceTime = refTime;
}
- clock.CurrentTime = Math.Min((lastReferenceTime ?? 0) + offset, Length);
-
if (CurrentTime >= Length)
{
Stop();
diff --git a/osu.Game/Users/Drawables/UpdateableAvatar.cs b/osu.Game/Users/Drawables/UpdateableAvatar.cs
index 59fbb5f910..171462f3fc 100644
--- a/osu.Game/Users/Drawables/UpdateableAvatar.cs
+++ b/osu.Game/Users/Drawables/UpdateableAvatar.cs
@@ -43,6 +43,8 @@ namespace osu.Game.Users.Drawables
set => base.EdgeEffect = value;
}
+ protected override double LoadDelay => 200;
+
///
/// Whether to show a default guest representation on null user (as opposed to nothing).
///
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 4d59b709aa..855bda3679 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 6897d3e625..e2c4c09047 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -71,7 +71,7 @@
-
+
@@ -79,7 +79,7 @@
-
+