From 162e183b36721e0aa3520dd80db1ebc19fbe7f7c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 24 Jan 2017 16:01:49 +0900 Subject: [PATCH 01/18] Fix some nullrefs when running visualtests with no maps loaded. --- osu.Desktop.VisualTests/Tests/TestCasePlayer.cs | 4 +++- osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs | 3 ++- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 ++ osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs | 4 ++-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs index 9e3ad1bbc8..3be8c83299 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs @@ -29,7 +29,9 @@ namespace osu.Desktop.VisualTests.Tests [BackgroundDependencyLoader] private void load(BeatmapDatabase db) { - beatmap = db.GetWorkingBeatmap(db.Query().Where(b => b.Mode == PlayMode.Osu).FirstOrDefault()); + var beatmapInfo = db.Query().Where(b => b.Mode == PlayMode.Osu).FirstOrDefault(); + if (beatmapInfo != null) + beatmap = db.GetWorkingBeatmap(beatmapInfo); } public override void Reset() diff --git a/osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs index e90829873f..f8cec43f14 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs @@ -18,7 +18,8 @@ namespace osu.Game.Beatmaps.Drawables [BackgroundDependencyLoader] private void load(OsuGameBase game) { - Texture = working.Background; + if (working.Background != null) + Texture = working.Background; } } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 9184607398..a898465610 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -30,6 +30,8 @@ namespace osu.Game.Beatmaps { if (background != null) return background; + if (BeatmapInfo.Metadata?.BackgroundFile == null) return null; + try { using (var reader = GetReader()) diff --git a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs index 7ce71acf3e..58f39013a8 100644 --- a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs @@ -56,8 +56,8 @@ namespace osu.Game.Modes.Objects.Drawables [BackgroundDependencyLoader] private void load(AudioManager audio) { - string hitType = (HitObject.Sample.Type == SampleType.None ? SampleType.Normal : HitObject.Sample.Type).ToString().ToLower(); - string sampleSet = HitObject.Sample.Set.ToString().ToLower(); + string hitType = ((HitObject.Sample?.Type ?? SampleType.None) == SampleType.None ? SampleType.Normal : HitObject.Sample.Type).ToString().ToLower(); + string sampleSet = (HitObject.Sample?.Set ?? SampleSet.Normal).ToString().ToLower(); sample = audio.Sample.Get($@"Gameplay/{sampleSet}-hit{hitType}"); } From 4aa2834082bd5d8a034749317d734176980a60a5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 24 Jan 2017 17:02:11 +0900 Subject: [PATCH 02/18] Fix TestCasePlaySongSelect not working on consecutive executions. --- osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs b/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs index adfa2556a0..0e45d58774 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs @@ -41,7 +41,11 @@ namespace osu.Desktop.VisualTests.Tests protected override void Dispose(bool isDisposing) { if (oldDb != null) + { Dependencies.Cache(oldDb, true); + db = null; + } + base.Dispose(isDisposing); } From c07001b566dbec4c9642841c615211253a1d49be Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 24 Jan 2017 17:12:31 +0900 Subject: [PATCH 03/18] Fix TestCasePlayer not working on consecutive executions (clock being set where it isn't necessary). --- osu.Desktop.VisualTests/Tests/TestCasePlayer.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs index 3be8c83299..b55d341100 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs @@ -38,12 +38,8 @@ namespace osu.Desktop.VisualTests.Tests { base.Reset(); - //ensure we are at offset 0 - Clock = new FramedClock(); - - if (beatmap == null) + if (beatmap?.Track == null) { - var objects = new List(); int time = 1500; From 7ee6a50404aee10aefe8250a156fa3ae3054933f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 24 Jan 2017 17:22:31 +0900 Subject: [PATCH 04/18] Fix checkbox design regressions. --- osu.Game/Overlays/Options/CheckBoxOption.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Options/CheckBoxOption.cs b/osu.Game/Overlays/Options/CheckBoxOption.cs index 310d33580d..cc1af1e3c9 100644 --- a/osu.Game/Overlays/Options/CheckBoxOption.cs +++ b/osu.Game/Overlays/Options/CheckBoxOption.cs @@ -168,14 +168,17 @@ namespace osu.Game.Overlays.Options private void load(OsuColour colours) { Colour = idleColour = colours.Pink; + glowingColour = colours.PinkLighter; EdgeEffect = new EdgeEffect { - Colour = glowingColour = colours.PinkDarker, + Colour = colours.PinkDarker, Type = EdgeEffectType.Glow, Radius = 10, Roundness = 8, }; + + FadeGlowTo(0); } public bool Glowing From a2501cc81de4aa45bbf687a72acafaf071e8e42a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 24 Jan 2017 18:09:45 +0900 Subject: [PATCH 05/18] Fix TestCaseHitObjects not working at all due to state being set before load is complete. --- osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs | 1 - osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs index 59ef75a909..18d8dcc814 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs @@ -49,7 +49,6 @@ namespace osu.Desktop.VisualTests.Tests DrawableHitCircle d = new DrawableHitCircle(h) { Anchor = Anchor.Centre, - Origin = Anchor.Centre, Depth = i, State = ArmedState.Hit, Judgement = new OsuJudgementInfo { Result = HitResult.Hit } diff --git a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs index 58f39013a8..f2dc7268ac 100644 --- a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs @@ -43,8 +43,8 @@ namespace osu.Game.Modes.Objects.Drawables state = value; UpdateState(state); - - Expire(); + if (IsLoaded) + Expire(); if (State == ArmedState.Hit) PlaySample(); From d4e30f65db194d5293ef85141683f06040414764 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 24 Jan 2017 18:12:02 +0900 Subject: [PATCH 06/18] Adjust timing of TestCaseHitObjects a bit. --- osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs index 18d8dcc814..d6112d7024 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs @@ -42,7 +42,7 @@ namespace osu.Desktop.VisualTests.Tests { var h = new HitCircle { - StartTime = Clock.CurrentTime + 1000 + i * 80, + StartTime = Clock.CurrentTime + 600 + i * 80, Position = new Vector2((i - count / 2) * 14), }; From 4a7b3cf39171137d1ccd5f578e8758b74d0574cf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 26 Jan 2017 23:07:49 +0900 Subject: [PATCH 07/18] Initial implementation of song select footer area. --- osu.Game/Graphics/UserInterface/BackButton.cs | 10 +- osu.Game/Screens/Select/CarouselContainer.cs | 36 ++++-- osu.Game/Screens/Select/Footer.cs | 115 +++++++++++++++++ osu.Game/Screens/Select/FooterButton.cs | 117 ++++++++++++++++++ osu.Game/Screens/Select/PlaySongSelect.cs | 54 ++------ osu.Game/osu.Game.csproj | 2 + 6 files changed, 276 insertions(+), 58 deletions(-) create mode 100644 osu.Game/Screens/Select/Footer.cs create mode 100644 osu.Game/Screens/Select/FooterButton.cs diff --git a/osu.Game/Graphics/UserInterface/BackButton.cs b/osu.Game/Graphics/UserInterface/BackButton.cs index 2f9a026b8f..d246b421a2 100644 --- a/osu.Game/Graphics/UserInterface/BackButton.cs +++ b/osu.Game/Graphics/UserInterface/BackButton.cs @@ -27,13 +27,13 @@ namespace osu.Game.Graphics.UserInterface private const float shear = 0.1f; - private static readonly Vector2 size_extended = new Vector2(140, 50); - private static readonly Vector2 size_retracted = new Vector2(100, 50); + public static readonly Vector2 SIZE_EXTENDED = new Vector2(140, 50); + public static readonly Vector2 SIZE_RETRACTED = new Vector2(100, 50); private AudioSample sampleClick; public BackButton() { - Size = size_retracted; + Size = SIZE_RETRACTED; } public override bool Contains(Vector2 screenSpacePos) => leftBox.Contains(screenSpacePos) || rightBox.Contains(screenSpacePos); @@ -42,7 +42,7 @@ namespace osu.Game.Graphics.UserInterface { icon.ClearTransformations(); - ResizeTo(size_extended, transform_time, EasingTypes.OutElastic); + ResizeTo(SIZE_EXTENDED, transform_time, EasingTypes.OutElastic); int duration = 0; //(int)(Game.Audio.BeatLength / 2); if (duration == 0) duration = pulse_length; @@ -69,7 +69,7 @@ namespace osu.Game.Graphics.UserInterface { icon.ClearTransformations(); - ResizeTo(size_retracted, transform_time, EasingTypes.OutElastic); + ResizeTo(SIZE_RETRACTED, transform_time, EasingTypes.OutElastic); int duration = 0; //(int)(Game.Audio.BeatLength); if (duration == 0) duration = pulse_length * 2; diff --git a/osu.Game/Screens/Select/CarouselContainer.cs b/osu.Game/Screens/Select/CarouselContainer.cs index 144e4cabba..258e2e03d8 100644 --- a/osu.Game/Screens/Select/CarouselContainer.cs +++ b/osu.Game/Screens/Select/CarouselContainer.cs @@ -1,21 +1,22 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; -using osu.Framework.Caching; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Transformations; -using osu.Game.Database; -using System; -using System.Collections.Generic; -using System.Linq; -using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Framework.Lists; -using osu.Game.Beatmaps.Drawables; +using OpenTK; +using osu.Framework.Caching; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Transformations; +using osu.Game.Database; +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Lists; +using osu.Game.Beatmaps.Drawables; using osu.Framework.Timing; using osu.Framework.Input; using OpenTK.Input; +using osu.Framework.MathUtils; namespace osu.Game.Screens.Select { @@ -287,6 +288,17 @@ namespace osu.Game.Screens.Select } return base.OnKeyDown(state, args); + } + + public void SelectRandom() + { + if (groups.Count < 1) + return; + BeatmapGroup group = groups[RNG.Next(groups.Count)]; + BeatmapPanel panel = group?.BeatmapPanels.First(); + if (panel == null) + return; + SelectGroup(group, panel); } } } diff --git a/osu.Game/Screens/Select/Footer.cs b/osu.Game/Screens/Select/Footer.cs new file mode 100644 index 0000000000..bb280f56c1 --- /dev/null +++ b/osu.Game/Screens/Select/Footer.cs @@ -0,0 +1,115 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transformations; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using osu.Game.Screens.Menu; + +namespace osu.Game.Screens.Select +{ + public class Footer : Container + { + private Box modeLight; + + private const float play_song_select_button_width = 100; + private const float play_song_select_button_height = 50; + + public const int TRANSITION_LENGTH = 300; + + private const float padding = 80; + + public Action OnBack; + public Action OnStart; + + private FlowContainer buttons; + + public void AddButton(string text, Color4 colour, Action action) + { + var button = new FooterButton + { + Text = text, + Height = play_song_select_button_height, + Width = play_song_select_button_width, + SelectedColour = colour, + DeselectedColour = colour.Opacity(0.5f), + }; + + button.Hovered = () => updateModeLight(button); + button.HoverLost = () => updateModeLight(); + button.Action = action; + buttons.Add(button); + } + + private void updateModeLight(FooterButton button = null) + { + modeLight.FadeColour(button?.SelectedColour ?? Color4.Transparent, TRANSITION_LENGTH, EasingTypes.OutQuint); + } + + public Footer() + { + const float bottomToolHeight = 50; + + RelativeSizeAxes = Axes.X; + Height = bottomToolHeight; + Anchor = Anchor.BottomCentre; + Origin = Anchor.BottomCentre; + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Size = Vector2.One, + Colour = Color4.Black.Opacity(0.5f), + }, + modeLight = new Box + { + RelativeSizeAxes = Axes.X, + Height = 3, + Position = new Vector2(0, -3), + }, + new OsuLogo() + { + Anchor = Anchor.BottomRight, + Scale = new Vector2(0.4f), + Position = new Vector2(-70, -25), + Action = () => OnStart?.Invoke() + }, + new BackButton + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Action = () => OnBack?.Invoke(), + }, + new FlowContainer + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Position = new Vector2(BackButton.SIZE_EXTENDED.X + padding, 0), + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Direction = FlowDirection.HorizontalOnly, + Spacing = new Vector2(padding, 0), + Children = new Drawable[] + { + + buttons = new FlowContainer + { + Direction = FlowDirection.HorizontalOnly, + Spacing = new Vector2(0.2f, 0), + AutoSizeAxes = Axes.Both, + } + } + } + }; + + updateModeLight(); + } + } +} diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs new file mode 100644 index 0000000000..9d49e88716 --- /dev/null +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -0,0 +1,117 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input; +using System; +using osu.Framework.Graphics.Transformations; + +namespace osu.Game.Screens.Select +{ + public class FooterButton : ClickableContainer + { + private static readonly Vector2 shearing = new Vector2(0.15f, 0); + + public string Text + { + get { return spriteText?.Text; } + set + { + if (spriteText != null) + spriteText.Text = value; + } + } + + private Color4 deselectedColour; + public Color4 DeselectedColour + { + get { return deselectedColour; } + set + { + deselectedColour = value; + if(light.Colour != SelectedColour) + light.Colour = value; + } + } + + private Color4 selectedColour; + public Color4 SelectedColour + { + get { return selectedColour; } + set + { + selectedColour = value; + box.Colour = selectedColour; + } + } + + private SpriteText spriteText; + private Box box; + private Box light; + + public FooterButton() + { + Children = new Drawable[] + { + box = new Box + { + RelativeSizeAxes = Axes.Both, + Shear = shearing, + EdgeSmoothness = new Vector2(2, 0), + Colour = Color4.White, + Alpha = 0, + }, + light = new Box + { + Shear = shearing, + Height = 4, + EdgeSmoothness = new Vector2(2, 0), + RelativeSizeAxes = Axes.X, + }, + spriteText = new SpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }; + } + + public Action Hovered; + public Action HoverLost; + + protected override bool OnHover(InputState state) + { + Hovered?.Invoke(); + light.ScaleTo(new Vector2(1, 2), Footer.TRANSITION_LENGTH, EasingTypes.OutQuint); + light.FadeColour(SelectedColour, Footer.TRANSITION_LENGTH, EasingTypes.OutQuint); + return true; + } + + protected override void OnHoverLost(InputState state) + { + HoverLost?.Invoke(); + light.ScaleTo(new Vector2(1, 1), Footer.TRANSITION_LENGTH, EasingTypes.OutQuint); + light.FadeColour(DeselectedColour, Footer.TRANSITION_LENGTH, EasingTypes.OutQuint); + box.FadeOut(Footer.TRANSITION_LENGTH, EasingTypes.OutQuint); + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + box.FadeTo(0.3f, Footer.TRANSITION_LENGTH * 2, EasingTypes.OutQuint); + return base.OnMouseDown(state, args); + } + + protected override bool OnClick(InputState state) + { + box.ClearTransformations(); + box.Alpha = 1; + box.FadeOut(Footer.TRANSITION_LENGTH * 3, EasingTypes.OutQuint); + return base.OnClick(state); + } + + } +} diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index e0860fda4c..23aed2d1a3 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -14,12 +14,10 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.UserInterface; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Modes; using osu.Game.Screens.Backgrounds; -using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; using osu.Game.Screens.Play; @@ -28,9 +26,9 @@ using osu.Framework.Audio.Sample; using osu.Framework.Graphics.Transformations; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics.Containers; +using osu.Game.Graphics; using osu.Framework.Input; using OpenTK.Input; -using osu.Game.Graphics; namespace osu.Game.Screens.Select { @@ -53,6 +51,8 @@ namespace osu.Game.Screens.Select private AudioSample sampleChangeDifficulty; private AudioSample sampleChangeBeatmap; + private Footer footer; + class WedgeBackground : Container { public WedgeBackground() @@ -111,7 +111,7 @@ namespace osu.Game.Screens.Select OsuGame osuGame, OsuColour colours) { const float carouselWidth = 640; - const float bottomToolHeight = 50; + Children = new Drawable[] { new ParallaxContainer @@ -142,41 +142,17 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.X, Margin = new MarginPadding { Top = 20, Right = 20, }, }, - new Container + footer = new Footer() { - RelativeSizeAxes = Axes.X, - Height = bottomToolHeight, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Size = Vector2.One, - Colour = Color4.Black.Opacity(0.5f), - }, - new BackButton - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - //RelativeSizeAxes = Axes.Y, - Action = () => Exit() - }, - new Button - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.Y, - Width = 100, - Text = "Play", - Colour = colours.Pink, - Action = start - }, - } + OnBack = Exit, + OnStart = start, } }; - + + footer.AddButton(@"mods", colours.Yellow, null); + footer.AddButton(@"random", colours.Green, carousel.SelectRandom); + footer.AddButton(@"options", colours.Blue, null); + if (osuGame != null) { playMode = osuGame.PlayMode; @@ -286,14 +262,10 @@ namespace osu.Game.Screens.Select //todo: change background in selectionChanged instead; support per-difficulty backgrounds. changeBackground(beatmap); - selectBeatmap(beatmap.BeatmapInfo); } - private void selectBeatmap(BeatmapInfo beatmap) - { - carousel.SelectBeatmap(beatmap); - } + private void selectBeatmap(BeatmapInfo beatmap) => carousel.SelectBeatmap(beatmap); /// /// selection has been changed as the result of interaction with the carousel. diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2261605f50..207fa563ab 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -232,6 +232,8 @@ + + From 70271fee35db09e3d93c6dd72feaef1135651c37 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2017 11:40:52 +0800 Subject: [PATCH 08/18] Move PlayerInputManager to own file. --- osu.Game/Screens/Play/Player.cs | 45 ----------------- osu.Game/Screens/Play/PlayerInputManager.cs | 56 +++++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 3 files changed, 57 insertions(+), 45 deletions(-) create mode 100644 osu.Game/Screens/Play/PlayerInputManager.cs diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index fe9345eca8..9240a7c35e 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -167,50 +167,5 @@ namespace osu.Game.Screens.Play { Background?.FadeTo((100f - dimLevel) / 100, 800); } - - class PlayerInputManager : UserInputManager - { - public PlayerInputManager(BasicGameHost host) - : base(host) - { - } - - bool leftViaKeyboard; - bool rightViaKeyboard; - Bindable mouseDisabled; - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - mouseDisabled = config.GetBindable(OsuConfig.MouseDisableButtons) - ?? new Bindable(false); - } - - protected override void TransformState(InputState state) - { - base.TransformState(state); - - if (state.Keyboard != null) - { - leftViaKeyboard = state.Keyboard.Keys.Contains(Key.Z); - rightViaKeyboard = state.Keyboard.Keys.Contains(Key.X); - } - - MouseState mouse = (MouseState)state.Mouse; - if (state.Mouse != null) - { - if (mouseDisabled.Value) - { - mouse.ButtonStates.Find(s => s.Button == MouseButton.Left).State = false; - mouse.ButtonStates.Find(s => s.Button == MouseButton.Right).State = false; - } - - if (leftViaKeyboard) - mouse.ButtonStates.Find(s => s.Button == MouseButton.Left).State = true; - if (rightViaKeyboard) - mouse.ButtonStates.Find(s => s.Button == MouseButton.Right).State = true; - } - } - } } } \ No newline at end of file diff --git a/osu.Game/Screens/Play/PlayerInputManager.cs b/osu.Game/Screens/Play/PlayerInputManager.cs new file mode 100644 index 0000000000..b0da57ce0a --- /dev/null +++ b/osu.Game/Screens/Play/PlayerInputManager.cs @@ -0,0 +1,56 @@ +using OpenTK.Input; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Input; +using osu.Framework.Platform; +using osu.Game.Configuration; +using System; +using System.Linq; + +namespace osu.Game.Screens.Play +{ + class PlayerInputManager : UserInputManager + { + public PlayerInputManager(BasicGameHost host) + : base(host) + { + } + + bool leftViaKeyboard; + bool rightViaKeyboard; + Bindable mouseDisabled; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + mouseDisabled = config.GetBindable(OsuConfig.MouseDisableButtons) + ?? new Bindable(false); + } + + protected override void TransformState(InputState state) + { + base.TransformState(state); + + if (state.Keyboard != null) + { + leftViaKeyboard = state.Keyboard.Keys.Contains(Key.Z); + rightViaKeyboard = state.Keyboard.Keys.Contains(Key.X); + } + + var mouse = (Framework.Input.MouseState)state.Mouse; + if (state.Mouse != null) + { + if (mouseDisabled.Value) + { + mouse.ButtonStates.Find(s => s.Button == MouseButton.Left).State = false; + mouse.ButtonStates.Find(s => s.Button == MouseButton.Right).State = false; + } + + if (leftViaKeyboard) + mouse.ButtonStates.Find(s => s.Button == MouseButton.Left).State = true; + if (rightViaKeyboard) + mouse.ButtonStates.Find(s => s.Button == MouseButton.Right).State = true; + } + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2261605f50..5f0a29359f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -116,6 +116,7 @@ + From 8c7bb4990c01cecb3fcb96cb6e062890937c6de3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2017 13:28:30 +0800 Subject: [PATCH 09/18] Add support for failing. --- osu.Game/Screens/Play/Player.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 9240a7c35e..fbee5db865 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -35,6 +35,8 @@ namespace osu.Game.Screens.Play internal override bool ShowOverlays => false; + protected bool CanFail => true; + public BeatmapInfo BeatmapInfo; public PlayMode PreferredPlayMode; From cd149f04fcc94f39a981085a085fa8a817bc41d3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2017 13:40:13 +0800 Subject: [PATCH 10/18] Use bindable for HealthDisplay. --- osu.Game/Modes/UI/HealthDisplay.cs | 9 +++++---- osu.Game/Modes/UI/ScoreOverlay.cs | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/Modes/UI/HealthDisplay.cs b/osu.Game/Modes/UI/HealthDisplay.cs index 0645d54b50..1892c6e593 100644 --- a/osu.Game/Modes/UI/HealthDisplay.cs +++ b/osu.Game/Modes/UI/HealthDisplay.cs @@ -14,6 +14,8 @@ namespace osu.Game.Modes.UI private Box background; private Box fill; + public BindableDouble Current = new BindableDouble(); + public HealthDisplay() { Children = new Drawable[] @@ -30,13 +32,12 @@ namespace osu.Game.Modes.UI Scale = new Vector2(0, 1), }, }; + + Current.ValueChanged += current_ValueChanged; } - public double Current; - - public void Set(double value) + private void current_ValueChanged(object sender, EventArgs e) { - Current = value; fill.ScaleTo(new Vector2((float)Current, 1), 200, EasingTypes.OutQuint); } } diff --git a/osu.Game/Modes/UI/ScoreOverlay.cs b/osu.Game/Modes/UI/ScoreOverlay.cs index fbdd75b97d..8fd070e9dd 100644 --- a/osu.Game/Modes/UI/ScoreOverlay.cs +++ b/osu.Game/Modes/UI/ScoreOverlay.cs @@ -63,7 +63,7 @@ namespace osu.Game.Modes.UI processor.TotalScore.ValueChanged += delegate { ScoreCounter?.Set((ulong)processor.TotalScore.Value); }; processor.Accuracy.ValueChanged += delegate { AccuracyCounter?.Set((float)processor.Accuracy.Value); }; processor.Combo.ValueChanged += delegate { ComboCounter?.Set((ulong)processor.Combo.Value); }; - processor.Health.ValueChanged += delegate { HealthDisplay?.Set(processor.Health.Value); }; + if (HealthDisplay != null) processor.Health.Weld(HealthDisplay.Current); } } } From 9f44e634a4995c611ab8d10e5aece9158b67d258 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Jan 2017 11:22:16 +0800 Subject: [PATCH 11/18] Allow visualtests to share config etc. with osu!. --- osu.Desktop.VisualTests/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop.VisualTests/Program.cs b/osu.Desktop.VisualTests/Program.cs index c4f5075ef9..a6205fe6ba 100644 --- a/osu.Desktop.VisualTests/Program.cs +++ b/osu.Desktop.VisualTests/Program.cs @@ -18,7 +18,7 @@ namespace osu.Desktop.VisualTests [STAThread] public static void Main(string[] args) { - using (BasicGameHost host = Host.GetSuitableHost(@"osu-visual-tests")) + using (BasicGameHost host = Host.GetSuitableHost(@"osu")) { Ruleset.Register(new OsuRuleset()); Ruleset.Register(new TaikoRuleset()); From c01863dfa2e408a6530967a2382ef3c87ed74e42 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 20 Jan 2017 03:13:27 +0800 Subject: [PATCH 12/18] Add min/max constraints to HealthDisplay. --- osu.Game/Modes/UI/HealthDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Modes/UI/HealthDisplay.cs b/osu.Game/Modes/UI/HealthDisplay.cs index 1892c6e593..f4f1cc37f9 100644 --- a/osu.Game/Modes/UI/HealthDisplay.cs +++ b/osu.Game/Modes/UI/HealthDisplay.cs @@ -14,7 +14,7 @@ namespace osu.Game.Modes.UI private Box background; private Box fill; - public BindableDouble Current = new BindableDouble(); + public BindableDouble Current = new BindableDouble() { MinValue = 0, MaxValue = 1 }; public HealthDisplay() { From c3699c139596773e626c13e965219ff5b74d1a30 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 20 Jan 2017 03:15:52 +0800 Subject: [PATCH 13/18] Remove unused prevCount variable. --- osu.Game/Graphics/UserInterface/RollingCounter.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs index 6a21da9bce..e55001fd99 100644 --- a/osu.Game/Graphics/UserInterface/RollingCounter.cs +++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs @@ -1,7 +1,6 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -9,10 +8,6 @@ using osu.Framework.Graphics.Transformations; using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using osu.Framework.Allocation; namespace osu.Game.Graphics.UserInterface { @@ -64,7 +59,6 @@ namespace osu.Game.Graphics.UserInterface } } - protected T prevCount; protected T count; /// @@ -78,7 +72,6 @@ namespace osu.Game.Graphics.UserInterface } set { - prevCount = count; count = value; if (IsLoaded) { From 1d24ad3db6283f620a425d00c7d60e8bbf68e91e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 20 Jan 2017 15:51:21 +0800 Subject: [PATCH 14/18] osu! mode starts with health being full. --- osu.Game.Modes.Osu/OsuScoreProcessor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Modes.Osu/OsuScoreProcessor.cs b/osu.Game.Modes.Osu/OsuScoreProcessor.cs index 6cb14831f6..6059949fad 100644 --- a/osu.Game.Modes.Osu/OsuScoreProcessor.cs +++ b/osu.Game.Modes.Osu/OsuScoreProcessor.cs @@ -11,6 +11,7 @@ namespace osu.Game.Modes.Osu public OsuScoreProcessor(int hitObjectCount) : base(hitObjectCount) { + Health.Value = 1; } protected override void UpdateCalculations(JudgementInfo judgement) From 139cac5e572235d0c951513b9fb3d756503aec77 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 20 Jan 2017 15:51:43 +0800 Subject: [PATCH 15/18] Add fail dialog and flow. --- osu.Game/Modes/ScoreProcesssor.cs | 21 ++++++++++++++ osu.Game/Modes/UI/ScoreOverlay.cs | 2 +- osu.Game/Screens/Play/FailDialog.cs | 45 +++++++++++++++++++++++++++++ osu.Game/Screens/Play/Player.cs | 26 +++++++++++++---- osu.Game/osu.Game.csproj | 1 + 5 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 osu.Game/Screens/Play/FailDialog.cs diff --git a/osu.Game/Modes/ScoreProcesssor.cs b/osu.Game/Modes/ScoreProcesssor.cs index 3c8d2f4d25..63521996e5 100644 --- a/osu.Game/Modes/ScoreProcesssor.cs +++ b/osu.Game/Modes/ScoreProcesssor.cs @@ -30,6 +30,22 @@ namespace osu.Game.Modes public readonly BindableInt Combo = new BindableInt(); + /// + /// Are we allowed to fail? + /// + protected bool CanFail => true; + + protected bool HasFailed; + + /// + /// Called when we reach a failing health of zero. + /// + public event Action Failed; + + /// + /// Keeps track of the highest combo ever achieved in this play. + /// This is handled automatically by ScoreProcessor. + /// public readonly BindableInt HighestCombo = new BindableInt(); public readonly List Judgements; @@ -51,6 +67,11 @@ namespace osu.Game.Modes UpdateCalculations(judgement); judgement.ComboAtHit = (ulong)Combo.Value; + if (Health.Value == Health.MinValue && !HasFailed) + { + HasFailed = true; + Failed?.Invoke(); + } } /// diff --git a/osu.Game/Modes/UI/ScoreOverlay.cs b/osu.Game/Modes/UI/ScoreOverlay.cs index 8fd070e9dd..4e16571b60 100644 --- a/osu.Game/Modes/UI/ScoreOverlay.cs +++ b/osu.Game/Modes/UI/ScoreOverlay.cs @@ -63,7 +63,7 @@ namespace osu.Game.Modes.UI processor.TotalScore.ValueChanged += delegate { ScoreCounter?.Set((ulong)processor.TotalScore.Value); }; processor.Accuracy.ValueChanged += delegate { AccuracyCounter?.Set((float)processor.Accuracy.Value); }; processor.Combo.ValueChanged += delegate { ComboCounter?.Set((ulong)processor.Combo.Value); }; - if (HealthDisplay != null) processor.Health.Weld(HealthDisplay.Current); + if (HealthDisplay != null) HealthDisplay.Current.Weld(processor.Health); } } } diff --git a/osu.Game/Screens/Play/FailDialog.cs b/osu.Game/Screens/Play/FailDialog.cs new file mode 100644 index 0000000000..c8718c1618 --- /dev/null +++ b/osu.Game/Screens/Play/FailDialog.cs @@ -0,0 +1,45 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.GameModes; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transformations; +using osu.Game.Modes; +using osu.Game.Screens.Backgrounds; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Screens.Play +{ + class FailDialog : OsuGameMode + { + protected override BackgroundMode CreateBackground() => new BackgroundModeBeatmap(Beatmap); + + private static readonly Vector2 BACKGROUND_BLUR = new Vector2(20); + + public FailDialog() + { + Add(new SpriteText + { + Text = "You failed!", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + TextSize = 50 + }); + } + + protected override void OnEntering(GameMode last) + { + base.OnEntering(last); + Background.Schedule(() => (Background as BackgroundModeBeatmap)?.BlurTo(BACKGROUND_BLUR, 1000)); + } + + protected override bool OnExiting(GameMode next) + { + Background.Schedule(() => Background.FadeColour(Color4.White, 500)); + return base.OnExiting(next); + } + } +} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index fbee5db865..d6594dd2be 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -24,6 +24,7 @@ using osu.Game.Screens.Ranking; using osu.Game.Configuration; using osu.Framework.Configuration; using System; +using OpenTK.Graphics; namespace osu.Game.Screens.Play { @@ -31,12 +32,10 @@ namespace osu.Game.Screens.Play { public bool Autoplay; - protected override BackgroundMode CreateBackground() => null; + protected override BackgroundMode CreateBackground() => new BackgroundModeBeatmap(Beatmap); internal override bool ShowOverlays => false; - protected bool CanFail => true; - public BeatmapInfo BeatmapInfo; public PlayMode PreferredPlayMode; @@ -98,8 +97,12 @@ namespace osu.Game.Screens.Play hitRenderer = ruleset.CreateHitRendererWith(beatmap.HitObjects); + //bind HitRenderer to ScoreProcessor and ourselves (for a pass situation) hitRenderer.OnJudgement += scoreProcessor.AddJudgement; - hitRenderer.OnAllJudged += hitRenderer_OnAllJudged; + hitRenderer.OnAllJudged += onPass; + + //bind ScoreProcessor to ourselves (for a fail situation) + scoreProcessor.Failed += onFail; if (Autoplay) hitRenderer.Schedule(() => hitRenderer.DrawableObjects.ForEach(h => h.State = ArmedState.Hit)); @@ -134,7 +137,7 @@ namespace osu.Game.Screens.Play }); } - private void hitRenderer_OnAllJudged() + private void onPass() { Delay(1000); Schedule(delegate @@ -147,6 +150,19 @@ namespace osu.Game.Screens.Play }); } + private void onFail() + { + Content.FadeColour(Color4.Red, 500); + sourceClock.Stop(); + + Delay(500); + Schedule(delegate + { + ValidForResume = false; + Push(new FailDialog()); + }); + } + protected override void OnEntering(GameMode last) { base.OnEntering(last); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 5f0a29359f..c4ae8a16bb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -116,6 +116,7 @@ + From f07b9591cd8d525b1d952aac41277b0c16c5c79f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 20 Jan 2017 16:20:56 +0800 Subject: [PATCH 16/18] Add null check when popping backgrounds from the mode stack. --- osu.Game/Screens/OsuGameMode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OsuGameMode.cs b/osu.Game/Screens/OsuGameMode.cs index b5e45f2097..b938a450f8 100644 --- a/osu.Game/Screens/OsuGameMode.cs +++ b/osu.Game/Screens/OsuGameMode.cs @@ -130,7 +130,7 @@ namespace osu.Game.Screens { if (nextOsu != null) //We need to use MakeCurrent in case we are jumping up multiple game modes. - nextOsu.Background.MakeCurrent(); + nextOsu.Background?.MakeCurrent(); else Background.Exit(); } From 4efedd942d798fdd899fa2ddbc56aa3171649a38 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 24 Jan 2017 19:04:03 +0900 Subject: [PATCH 17/18] Use null propagation. --- osu.Game/Modes/UI/ScoreOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Modes/UI/ScoreOverlay.cs b/osu.Game/Modes/UI/ScoreOverlay.cs index 4e16571b60..144370c826 100644 --- a/osu.Game/Modes/UI/ScoreOverlay.cs +++ b/osu.Game/Modes/UI/ScoreOverlay.cs @@ -63,7 +63,7 @@ namespace osu.Game.Modes.UI processor.TotalScore.ValueChanged += delegate { ScoreCounter?.Set((ulong)processor.TotalScore.Value); }; processor.Accuracy.ValueChanged += delegate { AccuracyCounter?.Set((float)processor.Accuracy.Value); }; processor.Combo.ValueChanged += delegate { ComboCounter?.Set((ulong)processor.Combo.Value); }; - if (HealthDisplay != null) HealthDisplay.Current.Weld(processor.Health); + HealthDisplay?.Current.Weld(processor.Health); } } } From 629605c6b404dfb62e7103eb86ca2fcb5cae126a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 24 Jan 2017 19:04:42 +0900 Subject: [PATCH 18/18] Make HasFailed's set private. --- osu.Game/Modes/ScoreProcesssor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Modes/ScoreProcesssor.cs b/osu.Game/Modes/ScoreProcesssor.cs index 63521996e5..fb58aabe97 100644 --- a/osu.Game/Modes/ScoreProcesssor.cs +++ b/osu.Game/Modes/ScoreProcesssor.cs @@ -35,7 +35,7 @@ namespace osu.Game.Modes /// protected bool CanFail => true; - protected bool HasFailed; + protected bool HasFailed { get; private set; } /// /// Called when we reach a failing health of zero.