From e9ec544bf65b929450c4bcd18a4ad63fe14207cb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Apr 2018 02:04:40 +0900 Subject: [PATCH 001/229] Implement joystick keybindings --- osu-framework | 2 +- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 85b3494117..3388ae24ba 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 85b3494117ccef1b396b70957e1cffaba06e2b54 +Subproject commit 3388ae24ba5cc75fc966ab1531f44701e74588a9 diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 379d25313e..81f24d2661 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -223,6 +223,26 @@ namespace osu.Game.Overlays.KeyBinding return true; } + protected override bool OnJoystickPress(InputState state, JoystickPressEventArgs args) + { + if (!HasFocus) + return false; + + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(state)); + finalise(); + + return true; + } + + protected override bool OnJoystickRelease(InputState state, JoystickReleaseEventArgs args) + { + if (!HasFocus) + return base.OnJoystickRelease(state, args); + + finalise(); + return true; + } + private void finalise() { if (bindTarget != null) From c39fb9a200712423e0656ba2ac2170748819ec4b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 3 Apr 2018 20:10:26 +0900 Subject: [PATCH 002/229] Update with framework changes --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 81f24d2661..9cf43c2bde 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -223,7 +223,7 @@ namespace osu.Game.Overlays.KeyBinding return true; } - protected override bool OnJoystickPress(InputState state, JoystickPressEventArgs args) + protected override bool OnJoystickPress(InputState state, Framework.Input.JoystickEventArgs args) { if (!HasFocus) return false; @@ -234,7 +234,7 @@ namespace osu.Game.Overlays.KeyBinding return true; } - protected override bool OnJoystickRelease(InputState state, JoystickReleaseEventArgs args) + protected override bool OnJoystickRelease(InputState state, Framework.Input.JoystickEventArgs args) { if (!HasFocus) return base.OnJoystickRelease(state, args); From dbee936748439445d049ed3ddf6a9d164d2d7429 Mon Sep 17 00:00:00 2001 From: aQaTL Date: Mon, 9 Apr 2018 18:48:47 +0200 Subject: [PATCH 003/229] Allow mapping delete key via alt+delete key combination --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 71c346d404..88005795ff 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -198,18 +198,29 @@ namespace osu.Game.Overlays.KeyBinding if (!HasFocus) return false; + KeyCombination keyCombination = KeyCombination.FromInputState(state); + switch (args.Key) { case Key.Escape: finalise(); return true; case Key.Delete: - bindTarget.UpdateKeyCombination(InputKey.None); - finalise(); - return true; + if (keyCombination.Equals(InputKey.Delete)) + { + bindTarget.UpdateKeyCombination(InputKey.None); + finalise(); + return true; + } + else if (keyCombination.Equals(new[] { InputKey.Alt, InputKey.Delete })) + { + keyCombination = InputKey.Delete; + } + + break; } - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(state)); + bindTarget.UpdateKeyCombination(keyCombination); if (!isModifier(args.Key)) finalise(); return true; From 38277bff35f5eb945958ecd485be489374dad3fc Mon Sep 17 00:00:00 2001 From: aQaTL Date: Tue, 10 Apr 2018 18:00:22 +0200 Subject: [PATCH 004/229] Changed mapping of deleting key binding to shift+delete --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 88005795ff..63b5e8a7c1 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -200,24 +200,17 @@ namespace osu.Game.Overlays.KeyBinding KeyCombination keyCombination = KeyCombination.FromInputState(state); - switch (args.Key) + if (keyCombination.Equals(InputKey.Escape)) { - case Key.Escape: - finalise(); - return true; - case Key.Delete: - if (keyCombination.Equals(InputKey.Delete)) - { - bindTarget.UpdateKeyCombination(InputKey.None); - finalise(); - return true; - } - else if (keyCombination.Equals(new[] { InputKey.Alt, InputKey.Delete })) - { - keyCombination = InputKey.Delete; - } + finalise(); + return true; + } - break; + if (keyCombination.Equals(new[] { InputKey.Shift, InputKey.Delete })) + { + bindTarget.UpdateKeyCombination(InputKey.None); + finalise(); + return true; } bindTarget.UpdateKeyCombination(keyCombination); From 90beff83f6cabb47a26b4fb031322f9a3ccc2b0d Mon Sep 17 00:00:00 2001 From: aQaTL Date: Wed, 11 Apr 2018 08:07:26 +0200 Subject: [PATCH 005/229] Updated KeyBindingRow sprite text, adjusted KeyBindingOverlay width --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 2 +- osu.Game/Overlays/KeyBindingOverlay.cs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 63b5e8a7c1..6926e3d966 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -97,7 +97,7 @@ namespace osu.Game.Overlays.KeyBinding }, pressAKey = new OsuSpriteText { - Text = "Press a key to change binding, DEL to delete, ESC to cancel.", + Text = "Press a key to change binding, SHIFT+DEL to delete, ESC to cancel.", Y = height, Margin = new MarginPadding(padding), Alpha = 0, diff --git a/osu.Game/Overlays/KeyBindingOverlay.cs b/osu.Game/Overlays/KeyBindingOverlay.cs index b311ee68c0..3f393851c2 100644 --- a/osu.Game/Overlays/KeyBindingOverlay.cs +++ b/osu.Game/Overlays/KeyBindingOverlay.cs @@ -12,6 +12,8 @@ namespace osu.Game.Overlays { public class KeyBindingOverlay : SettingsOverlay { + protected const float WIDTH = 430; + protected override Drawable CreateHeader() => new SettingsHeader("key configuration", "Customise your keys!"); [BackgroundDependencyLoader(permitNulls: true)] @@ -21,6 +23,8 @@ namespace osu.Game.Overlays foreach (var ruleset in rulesets.AvailableRulesets) AddSection(new RulesetBindingsSection(ruleset)); + + ContentContainer.Width = WIDTH; } public KeyBindingOverlay() From 1dc8986c22cec2011005cc77f5f6a0d5fa691f55 Mon Sep 17 00:00:00 2001 From: aQaTL Date: Wed, 18 Apr 2018 15:06:03 +0200 Subject: [PATCH 006/229] Switched back to switch --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 6926e3d966..4e06ce8211 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -198,22 +198,25 @@ namespace osu.Game.Overlays.KeyBinding if (!HasFocus) return false; - KeyCombination keyCombination = KeyCombination.FromInputState(state); - - if (keyCombination.Equals(InputKey.Escape)) + switch (args.Key) { - finalise(); - return true; + case Key.Escape: + finalise(); + return true; + case Key.Delete: + { + if (state.Keyboard.ShiftPressed) + { + bindTarget.UpdateKeyCombination(InputKey.None); + finalise(); + return true; + } + + break; + } } - if (keyCombination.Equals(new[] { InputKey.Shift, InputKey.Delete })) - { - bindTarget.UpdateKeyCombination(InputKey.None); - finalise(); - return true; - } - - bindTarget.UpdateKeyCombination(keyCombination); + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(state)); if (!isModifier(args.Key)) finalise(); return true; From b5a55a0dcea31751a0fc7ceebc96f53bad87e426 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 19 Apr 2018 18:14:21 +0900 Subject: [PATCH 007/229] Make an interface for beatmaps --- osu.Game/Beatmaps/Beatmap.cs | 118 +++++++++++++--------- osu.Game/Beatmaps/BeatmapConverter.cs | 2 +- osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs | 9 -- osu.Game/Screens/Play/BreakOverlay.cs | 4 +- osu.Game/Tests/Beatmaps/TestBeatmap.cs | 8 +- 5 files changed, 79 insertions(+), 62 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 12a017f68c..541f7f85b6 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -12,24 +12,69 @@ using osu.Game.IO.Serialization.Converters; namespace osu.Game.Beatmaps { + public interface IBeatmap : IJsonSerializable + { + /// + /// This beatmap's info. + /// + BeatmapInfo BeatmapInfo { get; } + + /// + /// This beatmap's metadata. + /// + BeatmapMetadata Metadata { get; } + + /// + /// The control points in this beatmap. + /// + ControlPointInfo ControlPointInfo { get; } + + /// + /// The breaks in this beatmap. + /// + List Breaks { get; } + + /// + /// Total amount of break time in the beatmap. + /// + double TotalBreakTime { get; } + + /// + /// The hitobjects contained by this beatmap. + /// + IEnumerable HitObjects { get; } + + /// + /// Creates a shallow-clone of this beatmap and returns it. + /// + /// The shallow-cloned beatmap. + IBeatmap Clone(); + } + /// /// A Beatmap containing converted HitObjects. /// - public class Beatmap : IJsonSerializable + public class Beatmap : IBeatmap where T : HitObject { - public BeatmapInfo BeatmapInfo = new BeatmapInfo(); - public ControlPointInfo ControlPointInfo = new ControlPointInfo(); - public List Breaks = new List(); + public BeatmapInfo BeatmapInfo { get; set; } = new BeatmapInfo + { + Metadata = new BeatmapMetadata + { + Artist = @"Unknown", + Title = @"Unknown", + AuthorString = @"Unknown Creator", + }, + Version = @"Normal", + BaseDifficulty = new BeatmapDifficulty() + }; [JsonIgnore] public BeatmapMetadata Metadata => BeatmapInfo?.Metadata ?? BeatmapInfo?.BeatmapSet?.Metadata; - /// - /// The HitObjects this Beatmap contains. - /// - [JsonConverter(typeof(TypedListConverter))] - public List HitObjects = new List(); + public ControlPointInfo ControlPointInfo { get; set; } = new ControlPointInfo(); + + public List Breaks { get; set; } = new List(); /// /// Total amount of break time in the beatmap. @@ -38,51 +83,26 @@ namespace osu.Game.Beatmaps public double TotalBreakTime => Breaks.Sum(b => b.Duration); /// - /// Constructs a new beatmap. + /// The HitObjects this Beatmap contains. /// - /// The original beatmap to use the parameters of. - public Beatmap(Beatmap original = null) - { - BeatmapInfo = original?.BeatmapInfo.DeepClone() ?? BeatmapInfo; - ControlPointInfo = original?.ControlPointInfo ?? ControlPointInfo; - Breaks = original?.Breaks ?? Breaks; - HitObjects = original?.HitObjects ?? HitObjects; + [JsonConverter(typeof(TypedListConverter))] + public List HitObjects = new List(); - if (original == null && Metadata == null) - { - // we may have no metadata in cases we weren't sourced from the database. - // let's fill it (and other related fields) so we don't need to null-check it in future usages. - BeatmapInfo = new BeatmapInfo - { - Metadata = new BeatmapMetadata - { - Artist = @"Unknown", - Title = @"Unknown", - AuthorString = @"Unknown Creator", - }, - Version = @"Normal", - BaseDifficulty = new BeatmapDifficulty() - }; - } - } + IEnumerable IBeatmap.HitObjects => HitObjects; + + public Beatmap Clone() => new Beatmap + { + BeatmapInfo = BeatmapInfo.DeepClone(), + ControlPointInfo = ControlPointInfo, + Breaks = Breaks, + HitObjects = HitObjects + }; + + IBeatmap IBeatmap.Clone() => Clone(); } - /// - /// A Beatmap containing un-converted HitObjects. - /// public class Beatmap : Beatmap { - /// - /// Constructs a new beatmap. - /// - /// The original beatmap to use the parameters of. - public Beatmap(Beatmap original) - : base(original) - { - } - - public Beatmap() - { - } + public new Beatmap Clone() => (Beatmap)base.Clone(); } } diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index 153cace187..f46e6abc87 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -37,7 +37,7 @@ namespace osu.Game.Beatmaps public Beatmap Convert(Beatmap original) { // We always operate on a clone of the original beatmap, to not modify it game-wide - return ConvertBeatmap(new Beatmap(original)); + return ConvertBeatmap(original.Clone()); } void IBeatmapConverter.Convert(Beatmap original) => Convert(original); diff --git a/osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs b/osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs index eea82dac6d..4daa014804 100644 --- a/osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs +++ b/osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs @@ -8,14 +8,5 @@ namespace osu.Game.Beatmaps.Legacy /// public class LegacyBeatmap : Beatmap { - /// - /// Constructs a new beatmap. - /// - /// The original beatmap to use the parameters of. - internal LegacyBeatmap(Beatmap original = null) - : base(original) - { - HitObjects = original?.HitObjects; - } } } diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index b2df996d35..ca252dd6fd 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -18,11 +18,11 @@ namespace osu.Game.Screens.Play private const float remaining_time_container_max_size = 0.3f; private const int vertical_margin = 25; - private List breaks; + private IReadOnlyList breaks; private readonly Container fadeContainer; - public List Breaks + public IReadOnlyList Breaks { get => breaks; set diff --git a/osu.Game/Tests/Beatmaps/TestBeatmap.cs b/osu.Game/Tests/Beatmaps/TestBeatmap.cs index 09a3a7af8c..6bad08baaa 100644 --- a/osu.Game/Tests/Beatmaps/TestBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestBeatmap.cs @@ -12,8 +12,14 @@ namespace osu.Game.Tests.Beatmaps public class TestBeatmap : Beatmap { public TestBeatmap(RulesetInfo ruleset) - : base(createTestBeatmap()) { + var baseBeatmap = createTestBeatmap(); + + BeatmapInfo = baseBeatmap.BeatmapInfo; + ControlPointInfo = baseBeatmap.ControlPointInfo; + Breaks = baseBeatmap.Breaks; + HitObjects = baseBeatmap.HitObjects; + BeatmapInfo.Ruleset = ruleset; } From ac64f9d958be5c2630dbf799b704df1f3d5e56eb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 19 Apr 2018 18:40:01 +0900 Subject: [PATCH 008/229] Remove LegacyBeatmap --- osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs diff --git a/osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs b/osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs deleted file mode 100644 index 4daa014804..0000000000 --- a/osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -namespace osu.Game.Beatmaps.Legacy -{ - /// - /// A type of Beatmap loaded from a legacy .osu beatmap file (version <=15). - /// - public class LegacyBeatmap : Beatmap - { - } -} From e666a82e1f01a6b6fc891b7c8b52660752d67cf8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 19 Apr 2018 18:50:21 +0900 Subject: [PATCH 009/229] Fix cloning --- osu.Game/Beatmaps/Beatmap.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 541f7f85b6..7066432c5c 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -90,19 +90,19 @@ namespace osu.Game.Beatmaps IEnumerable IBeatmap.HitObjects => HitObjects; - public Beatmap Clone() => new Beatmap - { - BeatmapInfo = BeatmapInfo.DeepClone(), - ControlPointInfo = ControlPointInfo, - Breaks = Breaks, - HitObjects = HitObjects - }; - IBeatmap IBeatmap.Clone() => Clone(); + + public Beatmap Clone() + { + var newInstance = (Beatmap)MemberwiseClone(); + newInstance.BeatmapInfo = BeatmapInfo.DeepClone(); + + return newInstance; + } } public class Beatmap : Beatmap { - public new Beatmap Clone() => (Beatmap)base.Clone(); + public Beatmap Clone() => (Beatmap)base.Clone(); } } From 7a550e3f071f40ceded70e0dcebad8d99670ddac Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 19 Apr 2018 20:20:56 +0900 Subject: [PATCH 010/229] Revert unnecessary change for now --- osu.Game/Screens/Play/BreakOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index ca252dd6fd..b2df996d35 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -18,11 +18,11 @@ namespace osu.Game.Screens.Play private const float remaining_time_container_max_size = 0.3f; private const int vertical_margin = 25; - private IReadOnlyList breaks; + private List breaks; private readonly Container fadeContainer; - public IReadOnlyList Breaks + public List Breaks { get => breaks; set From 66b3b295e74860fe60a105decfc742732bf87256 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 19 Apr 2018 20:44:38 +0900 Subject: [PATCH 011/229] Use IBeatmap wherever possible --- .../CatchBeatmapConversionTest.cs | 2 +- .../TestCaseAutoJuiceStream.cs | 2 +- .../TestCaseBananaShower.cs | 2 +- .../TestCaseCatchStacker.cs | 2 +- osu.Game.Rulesets.Catch.Tests/TestCaseHyperdash.cs | 2 +- .../Beatmaps/CatchBeatmapConverter.cs | 2 +- .../CatchDifficultyCalculator.cs | 4 ++-- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- .../Replays/CatchReplayFrame.cs | 2 +- .../ManiaBeatmapConversionTest.cs | 2 +- .../Beatmaps/ManiaBeatmapConverter.cs | 14 +++++++------- .../Legacy/DistanceObjectPatternGenerator.cs | 2 +- .../Legacy/EndTimeObjectPatternGenerator.cs | 2 +- .../Patterns/Legacy/HitObjectPatternGenerator.cs | 2 +- .../Beatmaps/Patterns/Legacy/PatternGenerator.cs | 6 +++--- .../ManiaDifficultyCalculator.cs | 6 +++--- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- .../Replays/ManiaReplayFrame.cs | 2 +- .../OsuBeatmapConversionTest.cs | 2 +- .../Beatmaps/OsuBeatmapConverter.cs | 2 +- .../OsuDifficulty/OsuDifficultyCalculator.cs | 6 +++--- osu.Game.Rulesets.Osu/OsuRuleset.cs | 4 ++-- osu.Game.Rulesets.Osu/Replays/OsuReplayFrame.cs | 2 +- .../Scoring/OsuPerformanceCalculator.cs | 2 +- .../TaikoBeatmapConversionTest.cs | 2 +- .../Beatmaps/TaikoBeatmapConverter.cs | 4 ++-- .../Replays/TaikoReplayFrame.cs | 2 +- .../TaikoDifficultyCalculator.cs | 4 ++-- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 8 ++++---- osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs | 4 ++-- .../Visual/TestCaseEditorSeekSnapping.cs | 2 +- osu.Game/Beatmaps/Beatmap.cs | 2 +- osu.Game/Beatmaps/BeatmapConverter.cs | 12 ++++++------ osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/DifficultyCalculator.cs | 4 ++-- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 4 ++-- osu.Game/Beatmaps/IBeatmapConverter.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 12 ++++++------ .../Replays/Types/IConvertibleReplayFrame.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 4 ++-- .../Rulesets/Scoring/Legacy/LegacyScoreParser.cs | 2 +- osu.Game/Rulesets/Scoring/PerformanceCalculator.cs | 2 +- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 6 +++--- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 4 ++-- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 6 +++--- osu.Game/Tests/Visual/TestCasePerformancePoints.cs | 4 ++-- osu.Game/Tests/Visual/TestCasePlayer.cs | 2 +- 50 files changed, 89 insertions(+), 89 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index bd0cc209b6..bf373867e8 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Catch.Tests } } - protected override IBeatmapConverter CreateConverter(Beatmap beatmap) => new CatchBeatmapConverter(); + protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new CatchBeatmapConverter(); } public struct ConvertValue : IEquatable diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs index bce20520d3..097750d7e0 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Tests { } - protected override Beatmap CreateBeatmap(Ruleset ruleset) + protected override IBeatmap CreateBeatmap(Ruleset ruleset) { var beatmap = new Beatmap { diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseBananaShower.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseBananaShower.cs index d13a6bb860..b5cf0e3d1d 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseBananaShower.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseBananaShower.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Tests { } - protected override Beatmap CreateBeatmap(Ruleset ruleset) + protected override IBeatmap CreateBeatmap(Ruleset ruleset) { var beatmap = new Beatmap { diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseCatchStacker.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseCatchStacker.cs index 2b58fcc93c..8a90b48180 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseCatchStacker.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseCatchStacker.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Tests { } - protected override Beatmap CreateBeatmap(Ruleset ruleset) + protected override IBeatmap CreateBeatmap(Ruleset ruleset) { var beatmap = new Beatmap { diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseHyperdash.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseHyperdash.cs index e7f936ca2a..896582bf0a 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseHyperdash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseHyperdash.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Tests { } - protected override Beatmap CreateBeatmap(Ruleset ruleset) + protected override IBeatmap CreateBeatmap(Ruleset ruleset) { var beatmap = new Beatmap { BeatmapInfo = { Ruleset = ruleset.RulesetInfo } }; diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index 34e5f425fd..b1b101e797 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) }; - protected override IEnumerable ConvertHitObject(HitObject obj, Beatmap beatmap) + protected override IEnumerable ConvertHitObject(HitObject obj, IBeatmap beatmap) { var curveData = obj as IHasCurve; var positionData = obj as IHasXPosition; diff --git a/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs index 876b394da0..626a3d186a 100644 --- a/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs @@ -10,12 +10,12 @@ namespace osu.Game.Rulesets.Catch { public class CatchDifficultyCalculator : DifficultyCalculator { - public CatchDifficultyCalculator(Beatmap beatmap) : base(beatmap) + public CatchDifficultyCalculator(IBeatmap beatmap) : base(beatmap) { } public override double Calculate(Dictionary categoryDifficulty = null) => 0; - protected override BeatmapConverter CreateBeatmapConverter(Beatmap beatmap) => new CatchBeatmapConverter(); + protected override BeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(); } } diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index cfe0fc5cec..e2cb7b1d9b 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -138,7 +138,7 @@ namespace osu.Game.Rulesets.Catch public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o }; - public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new CatchDifficultyCalculator(beatmap); + public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new CatchDifficultyCalculator(beatmap); public override int? LegacyID => 2; diff --git a/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs b/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs index d63d1bd331..d5c5eb844a 100644 --- a/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs +++ b/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.Replays Dashing = dashing; } - public void ConvertFrom(LegacyReplayFrame legacyFrame, Beatmap beatmap) + public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap) { Position = legacyFrame.Position.X / CatchPlayfield.BASE_WIDTH; Dashing = legacyFrame.ButtonState == ReplayButtonState.Left1; diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index 81c537e53c..fb1fce4279 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Tests }; } - protected override IBeatmapConverter CreateConverter(Beatmap beatmap) => new ManiaBeatmapConverter(isForCurrentRuleset, beatmap); + protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(isForCurrentRuleset, beatmap); } public struct ConvertValue : IEquatable diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 60b92cb7b3..a142db8fed 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps private ManiaBeatmap beatmap; - public ManiaBeatmapConverter(bool isForCurrentRuleset, Beatmap original) + public ManiaBeatmapConverter(bool isForCurrentRuleset, IBeatmap original) { IsForCurrentRuleset = isForCurrentRuleset; @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps TargetColumns = (int)Math.Max(1, roundedCircleSize); else { - float percentSliderOrSpinner = (float)original.HitObjects.Count(h => h is IHasEndTime) / original.HitObjects.Count; + float percentSliderOrSpinner = (float)original.HitObjects.Count(h => h is IHasEndTime) / original.HitObjects.Count(); if (percentSliderOrSpinner < 0.2) TargetColumns = 7; else if (percentSliderOrSpinner < 0.3 || roundedCircleSize >= 5) @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps } } - protected override Beatmap ConvertBeatmap(Beatmap original) + protected override Beatmap ConvertBeatmap(IBeatmap original) { BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty; @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps protected override Beatmap CreateBeatmap() => beatmap = new ManiaBeatmap(new StageDefinition { Columns = TargetColumns }); - protected override IEnumerable ConvertHitObject(HitObject original, Beatmap beatmap) + protected override IEnumerable ConvertHitObject(HitObject original, IBeatmap beatmap) { var maniaOriginal = original as ManiaHitObject; if (maniaOriginal != null) @@ -112,7 +112,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// The original hit object. /// The original beatmap. This is used to look-up any values dependent on a fully-loaded beatmap. /// The hit objects generated. - private IEnumerable generateSpecific(HitObject original, Beatmap originalBeatmap) + private IEnumerable generateSpecific(HitObject original, IBeatmap originalBeatmap) { var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern, originalBeatmap); @@ -128,7 +128,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// The original hit object. /// The original beatmap. This is used to look-up any values dependent on a fully-loaded beatmap. /// The hit objects generated. - private IEnumerable generateConverted(HitObject original, Beatmap originalBeatmap) + private IEnumerable generateConverted(HitObject original, IBeatmap originalBeatmap) { var endTimeData = original as IHasEndTime; var distanceData = original as IHasDistance; @@ -165,7 +165,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator { - public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, Beatmap originalBeatmap) + public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap) : base(random, hitObject, beatmap, previousPattern, originalBeatmap) { } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 3b5c028bfd..afa9bdbbd7 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy private PatternType convertType; - public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, Beatmap originalBeatmap) + public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap) : base(random, hitObject, beatmap, previousPattern, originalBeatmap) { convertType = PatternType.None; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs index 743e230cb2..3f34afee85 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { private readonly double endTime; - public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Beatmap originalBeatmap) + public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, IBeatmap originalBeatmap) : base(random, hitObject, beatmap, new Pattern(), originalBeatmap) { var endtimeData = HitObject as IHasEndTime; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index 652c92dd78..cec3e18ad6 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy private readonly PatternType convertType; - public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair, Beatmap originalBeatmap) + public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair, IBeatmap originalBeatmap) : base(random, hitObject, beatmap, previousPattern, originalBeatmap) { if (previousTime > hitObject.StartTime) throw new ArgumentOutOfRangeException(nameof(previousTime)); diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs index 02306846a3..930597c1ad 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs @@ -28,9 +28,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// /// The beatmap which is being converted from. /// - protected readonly Beatmap OriginalBeatmap; + protected readonly IBeatmap OriginalBeatmap; - protected PatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, Beatmap originalBeatmap) + protected PatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap) : base(hitObject, beatmap, previousPattern) { if (random == null) throw new ArgumentNullException(nameof(random)); @@ -113,7 +113,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy drainTime /= 1000; BeatmapDifficulty difficulty = OriginalBeatmap.BeatmapInfo.BaseDifficulty; - conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + OriginalBeatmap.HitObjects.Count / drainTime * 9f) / 38f * 5f / 1.15; + conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + OriginalBeatmap.HitObjects.Count() / drainTime * 9f) / 38f * 5f / 1.15; conversionDifficulty = Math.Min(conversionDifficulty.Value, 12); return conversionDifficulty.Value; diff --git a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs index 5eea346836..24fe72faec 100644 --- a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs @@ -31,12 +31,12 @@ namespace osu.Game.Rulesets.Mania /// private readonly List difficultyHitObjects = new List(); - public ManiaDifficultyCalculator(Beatmap beatmap) + public ManiaDifficultyCalculator(IBeatmap beatmap) : base(beatmap) { } - public ManiaDifficultyCalculator(Beatmap beatmap, Mod[] mods) + public ManiaDifficultyCalculator(IBeatmap beatmap, Mod[] mods) : base(beatmap, mods) { } @@ -141,6 +141,6 @@ namespace osu.Game.Rulesets.Mania return difficulty; } - protected override BeatmapConverter CreateBeatmapConverter(Beatmap beatmap) => new ManiaBeatmapConverter(true, beatmap); + protected override BeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(true, beatmap); } } diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 0546cbc174..d5bf1b30fc 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -182,7 +182,7 @@ namespace osu.Game.Rulesets.Mania public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o }; - public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new ManiaDifficultyCalculator(beatmap, mods); + public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new ManiaDifficultyCalculator(beatmap, mods); public override int? LegacyID => 3; diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs b/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs index 8d86325dd9..926a3a8923 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Mania.Replays Actions.AddRange(actions); } - public void ConvertFrom(LegacyReplayFrame legacyFrame, Beatmap beatmap) + public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap) { // We don't need to fully convert, just create the converter var converter = new ManiaBeatmapConverter(beatmap.BeatmapInfo.RulesetID == 3, beatmap); diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index 6ac3c016a0..a77b20e83b 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Osu.Tests }; } - protected override IBeatmapConverter CreateConverter(Beatmap beatmap) => new OsuBeatmapConverter(); + protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new OsuBeatmapConverter(); } public struct ConvertValue : IEquatable diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs index 1236076f48..b1a52c5469 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps { protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(IHasPosition) }; - protected override IEnumerable ConvertHitObject(HitObject original, Beatmap beatmap) + protected override IEnumerable ConvertHitObject(HitObject original, IBeatmap beatmap) { var curveData = original as IHasCurve; var endTimeData = original as IHasEndTime; diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs index 926a7975f3..197bc16fc1 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs @@ -17,12 +17,12 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty private const int section_length = 400; private const double difficulty_multiplier = 0.0675; - public OsuDifficultyCalculator(Beatmap beatmap) + public OsuDifficultyCalculator(IBeatmap beatmap) : base(beatmap) { } - public OsuDifficultyCalculator(Beatmap beatmap, Mod[] mods) + public OsuDifficultyCalculator(IBeatmap beatmap, Mod[] mods) : base(beatmap, mods) { } @@ -73,6 +73,6 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty return starRating; } - protected override BeatmapConverter CreateBeatmapConverter(Beatmap beatmap) => new OsuBeatmapConverter(); + protected override BeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(); } } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index e0ecee97a3..ed750882f4 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -181,9 +181,9 @@ namespace osu.Game.Rulesets.Osu public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_osu_o }; - public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new OsuDifficultyCalculator(beatmap, mods); + public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new OsuDifficultyCalculator(beatmap, mods); - public override PerformanceCalculator CreatePerformanceCalculator(Beatmap beatmap, Score score) => new OsuPerformanceCalculator(this, beatmap, score); + public override PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => new OsuPerformanceCalculator(this, beatmap, score); public override HitObjectComposer CreateHitObjectComposer() => new OsuHitObjectComposer(this); diff --git a/osu.Game.Rulesets.Osu/Replays/OsuReplayFrame.cs b/osu.Game.Rulesets.Osu/Replays/OsuReplayFrame.cs index 6f2512cc33..4412b6efab 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuReplayFrame.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuReplayFrame.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Replays Actions.AddRange(actions); } - public void ConvertFrom(LegacyReplayFrame legacyFrame, Beatmap beatmap) + public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap) { Position = legacyFrame.Position; if (legacyFrame.MouseLeft) Actions.Add(OsuAction.LeftButton); diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index 8f0feca207..c8806cbdb1 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Scoring private int count50; private int countMiss; - public OsuPerformanceCalculator(Ruleset ruleset, Beatmap beatmap, Score score) + public OsuPerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) : base(ruleset, beatmap, score) { countHitCircles = Beatmap.HitObjects.Count(h => h is HitCircle); diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs index aa61f2d60b..3d236af8ad 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Taiko.Tests }; } - protected override IBeatmapConverter CreateConverter(Beatmap beatmap) => new TaikoBeatmapConverter(isForCurrentRuleset); + protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(isForCurrentRuleset); } public struct ConvertValue : IEquatable diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 2f175a9922..eabe7eb91a 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps this.isForCurrentRuleset = isForCurrentRuleset; } - protected override Beatmap ConvertBeatmap(Beatmap original) + protected override Beatmap ConvertBeatmap(IBeatmap original) { // Rewrite the beatmap info to add the slider velocity multiplier BeatmapInfo info = original.BeatmapInfo.DeepClone(); @@ -70,7 +70,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps return converted; } - protected override IEnumerable ConvertHitObject(HitObject obj, Beatmap beatmap) + protected override IEnumerable ConvertHitObject(HitObject obj, IBeatmap beatmap) { var distanceData = obj as IHasDistance; var repeatsData = obj as IHasRepeats; diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs index e510b34ad7..2177a3cbdc 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko.Replays Actions.AddRange(actions); } - public void ConvertFrom(LegacyReplayFrame legacyFrame, Beatmap beatmap) + public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap) { if (legacyFrame.MouseRight1) Actions.Add(TaikoAction.LeftRim); if (legacyFrame.MouseRight2) Actions.Add(TaikoAction.RightRim); diff --git a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs index 58661d7881..66b8459d1f 100644 --- a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Taiko /// private readonly List difficultyHitObjects = new List(); - public TaikoDifficultyCalculator(Beatmap beatmap) + public TaikoDifficultyCalculator(IBeatmap beatmap) : base(beatmap) { } @@ -133,6 +133,6 @@ namespace osu.Game.Rulesets.Taiko return difficulty; } - protected override BeatmapConverter CreateBeatmapConverter(Beatmap beatmap) => new TaikoBeatmapConverter(true); + protected override BeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(true); } } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 06a8e44a14..e5f3b33355 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -140,7 +140,7 @@ namespace osu.Game.Rulesets.Taiko public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o }; - public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new TaikoDifficultyCalculator(beatmap); + public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new TaikoDifficultyCalculator(beatmap); public override int? LegacyID => 1; diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 6453cdbd3e..f60caf2397 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -275,13 +275,13 @@ namespace osu.Game.Tests.Beatmaps.IO Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineBeatmapID == b.OnlineBeatmapID)); Assert.IsTrue(set.Beatmaps.Count > 0); var beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 0))?.Beatmap; - Assert.IsTrue(beatmap?.HitObjects.Count > 0); + Assert.IsTrue(beatmap?.HitObjects.Any() == true); beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 1))?.Beatmap; - Assert.IsTrue(beatmap?.HitObjects.Count > 0); + Assert.IsTrue(beatmap?.HitObjects.Any() == true); beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 2))?.Beatmap; - Assert.IsTrue(beatmap?.HitObjects.Count > 0); + Assert.IsTrue(beatmap?.HitObjects.Any() == true); beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap; - Assert.IsTrue(beatmap?.HitObjects.Count > 0); + Assert.IsTrue(beatmap?.HitObjects.Any() == true); } private void waitForOrAssert(Func result, string failureMessage, int timeout = 60000) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 790c4cedc3..0c5c5dba22 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual { private RulesetStore rulesets; private TestBeatmapInfoWedge infoWedge; - private readonly List beatmaps = new List(); + private readonly List beatmaps = new List(); private readonly Bindable beatmap = new Bindable(); [BackgroundDependencyLoader] @@ -130,7 +130,7 @@ namespace osu.Game.Tests.Visual }); } - private Beatmap createTestBeatmap(RulesetInfo ruleset) + private IBeatmap createTestBeatmap(RulesetInfo ruleset) { List objects = new List(); for (double i = 0; i < 50000; i += 1000) diff --git a/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs b/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs index 582ab5ecc9..f037d70493 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs @@ -332,7 +332,7 @@ namespace osu.Game.Tests.Visual private readonly Drawable tracker; - public TimingPointVisualiser(Beatmap beatmap, double length) + public TimingPointVisualiser(IBeatmap beatmap, double length) { this.length = length; diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 7066432c5c..6a7d2690ff 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps /// /// This beatmap's info. /// - BeatmapInfo BeatmapInfo { get; } + BeatmapInfo BeatmapInfo { get; set; } /// /// This beatmap's metadata. diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index f46e6abc87..fab7860077 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -27,27 +27,27 @@ namespace osu.Game.Beatmaps /// /// The Beatmap to check. /// Whether the Beatmap can be converted using this Beatmap Converter. - public bool CanConvert(Beatmap beatmap) => ValidConversionTypes.All(t => beatmap.HitObjects.Any(t.IsInstanceOfType)); + public bool CanConvert(IBeatmap beatmap) => ValidConversionTypes.All(t => beatmap.HitObjects.Any(t.IsInstanceOfType)); /// /// Converts a Beatmap using this Beatmap Converter. /// /// The un-converted Beatmap. /// The converted Beatmap. - public Beatmap Convert(Beatmap original) + public Beatmap Convert(IBeatmap original) { // We always operate on a clone of the original beatmap, to not modify it game-wide return ConvertBeatmap(original.Clone()); } - void IBeatmapConverter.Convert(Beatmap original) => Convert(original); + void IBeatmapConverter.Convert(IBeatmap original) => Convert(original); /// /// Performs the conversion of a Beatmap using this Beatmap Converter. /// /// The un-converted Beatmap. /// The converted Beatmap. - protected virtual Beatmap ConvertBeatmap(Beatmap original) + protected virtual Beatmap ConvertBeatmap(IBeatmap original) { var beatmap = CreateBeatmap(); @@ -67,7 +67,7 @@ namespace osu.Game.Beatmaps /// The hit object to convert. /// The un-converted Beatmap. /// The converted hit object. - private IEnumerable convert(HitObject original, Beatmap beatmap) + private IEnumerable convert(HitObject original, IBeatmap beatmap) { // Check if the hitobject is already the converted type T tObject = original as T; @@ -107,6 +107,6 @@ namespace osu.Game.Beatmaps /// The hit object to convert. /// The un-converted Beatmap. /// The converted hit object. - protected abstract IEnumerable ConvertHitObject(HitObject original, Beatmap beatmap); + protected abstract IEnumerable ConvertHitObject(HitObject original, IBeatmap beatmap); } } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 645e52a6c6..14436fce13 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -333,7 +333,7 @@ namespace osu.Game.Beatmaps ms.Position = 0; var decoder = Decoder.GetDecoder(sr); - Beatmap beatmap = decoder.Decode(sr); + IBeatmap beatmap = decoder.Decode(sr); beatmap.BeatmapInfo.Path = name; beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash(); diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 8e09d66c42..71406c6034 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -30,7 +30,7 @@ namespace osu.Game.Beatmaps this.audioManager = audioManager; } - protected override Beatmap GetBeatmap() + protected override IBeatmap GetBeatmap() { try { diff --git a/osu.Game/Beatmaps/DifficultyCalculator.cs b/osu.Game/Beatmaps/DifficultyCalculator.cs index 5e2d9afd23..bf252ff51f 100644 --- a/osu.Game/Beatmaps/DifficultyCalculator.cs +++ b/osu.Game/Beatmaps/DifficultyCalculator.cs @@ -22,7 +22,7 @@ namespace osu.Game.Beatmaps protected readonly Beatmap Beatmap; protected readonly Mod[] Mods; - protected DifficultyCalculator(Beatmap beatmap, Mod[] mods = null) + protected DifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) { Mods = mods ?? new Mod[0]; @@ -59,6 +59,6 @@ namespace osu.Game.Beatmaps { } - protected abstract BeatmapConverter CreateBeatmapConverter(Beatmap beatmap); + protected abstract BeatmapConverter CreateBeatmapConverter(IBeatmap beatmap); } } diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 0424ff84f1..0d325284e1 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -39,7 +39,7 @@ namespace osu.Game.Beatmaps this.game = game; } - protected override Beatmap GetBeatmap() => new Beatmap(); + protected override IBeatmap GetBeatmap() => new Beatmap(); protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4"); @@ -58,7 +58,7 @@ namespace osu.Game.Beatmaps throw new NotImplementedException(); } - public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => null; + public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => null; public override string Description => "dummy"; diff --git a/osu.Game/Beatmaps/IBeatmapConverter.cs b/osu.Game/Beatmaps/IBeatmapConverter.cs index 6c25395a56..4df250ad17 100644 --- a/osu.Game/Beatmaps/IBeatmapConverter.cs +++ b/osu.Game/Beatmaps/IBeatmapConverter.cs @@ -20,6 +20,6 @@ namespace osu.Game.Beatmaps /// Converts a Beatmap using this Beatmap Converter. /// /// The un-converted Beatmap. - void Convert(Beatmap beatmap); + void Convert(IBeatmap beatmap); } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 4080e34e81..fc67d2e508 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -36,7 +36,7 @@ namespace osu.Game.Beatmaps Mods.ValueChanged += mods => applyRateAdjustments(); - beatmap = new AsyncLazy(populateBeatmap); + beatmap = new AsyncLazy(populateBeatmap); background = new AsyncLazy(populateBackground, b => b == null || !b.IsDisposed); track = new AsyncLazy(populateTrack); waveform = new AsyncLazy(populateWaveform); @@ -55,7 +55,7 @@ namespace osu.Game.Beatmaps Process.Start(path); } - protected abstract Beatmap GetBeatmap(); + protected abstract IBeatmap GetBeatmap(); protected abstract Texture GetBackground(); protected abstract Track GetTrack(); protected virtual Skin GetSkin() => new DefaultSkin(); @@ -63,12 +63,12 @@ namespace osu.Game.Beatmaps protected virtual Storyboard GetStoryboard() => new Storyboard { BeatmapInfo = BeatmapInfo }; public bool BeatmapLoaded => beatmap.IsResultAvailable; - public Beatmap Beatmap => beatmap.Value.Result; - public async Task GetBeatmapAsync() => await beatmap.Value; + public IBeatmap Beatmap => beatmap.Value.Result; + public async Task GetBeatmapAsync() => await beatmap.Value; - private readonly AsyncLazy beatmap; + private readonly AsyncLazy beatmap; - private Beatmap populateBeatmap() + private IBeatmap populateBeatmap() { var b = GetBeatmap() ?? new Beatmap(); diff --git a/osu.Game/Rulesets/Replays/Types/IConvertibleReplayFrame.cs b/osu.Game/Rulesets/Replays/Types/IConvertibleReplayFrame.cs index adf35ce078..fdd528f296 100644 --- a/osu.Game/Rulesets/Replays/Types/IConvertibleReplayFrame.cs +++ b/osu.Game/Rulesets/Replays/Types/IConvertibleReplayFrame.cs @@ -16,6 +16,6 @@ namespace osu.Game.Rulesets.Replays.Types /// /// The to extract values from. /// The beatmap. - void ConvertFrom(LegacyReplayFrame legacyFrame, Beatmap beatmap); + void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap); } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index cd1d030afe..3f8512eb90 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -57,9 +57,9 @@ namespace osu.Game.Rulesets /// public abstract RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset); - public abstract DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null); + public abstract DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null); - public virtual PerformanceCalculator CreatePerformanceCalculator(Beatmap beatmap, Score score) => null; + public virtual PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => null; public virtual HitObjectComposer CreateHitObjectComposer() => null; diff --git a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs index 239f200e29..d5ab856697 100644 --- a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Scoring.Legacy this.beatmaps = beatmaps; } - private Beatmap currentBeatmap; + private IBeatmap currentBeatmap; private Ruleset currentRuleset; public Score Parse(Stream stream) diff --git a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs b/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs index 0f115fff6b..6392d2c0ae 100644 --- a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs +++ b/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Scoring protected readonly Beatmap Beatmap; protected readonly Score Score; - protected PerformanceCalculator(Ruleset ruleset, Beatmap beatmap, Score score) + protected PerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) { Score = score; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index ec7c1a1009..32685935a1 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -96,7 +96,7 @@ namespace osu.Game.Screens.Play mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); - Beatmap beatmap; + IBeatmap beatmap; try { diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index f005261ffa..da82a49f51 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -215,7 +215,7 @@ namespace osu.Game.Screens.Select List labels = new List(); - if (beatmap?.HitObjects?.Count > 0) + if (beatmap?.HitObjects?.Any() == true) { HitObject lastObject = beatmap.HitObjects.LastOrDefault(); double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; @@ -224,7 +224,7 @@ namespace osu.Game.Screens.Select { Name = "Length", Icon = FontAwesome.fa_clock_o, - Content = beatmap.HitObjects.Count == 0 ? "-" : TimeSpan.FromMilliseconds(endTime - beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"), + Content = TimeSpan.FromMilliseconds(endTime - beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"), })); labels.Add(new InfoLabel(new BeatmapStatistic @@ -241,7 +241,7 @@ namespace osu.Game.Screens.Select return labels.ToArray(); } - private string getBPMRange(Beatmap beatmap) + private string getBPMRange(IBeatmap beatmap) { double bpmMax = beatmap.ControlPointInfo.BPMMaximum; double bpmMin = beatmap.ControlPointInfo.BPMMinimum; diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 2850de8ba5..d02ccaff16 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Beatmaps } } - private Beatmap getBeatmap(string name) + private IBeatmap getBeatmap(string name) { using (var resStream = openResource($"{resource_namespace}.{name}.osu")) using (var stream = new StreamReader(resStream)) @@ -125,7 +125,7 @@ namespace osu.Game.Tests.Beatmaps } protected abstract IEnumerable CreateConvertValue(HitObject hitObject); - protected abstract IBeatmapConverter CreateConverter(Beatmap beatmap); + protected abstract IBeatmapConverter CreateConverter(IBeatmap beatmap); private class ConvertMapping { diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index e24fbab3ac..37693c99e8 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -17,14 +17,14 @@ namespace osu.Game.Tests.Beatmaps { } - public TestWorkingBeatmap(Beatmap beatmap) + public TestWorkingBeatmap(IBeatmap beatmap) : base(beatmap.BeatmapInfo) { this.beatmap = beatmap; } - private readonly Beatmap beatmap; - protected override Beatmap GetBeatmap() => beatmap; + private readonly IBeatmap beatmap; + protected override IBeatmap GetBeatmap() => beatmap; protected override Texture GetBackground() => null; protected override Track GetTrack() diff --git a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs index 29132258c2..51460ecb6d 100644 --- a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs +++ b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs @@ -259,9 +259,9 @@ namespace osu.Game.Tests.Visual private readonly OsuSpriteText text; private readonly Score score; - private readonly Beatmap beatmap; + private readonly IBeatmap beatmap; - public PerformanceDisplay(Score score, Beatmap beatmap) + public PerformanceDisplay(Score score, IBeatmap beatmap) { this.score = score; this.beatmap = beatmap; diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index 5ed43b2814..bda438d906 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual } } - protected virtual Beatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo); + protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo); private Player loadPlayerFor(RulesetInfo ri) => loadPlayerFor(ri.CreateInstance()); From 03a5df84c6860738ec0723bc83df634d02666085 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 19 Apr 2018 22:04:12 +0900 Subject: [PATCH 012/229] Initial rework of beatmap conversion process --- .../CatchBeatmapConversionTest.cs | 2 +- .../Beatmaps/CatchBeatmapConverter.cs | 5 ++ .../Beatmaps/CatchBeatmapProcessor.cs | 15 +++-- .../CatchDifficultyCalculator.cs | 6 +- osu.Game.Rulesets.Catch/CatchRuleset.cs | 3 + .../Mods/CatchModHardRock.cs | 13 +++-- .../UI/CatchRulesetContainer.cs | 5 -- .../ManiaBeatmapConversionTest.cs | 2 +- .../Beatmaps/ManiaBeatmapConverter.cs | 16 +++--- .../ManiaDifficultyCalculator.cs | 6 +- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 + osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs | 5 +- .../Mods/ManiaModDualStages.cs | 4 +- .../Replays/ManiaReplayFrame.cs | 2 +- .../UI/ManiaRulesetContainer.cs | 2 - .../OsuBeatmapConversionTest.cs | 2 +- .../Beatmaps/OsuBeatmapConverter.cs | 5 ++ .../Beatmaps/OsuBeatmapProcessor.cs | 13 +++-- osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs | 9 ++- .../OsuDifficulty/OsuDifficultyCalculator.cs | 12 +--- osu.Game.Rulesets.Osu/OsuRuleset.cs | 5 +- .../Scoring/OsuPerformanceCalculator.cs | 7 +-- .../UI/OsuRulesetContainer.cs | 5 -- .../TaikoBeatmapConversionTest.cs | 7 +-- .../Beatmaps/TaikoBeatmapConverter.cs | 5 +- .../TaikoDifficultyCalculator.cs | 7 +-- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 + .../UI/TaikoRulesetContainer.cs | 3 - .../Beatmaps/IO/ImportBeatmapTest.cs | 8 +-- .../Visual/TestCaseBeatSyncedContainer.cs | 2 +- osu.Game/Beatmaps/BeatmapConverter.cs | 32 ++++++----- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/BeatmapProcessor.cs | 29 ++++++++-- osu.Game/Beatmaps/DifficultyCalculator.cs | 34 ++--------- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 13 ++++- osu.Game/Beatmaps/IBeatmapConverter.cs | 12 +++- osu.Game/Beatmaps/WorkingBeatmap.cs | 56 +++++++++++++++---- .../Containers/BeatSyncedContainer.cs | 2 +- osu.Game/Overlays/MusicController.cs | 2 +- .../Mods/IApplicableToBeatmapConverter.cs | 5 +- .../Rulesets/Mods/IApplicableToHitObject.cs | 5 +- osu.Game/Rulesets/Ruleset.cs | 4 ++ .../Scoring/Legacy/LegacyScoreParser.cs | 2 +- .../Rulesets/Scoring/PerformanceCalculator.cs | 20 +------ osu.Game/Rulesets/UI/RulesetContainer.cs | 42 +------------- .../Timelines/Summary/Parts/BreakPart.cs | 2 +- .../Summary/Parts/ControlPointPart.cs | 2 +- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 2 +- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Ranking/ResultsPageScore.cs | 2 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 2 +- .../Tests/Beatmaps/BeatmapConversionTest.cs | 2 +- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 2 +- osu.Game/Tests/Visual/EditorClockTestCase.cs | 2 +- .../Tests/Visual/TestCasePerformancePoints.cs | 4 +- 56 files changed, 230 insertions(+), 234 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index bf373867e8..a94d29ca2c 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Catch.Tests } } - protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new CatchBeatmapConverter(); + protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap); } public struct ConvertValue : IEquatable diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index b1b101e797..3b22c47ac8 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -13,6 +13,11 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { public class CatchBeatmapConverter : BeatmapConverter { + public CatchBeatmapConverter(IBeatmap beatmap) + : base(beatmap) + { + } + protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) }; protected override IEnumerable ConvertHitObject(HitObject obj, IBeatmap beatmap) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index dfd10e0df7..e16f5fcb60 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -12,16 +12,21 @@ using OpenTK; namespace osu.Game.Rulesets.Catch.Beatmaps { - public class CatchBeatmapProcessor : BeatmapProcessor + public class CatchBeatmapProcessor : BeatmapProcessor { - public override void PostProcess(Beatmap beatmap) + public CatchBeatmapProcessor(IBeatmap beatmap) + : base(beatmap) { - initialiseHyperDash(beatmap.HitObjects); + } - base.PostProcess(beatmap); + public override void PostProcess() + { + initialiseHyperDash((List)Beatmap.HitObjects); + + base.PostProcess(); int index = 0; - foreach (var obj in beatmap.HitObjects) + foreach (var obj in Beatmap.HitObjects.OfType()) obj.IndexInBeatmap = index++; } diff --git a/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs index 626a3d186a..f47d09fe20 100644 --- a/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs @@ -2,20 +2,16 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Beatmaps; -using osu.Game.Rulesets.Catch.Beatmaps; -using osu.Game.Rulesets.Catch.Objects; using System.Collections.Generic; namespace osu.Game.Rulesets.Catch { - public class CatchDifficultyCalculator : DifficultyCalculator + public class CatchDifficultyCalculator : DifficultyCalculator { public CatchDifficultyCalculator(IBeatmap beatmap) : base(beatmap) { } public override double Calculate(Dictionary categoryDifficulty = null) => 0; - - protected override BeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(); } } diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index e2cb7b1d9b..f091fbbee4 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -13,12 +13,15 @@ using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; +using osu.Game.Rulesets.Catch.Beatmaps; namespace osu.Game.Rulesets.Catch { public class CatchRuleset : Ruleset { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap); + public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap); public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] { diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs index df7578799f..8e19c0614a 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs @@ -6,10 +6,11 @@ using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Mods; using System; +using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Catch.Mods { - public class CatchModHardRock : ModHardRock, IApplicableToHitObject + public class CatchModHardRock : ModHardRock, IApplicableToHitObject { public override double ScoreMultiplier => 1.12; public override bool Ranked => true; @@ -17,9 +18,11 @@ namespace osu.Game.Rulesets.Catch.Mods private float lastStartX; private int lastStartTime; - public void ApplyToHitObject(CatchHitObject hitObject) + public void ApplyToHitObject(HitObject hitObject) { - float position = hitObject.X; + var catchObject = (CatchHitObject)hitObject; + + float position = catchObject.X; int startTime = (int)hitObject.StartTime; if (lastStartX == 0) @@ -60,7 +63,7 @@ namespace osu.Game.Rulesets.Catch.Mods position += rand; } - hitObject.X = position; + catchObject.X = position; return; } @@ -79,7 +82,7 @@ namespace osu.Game.Rulesets.Catch.Mods } } - hitObject.X = position; + catchObject.X = position; lastStartX = position; lastStartTime = startTime; diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index 022a8a8b43..6e8a2c1660 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -4,7 +4,6 @@ using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Input.Handlers; -using osu.Game.Rulesets.Catch.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Catch.Replays; @@ -29,10 +28,6 @@ namespace osu.Game.Rulesets.Catch.UI protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay); - protected override BeatmapProcessor CreateBeatmapProcessor() => new CatchBeatmapProcessor(); - - protected override BeatmapConverter CreateBeatmapConverter() => new CatchBeatmapConverter(); - protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, GetVisualRepresentation); public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo); diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index fb1fce4279..e52fc11518 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Tests }; } - protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(isForCurrentRuleset, beatmap); + protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap); } public struct ConvertValue : IEquatable diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index a142db8fed..93feddc143 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -33,18 +33,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps private ManiaBeatmap beatmap; - public ManiaBeatmapConverter(bool isForCurrentRuleset, IBeatmap original) + public ManiaBeatmapConverter(IBeatmap beatmap) + : base(beatmap) { - IsForCurrentRuleset = isForCurrentRuleset; + IsForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(new ManiaRuleset().RulesetInfo); + + var roundedCircleSize = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.CircleSize); + var roundedOverallDifficulty = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); - var roundedCircleSize = Math.Round(original.BeatmapInfo.BaseDifficulty.CircleSize); - var roundedOverallDifficulty = Math.Round(original.BeatmapInfo.BaseDifficulty.OverallDifficulty); - - if (isForCurrentRuleset) + if (beatmap.BeatmapInfo.Ruleset == new ManiaRuleset().RulesetInfo) TargetColumns = (int)Math.Max(1, roundedCircleSize); else { - float percentSliderOrSpinner = (float)original.HitObjects.Count(h => h is IHasEndTime) / original.HitObjects.Count(); + float percentSliderOrSpinner = (float)beatmap.HitObjects.Count(h => h is IHasEndTime) / beatmap.HitObjects.Count(); if (percentSliderOrSpinner < 0.2) TargetColumns = 7; else if (percentSliderOrSpinner < 0.3 || roundedCircleSize >= 5) @@ -58,6 +59,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps protected override Beatmap ConvertBeatmap(IBeatmap original) { + BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty; int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate); diff --git a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs index 24fe72faec..822ba53eeb 100644 --- a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs @@ -10,7 +10,7 @@ using System.Collections.Generic; namespace osu.Game.Rulesets.Mania { - internal class ManiaDifficultyCalculator : DifficultyCalculator + internal class ManiaDifficultyCalculator : DifficultyCalculator { private const double star_scaling_factor = 0.018; @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Mania int columnCount = (Beatmap as ManiaBeatmap)?.TotalColumns ?? 7; foreach (var hitObject in Beatmap.HitObjects) - difficultyHitObjects.Add(new ManiaHitObjectDifficulty(hitObject, columnCount)); + difficultyHitObjects.Add(new ManiaHitObjectDifficulty((ManiaHitObject)hitObject, columnCount)); // Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure. difficultyHitObjects.Sort((a, b) => a.BaseHitObject.StartTime.CompareTo(b.BaseHitObject.StartTime)); @@ -140,7 +140,5 @@ namespace osu.Game.Rulesets.Mania return difficulty; } - - protected override BeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(true, beatmap); } } diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index d5bf1b30fc..75b1e38a2f 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -15,12 +15,14 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Mania.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; +using osu.Game.Rulesets.Mania.Beatmaps; namespace osu.Game.Rulesets.Mania { public class ManiaRuleset : Ruleset { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new ManiaRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap); public override IEnumerable ConvertLegacyMods(LegacyMods mods) { diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs index dbd30121a8..e02db68a28 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs @@ -3,19 +3,18 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps; -using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Mania.Mods { - public abstract class ManiaKeyMod : Mod, IApplicableToBeatmapConverter + public abstract class ManiaKeyMod : Mod, IApplicableToBeatmapConverter { public override string ShortenedName => Name; public abstract int KeyCount { get; } public override double ScoreMultiplier => 1; // TODO: Implement the mania key mod score multiplier public override bool Ranked => true; - public void ApplyToBeatmapConverter(BeatmapConverter beatmapConverter) + public void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter) { var mbc = (ManiaBeatmapConverter)beatmapConverter; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs index 197b37b3f5..dde8acf428 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs @@ -11,14 +11,14 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mania.Mods { - public class ManiaModDualStages : Mod, IPlayfieldTypeMod, IApplicableToBeatmapConverter, IApplicableToRulesetContainer + public class ManiaModDualStages : Mod, IPlayfieldTypeMod, IApplicableToBeatmapConverter, IApplicableToRulesetContainer { public override string Name => "Dual Stages"; public override string ShortenedName => "DS"; public override string Description => @"Double the stages, double the fun!"; public override double ScoreMultiplier => 0; - public void ApplyToBeatmapConverter(BeatmapConverter beatmapConverter) + public void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter) { var mbc = (ManiaBeatmapConverter)beatmapConverter; diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs b/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs index 926a3a8923..bc9fd6e06f 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Replays public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap) { // We don't need to fully convert, just create the converter - var converter = new ManiaBeatmapConverter(beatmap.BeatmapInfo.RulesetID == 3, beatmap); + var converter = new ManiaBeatmapConverter(beatmap); // NB: Via co-op mod, osu-stable can have two stages with floor(col/2) and ceil(col/2) columns. This will need special handling // elsewhere in the game if we do choose to support the old co-op mod anyway. For now, assume that there is only one stage. diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 76afaf270f..059eaaadcd 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -85,8 +85,6 @@ namespace osu.Game.Rulesets.Mania.UI public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Variant); - protected override BeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter(IsForCurrentRuleset, WorkingBeatmap.Beatmap); - protected override DrawableHitObject GetVisualRepresentation(ManiaHitObject h) { ManiaAction action = Playfield.Columns.ElementAt(h.Column).Action; diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index a77b20e83b..a8f82a112b 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Osu.Tests }; } - protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new OsuBeatmapConverter(); + protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap); } public struct ConvertValue : IEquatable diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs index b1a52c5469..1cd4ec5668 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs @@ -14,6 +14,11 @@ namespace osu.Game.Rulesets.Osu.Beatmaps { internal class OsuBeatmapConverter : BeatmapConverter { + public OsuBeatmapConverter(IBeatmap beatmap) + : base(beatmap) + { + } + protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(IHasPosition) }; protected override IEnumerable ConvertHitObject(HitObject original, IBeatmap beatmap) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index afa2437bf6..c7c9f4a01a 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -8,12 +8,17 @@ using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Rulesets.Osu.Beatmaps { - internal class OsuBeatmapProcessor : BeatmapProcessor + internal class OsuBeatmapProcessor : BeatmapProcessor { - public override void PostProcess(Beatmap beatmap) + public OsuBeatmapProcessor(IBeatmap beatmap) + : base(beatmap) { - applyStacking(beatmap); - base.PostProcess(beatmap); + } + + public override void PostProcess() + { + applyStacking((Beatmap)Beatmap); + base.PostProcess(); } private void applyStacking(Beatmap beatmap) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs index cf71116d47..7a30e6b134 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs @@ -5,20 +5,23 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; using OpenTK; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModHardRock : ModHardRock, IApplicableToHitObject + public class OsuModHardRock : ModHardRock, IApplicableToHitObject { public override double ScoreMultiplier => 1.06; public override bool Ranked => true; - public void ApplyToHitObject(OsuHitObject hitObject) + public void ApplyToHitObject(HitObject hitObject) { - hitObject.Position = new Vector2(hitObject.Position.X, OsuPlayfield.BASE_SIZE.Y - hitObject.Y); + var osuObject = (OsuHitObject)hitObject; + + osuObject.Position = new Vector2(osuObject.Position.X, OsuPlayfield.BASE_SIZE.Y - osuObject.Y); var slider = hitObject as Slider; if (slider == null) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs index 197bc16fc1..4853cd66cd 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs @@ -5,14 +5,13 @@ using System; using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; using osu.Game.Rulesets.Osu.OsuDifficulty.Skills; namespace osu.Game.Rulesets.Osu.OsuDifficulty { - public class OsuDifficultyCalculator : DifficultyCalculator + public class OsuDifficultyCalculator : DifficultyCalculator { private const int section_length = 400; private const double difficulty_multiplier = 0.0675; @@ -27,14 +26,9 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty { } - protected override void PreprocessHitObjects() - { - new OsuBeatmapProcessor().PostProcess(Beatmap); - } - public override double Calculate(Dictionary categoryDifficulty = null) { - OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap(Beatmap.HitObjects, TimeRate); + OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap((List)Beatmap.HitObjects, TimeRate); Skill[] skills = { new Aim(), @@ -72,7 +66,5 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty return starRating; } - - protected override BeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(); } } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index ed750882f4..02b887f1b9 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -22,12 +22,15 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; +using osu.Game.Rulesets.Osu.Beatmaps; namespace osu.Game.Rulesets.Osu { public class OsuRuleset : Ruleset { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new OsuRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap); + public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap); public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] { @@ -39,7 +42,7 @@ namespace osu.Game.Rulesets.Osu public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) { - IEnumerable hitObjects = beatmap.Beatmap.HitObjects; + IEnumerable hitObjects = beatmap.OriginalBeatmap.HitObjects; IEnumerable circles = hitObjects.Where(c => !(c is IHasEndTime)); IEnumerable sliders = hitObjects.Where(s => s is IHasCurve); IEnumerable spinners = hitObjects.Where(s => s is IHasEndTime && !(s is IHasCurve)); diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index c8806cbdb1..6b9214d9dc 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -6,14 +6,13 @@ using System.Collections.Generic; using System.Linq; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Osu.Scoring { - public class OsuPerformanceCalculator : PerformanceCalculator + public class OsuPerformanceCalculator : PerformanceCalculator { private readonly int countHitCircles; private readonly int beatmapMaxCombo; @@ -32,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Scoring { countHitCircles = Beatmap.HitObjects.Count(h => h is HitCircle); - beatmapMaxCombo = Beatmap.HitObjects.Count; + beatmapMaxCombo = Beatmap.HitObjects.Count(); beatmapMaxCombo += Beatmap.HitObjects.OfType().Sum(s => s.NestedHitObjects.Count) + 1; } @@ -193,7 +192,5 @@ namespace osu.Game.Rulesets.Osu.Scoring private double totalHits => count300 + count100 + count50 + countMiss; private double totalSuccessfulHits => count300 + count100 + count50; - - protected override BeatmapConverter CreateBeatmapConverter() => new OsuBeatmapConverter(); } } diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs index 22c7b719cd..603f95dc47 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs @@ -7,7 +7,6 @@ using OpenTK; using osu.Game.Beatmaps; using osu.Game.Input.Handlers; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Replays; @@ -28,10 +27,6 @@ namespace osu.Game.Rulesets.Osu.UI public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor(this); - protected override BeatmapConverter CreateBeatmapConverter() => new OsuBeatmapConverter(); - - protected override BeatmapProcessor CreateBeatmapProcessor() => new OsuBeatmapProcessor(); - protected override Playfield CreatePlayfield() => new OsuPlayfield(); public override PassThroughInputManager CreateInputManager() => new OsuInputManager(Ruleset.RulesetInfo); diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs index 3d236af8ad..cbab53fa75 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -18,14 +18,11 @@ namespace osu.Game.Rulesets.Taiko.Tests { protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; - private bool isForCurrentRuleset; - [NonParallelizable] [TestCase("basic", false), Ignore("See: https://github.com/ppy/osu/issues/2152")] [TestCase("slider-generating-drumroll", false)] - public void Test(string name, bool isForCurrentRuleset) + public new void Test(string name) { - this.isForCurrentRuleset = isForCurrentRuleset; base.Test(name); } @@ -43,7 +40,7 @@ namespace osu.Game.Rulesets.Taiko.Tests }; } - protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(isForCurrentRuleset); + protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap); } public struct ConvertValue : IEquatable diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index eabe7eb91a..eeb0fa1871 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -42,9 +42,10 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(HitObject) }; - public TaikoBeatmapConverter(bool isForCurrentRuleset) + public TaikoBeatmapConverter(IBeatmap beatmap) + : base(beatmap) { - this.isForCurrentRuleset = isForCurrentRuleset; + isForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(new TaikoRuleset().RulesetInfo); } protected override Beatmap ConvertBeatmap(IBeatmap original) diff --git a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs index 66b8459d1f..f14c53f7ae 100644 --- a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs @@ -2,14 +2,13 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Beatmaps; -using osu.Game.Rulesets.Taiko.Beatmaps; using osu.Game.Rulesets.Taiko.Objects; using System.Collections.Generic; using System; namespace osu.Game.Rulesets.Taiko { - internal class TaikoDifficultyCalculator : DifficultyCalculator + internal class TaikoDifficultyCalculator : DifficultyCalculator { private const double star_scaling_factor = 0.04125; @@ -41,7 +40,7 @@ namespace osu.Game.Rulesets.Taiko difficultyHitObjects.Clear(); foreach (var hitObject in Beatmap.HitObjects) - difficultyHitObjects.Add(new TaikoHitObjectDifficulty(hitObject)); + difficultyHitObjects.Add(new TaikoHitObjectDifficulty((TaikoHitObject)hitObject)); // Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure. difficultyHitObjects.Sort((a, b) => a.BaseHitObject.StartTime.CompareTo(b.BaseHitObject.StartTime)); @@ -132,7 +131,5 @@ namespace osu.Game.Rulesets.Taiko return difficulty; } - - protected override BeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(true); } } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index e5f3b33355..2e27b34e69 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -13,12 +13,14 @@ using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Taiko.Replays; using osu.Game.Beatmaps.Legacy; +using osu.Game.Rulesets.Taiko.Beatmaps; namespace osu.Game.Rulesets.Taiko { public class TaikoRuleset : Ruleset { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new TaikoRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap); public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] { diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index 3d3c6ab2f3..0a84d74c27 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -8,7 +8,6 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Taiko.Beatmaps; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Game.Rulesets.Taiko.Scoring; @@ -93,8 +92,6 @@ namespace osu.Game.Rulesets.Taiko.UI public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this); - protected override BeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter(IsForCurrentRuleset); - public override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo); protected override Playfield CreatePlayfield() => new TaikoPlayfield(Beatmap.ControlPointInfo) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index f60caf2397..3530ae928d 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -274,13 +274,13 @@ namespace osu.Game.Tests.Beatmaps.IO foreach (BeatmapInfo b in set.Beatmaps) Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineBeatmapID == b.OnlineBeatmapID)); Assert.IsTrue(set.Beatmaps.Count > 0); - var beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 0))?.Beatmap; + var beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 0))?.OriginalBeatmap; Assert.IsTrue(beatmap?.HitObjects.Any() == true); - beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 1))?.Beatmap; + beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 1))?.OriginalBeatmap; Assert.IsTrue(beatmap?.HitObjects.Any() == true); - beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 2))?.Beatmap; + beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 2))?.OriginalBeatmap; Assert.IsTrue(beatmap?.HitObjects.Any() == true); - beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap; + beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.OriginalBeatmap; Assert.IsTrue(beatmap?.HitObjects.Any() == true); } diff --git a/osu.Game.Tests/Visual/TestCaseBeatSyncedContainer.cs b/osu.Game.Tests/Visual/TestCaseBeatSyncedContainer.cs index 596b7839e0..4e3462b5ea 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatSyncedContainer.cs @@ -139,7 +139,7 @@ namespace osu.Game.Tests.Visual }; } - private SortedList timingPoints => Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints; + private SortedList timingPoints => Beatmap.Value.OriginalBeatmap.ControlPointInfo.TimingPoints; private TimingControlPoint getNextTimingPoint(TimingControlPoint current) { if (timingPoints[timingPoints.Count - 1] == current) diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index fab7860077..263a4c36ee 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -22,25 +22,27 @@ namespace osu.Game.Beatmaps remove => ObjectConverted -= value; } - /// - /// Checks if a Beatmap can be converted using this Beatmap Converter. - /// - /// The Beatmap to check. - /// Whether the Beatmap can be converted using this Beatmap Converter. - public bool CanConvert(IBeatmap beatmap) => ValidConversionTypes.All(t => beatmap.HitObjects.Any(t.IsInstanceOfType)); + public IBeatmap Beatmap { get; } - /// - /// Converts a Beatmap using this Beatmap Converter. - /// - /// The un-converted Beatmap. - /// The converted Beatmap. - public Beatmap Convert(IBeatmap original) + protected BeatmapConverter(IBeatmap beatmap) { - // We always operate on a clone of the original beatmap, to not modify it game-wide - return ConvertBeatmap(original.Clone()); + Beatmap = beatmap; } - void IBeatmapConverter.Convert(IBeatmap original) => Convert(original); + /// + /// Whether can be converted by this . + /// + public bool CanConvert => ValidConversionTypes.All(t => Beatmap.HitObjects.Any(t.IsInstanceOfType)); + + /// + /// Converts . + /// + /// The converted Beatmap. + public IBeatmap Convert() + { + // We always operate on a clone of the original beatmap, to not modify it game-wide + return ConvertBeatmap(Beatmap.Clone()); + } /// /// Performs the conversion of a Beatmap using this Beatmap Converter. diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 71406c6034..cff500fabf 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -30,7 +30,7 @@ namespace osu.Game.Beatmaps this.audioManager = audioManager; } - protected override IBeatmap GetBeatmap() + protected override IBeatmap GetOriginalBeatmap() { try { diff --git a/osu.Game/Beatmaps/BeatmapProcessor.cs b/osu.Game/Beatmaps/BeatmapProcessor.cs index 8f5a2a4cab..bf1cd7d4ee 100644 --- a/osu.Game/Beatmaps/BeatmapProcessor.cs +++ b/osu.Game/Beatmaps/BeatmapProcessor.cs @@ -2,30 +2,47 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Linq; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Beatmaps { + public interface IBeatmapProcessor + { + IBeatmap Beatmap { get; } + + /// + /// Post-processes to add mode-specific components that aren't added during conversion. + /// + /// An example of such a usage is for combo colours. + /// + /// + void PostProcess(); + } + /// /// Processes a post-converted Beatmap. /// /// The type of HitObject contained in the Beatmap. - public class BeatmapProcessor - where TObject : HitObject + public class BeatmapProcessor : IBeatmapProcessor { + public IBeatmap Beatmap { get; } + + public BeatmapProcessor(IBeatmap beatmap) + { + Beatmap = beatmap; + } + /// /// Post-processes a Beatmap to add mode-specific components that aren't added during conversion. /// /// An example of such a usage is for combo colours. /// /// - /// The Beatmap to process. - public virtual void PostProcess(Beatmap beatmap) + public virtual void PostProcess() { IHasComboInformation lastObj = null; - foreach (var obj in beatmap.HitObjects.OfType()) + foreach (var obj in Beatmap.HitObjects.OfType()) { if (obj.NewCombo) { diff --git a/osu.Game/Beatmaps/DifficultyCalculator.cs b/osu.Game/Beatmaps/DifficultyCalculator.cs index bf252ff51f..37155c09cd 100644 --- a/osu.Game/Beatmaps/DifficultyCalculator.cs +++ b/osu.Game/Beatmaps/DifficultyCalculator.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Rulesets.Objects; using System.Collections.Generic; using osu.Game.Rulesets.Mods; using osu.Framework.Timing; @@ -12,30 +11,17 @@ namespace osu.Game.Beatmaps { public abstract class DifficultyCalculator { - protected double TimeRate = 1; - - public abstract double Calculate(Dictionary categoryDifficulty = null); - } - - public abstract class DifficultyCalculator : DifficultyCalculator where T : HitObject - { - protected readonly Beatmap Beatmap; + protected readonly IBeatmap Beatmap; protected readonly Mod[] Mods; + protected double TimeRate = 1; + protected DifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) { + Beatmap = beatmap; Mods = mods ?? new Mod[0]; - var converter = CreateBeatmapConverter(beatmap); - - foreach (var mod in Mods.OfType>()) - mod.ApplyToBeatmapConverter(converter); - - Beatmap = converter.Convert(beatmap); - ApplyMods(Mods); - - PreprocessHitObjects(); } protected virtual void ApplyMods(Mod[] mods) @@ -43,22 +29,12 @@ namespace osu.Game.Beatmaps var clock = new StopwatchClock(); mods.OfType().ForEach(m => m.ApplyToClock(clock)); TimeRate = clock.Rate; - - foreach (var mod in Mods.OfType()) - mod.ApplyToDifficulty(Beatmap.BeatmapInfo.BaseDifficulty); - - foreach (var h in Beatmap.HitObjects) - h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty); - - foreach (var mod in mods.OfType>()) - foreach (var obj in Beatmap.HitObjects) - mod.ApplyToHitObject(obj); } protected virtual void PreprocessHitObjects() { } - protected abstract BeatmapConverter CreateBeatmapConverter(IBeatmap beatmap); + public abstract double Calculate(Dictionary categoryDifficulty = null); } } diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 0d325284e1..23ddc5a976 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -7,6 +7,7 @@ using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.UI; namespace osu.Game.Beatmaps @@ -39,7 +40,7 @@ namespace osu.Game.Beatmaps this.game = game; } - protected override IBeatmap GetBeatmap() => new Beatmap(); + protected override IBeatmap GetOriginalBeatmap() => new Beatmap(); protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4"); @@ -58,6 +59,8 @@ namespace osu.Game.Beatmaps throw new NotImplementedException(); } + public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new DummyBeatmapConverter { Beatmap = beatmap }; + public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => null; public override string Description => "dummy"; @@ -68,6 +71,14 @@ namespace osu.Game.Beatmaps : base(rulesetInfo) { } + + private class DummyBeatmapConverter : IBeatmapConverter + { + public event Action> ObjectConverted; + public IBeatmap Beatmap { get; set; } + public bool CanConvert => true; + public IBeatmap Convert() => Beatmap; + } } } } diff --git a/osu.Game/Beatmaps/IBeatmapConverter.cs b/osu.Game/Beatmaps/IBeatmapConverter.cs index 4df250ad17..00566093b8 100644 --- a/osu.Game/Beatmaps/IBeatmapConverter.cs +++ b/osu.Game/Beatmaps/IBeatmapConverter.cs @@ -16,10 +16,16 @@ namespace osu.Game.Beatmaps /// event Action> ObjectConverted; + IBeatmap Beatmap { get; } + /// - /// Converts a Beatmap using this Beatmap Converter. + /// Whether can be converted by this . /// - /// The un-converted Beatmap. - void Convert(IBeatmap beatmap); + bool CanConvert { get; } + + /// + /// Converts . + /// + IBeatmap Convert(); } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index fc67d2e508..7d6c23dad0 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -14,6 +14,8 @@ using osu.Framework.IO.File; using System.IO; using osu.Game.IO.Serialization; using System.Diagnostics; +using osu.Game.Rulesets; +using osu.Game.Rulesets.UI; using osu.Game.Skinning; namespace osu.Game.Beatmaps @@ -36,7 +38,7 @@ namespace osu.Game.Beatmaps Mods.ValueChanged += mods => applyRateAdjustments(); - beatmap = new AsyncLazy(populateBeatmap); + originalBeatmap = new AsyncLazy(populateOriginalBeatmap); background = new AsyncLazy(populateBackground, b => b == null || !b.IsDisposed); track = new AsyncLazy(populateTrack); waveform = new AsyncLazy(populateWaveform); @@ -51,26 +53,25 @@ namespace osu.Game.Beatmaps { var path = FileSafety.GetTempPath(Guid.NewGuid().ToString().Replace("-", string.Empty) + ".json"); using (var sw = new StreamWriter(path)) - sw.WriteLine(Beatmap.Serialize()); + sw.WriteLine(OriginalBeatmap.Serialize()); Process.Start(path); } - protected abstract IBeatmap GetBeatmap(); + protected abstract IBeatmap GetOriginalBeatmap(); protected abstract Texture GetBackground(); protected abstract Track GetTrack(); protected virtual Skin GetSkin() => new DefaultSkin(); protected virtual Waveform GetWaveform() => new Waveform(); protected virtual Storyboard GetStoryboard() => new Storyboard { BeatmapInfo = BeatmapInfo }; - public bool BeatmapLoaded => beatmap.IsResultAvailable; - public IBeatmap Beatmap => beatmap.Value.Result; - public async Task GetBeatmapAsync() => await beatmap.Value; + public bool BeatmapLoaded => originalBeatmap.IsResultAvailable; + public IBeatmap OriginalBeatmap => originalBeatmap.Value.Result; + public async Task GetOriginalBeatmapAsync() => await originalBeatmap.Value; + private readonly AsyncLazy originalBeatmap; - private readonly AsyncLazy beatmap; - - private IBeatmap populateBeatmap() + private IBeatmap populateOriginalBeatmap() { - var b = GetBeatmap() ?? new Beatmap(); + var b = GetOriginalBeatmap() ?? new Beatmap(); // use the database-backed info. b.BeatmapInfo = BeatmapInfo; @@ -78,6 +79,41 @@ namespace osu.Game.Beatmaps return b; } + public IBeatmap GetBeatmap(RulesetInfo ruleset) + { + var rulesetInstance = ruleset.CreateInstance(); + + IBeatmapConverter converter = rulesetInstance.CreateBeatmapConverter(OriginalBeatmap); + + // Check if the beatmap can be converted + if (!converter.CanConvert) + throw new BeatmapInvalidForRulesetException($"{nameof(Beatmap)} can not be converted for the current ruleset (converter: {converter})."); + + // Apply conversion mods + foreach (var mod in Mods.Value.OfType()) + mod.ApplyToBeatmapConverter(converter); + + // Convert + IBeatmap converted = converter.Convert(); + + // Apply difficulty mods + foreach (var mod in Mods.Value.OfType()) + mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty); + + // Post-process + rulesetInstance.CreateBeatmapProcessor(converted)?.PostProcess(); + + // Compute default values for hitobjects, including creating nested hitobjects in-case they're needed + foreach (var obj in converted.HitObjects) + obj.ApplyDefaults(converted.ControlPointInfo, converted.BeatmapInfo.BaseDifficulty); + + foreach (var mod in Mods.Value.OfType()) + foreach (var obj in converted.HitObjects) + mod.ApplyToHitObject(obj); + + return converted; + } + public bool BackgroundLoaded => background.IsResultAvailable; public Texture Background => background.Value.Result; public async Task GetBackgroundAsync() => await background.Value; diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index bf16af4706..8d8717a612 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -38,7 +38,7 @@ namespace osu.Game.Graphics.Containers if (!Beatmap.Value.TrackLoaded || !Beatmap.Value.BeatmapLoaded) return; var track = Beatmap.Value.Track; - var beatmap = Beatmap.Value.Beatmap; + var beatmap = Beatmap.Value.OriginalBeatmap; if (track == null || beatmap == null) return; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index b4021f2808..eb88fe0eb4 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -343,7 +343,7 @@ namespace osu.Game.Overlays // todo: this can likely be replaced with WorkingBeatmap.GetBeatmapAsync() Task.Run(() => { - if (beatmap?.Beatmap == null) //this is not needed if a placeholder exists + if (beatmap?.OriginalBeatmap == null) //this is not needed if a placeholder exists { title.Current = null; title.Text = @"Nothing to play"; diff --git a/osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs b/osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs index a03a003810..1b8e62b53c 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs @@ -10,13 +10,12 @@ namespace osu.Game.Rulesets.Mods /// Interface for a that applies changes to a . /// /// The type of converted . - public interface IApplicableToBeatmapConverter : IApplicableMod - where TObject : HitObject + public interface IApplicableToBeatmapConverter : IApplicableMod { /// /// Applies this to a . /// /// The to apply to. - void ApplyToBeatmapConverter(BeatmapConverter beatmapConverter); + void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter); } } diff --git a/osu.Game/Rulesets/Mods/IApplicableToHitObject.cs b/osu.Game/Rulesets/Mods/IApplicableToHitObject.cs index 0fd2e398c8..d6f330d9df 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToHitObject.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToHitObject.cs @@ -8,13 +8,12 @@ namespace osu.Game.Rulesets.Mods /// /// An interface for s that can be applied to s. /// - public interface IApplicableToHitObject : IApplicableMod - where TObject : HitObject + public interface IApplicableToHitObject : IApplicableMod { /// /// Applies this to a . /// /// The to apply to. - void ApplyToHitObject(TObject hitObject); + void ApplyToHitObject(HitObject hitObject); } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 3f8512eb90..6f117332b2 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -57,6 +57,10 @@ namespace osu.Game.Rulesets /// public abstract RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset); + public abstract IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap); + + public virtual IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => null; + public abstract DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null); public virtual PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => null; diff --git a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs index d5ab856697..3145561001 100644 --- a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Scoring.Legacy /* score.FileChecksum = */ var beatmapHash = sr.ReadString(); score.Beatmap = beatmaps.QueryBeatmap(b => b.MD5Hash == beatmapHash); - currentBeatmap = beatmaps.GetWorkingBeatmap(score.Beatmap).Beatmap; + currentBeatmap = beatmaps.GetWorkingBeatmap(score.Beatmap).OriginalBeatmap; /* score.PlayerName = */ score.User = new User { Username = sr.ReadString() }; diff --git a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs b/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs index 6392d2c0ae..5b8f5f0d0f 100644 --- a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs +++ b/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs @@ -2,42 +2,28 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using System.Linq; using osu.Game.Beatmaps; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Scoring { public abstract class PerformanceCalculator - { - public abstract double Calculate(Dictionary categoryDifficulty = null); - } - - public abstract class PerformanceCalculator : PerformanceCalculator - where TObject : HitObject { private readonly Dictionary attributes = new Dictionary(); protected IDictionary Attributes => attributes; - protected readonly Beatmap Beatmap; + protected readonly IBeatmap Beatmap; protected readonly Score Score; protected PerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) { Score = score; - var converter = CreateBeatmapConverter(); - - foreach (var mod in score.Mods.OfType>()) - mod.ApplyToBeatmapConverter(converter); - - Beatmap = converter.Convert(beatmap); + Beatmap = beatmap; var diffCalc = ruleset.CreateDifficultyCalculator(beatmap, score.Mods); diffCalc.Calculate(attributes); } - protected abstract BeatmapConverter CreateBeatmapConverter(); + public abstract double Calculate(Dictionary categoryDifficulty = null); } } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index d1f1807937..074380da56 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -219,30 +219,7 @@ namespace osu.Game.Rulesets.UI RelativeSizeAxes = Axes.Both; - BeatmapConverter converter = CreateBeatmapConverter(); - BeatmapProcessor processor = CreateBeatmapProcessor(); - - // Check if the beatmap can be converted - if (!converter.CanConvert(workingBeatmap.Beatmap)) - throw new BeatmapInvalidForRulesetException($"{nameof(Beatmap)} can not be converted for the current ruleset (converter: {converter})."); - - // Apply conversion adjustments before converting - foreach (var mod in Mods.OfType>()) - mod.ApplyToBeatmapConverter(converter); - - // Convert the beatmap - Beatmap = converter.Convert(workingBeatmap.Beatmap); - - // Apply difficulty adjustments from mods before using Difficulty. - foreach (var mod in Mods.OfType()) - mod.ApplyToDifficulty(Beatmap.BeatmapInfo.BaseDifficulty); - - // Post-process the beatmap - processor.PostProcess(Beatmap); - - // Apply defaults - foreach (var h in Beatmap.HitObjects) - h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty); + Beatmap = (Beatmap)workingBeatmap.GetBeatmap(ruleset.RulesetInfo); KeyBindingInputManager = CreateInputManager(); KeyBindingInputManager.RelativeSizeAxes = Axes.Both; @@ -277,10 +254,6 @@ namespace osu.Game.Rulesets.UI if (mods == null) return; - foreach (var mod in mods.OfType>()) - foreach (var obj in Beatmap.HitObjects) - mod.ApplyToHitObject(obj); - foreach (var mod in mods.OfType>()) mod.ApplyToRulesetContainer(this); } @@ -324,13 +297,6 @@ namespace osu.Game.Rulesets.UI Playfield.Size = GetAspectAdjustedSize() * PlayfieldArea; } - /// - /// Creates a processor to perform post-processing operations - /// on HitObjects in converted Beatmaps. - /// - /// The Beatmap processor. - protected virtual BeatmapProcessor CreateBeatmapProcessor() => new BeatmapProcessor(); - /// /// Computes the size of the in relative coordinate space after aspect adjustments. /// @@ -344,12 +310,6 @@ namespace osu.Game.Rulesets.UI /// protected virtual Vector2 PlayfieldArea => new Vector2(0.75f); // A sane default - /// - /// Creates a converter to convert Beatmap to a specific mode. - /// - /// The Beatmap converter. - protected abstract BeatmapConverter CreateBeatmapConverter(); - /// /// Creates a DrawableHitObject from a HitObject. /// diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs index 1146037004..e081897339 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected override void LoadBeatmap(WorkingBeatmap beatmap) { base.LoadBeatmap(beatmap); - foreach (var breakPeriod in beatmap.Beatmap.Breaks) + foreach (var breakPeriod in beatmap.OriginalBeatmap.Breaks) Add(new BreakVisualisation(breakPeriod)); } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs index 4bef22463e..faf090bfd9 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { base.LoadBeatmap(beatmap); - ControlPointInfo cpi = beatmap.Beatmap.ControlPointInfo; + ControlPointInfo cpi = beatmap.OriginalBeatmap.ControlPointInfo; cpi.TimingPoints.ForEach(addTimingPoint); diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index ea1d85bb5b..4ad11e6a91 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -47,7 +47,7 @@ namespace osu.Game.Screens.Edit { // TODO: should probably be done at a RulesetContainer level to share logic with Player. var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); - clock = new EditorClock(Beatmap.Value.Beatmap.ControlPointInfo, beatDivisor) { IsCoupled = false }; + clock = new EditorClock(Beatmap.Value.OriginalBeatmap.ControlPointInfo, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); dependencies.CacheAs(clock); diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 1f2cb915b3..bbd50d8f1b 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -87,7 +87,7 @@ namespace osu.Game.Screens.Menu private void updateAmplitudes() { var track = beatmap.Value.TrackLoaded ? beatmap.Value.Track : null; - var effect = beatmap.Value.BeatmapLoaded ? beatmap.Value.Beatmap.ControlPointInfo.EffectPointAt(track?.CurrentTime ?? Time.Current) : null; + var effect = beatmap.Value.BeatmapLoaded ? beatmap.Value.OriginalBeatmap.ControlPointInfo.EffectPointAt(track?.CurrentTime ?? Time.Current) : null; float[] temporalAmplitudes = track?.CurrentAmplitudes.FrequencyAmplitudes ?? new float[256]; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 32685935a1..bfc0cec18f 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Play try { - beatmap = working.Beatmap; + beatmap = working.OriginalBeatmap; if (beatmap == null) throw new InvalidOperationException("Beatmap was not loaded"); diff --git a/osu.Game/Screens/Ranking/ResultsPageScore.cs b/osu.Game/Screens/Ranking/ResultsPageScore.cs index 9d92439a4b..6d3812ac4b 100644 --- a/osu.Game/Screens/Ranking/ResultsPageScore.cs +++ b/osu.Game/Screens/Ranking/ResultsPageScore.cs @@ -88,7 +88,7 @@ namespace osu.Game.Screens.Ranking { RelativeSizeAxes = Axes.Both, Alpha = 0.5f, - Objects = Beatmap.Beatmap.HitObjects, + Objects = Beatmap.OriginalBeatmap.HitObjects, }, scoreCounter = new SlowScoreCounter(6) { diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index da82a49f51..2dad5a9008 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -210,7 +210,7 @@ namespace osu.Game.Screens.Select private InfoLabel[] getInfoLabels() { - var beatmap = working.Beatmap; + var beatmap = working.OriginalBeatmap; var info = working.BeatmapInfo; List labels = new List(); diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index d02ccaff16..735c0ef76c 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -92,7 +92,7 @@ namespace osu.Game.Tests.Beatmaps result.Mappings.Add(mapping); }; - converter.Convert(beatmap); + converter.Convert(); return result; } diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index 37693c99e8..71893cfe37 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tests.Beatmaps } private readonly IBeatmap beatmap; - protected override IBeatmap GetBeatmap() => beatmap; + protected override IBeatmap GetOriginalBeatmap() => beatmap; protected override Texture GetBackground() => null; protected override Track GetTrack() diff --git a/osu.Game/Tests/Visual/EditorClockTestCase.cs b/osu.Game/Tests/Visual/EditorClockTestCase.cs index 43b20f7021..c6a98a4f43 100644 --- a/osu.Game/Tests/Visual/EditorClockTestCase.cs +++ b/osu.Game/Tests/Visual/EditorClockTestCase.cs @@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(WorkingBeatmap working) { - Clock.ControlPointInfo = working.Beatmap.ControlPointInfo; + Clock.ControlPointInfo = working.OriginalBeatmap.ControlPointInfo; Clock.ChangeSource((IAdjustableClock)working.Track ?? new StopwatchClock()); Clock.ProcessFrame(); } diff --git a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs index 51460ecb6d..5d78b95c04 100644 --- a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs +++ b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs @@ -250,7 +250,7 @@ namespace osu.Game.Tests.Visual return; lastRequest = new GetScoresRequest(newBeatmap.BeatmapInfo, newBeatmap.BeatmapInfo.Ruleset); - lastRequest.Success += res => res.Scores.ForEach(s => scores.Add(new PerformanceDisplay(s, newBeatmap.Beatmap))); + lastRequest.Success += res => res.Scores.ForEach(s => scores.Add(new PerformanceDisplay(s, newBeatmap.OriginalBeatmap))); api.Queue(lastRequest); } @@ -381,7 +381,7 @@ namespace osu.Game.Tests.Visual var allMods = ruleset.GetAllMods().ToList(); Mod[] activeMods = modFlow.Where(c => c.Current.Value).Select(c => allMods.First(m => m.ShortenedName == c.LabelText)).ToArray(); - var diffCalc = ruleset.CreateDifficultyCalculator(beatmap.Beatmap, activeMods); + var diffCalc = ruleset.CreateDifficultyCalculator(beatmap.OriginalBeatmap, activeMods); if (diffCalc != null) { var categories = new Dictionary(); From c34ef42f0071a0bec598fd0b27d13f0a5bd3b729 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Fri, 20 Apr 2018 12:50:19 +0300 Subject: [PATCH 013/229] Add 'End replay' button --- osu.Game/Screens/Play/Player.cs | 2 ++ osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index ec7c1a1009..84021fe8d4 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -218,6 +218,8 @@ namespace osu.Game.Screens.Play } }; + hudOverlay.PlayerSettingsOverlay.PlaybackSettings.EndReplayButton.Action = Exit; + if (ShowStoryboard) initializeStoryboard(false); diff --git a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs index 13e403e899..3303ebaf97 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Play.PlayerSettings { @@ -18,6 +19,7 @@ namespace osu.Game.Screens.Play.PlayerSettings public IAdjustableClock AdjustableClock { set; get; } private readonly PlayerSliderBar sliderbar; + public readonly SettingsButton EndReplayButton; public PlaybackSettings() { @@ -55,6 +57,10 @@ namespace osu.Game.Screens.Play.PlayerSettings MaxValue = 2, Precision = 0.1, }, + }, + EndReplayButton = new SettingsButton + { + Text = "End replay" } }; From 633c775306c928088e40da8db602b7fa23f1384f Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sat, 21 Apr 2018 18:24:31 +0300 Subject: [PATCH 014/229] Initial HoldToQuit commit --- osu.Game/Screens/Play/HUD/HoldToQuit.cs | 118 ++++++++++++++++++++++++ osu.Game/Screens/Play/HUDOverlay.cs | 9 ++ 2 files changed, 127 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/HoldToQuit.cs diff --git a/osu.Game/Screens/Play/HUD/HoldToQuit.cs b/osu.Game/Screens/Play/HUD/HoldToQuit.cs new file mode 100644 index 0000000000..55cbff4d86 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/HoldToQuit.cs @@ -0,0 +1,118 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Threading; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input; +using osu.Framework.Threading; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using OpenTK; + +namespace osu.Game.Screens.Play.HUD +{ + public class HoldToQuit : Container + { + private readonly OsuSpriteText text; + private readonly HoldToQuitButton button; + + public HoldToQuit() + { + Children = new Drawable[] + { + text = new OsuSpriteText + { + Text = "Hold to Quit", + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft + }, + button = new HoldToQuitButton(text) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight + } + }; + AutoSizeAxes = Axes.Both; + } + + private class HoldToQuitButton : CircularContainer + { + private readonly OsuSpriteText text; + private SpriteIcon icon; + private CircularProgress progress; + + private Action exitAction; + private readonly Scheduler scheduler; + private ScheduledDelegate scheduledExitAction; + + private const int fade_duration = 200; + + public HoldToQuitButton(OsuSpriteText text) + { + this.text = text; + scheduler = new Scheduler(); + + // TODO provide action + exitAction = () => Thread.Sleep(1); + } + + private void hideText() => scheduler.AddDelayed(() => text.FadeOut(fade_duration), 5000); + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Masking = true; + Size = new Vector2(60); + AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + Alpha = 0.8f, + }, + icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(15), + Icon = FontAwesome.fa_close + }, + progress = new CircularProgress { RelativeSizeAxes = Axes.Both, InnerRadius = 0.1f, Current = { Value = 1 } } + }); + progress.Hide(); + hideText(); + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + icon.ScaleTo(1.5f); + text.FadeIn(fade_duration); + progress.FadeIn(1000); + scheduledExitAction = scheduler.AddDelayed(exitAction, 1000); + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + icon.ScaleTo(1f); + hideText(); + if (scheduledExitAction != null && !scheduledExitAction.Completed) + scheduledExitAction.Cancel(); + progress.FadeOut(fade_duration); + return base.OnMouseUp(state, args); + } + + protected override void Update() + { + scheduler.Update(); + base.Update(); + } + } + } +} diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 36d8bb75c0..c2471c967e 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -34,6 +34,7 @@ namespace osu.Game.Screens.Play public readonly HealthDisplay HealthDisplay; public readonly SongProgress Progress; public readonly ModDisplay ModDisplay; + public readonly HoldToQuit HoldToQuit; public readonly PlayerSettingsOverlay PlayerSettingsOverlay; private Bindable showHud; @@ -57,6 +58,7 @@ namespace osu.Game.Screens.Play AccuracyCounter = CreateAccuracyCounter(), HealthDisplay = CreateHealthDisplay(), Progress = CreateProgress(), + HoldToQuit = CreateHoldToQuit(), ModDisplay = CreateModsContainer(), PlayerSettingsOverlay = CreatePlayerSettingsOverlay() } @@ -205,6 +207,13 @@ namespace osu.Game.Screens.Play RelativeSizeAxes = Axes.X, }; + protected virtual HoldToQuit CreateHoldToQuit() => new HoldToQuit + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + Margin = new MarginPadding { Bottom = Progress.Size.Y * 1.25f, Right = 5 } + }; + protected virtual ModDisplay CreateModsContainer() => new ModDisplay { Anchor = Anchor.TopRight, From 3b621db460cdf6226559eb6a25b6f6443635c935 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sat, 21 Apr 2018 19:25:21 +0300 Subject: [PATCH 015/229] Implement CircularProgress filling --- osu.Game/Screens/Play/HUD/HoldToQuit.cs | 29 +++++++++++++++++-------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HoldToQuit.cs b/osu.Game/Screens/Play/HUD/HoldToQuit.cs index 55cbff4d86..59569aacbd 100644 --- a/osu.Game/Screens/Play/HUD/HoldToQuit.cs +++ b/osu.Game/Screens/Play/HUD/HoldToQuit.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; using osu.Framework.Threading; +using osu.Framework.Timing; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using OpenTK; @@ -47,22 +48,24 @@ namespace osu.Game.Screens.Play.HUD private CircularProgress progress; private Action exitAction; - private readonly Scheduler scheduler; private ScheduledDelegate scheduledExitAction; + private readonly Scheduler scheduler; + private readonly StopwatchClock stopwatchClock; + private const int fade_duration = 200; + private const int text_display_time = 5000; public HoldToQuitButton(OsuSpriteText text) { this.text = text; scheduler = new Scheduler(); + stopwatchClock = new StopwatchClock(); // TODO provide action exitAction = () => Thread.Sleep(1); } - private void hideText() => scheduler.AddDelayed(() => text.FadeOut(fade_duration), 5000); - [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -83,34 +86,42 @@ namespace osu.Game.Screens.Play.HUD Size = new Vector2(15), Icon = FontAwesome.fa_close }, - progress = new CircularProgress { RelativeSizeAxes = Axes.Both, InnerRadius = 0.1f, Current = { Value = 1 } } + progress = new CircularProgress { RelativeSizeAxes = Axes.Both, InnerRadius = 0.1f } }); - progress.Hide(); - hideText(); + scheduler.AddDelayed(() => text.FadeOut(fade_duration), text_display_time); } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { icon.ScaleTo(1.5f); text.FadeIn(fade_duration); - progress.FadeIn(1000); + stopwatchClock.Restart(); scheduledExitAction = scheduler.AddDelayed(exitAction, 1000); + return base.OnMouseDown(state, args); } protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { icon.ScaleTo(1f); - hideText(); + scheduler.AddDelayed(() => text.FadeOut(fade_duration), text_display_time); + stopwatchClock.Stop(); if (scheduledExitAction != null && !scheduledExitAction.Completed) scheduledExitAction.Cancel(); - progress.FadeOut(fade_duration); + progress.Current.SetDefault(); + return base.OnMouseUp(state, args); } protected override void Update() { scheduler.Update(); + if (stopwatchClock.IsRunning) + { + var clampedTime = MathHelper.Clamp(stopwatchClock.CurrentTime, 0, 1000); + progress.Current.Value = clampedTime / 1000; + } + base.Update(); } } From 21454d1f10848a38c71c16e77695c5a0f241dc93 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sat, 21 Apr 2018 19:27:17 +0300 Subject: [PATCH 016/229] Revert "Add 'End replay' button" This reverts commit c34ef42f0071a0bec598fd0b27d13f0a5bd3b729. --- osu.Game/Screens/Play/Player.cs | 2 -- osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs | 6 ------ 2 files changed, 8 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 84021fe8d4..ec7c1a1009 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -218,8 +218,6 @@ namespace osu.Game.Screens.Play } }; - hudOverlay.PlayerSettingsOverlay.PlaybackSettings.EndReplayButton.Action = Exit; - if (ShowStoryboard) initializeStoryboard(false); diff --git a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs index 3303ebaf97..13e403e899 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs @@ -6,7 +6,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Graphics.Sprites; -using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Play.PlayerSettings { @@ -19,7 +18,6 @@ namespace osu.Game.Screens.Play.PlayerSettings public IAdjustableClock AdjustableClock { set; get; } private readonly PlayerSliderBar sliderbar; - public readonly SettingsButton EndReplayButton; public PlaybackSettings() { @@ -57,10 +55,6 @@ namespace osu.Game.Screens.Play.PlayerSettings MaxValue = 2, Precision = 0.1, }, - }, - EndReplayButton = new SettingsButton - { - Text = "End replay" } }; From e6d7136a9206153a0132961efe8c2adb9bbcca1d Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sat, 21 Apr 2018 20:21:09 +0300 Subject: [PATCH 017/229] Fix HoldToQuit appearance and set HoldToQuitButton.ExitAction --- osu.Game/Screens/Play/HUD/HoldToQuit.cs | 23 +++++++++-------------- osu.Game/Screens/Play/Player.cs | 2 ++ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HoldToQuit.cs b/osu.Game/Screens/Play/HUD/HoldToQuit.cs index 59569aacbd..f4848ff730 100644 --- a/osu.Game/Screens/Play/HUD/HoldToQuit.cs +++ b/osu.Game/Screens/Play/HUD/HoldToQuit.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Threading; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -17,37 +16,36 @@ using OpenTK; namespace osu.Game.Screens.Play.HUD { - public class HoldToQuit : Container + public class HoldToQuit : FillFlowContainer { private readonly OsuSpriteText text; - private readonly HoldToQuitButton button; + public readonly HoldToQuitButton Button; public HoldToQuit() { + Direction = FillDirection.Horizontal; + Spacing = new Vector2(20, 0); Children = new Drawable[] { text = new OsuSpriteText { Text = "Hold to Quit", + Font = @"Exo2.0-Bold", Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft }, - button = new HoldToQuitButton(text) - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight - } + Button = new HoldToQuitButton(text) }; AutoSizeAxes = Axes.Both; } - private class HoldToQuitButton : CircularContainer + public class HoldToQuitButton : CircularContainer { private readonly OsuSpriteText text; private SpriteIcon icon; private CircularProgress progress; - private Action exitAction; + public Action ExitAction { get; set; } private ScheduledDelegate scheduledExitAction; private readonly Scheduler scheduler; @@ -61,9 +59,6 @@ namespace osu.Game.Screens.Play.HUD this.text = text; scheduler = new Scheduler(); stopwatchClock = new StopwatchClock(); - - // TODO provide action - exitAction = () => Thread.Sleep(1); } [BackgroundDependencyLoader] @@ -96,7 +91,7 @@ namespace osu.Game.Screens.Play.HUD icon.ScaleTo(1.5f); text.FadeIn(fade_duration); stopwatchClock.Restart(); - scheduledExitAction = scheduler.AddDelayed(exitAction, 1000); + scheduledExitAction = scheduler.AddDelayed(ExitAction, 1000); return base.OnMouseDown(state, args); } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index ec7c1a1009..6c5e10c836 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -218,6 +218,8 @@ namespace osu.Game.Screens.Play } }; + hudOverlay.HoldToQuit.Button.ExitAction = Exit; + if (ShowStoryboard) initializeStoryboard(false); From 630980255ed479d391f6860bc89f762633917a70 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sat, 21 Apr 2018 20:35:24 +0300 Subject: [PATCH 018/229] Convert HoldToQuit.text to local variable --- osu.Game/Screens/Play/HUD/HoldToQuit.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/HoldToQuit.cs b/osu.Game/Screens/Play/HUD/HoldToQuit.cs index f4848ff730..3f14582d50 100644 --- a/osu.Game/Screens/Play/HUD/HoldToQuit.cs +++ b/osu.Game/Screens/Play/HUD/HoldToQuit.cs @@ -18,11 +18,11 @@ namespace osu.Game.Screens.Play.HUD { public class HoldToQuit : FillFlowContainer { - private readonly OsuSpriteText text; public readonly HoldToQuitButton Button; public HoldToQuit() { + OsuSpriteText text; Direction = FillDirection.Horizontal; Spacing = new Vector2(20, 0); Children = new Drawable[] From f41006def7ee4aa1b3308a7186348145b3140ee4 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Tue, 24 Apr 2018 21:17:04 +0200 Subject: [PATCH 019/229] Set game ruleset to the score ruleset --- osu.Game/OsuGame.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 3852580c49..d443ed36ae 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -201,6 +201,8 @@ namespace osu.Game return; } + Ruleset.Value = s.Ruleset; + Beatmap.Value = BeatmapManager.GetWorkingBeatmap(s.Beatmap); Beatmap.Value.Mods.Value = s.Mods; From ad8ba37ee370bd81464756c71d40e546af7ea4f4 Mon Sep 17 00:00:00 2001 From: Nobbele <4ppleCracker@gmail.com> Date: Thu, 26 Apr 2018 12:57:24 +0200 Subject: [PATCH 020/229] Updated UserStatus.cs to make more sense(UNTESTED) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Untested code, on my ipad in school so i can’t compile the code or check for refrences to stuff Modding, playing multiplayer/singleplayer, Busy, etc are all done when user is online so they may just be a class of type UserStatusOnline(used to be UserStatusAvailable but since available and online are basically the same i just made available be online). I don’t know how PM’s are handled but i assume that the client recieves the PM and then decides what to do based on your status. By doing this you can interupt the user with the message if typeof(status) != typeof(UserStatusBusy), making multiplaying, solo game, etc not interupt the user, but when typeof(status) == typeof(UserStatusBusy) show a less intrusive message box to not interupt the user --- osu.Game/Users/UserStatus.cs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/osu.Game/Users/UserStatus.cs b/osu.Game/Users/UserStatus.cs index 22bc9ed1a0..1584605166 100644 --- a/osu.Game/Users/UserStatus.cs +++ b/osu.Game/Users/UserStatus.cs @@ -12,12 +12,13 @@ namespace osu.Game.Users public abstract Color4 GetAppropriateColour(OsuColour colours); } - public abstract class UserStatusAvailable : UserStatus + public class UserStatusOnline : UserStatus { + public override string Message => @"Online"; public override Color4 GetAppropriateColour(OsuColour colours) => colours.BlueDarker; } - public abstract class UserStatusBusy : UserStatus + public abstract class UserStatusBusy : UserStatusOnline { public override Color4 GetAppropriateColour(OsuColour colours) => colours.YellowDark; } @@ -28,17 +29,12 @@ namespace osu.Game.Users public override Color4 GetAppropriateColour(OsuColour colours) => colours.Gray7; } - public class UserStatusOnline : UserStatusAvailable - { - public override string Message => @"Online"; - } - - public class UserStatusSpectating : UserStatusAvailable + public class UserStatusSpectating : UserStatusOnline { public override string Message => @"Spectating a game"; } - public class UserStatusInLobby : UserStatusAvailable + public class UserStatusInLobby : UserStatusOnline { public override string Message => @"in Multiplayer Lobby"; } @@ -53,13 +49,13 @@ namespace osu.Game.Users public override string Message => @"Multiplaying"; } - public class UserStatusModding : UserStatus + public class UserStatusModding : UserStatusOnline { public override string Message => @"Modding a map"; public override Color4 GetAppropriateColour(OsuColour colours) => colours.PurpleDark; } - public class UserStatusDoNotDisturb : UserStatus + public class UserStatusDoNotDisturb : UserStatusBusy { public override string Message => @"Do not disturb"; public override Color4 GetAppropriateColour(OsuColour colours) => colours.RedDark; From b3cf381c5d3b883be24df2db2b8210e38e8b348c Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sat, 28 Apr 2018 19:24:49 +0300 Subject: [PATCH 021/229] Add TestCaseHoldToQuit --- osu.Game.Tests/Visual/TestCaseHoldToQuit.cs | 56 +++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseHoldToQuit.cs diff --git a/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs b/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs new file mode 100644 index 0000000000..d7f024d905 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs @@ -0,0 +1,56 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Linq; +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Game.Screens.Play.HUD; + +namespace osu.Game.Tests.Visual +{ + [Description("'Hold to Quit' UI element")] + public class TestCaseHoldToQuit : OsuTestCase + { + private bool exitAction; + + public TestCaseHoldToQuit() + { + HoldToQuit holdToQuit; + Add(holdToQuit = new HoldToQuit + { + Origin = Anchor.BottomRight, + Anchor = Anchor.BottomRight, + }); + holdToQuit.Button.ExitAction = () => exitAction = true; + + var text = holdToQuit.Children.OfType().Single(); + + AddStep("Text fade in", () => + { + exitAction = false; + holdToQuit.Button.TriggerOnMouseDown(); + holdToQuit.Button.TriggerOnMouseUp(); + }); + + AddUntilStep(() => text.IsPresent && !exitAction, "Text visible"); + + AddStep("Text fade out", () => + { + exitAction = false; + holdToQuit.Button.TriggerOnMouseDown(); + holdToQuit.Button.TriggerOnMouseUp(); + }); + + AddUntilStep(() => !text.IsPresent && !exitAction, "Text is not visible"); + + AddStep("Trigger exit action", () => + { + exitAction = false; + holdToQuit.Button.TriggerOnMouseDown(); + }); + + AddUntilStep(() => exitAction, $"{nameof(holdToQuit.Button.ExitAction)} was triggered"); + } + } +} From c78c5195f352dcb5bc657cf0e29f66cf61e6a369 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sat, 28 Apr 2018 20:43:41 +0300 Subject: [PATCH 022/229] HoldToQuitButton cleanup --- osu.Game/Screens/Play/HUD/HoldToQuit.cs | 38 ++++--------------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HoldToQuit.cs b/osu.Game/Screens/Play/HUD/HoldToQuit.cs index 3f14582d50..59338f8cdc 100644 --- a/osu.Game/Screens/Play/HUD/HoldToQuit.cs +++ b/osu.Game/Screens/Play/HUD/HoldToQuit.cs @@ -8,8 +8,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; -using osu.Framework.Threading; -using osu.Framework.Timing; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using OpenTK; @@ -46,20 +44,12 @@ namespace osu.Game.Screens.Play.HUD private CircularProgress progress; public Action ExitAction { get; set; } - private ScheduledDelegate scheduledExitAction; - - private readonly Scheduler scheduler; - private readonly StopwatchClock stopwatchClock; private const int fade_duration = 200; + private const int progress_duration = 1000; private const int text_display_time = 5000; - public HoldToQuitButton(OsuSpriteText text) - { - this.text = text; - scheduler = new Scheduler(); - stopwatchClock = new StopwatchClock(); - } + public HoldToQuitButton(OsuSpriteText text) => this.text = text; [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -83,15 +73,14 @@ namespace osu.Game.Screens.Play.HUD }, progress = new CircularProgress { RelativeSizeAxes = Axes.Both, InnerRadius = 0.1f } }); - scheduler.AddDelayed(() => text.FadeOut(fade_duration), text_display_time); + Scheduler.AddDelayed(() => text.FadeOut(fade_duration), text_display_time); } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { icon.ScaleTo(1.5f); text.FadeIn(fade_duration); - stopwatchClock.Restart(); - scheduledExitAction = scheduler.AddDelayed(ExitAction, 1000); + progress.FillTo(1, progress_duration).OnComplete(cp => ExitAction()); return base.OnMouseDown(state, args); } @@ -99,26 +88,11 @@ namespace osu.Game.Screens.Play.HUD protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { icon.ScaleTo(1f); - scheduler.AddDelayed(() => text.FadeOut(fade_duration), text_display_time); - stopwatchClock.Stop(); - if (scheduledExitAction != null && !scheduledExitAction.Completed) - scheduledExitAction.Cancel(); - progress.Current.SetDefault(); + Scheduler.AddDelayed(() => text.FadeOut(fade_duration), text_display_time); + progress.FillTo(0, progress_duration / 4).OnComplete(cp => progress.Current.SetDefault()); return base.OnMouseUp(state, args); } - - protected override void Update() - { - scheduler.Update(); - if (stopwatchClock.IsRunning) - { - var clampedTime = MathHelper.Clamp(stopwatchClock.CurrentTime, 0, 1000); - progress.Current.Value = clampedTime / 1000; - } - - base.Update(); - } } } } From 8de05450c4eb99c6d993d193b3c87ede35301a62 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sun, 29 Apr 2018 17:53:38 +0300 Subject: [PATCH 023/229] Cleanup UserProfileOverlay during PopOut --- osu.Game/Overlays/UserProfileOverlay.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index a4dd0c9ec3..d8f858b95e 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -71,6 +71,7 @@ namespace osu.Game.Overlays { base.PopOut(); FadeEdgeEffectTo(0, WaveContainer.DISAPPEAR_DURATION, Easing.Out); + cleanup(); } public void ShowUser(long userId) @@ -83,9 +84,7 @@ namespace osu.Game.Overlays public void ShowUser(User user, bool fetchOnline = true) { - userReq?.Cancel(); - Clear(); - lastSection = null; + cleanup(); sections = new ProfileSection[] { @@ -165,6 +164,13 @@ namespace osu.Game.Overlays sectionsContainer.ScrollToTop(); } + private void cleanup() + { + userReq?.Cancel(); + Clear(); + lastSection = null; + } + private void userLoadComplete(User user) { Header.User = user; From ca574f2345d7e355493e95e59141bc5bd7dd1c1f Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sun, 29 Apr 2018 18:36:19 +0300 Subject: [PATCH 024/229] Disable RulesetToggleButton whenever the ruleset can't be changed --- osu.Game/Overlays/Direct/FilterControl.cs | 10 +++++++--- osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 8883dfdebb..a2da516257 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -49,14 +49,14 @@ namespace osu.Game.Overlays.Direct { private Drawable icon { - get { return iconContainer.Icon; } - set { iconContainer.Icon = value; } + get => iconContainer.Icon; + set => iconContainer.Icon = value; } private RulesetInfo ruleset; public RulesetInfo Ruleset { - get { return ruleset; } + get => ruleset; set { ruleset = value; @@ -73,6 +73,9 @@ namespace osu.Game.Overlays.Direct iconContainer.FadeTo(Ruleset.ID == obj?.ID ? 1f : 0.5f, 100); } + public override bool HandleKeyboardInput => !bindable.Disabled && base.HandleKeyboardInput; + public override bool HandleMouseInput => !bindable.Disabled && base.HandleMouseInput; + public RulesetToggleButton(Bindable bindable, RulesetInfo ruleset) { this.bindable = bindable; @@ -90,6 +93,7 @@ namespace osu.Game.Overlays.Direct Ruleset = ruleset; bindable.ValueChanged += Bindable_ValueChanged; + bindable.DisabledChanged += isDisabled => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300); Bindable_ValueChanged(bindable.Value); Action = () => bindable.Value = Ruleset; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 05866f7002..1da51e4a5a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -87,8 +87,8 @@ namespace osu.Game.Overlays.Toolbar ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(); } - public override bool HandleKeyboardInput => !ruleset.Disabled; - public override bool HandleMouseInput => !ruleset.Disabled; + public override bool HandleKeyboardInput => !ruleset.Disabled && base.HandleKeyboardInput; + public override bool HandleMouseInput => !ruleset.Disabled && base.HandleMouseInput; private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300); From 42aa02579bb909918ecc0cd50a6a163366c372aa Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sun, 29 Apr 2018 19:52:33 +0300 Subject: [PATCH 025/229] Add 'Back' global key binding --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index dd8f00f6cd..565d530395 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Input.Bindings { new KeyBinding(InputKey.F8, GlobalAction.ToggleChat), new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial), - new KeyBinding(InputKey.F12,GlobalAction.TakeScreenshot), + new KeyBinding(InputKey.F12, GlobalAction.TakeScreenshot), new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings), new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar), @@ -36,6 +36,9 @@ namespace osu.Game.Input.Bindings new KeyBinding(InputKey.Down, GlobalAction.DecreaseVolume), new KeyBinding(InputKey.MouseWheelDown, GlobalAction.DecreaseVolume), new KeyBinding(InputKey.F4, GlobalAction.ToggleMute), + + new KeyBinding(InputKey.Escape, GlobalAction.Back), + new KeyBinding(InputKey.MouseButton1, GlobalAction.Back) }; public IEnumerable InGameKeyBindings => new[] @@ -76,6 +79,9 @@ namespace osu.Game.Input.Bindings QuickRetry, [Description("Take screenshot")] - TakeScreenshot + TakeScreenshot, + + [Description("Go back")] + Back } } From 804b59ee8073cf54fa475e8dc9780edab842a18d Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sun, 29 Apr 2018 20:15:09 +0300 Subject: [PATCH 026/229] Handle GlobalAction.Back --- osu.Game/Screens/Menu/ButtonSystem.cs | 42 +++++++++++++++++++++------ osu.Game/Screens/OsuScreen.cs | 35 +++++++++++++--------- 2 files changed, 55 insertions(+), 22 deletions(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index f48e1925c5..8cf0d24f7d 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -6,22 +6,24 @@ using System.Collections.Generic; using System.Linq; using osu.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input; +using osu.Framework.Input.Bindings; +using osu.Framework.Threading; using osu.Game.Graphics; +using osu.Game.Input.Bindings; using OpenTK; using OpenTK.Graphics; using OpenTK.Input; -using osu.Framework.Audio.Sample; -using osu.Framework.Audio; -using osu.Framework.Configuration; -using osu.Framework.Threading; namespace osu.Game.Screens.Menu { - public class ButtonSystem : Container, IStateful + public class ButtonSystem : Container, IStateful, IKeyBindingHandler { public event Action StateChanged; @@ -146,7 +148,16 @@ namespace osu.Game.Screens.Menu case Key.Space: logo?.TriggerOnClick(state); return true; - case Key.Escape: + } + + return false; + } + + public bool OnPressed(GlobalAction action) + { + switch (action) + { + case GlobalAction.Back: switch (State) { case MenuState.TopLevel: @@ -155,14 +166,26 @@ namespace osu.Game.Screens.Menu case MenuState.Play: backButton.TriggerOnClick(); return true; + default: + return false; } - + default: return false; } - - return false; } + public bool OnReleased(GlobalAction action) + { + switch (action) + { + case GlobalAction.Back: + return true; + default: + return false; + } + } + + private void onPlay() { State = MenuState.Play; @@ -337,6 +360,7 @@ namespace osu.Game.Screens.Menu logo.ScaleTo(0.5f, 200, Easing.OutQuint); break; } + break; case MenuState.EnteringMode: logoTracking = true; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 7a910574e0..5d2c46f438 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -3,22 +3,22 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Input.Bindings; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; -using OpenTK; -using osu.Framework.Audio.Sample; -using osu.Framework.Audio; -using osu.Framework.Graphics; +using osu.Game.Input.Bindings; using osu.Game.Rulesets; using osu.Game.Screens.Menu; -using osu.Framework.Input; -using OpenTK.Input; +using OpenTK; namespace osu.Game.Screens { - public abstract class OsuScreen : Screen + public abstract class OsuScreen : Screen, IKeyBindingHandler { public BackgroundScreen Background { get; private set; } @@ -90,18 +90,27 @@ namespace osu.Game.Screens sampleExit = audio.Sample.Get(@"UI/screen-back"); } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + public bool OnPressed(GlobalAction action) { - if (args.Repeat || !IsCurrentScreen) return false; - - switch (args.Key) + switch (action) { - case Key.Escape: + case GlobalAction.Back: Exit(); return true; + default: + return false; } + } - return base.OnKeyDown(state, args); + public bool OnReleased(GlobalAction action) + { + switch (action) + { + case GlobalAction.Back: + return true; + default: + return false; + } } protected override void OnResuming(Screen last) From 06c6f55995993a72842f15f775afec30556e7d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adonais=20Romero=20Gonz=C3=A1lez?= Date: Mon, 30 Apr 2018 00:43:32 -0700 Subject: [PATCH 027/229] Apply offset to end times on legacy converter --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 5 +++-- .../Rulesets/Objects/Legacy/ConvertHitObjectParser.cs | 11 ++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 366b4f163f..655355913c 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -373,17 +373,18 @@ namespace osu.Game.Beatmaps.Formats if (parser == null) parser = new Rulesets.Objects.Legacy.Osu.ConvertHitObjectParser(); - var obj = parser.Parse(line); + var obj = parser.Parse(line, getOffsetTime()); if (obj != null) { - obj.StartTime = getOffsetTime(obj.StartTime); beatmap.HitObjects.Add(obj); } } private int getOffsetTime(int time) => time + (ApplyOffsets ? offset : 0); + private double getOffsetTime() => ApplyOffsets ? offset : 0; + private double getOffsetTime(double time) => time + (ApplyOffsets ? offset : 0); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 95abc4edb3..9edd0f1f34 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -19,6 +19,11 @@ namespace osu.Game.Rulesets.Objects.Legacy public abstract class ConvertHitObjectParser : HitObjectParser { public override HitObject Parse(string text) + { + return Parse(text, 0); + } + + public HitObject Parse(string text, double offset) { try { @@ -146,7 +151,7 @@ namespace osu.Game.Rulesets.Objects.Legacy } else if ((type & ConvertHitObjectType.Spinner) > 0) { - result = CreateSpinner(new Vector2(512, 384) / 2, Convert.ToDouble(split[5], CultureInfo.InvariantCulture)); + result = CreateSpinner(new Vector2(512, 384) / 2, Convert.ToDouble(split[5], CultureInfo.InvariantCulture) + offset); if (split.Length > 6) readCustomSampleBanks(split[6], bankInfo); @@ -164,13 +169,13 @@ namespace osu.Game.Rulesets.Objects.Legacy readCustomSampleBanks(string.Join(":", ss.Skip(1)), bankInfo); } - result = CreateHold(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo, endTime); + result = CreateHold(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo, endTime + offset); } if (result == null) throw new InvalidOperationException($@"Unknown hit object type {type}."); - result.StartTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture); + result.StartTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture) + offset; result.Samples = convertSoundType(soundType, bankInfo); return result; From 3b84ce7c9f4317cf4a3f3d4e8011385579d6ec1f Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Tue, 1 May 2018 03:56:01 +0300 Subject: [PATCH 028/229] Remove redundant test step --- osu.Game.Tests/Visual/TestCaseHoldToQuit.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs b/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs index d7f024d905..04ea4249e5 100644 --- a/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs +++ b/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual var text = holdToQuit.Children.OfType().Single(); - AddStep("Text fade in", () => + AddStep("Trigger text fade in/out", () => { exitAction = false; holdToQuit.Button.TriggerOnMouseDown(); @@ -34,14 +34,6 @@ namespace osu.Game.Tests.Visual }); AddUntilStep(() => text.IsPresent && !exitAction, "Text visible"); - - AddStep("Text fade out", () => - { - exitAction = false; - holdToQuit.Button.TriggerOnMouseDown(); - holdToQuit.Button.TriggerOnMouseUp(); - }); - AddUntilStep(() => !text.IsPresent && !exitAction, "Text is not visible"); AddStep("Trigger exit action", () => From 9f9447d44149ff81e269ff5d2962589e8e57ec5a Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Wed, 2 May 2018 14:02:49 +0800 Subject: [PATCH 029/229] Revert "Merge pull request #2470 from UselessToucan/main_track_muted_preview_overlay_closed" This reverts commit 67793845b092f67ccce29f8d99f87c8db33270a1. --- osu.Game/Overlays/UserProfileOverlay.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index d8f858b95e..a4dd0c9ec3 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -71,7 +71,6 @@ namespace osu.Game.Overlays { base.PopOut(); FadeEdgeEffectTo(0, WaveContainer.DISAPPEAR_DURATION, Easing.Out); - cleanup(); } public void ShowUser(long userId) @@ -84,7 +83,9 @@ namespace osu.Game.Overlays public void ShowUser(User user, bool fetchOnline = true) { - cleanup(); + userReq?.Cancel(); + Clear(); + lastSection = null; sections = new ProfileSection[] { @@ -164,13 +165,6 @@ namespace osu.Game.Overlays sectionsContainer.ScrollToTop(); } - private void cleanup() - { - userReq?.Cancel(); - Clear(); - lastSection = null; - } - private void userLoadComplete(User user) { Header.User = user; From 8b99a3b8e6c4836af090293d633d6863d5a6a3aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 May 2018 15:07:18 +0800 Subject: [PATCH 030/229] Add squirrel dependency on net471 --- osu.Desktop.Deploy/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop.Deploy/Program.cs b/osu.Desktop.Deploy/Program.cs index 16bbf90cd4..594be45210 100644 --- a/osu.Desktop.Deploy/Program.cs +++ b/osu.Desktop.Deploy/Program.cs @@ -115,7 +115,7 @@ namespace osu.Desktop.Deploy checkReleaseFiles(); write("Running squirrel build..."); - runCommand(squirrelPath, $"--releasify {stagingPath}\\{nupkgFilename(version)} --setupIcon {iconPath} --icon {iconPath} {codeSigningCmd} --no-msi"); + runCommand(squirrelPath, $"--releasify {stagingPath}\\{nupkgFilename(version)} --framework-version=net471 --setupIcon {iconPath} --icon {iconPath} {codeSigningCmd} --no-msi"); //prune again to clean up before upload. pruneReleases(); From b37acf75102f166244c53751bf9fbf257ca6a4b2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 May 2018 16:23:42 +0800 Subject: [PATCH 031/229] Update squirrel version for net471 prereq support --- osu.Desktop.Deploy/osu.Desktop.Deploy.csproj | 2 +- osu.Desktop/osu.Desktop.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj index a97b8197b4..063fb89918 100644 --- a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj +++ b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj @@ -12,7 +12,7 @@ - + diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 27bc3f7597..fa378cf19e 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -31,7 +31,7 @@ - + From e92166b40f59bfd4142662266f9aea8d98d2a586 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 May 2018 16:33:48 +0800 Subject: [PATCH 032/229] Update csproj defaults --- osu.Desktop/osu.Desktop.csproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index fa378cf19e..3d64cab84e 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -1,4 +1,4 @@ - + net471;netcoreapp2.0 @@ -10,8 +10,8 @@ osu!lazer osu!lazer lazer.ico - 0.0.0.0 - 0.0.0.0 + 0.0.0 + 0.0.0 $(DefineConstants);NET_FRAMEWORK @@ -36,4 +36,4 @@ - \ No newline at end of file + From 6ecb09431f17301dc690efcfcd3f891d5cd074c7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 May 2018 16:37:44 +0800 Subject: [PATCH 033/229] Update squirrel path --- osu.Desktop.Deploy/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop.Deploy/Program.cs b/osu.Desktop.Deploy/Program.cs index 594be45210..a1c2a8aef2 100644 --- a/osu.Desktop.Deploy/Program.cs +++ b/osu.Desktop.Deploy/Program.cs @@ -19,7 +19,7 @@ namespace osu.Desktop.Deploy { private static string packages => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages"); private static string nugetPath => Path.Combine(packages, @"nuget.commandline\4.5.1\tools\NuGet.exe"); - private static string squirrelPath => Path.Combine(packages, @"squirrel.windows\1.7.8\tools\Squirrel.exe"); + private static string squirrelPath => Path.Combine(packages, @"squirrel.windows\1.8.0\tools\Squirrel.exe"); private const string msbuild_path = @"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"; public static string StagingFolder = ConfigurationManager.AppSettings["StagingFolder"]; From 2d6b2d10f7e83376a37433b84d30254c4575d838 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 May 2018 18:26:23 +0900 Subject: [PATCH 034/229] Use bindable transforms --- osu-framework | 2 +- osu.Game/Overlays/ChatOverlay.cs | 25 +---------------- .../UI/Scrolling/ScrollingPlayfield.cs | 27 ++----------------- 3 files changed, 4 insertions(+), 50 deletions(-) diff --git a/osu-framework b/osu-framework index 0773d895d9..96ef8c43b5 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 0773d895d9aa0729995cd4a23efc28238e35ceed +Subproject commit 96ef8c43b5e6b6ae14b01c3550c480c8d9a78518 diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 331dcec4c0..a2542c537f 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -12,10 +12,8 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Transforms; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; -using osu.Framework.MathUtils; using osu.Framework.Threading; using osu.Game.Configuration; using osu.Game.Graphics; @@ -181,7 +179,7 @@ namespace osu.Game.Overlays { textbox.HoldFocus = false; if (1f - ChatHeight.Value < channel_selection_min_height) - transformChatHeightTo(1f - channel_selection_min_height, 800, Easing.OutQuint); + this.TransformBindableTo(ChatHeight, 1f - channel_selection_min_height, 800, Easing.OutQuint); } else textbox.HoldFocus = true; @@ -533,26 +531,5 @@ namespace osu.Game.Overlays api.Queue(req); } - - private void transformChatHeightTo(double newChatHeight, double duration = 0, Easing easing = Easing.None) - { - this.TransformTo(this.PopulateTransform(new TransformChatHeight(), newChatHeight, duration, easing)); - } - - private class TransformChatHeight : Transform - { - private double valueAt(double time) - { - if (time < StartTime) return StartValue; - if (time >= EndTime) return EndValue; - - return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); - } - - public override string TargetMember => "ChatHeight.Value"; - - protected override void Apply(ChatOverlay d, double time) => d.ChatHeight.Value = valueAt(time); - protected override void ReadIntoStartValue(ChatOverlay d) => StartValue = d.ChatHeight.Value; - } } } diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index 1e7f561aba..6f86d20295 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -4,9 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Graphics.Transforms; using osu.Framework.Input; -using osu.Framework.MathUtils; using osu.Game.Rulesets.Objects.Drawables; using OpenTK.Input; @@ -90,10 +88,10 @@ namespace osu.Game.Rulesets.UI.Scrolling switch (args.Key) { case Key.Minus: - transformVisibleTimeRangeTo(VisibleTimeRange + time_span_step, 200, Easing.OutQuint); + this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange + time_span_step, 200, Easing.OutQuint); break; case Key.Plus: - transformVisibleTimeRangeTo(VisibleTimeRange - time_span_step, 200, Easing.OutQuint); + this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange - time_span_step, 200, Easing.OutQuint); break; } } @@ -101,27 +99,6 @@ namespace osu.Game.Rulesets.UI.Scrolling return false; } - private void transformVisibleTimeRangeTo(double newTimeRange, double duration = 0, Easing easing = Easing.None) - { - this.TransformTo(this.PopulateTransform(new TransformVisibleTimeRange(), newTimeRange, duration, easing)); - } - protected sealed override HitObjectContainer CreateHitObjectContainer() => new ScrollingHitObjectContainer(direction); - - private class TransformVisibleTimeRange : Transform - { - private double valueAt(double time) - { - if (time < StartTime) return StartValue; - if (time >= EndTime) return EndValue; - - return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); - } - - public override string TargetMember => "VisibleTimeRange.Value"; - - protected override void Apply(ScrollingPlayfield d, double time) => d.VisibleTimeRange.Value = valueAt(time); - protected override void ReadIntoStartValue(ScrollingPlayfield d) => StartValue = d.VisibleTimeRange.Value; - } } } From d4ada3000cb059b1a55ea43c3f348d6a731ed4d9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 May 2018 19:37:47 +0900 Subject: [PATCH 035/229] Add keybind to disable mouse buttons --- osu.Game/Configuration/OsuConfigManager.cs | 6 ++++++ osu.Game/Input/Bindings/GlobalActionContainer.cs | 5 ++++- osu.Game/OsuGame.cs | 3 +++ osu.Game/Overlays/OnScreenDisplay.cs | 4 +++- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 509622c2fe..b3082e49de 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Configuration; +using osu.Framework.Configuration.Tracking; using osu.Framework.Platform; using osu.Game.Overlays; using osu.Game.Screens.Select; @@ -95,6 +96,11 @@ namespace osu.Game.Configuration public OsuConfigManager(Storage storage) : base(storage) { } + + public override TrackedSettings CreateTrackedSettings() => new TrackedSettings + { + new TrackedSetting(OsuSetting.MouseDisableButtons, v => new SettingDescription(!v, "gameplay mouse buttons", v ? "disabled" : "enabled")) + }; } public enum OsuSetting diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index dd8f00f6cd..44e12be1dd 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -26,7 +26,8 @@ namespace osu.Game.Input.Bindings { new KeyBinding(InputKey.F8, GlobalAction.ToggleChat), new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial), - new KeyBinding(InputKey.F12,GlobalAction.TakeScreenshot), + new KeyBinding(InputKey.F10, GlobalAction.ToggleMouseButtons), + new KeyBinding(InputKey.F12, GlobalAction.TakeScreenshot), new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings), new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar), @@ -75,6 +76,8 @@ namespace osu.Game.Input.Bindings [Description("Quick Retry (Hold)")] QuickRetry, + [Description("Toggle gameplay mouse buttons")] + ToggleMouseButtons, [Description("Take screenshot")] TakeScreenshot } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index d443ed36ae..d2d47a78a6 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -466,6 +466,9 @@ namespace osu.Game case GlobalAction.ToggleDirect: direct.ToggleVisibility(); return true; + case GlobalAction.ToggleMouseButtons: + LocalConfig.Set(OsuSetting.MouseDisableButtons, !LocalConfig.Get(OsuSetting.MouseDisableButtons)); + return true; } return false; diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 3dd088891d..9882ea01f0 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -14,6 +14,7 @@ using osu.Game.Graphics; using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; +using osu.Game.Configuration; using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays @@ -116,9 +117,10 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(FrameworkConfigManager frameworkConfig) + private void load(FrameworkConfigManager frameworkConfig, OsuConfigManager osuConfig) { BeginTracking(this, frameworkConfig); + BeginTracking(this, osuConfig); } private readonly Dictionary<(object, IConfigManager), TrackedSettings> trackedConfigManagers = new Dictionary<(object, IConfigManager), TrackedSettings>(); From 482ae2db87e8cebec289a4b5090282b8a99c4c43 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 2 May 2018 19:42:03 +0900 Subject: [PATCH 036/229] Unify naming --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 4 ++-- osu.Game/OsuGame.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 44e12be1dd..2ae895785c 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Input.Bindings { new KeyBinding(InputKey.F8, GlobalAction.ToggleChat), new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial), - new KeyBinding(InputKey.F10, GlobalAction.ToggleMouseButtons), + new KeyBinding(InputKey.F10, GlobalAction.ToggleGameplayMouseButtons), new KeyBinding(InputKey.F12, GlobalAction.TakeScreenshot), new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings), @@ -77,7 +77,7 @@ namespace osu.Game.Input.Bindings QuickRetry, [Description("Toggle gameplay mouse buttons")] - ToggleMouseButtons, + ToggleGameplayMouseButtons, [Description("Take screenshot")] TakeScreenshot } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index d2d47a78a6..fe5ca4f278 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -466,7 +466,7 @@ namespace osu.Game case GlobalAction.ToggleDirect: direct.ToggleVisibility(); return true; - case GlobalAction.ToggleMouseButtons: + case GlobalAction.ToggleGameplayMouseButtons: LocalConfig.Set(OsuSetting.MouseDisableButtons, !LocalConfig.Get(OsuSetting.MouseDisableButtons)); return true; } From 89db7f81cbd9d1d4b7d452cfc584b259f98751c7 Mon Sep 17 00:00:00 2001 From: Santeri Nogelainen Date: Wed, 2 May 2018 17:11:55 +0300 Subject: [PATCH 037/229] Selecting a mod now triggers on mouseup --- osu.Game/Overlays/Mods/ModButton.cs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index 2a4f243606..3f1541aee3 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -147,18 +147,21 @@ namespace osu.Game.Overlays.Mods public virtual Mod SelectedMod => Mods.ElementAtOrDefault(selectedIndex); - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { - switch (args.Button) + // only trigger the event if we are inside the area of the button + if (Contains(ToScreenSpace(state.Mouse.Position - Position))) { - case MouseButton.Left: - SelectNext(1); - break; - case MouseButton.Right: - SelectNext(-1); - break; + switch (args.Button) + { + case MouseButton.Left: + SelectNext(1); + break; + case MouseButton.Right: + SelectNext(-1); + break; + } } - return true; } From 33e2b91cccdc470c924b85688dc6f98fc9d1e3c7 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Thu, 3 May 2018 22:59:49 +0300 Subject: [PATCH 038/229] Decouple FilterControl.Ruleset from the game-wide ruleset bindable --- osu.Game/Overlays/Direct/FilterControl.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index a2da516257..4f4348c131 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -1,8 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; -using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -12,6 +10,8 @@ using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests; using osu.Game.Overlays.SearchableList; using osu.Game.Rulesets; +using OpenTK; +using OpenTK.Graphics; namespace osu.Game.Overlays.Direct { @@ -22,6 +22,7 @@ namespace osu.Game.Overlays.Direct protected override Color4 BackgroundColour => OsuColour.FromHex(@"384552"); protected override DirectSortCriteria DefaultTab => DirectSortCriteria.Ranked; + protected override Drawable CreateSupplementaryControls() { modeButtons = new FillFlowContainer @@ -38,7 +39,7 @@ namespace osu.Game.Overlays.Direct { DisplayStyleControl.Dropdown.AccentColour = colours.BlueDark; - Ruleset.BindTo(game?.Ruleset ?? new Bindable { Value = rulesets.GetRuleset(0) }); + Ruleset.Value = game?.Ruleset.Value ?? rulesets.GetRuleset(0); foreach (var r in rulesets.AvailableRulesets) { modeButtons.Add(new RulesetToggleButton(Ruleset, r)); @@ -54,6 +55,7 @@ namespace osu.Game.Overlays.Direct } private RulesetInfo ruleset; + public RulesetInfo Ruleset { get => ruleset; @@ -93,7 +95,6 @@ namespace osu.Game.Overlays.Direct Ruleset = ruleset; bindable.ValueChanged += Bindable_ValueChanged; - bindable.DisabledChanged += isDisabled => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300); Bindable_ValueChanged(bindable.Value); Action = () => bindable.Value = Ruleset; } From f8630115d68b7dd610638ab037c8e69282043d00 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Thu, 3 May 2018 23:29:58 +0300 Subject: [PATCH 039/229] Do not expose HoldToQuit.HoldToQuitButton --- osu.Game.Tests/Visual/TestCaseHoldToQuit.cs | 10 +++++----- osu.Game/Screens/Play/HUD/HoldToQuit.cs | 9 +++++++-- osu.Game/Screens/Play/Player.cs | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs b/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs index 04ea4249e5..a9b391cd79 100644 --- a/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs +++ b/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs @@ -22,15 +22,15 @@ namespace osu.Game.Tests.Visual Origin = Anchor.BottomRight, Anchor = Anchor.BottomRight, }); - holdToQuit.Button.ExitAction = () => exitAction = true; + holdToQuit.ExitAction = () => exitAction = true; var text = holdToQuit.Children.OfType().Single(); AddStep("Trigger text fade in/out", () => { exitAction = false; - holdToQuit.Button.TriggerOnMouseDown(); - holdToQuit.Button.TriggerOnMouseUp(); + holdToQuit.TriggerOnMouseDown(); + holdToQuit.TriggerOnMouseUp(); }); AddUntilStep(() => text.IsPresent && !exitAction, "Text visible"); @@ -39,10 +39,10 @@ namespace osu.Game.Tests.Visual AddStep("Trigger exit action", () => { exitAction = false; - holdToQuit.Button.TriggerOnMouseDown(); + holdToQuit.TriggerOnMouseDown(); }); - AddUntilStep(() => exitAction, $"{nameof(holdToQuit.Button.ExitAction)} was triggered"); + AddUntilStep(() => exitAction, $"{nameof(holdToQuit.ExitAction)} was triggered"); } } } diff --git a/osu.Game/Screens/Play/HUD/HoldToQuit.cs b/osu.Game/Screens/Play/HUD/HoldToQuit.cs index 59338f8cdc..ee67dd35f8 100644 --- a/osu.Game/Screens/Play/HUD/HoldToQuit.cs +++ b/osu.Game/Screens/Play/HUD/HoldToQuit.cs @@ -16,7 +16,12 @@ namespace osu.Game.Screens.Play.HUD { public class HoldToQuit : FillFlowContainer { - public readonly HoldToQuitButton Button; + private readonly HoldToQuitButton button; + public Action ExitAction + { + get => button.ExitAction; + set => button.ExitAction = value; + } public HoldToQuit() { @@ -32,7 +37,7 @@ namespace osu.Game.Screens.Play.HUD Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft }, - Button = new HoldToQuitButton(text) + button = new HoldToQuitButton(text) }; AutoSizeAxes = Axes.Both; } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 836730e3f3..540950a853 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -216,7 +216,7 @@ namespace osu.Game.Screens.Play } }; - hudOverlay.HoldToQuit.Button.ExitAction = Exit; + hudOverlay.HoldToQuit.ExitAction = Exit; if (ShowStoryboard) initializeStoryboard(false); From 39db1e8cbb9ba539838e1ac4b117e1611cf04063 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Thu, 3 May 2018 23:50:30 +0300 Subject: [PATCH 040/229] Rename HoldToQuit to QuitButton --- osu.Game.Tests/Visual/TestCaseHoldToQuit.cs | 4 ++-- .../Play/HUD/{HoldToQuit.cs => QuitButton.cs} | 12 ++++++------ osu.Game/Screens/Play/HUDOverlay.cs | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) rename osu.Game/Screens/Play/HUD/{HoldToQuit.cs => QuitButton.cs} (91%) diff --git a/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs b/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs index a9b391cd79..9a2228c23c 100644 --- a/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs +++ b/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs @@ -16,8 +16,8 @@ namespace osu.Game.Tests.Visual public TestCaseHoldToQuit() { - HoldToQuit holdToQuit; - Add(holdToQuit = new HoldToQuit + QuitButton holdToQuit; + Add(holdToQuit = new QuitButton { Origin = Anchor.BottomRight, Anchor = Anchor.BottomRight, diff --git a/osu.Game/Screens/Play/HUD/HoldToQuit.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs similarity index 91% rename from osu.Game/Screens/Play/HUD/HoldToQuit.cs rename to osu.Game/Screens/Play/HUD/QuitButton.cs index ee67dd35f8..aa6dc388ac 100644 --- a/osu.Game/Screens/Play/HUD/HoldToQuit.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -14,16 +14,16 @@ using OpenTK; namespace osu.Game.Screens.Play.HUD { - public class HoldToQuit : FillFlowContainer + public class QuitButton : FillFlowContainer { - private readonly HoldToQuitButton button; + private readonly Button button; public Action ExitAction { get => button.ExitAction; set => button.ExitAction = value; } - public HoldToQuit() + public QuitButton() { OsuSpriteText text; Direction = FillDirection.Horizontal; @@ -37,12 +37,12 @@ namespace osu.Game.Screens.Play.HUD Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft }, - button = new HoldToQuitButton(text) + button = new Button(text) }; AutoSizeAxes = Axes.Both; } - public class HoldToQuitButton : CircularContainer + private class Button : CircularContainer { private readonly OsuSpriteText text; private SpriteIcon icon; @@ -54,7 +54,7 @@ namespace osu.Game.Screens.Play.HUD private const int progress_duration = 1000; private const int text_display_time = 5000; - public HoldToQuitButton(OsuSpriteText text) => this.text = text; + public Button(OsuSpriteText text) => this.text = text; [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index c2471c967e..cba5c94266 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -34,7 +34,7 @@ namespace osu.Game.Screens.Play public readonly HealthDisplay HealthDisplay; public readonly SongProgress Progress; public readonly ModDisplay ModDisplay; - public readonly HoldToQuit HoldToQuit; + public readonly QuitButton HoldToQuit; public readonly PlayerSettingsOverlay PlayerSettingsOverlay; private Bindable showHud; @@ -58,7 +58,7 @@ namespace osu.Game.Screens.Play AccuracyCounter = CreateAccuracyCounter(), HealthDisplay = CreateHealthDisplay(), Progress = CreateProgress(), - HoldToQuit = CreateHoldToQuit(), + HoldToQuit = CreateQuitButton(), ModDisplay = CreateModsContainer(), PlayerSettingsOverlay = CreatePlayerSettingsOverlay() } @@ -207,11 +207,11 @@ namespace osu.Game.Screens.Play RelativeSizeAxes = Axes.X, }; - protected virtual HoldToQuit CreateHoldToQuit() => new HoldToQuit + protected virtual QuitButton CreateQuitButton() => new QuitButton { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, - Margin = new MarginPadding { Bottom = Progress.Size.Y * 1.25f, Right = 5 } + Position = new Vector2(-5, -70) }; protected virtual ModDisplay CreateModsContainer() => new ModDisplay From b0e556d83fd1367fc4156516c026255b26f5cac2 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Fri, 4 May 2018 00:01:00 +0300 Subject: [PATCH 041/229] Actualize QuitButton visual test --- ...aseHoldToQuit.cs => TestCaseQuitButton.cs} | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) rename osu.Game.Tests/Visual/{TestCaseHoldToQuit.cs => TestCaseQuitButton.cs} (60%) diff --git a/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs b/osu.Game.Tests/Visual/TestCaseQuitButton.cs similarity index 60% rename from osu.Game.Tests/Visual/TestCaseHoldToQuit.cs rename to osu.Game.Tests/Visual/TestCaseQuitButton.cs index 9a2228c23c..545a8ff57b 100644 --- a/osu.Game.Tests/Visual/TestCaseHoldToQuit.cs +++ b/osu.Game.Tests/Visual/TestCaseQuitButton.cs @@ -4,33 +4,36 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual { [Description("'Hold to Quit' UI element")] - public class TestCaseHoldToQuit : OsuTestCase + public class TestCaseQuitButton : OsuTestCase { + private readonly QuitButton quitButton; + private Drawable innerButton => quitButton.Children.Single(child => child is CircularContainer); private bool exitAction; - public TestCaseHoldToQuit() + public TestCaseQuitButton() { - QuitButton holdToQuit; - Add(holdToQuit = new QuitButton + Add(quitButton = new QuitButton { Origin = Anchor.BottomRight, Anchor = Anchor.BottomRight, }); - holdToQuit.ExitAction = () => exitAction = true; + quitButton.ExitAction = () => exitAction = true; - var text = holdToQuit.Children.OfType().Single(); + var text = quitButton.Children.OfType().Single(); AddStep("Trigger text fade in/out", () => { exitAction = false; - holdToQuit.TriggerOnMouseDown(); - holdToQuit.TriggerOnMouseUp(); + + innerButton.TriggerOnMouseDown(); + innerButton.TriggerOnMouseUp(); }); AddUntilStep(() => text.IsPresent && !exitAction, "Text visible"); @@ -39,10 +42,10 @@ namespace osu.Game.Tests.Visual AddStep("Trigger exit action", () => { exitAction = false; - holdToQuit.TriggerOnMouseDown(); + innerButton.TriggerOnMouseDown(); }); - AddUntilStep(() => exitAction, $"{nameof(holdToQuit.ExitAction)} was triggered"); + AddUntilStep(() => exitAction, $"{nameof(quitButton.ExitAction)} was triggered"); } } } From b08b24b6da17260a2a028b6a070e36093429f6a4 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Fri, 4 May 2018 21:18:48 +0300 Subject: [PATCH 042/229] Introduce OsuScreen.AllowBackButton property --- osu.Game/Screens/OsuScreen.cs | 24 ++++++++---------------- osu.Game/Screens/Play/PlayerLoader.cs | 1 + 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 5d2c46f438..fb5d3d12e6 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -22,6 +22,8 @@ namespace osu.Game.Screens { public BackgroundScreen Background { get; private set; } + protected virtual bool AllowBackButton => true; + /// /// Override to create a BackgroundMode for the current screen. /// Note that the instance created may not be the used instance if it matches the BackgroundMode equality clause. @@ -92,26 +94,16 @@ namespace osu.Game.Screens public bool OnPressed(GlobalAction action) { - switch (action) + if (action == GlobalAction.Back && AllowBackButton) { - case GlobalAction.Back: - Exit(); - return true; - default: - return false; + Exit(); + return true; } + + return false; } - public bool OnReleased(GlobalAction action) - { - switch (action) - { - case GlobalAction.Back: - return true; - default: - return false; - } - } + public bool OnReleased(GlobalAction action) => action == GlobalAction.Back && AllowBackButton; protected override void OnResuming(Screen last) { diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 56fbd7b6e7..6eb156914e 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -27,6 +27,7 @@ namespace osu.Game.Screens.Play private bool showOverlays = true; public override bool ShowOverlaysOnEnter => showOverlays; + protected override bool AllowBackButton => false; private Task loadTask; From f3aa9269ff3e9b2cdcde32c4c552794af0d41148 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 09:17:12 +0900 Subject: [PATCH 043/229] Fix mania-specific beatmap conversion --- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 93feddc143..acd289a9e8 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps var roundedCircleSize = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.CircleSize); var roundedOverallDifficulty = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); - if (beatmap.BeatmapInfo.Ruleset == new ManiaRuleset().RulesetInfo) + if (IsForCurrentRuleset) TargetColumns = (int)Math.Max(1, roundedCircleSize); else { diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 6f117332b2..f4c78fd195 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -118,7 +118,8 @@ namespace osu.Game.Rulesets Name = Description, ShortName = ShortName, InstantiationInfo = GetType().AssemblyQualifiedName, - ID = LegacyID + ID = LegacyID, + Available = true }; } } From 20509b1cc2813a98829a31fa7e3663dc7131e3b4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 09:59:45 +0900 Subject: [PATCH 044/229] Fix non-IBeatmap usage --- osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index f6b0bb56c9..efd6c36ce2 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -112,7 +112,7 @@ namespace osu.Game.Tests.Visual AddAssert("check no infolabels", () => !infoWedge.Info.InfoLabelContainer.Children.Any()); } - private void selectBeatmap(Beatmap b) + private void selectBeatmap(IBeatmap b) { BeatmapInfoWedge.BufferedWedgeInfo infoBefore = null; From 27c8591d48d911e3884f755daabcf035e29b7e96 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 10:07:50 +0900 Subject: [PATCH 045/229] Fix reference to old name --- osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index efd6c36ce2..22945e726c 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual }); // select part is redundant, but wait for load isn't - selectBeatmap(beatmap.Value.Beatmap); + selectBeatmap(beatmap.Value.OriginalBeatmap); AddWaitStep(3); From 4ecdea8b2eb12282a9360b8048b3fb4cd033275b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 10:17:54 +0900 Subject: [PATCH 046/229] Remove now-unnecessary IsForCurrentRuleset property of RulesetContainer --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- .../UI/CatchRulesetContainer.cs | 4 ++-- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs | 8 ++++++-- .../UI/ManiaRulesetContainer.cs | 4 ++-- .../Edit/OsuEditRulesetContainer.cs | 2 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs | 4 ++-- .../TestCaseTaikoPlayfield.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- .../UI/TaikoRulesetContainer.cs | 4 ++-- osu.Game.Tests/Visual/TestCaseReplay.cs | 2 +- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 3 +-- osu.Game/Rulesets/UI/RulesetContainer.cs | 14 +++----------- .../UI/Scrolling/ScrollingRulesetContainer.cs | 4 ++-- osu.Game/Screens/Play/Player.cs | 4 ++-- 18 files changed, 31 insertions(+), 36 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index f091fbbee4..15e51fa126 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Catch { public class CatchRuleset : Ruleset { - public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchRulesetContainer(this, beatmap, isForCurrentRuleset); + public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) => new CatchRulesetContainer(this, beatmap); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap); diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index 6e8a2c1660..070dc19a6f 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Rulesets.Catch.UI { public class CatchRulesetContainer : ScrollingRulesetContainer { - public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) - : base(ruleset, beatmap, isForCurrentRuleset) + public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) + : base(ruleset, beatmap) { } diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 75b1e38a2f..f1d65f855b 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Mania { public class ManiaRuleset : Ruleset { - public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new ManiaRulesetContainer(this, beatmap, isForCurrentRuleset); + public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) => new ManiaRulesetContainer(this, beatmap); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap); public override IEnumerable ConvertLegacyMods(LegacyMods mods) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs index dde8acf428..7f3985b26d 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs @@ -18,12 +18,16 @@ namespace osu.Game.Rulesets.Mania.Mods public override string Description => @"Double the stages, double the fun!"; public override double ScoreMultiplier => 0; + private bool isForCurrentRuleset; + public void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter) { var mbc = (ManiaBeatmapConverter)beatmapConverter; + isForCurrentRuleset = mbc.IsForCurrentRuleset; + // Although this can work, for now let's not allow keymods for mania-specific beatmaps - if (mbc.IsForCurrentRuleset) + if (isForCurrentRuleset) return; mbc.TargetColumns *= 2; @@ -34,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Mods var mrc = (ManiaRulesetContainer)rulesetContainer; // Although this can work, for now let's not allow keymods for mania-specific beatmaps - if (mrc.IsForCurrentRuleset) + if (isForCurrentRuleset) return; var newDefinitions = new List(); diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 059eaaadcd..7123aab901 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -36,8 +36,8 @@ namespace osu.Game.Rulesets.Mania.UI public IEnumerable BarLines; - public ManiaRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) - : base(ruleset, beatmap, isForCurrentRuleset) + public ManiaRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) + : base(ruleset, beatmap) { // Generate the bar lines double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue; diff --git a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs index 8d4c342740..dce43f5bbb 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Edit public class OsuEditRulesetContainer : OsuRulesetContainer { public OsuEditRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) - : base(ruleset, beatmap, isForCurrentRuleset) + : base(ruleset, beatmap) { } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 02b887f1b9..ffc421217c 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu { public class OsuRuleset : Ruleset { - public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new OsuRulesetContainer(this, beatmap, isForCurrentRuleset); + public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) => new OsuRulesetContainer(this, beatmap); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap); public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap); diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs index 603f95dc47..ad1052f86a 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs @@ -20,8 +20,8 @@ namespace osu.Game.Rulesets.Osu.UI { public class OsuRulesetContainer : RulesetContainer { - public OsuRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) - : base(ruleset, beatmap, isForCurrentRuleset) + public OsuRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) + : base(ruleset, beatmap) { } diff --git a/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs index aa7318b863..f67726c022 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Taiko.Tests RelativeSizeAxes = Axes.X, Height = 768, Clock = new FramedClock(rateAdjustClock), - Children = new[] { rulesetContainer = new TaikoRulesetContainer(rulesets.GetRuleset(1).CreateInstance(), beatmap, true) } + Children = new[] { rulesetContainer = new TaikoRulesetContainer(rulesets.GetRuleset(1).CreateInstance(), beatmap) } }); } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 2e27b34e69..102de5717f 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Taiko { public class TaikoRuleset : Ruleset { - public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new TaikoRulesetContainer(this, beatmap, isForCurrentRuleset); + public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) => new TaikoRulesetContainer(this, beatmap); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap); public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index 0a84d74c27..313c205981 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -23,8 +23,8 @@ namespace osu.Game.Rulesets.Taiko.UI { public class TaikoRulesetContainer : ScrollingRulesetContainer { - public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) - : base(ruleset, beatmap, isForCurrentRuleset) + public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) + : base(ruleset, beatmap) { } diff --git a/osu.Game.Tests/Visual/TestCaseReplay.cs b/osu.Game.Tests/Visual/TestCaseReplay.cs index 6ba671c7fc..5bc16fe420 100644 --- a/osu.Game.Tests/Visual/TestCaseReplay.cs +++ b/osu.Game.Tests/Visual/TestCaseReplay.cs @@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual // We create a dummy RulesetContainer just to get the replay - we don't want to use mods here // to simulate setting a replay rather than having the replay already set for us beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); - var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(beatmap, beatmap.BeatmapInfo.Ruleset.Equals(ruleset.RulesetInfo)); + var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(beatmap); // We have the replay var replay = dummyRulesetContainer.Replay; diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 23ddc5a976..956034a279 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps { public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; - public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) + public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) { throw new NotImplementedException(); } diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 1820053d3d..5f1b9a6bad 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -125,7 +125,7 @@ namespace osu.Game.Rulesets.Edit private void setCompositionTool(ICompositionTool tool) => CurrentTool = tool; - protected virtual RulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => ruleset.CreateRulesetContainerWith(beatmap, true); + protected virtual RulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => ruleset.CreateRulesetContainerWith(beatmap); protected abstract IReadOnlyList CompositionTools { get; } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index f4c78fd195..d6d1d19628 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -52,10 +52,9 @@ namespace osu.Game.Rulesets /// Attempt to create a hit renderer for a beatmap /// /// The beatmap to create the hit renderer for. - /// Whether the hit renderer should assume the beatmap is for the current ruleset. /// Unable to successfully load the beatmap to be usable with this ruleset. /// - public abstract RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset); + public abstract RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap); public abstract IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap); diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 074380da56..3a2e66505a 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -190,11 +190,6 @@ namespace osu.Game.Rulesets.UI /// protected readonly WorkingBeatmap WorkingBeatmap; - /// - /// Whether the specified beatmap is assumed to be specific to the current ruleset. - /// - public readonly bool IsForCurrentRuleset; - public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(this); protected override Container Content => content; @@ -206,14 +201,12 @@ namespace osu.Game.Rulesets.UI /// /// The ruleset being repesented. /// The beatmap to create the hit renderer for. - /// Whether to assume the beatmap is for the current ruleset. - protected RulesetContainer(Ruleset ruleset, WorkingBeatmap workingBeatmap, bool isForCurrentRuleset) + protected RulesetContainer(Ruleset ruleset, WorkingBeatmap workingBeatmap) : base(ruleset) { Debug.Assert(workingBeatmap != null, "RulesetContainer initialized with a null beatmap."); WorkingBeatmap = workingBeatmap; - IsForCurrentRuleset = isForCurrentRuleset; // ReSharper disable once PossibleNullReferenceException Mods = workingBeatmap.Mods.Value; @@ -337,9 +330,8 @@ namespace osu.Game.Rulesets.UI /// /// The ruleset being repesented. /// The beatmap to create the hit renderer for. - /// Whether to assume the beatmap is for the current ruleset. - protected RulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) - : base(ruleset, beatmap, isForCurrentRuleset) + protected RulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) + : base(ruleset, beatmap) { } } diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs index 79f9eaa9e9..efd901240a 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs @@ -30,8 +30,8 @@ namespace osu.Game.Rulesets.UI.Scrolling /// protected readonly SortedList DefaultControlPoints = new SortedList(Comparer.Default); - protected ScrollingRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) - : base(ruleset, beatmap, isForCurrentRuleset) + protected ScrollingRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) + : base(ruleset, beatmap) { } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d5edff3a0c..d39b28bf25 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -107,7 +107,7 @@ namespace osu.Game.Screens.Play try { - RulesetContainer = rulesetInstance.CreateRulesetContainerWith(working, ruleset.ID == beatmap.BeatmapInfo.Ruleset.ID); + RulesetContainer = rulesetInstance.CreateRulesetContainerWith(working); } catch (BeatmapInvalidForRulesetException) { @@ -115,7 +115,7 @@ namespace osu.Game.Screens.Play // let's try again forcing the beatmap's ruleset. ruleset = beatmap.BeatmapInfo.Ruleset; rulesetInstance = ruleset.CreateInstance(); - RulesetContainer = rulesetInstance.CreateRulesetContainerWith(Beatmap, true); + RulesetContainer = rulesetInstance.CreateRulesetContainerWith(Beatmap); } if (!RulesetContainer.Objects.Any()) From b68ee39136bc5ac8359a96db294b509066a4ad71 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 10:18:47 +0900 Subject: [PATCH 047/229] Reword beatmap conversion error --- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 7d6c23dad0..2afaaf13f9 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -87,7 +87,7 @@ namespace osu.Game.Beatmaps // Check if the beatmap can be converted if (!converter.CanConvert) - throw new BeatmapInvalidForRulesetException($"{nameof(Beatmap)} can not be converted for the current ruleset (converter: {converter})."); + throw new BeatmapInvalidForRulesetException($"{nameof(Beatmap)} can not be converted for the ruleset (ruleset: {ruleset}, converter: {converter})."); // Apply conversion mods foreach (var mod in Mods.Value.OfType()) From 7e83c75888a0b7f0ef04cc062f5f2174512cabcc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 10:23:32 +0900 Subject: [PATCH 048/229] Add xmldoc --- osu.Game/Beatmaps/WorkingBeatmap.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 2afaaf13f9..ae83a14d61 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -79,6 +79,13 @@ namespace osu.Game.Beatmaps return b; } + /// + /// Retrieves the resulting from the conversion of to a specific . + /// All mods have been applied to the returned . + /// + /// The to convert to. + /// The converted . + /// If could not be converted to . public IBeatmap GetBeatmap(RulesetInfo ruleset) { var rulesetInstance = ruleset.CreateInstance(); From 9128e64c9a907e5cf2990115e305c0966a3ac28e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 10:29:38 +0900 Subject: [PATCH 049/229] Rename OriginalBeatmap back to Beatmap --- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- .../Beatmaps/IO/ImportBeatmapTest.cs | 8 ++--- .../Visual/TestCaseBeatSyncedContainer.cs | 2 +- .../Visual/TestCaseBeatmapInfoWedge.cs | 2 +- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 30 +++++++++---------- .../Containers/BeatSyncedContainer.cs | 2 +- osu.Game/Overlays/MusicController.cs | 2 +- .../Scoring/Legacy/LegacyScoreParser.cs | 2 +- .../Timelines/Summary/Parts/BreakPart.cs | 2 +- .../Summary/Parts/ControlPointPart.cs | 2 +- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 2 +- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Ranking/ResultsPageScore.cs | 2 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 2 +- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 2 +- osu.Game/Tests/Visual/EditorClockTestCase.cs | 2 +- .../Tests/Visual/TestCasePerformancePoints.cs | 4 +-- 20 files changed, 38 insertions(+), 38 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index ffc421217c..927ffa2146 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Osu public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) { - IEnumerable hitObjects = beatmap.OriginalBeatmap.HitObjects; + IEnumerable hitObjects = beatmap.Beatmap.HitObjects; IEnumerable circles = hitObjects.Where(c => !(c is IHasEndTime)); IEnumerable sliders = hitObjects.Where(s => s is IHasCurve); IEnumerable spinners = hitObjects.Where(s => s is IHasEndTime && !(s is IHasCurve)); diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 3530ae928d..f60caf2397 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -274,13 +274,13 @@ namespace osu.Game.Tests.Beatmaps.IO foreach (BeatmapInfo b in set.Beatmaps) Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineBeatmapID == b.OnlineBeatmapID)); Assert.IsTrue(set.Beatmaps.Count > 0); - var beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 0))?.OriginalBeatmap; + var beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 0))?.Beatmap; Assert.IsTrue(beatmap?.HitObjects.Any() == true); - beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 1))?.OriginalBeatmap; + beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 1))?.Beatmap; Assert.IsTrue(beatmap?.HitObjects.Any() == true); - beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 2))?.OriginalBeatmap; + beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 2))?.Beatmap; Assert.IsTrue(beatmap?.HitObjects.Any() == true); - beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.OriginalBeatmap; + beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap; Assert.IsTrue(beatmap?.HitObjects.Any() == true); } diff --git a/osu.Game.Tests/Visual/TestCaseBeatSyncedContainer.cs b/osu.Game.Tests/Visual/TestCaseBeatSyncedContainer.cs index 4e3462b5ea..596b7839e0 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatSyncedContainer.cs @@ -139,7 +139,7 @@ namespace osu.Game.Tests.Visual }; } - private SortedList timingPoints => Beatmap.Value.OriginalBeatmap.ControlPointInfo.TimingPoints; + private SortedList timingPoints => Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints; private TimingControlPoint getNextTimingPoint(TimingControlPoint current) { if (timingPoints[timingPoints.Count - 1] == current) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 22945e726c..efd6c36ce2 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual }); // select part is redundant, but wait for load isn't - selectBeatmap(beatmap.Value.OriginalBeatmap); + selectBeatmap(beatmap.Value.Beatmap); AddWaitStep(3); diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index cff500fabf..71406c6034 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -30,7 +30,7 @@ namespace osu.Game.Beatmaps this.audioManager = audioManager; } - protected override IBeatmap GetOriginalBeatmap() + protected override IBeatmap GetBeatmap() { try { diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 956034a279..da52dc7284 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -40,7 +40,7 @@ namespace osu.Game.Beatmaps this.game = game; } - protected override IBeatmap GetOriginalBeatmap() => new Beatmap(); + protected override IBeatmap GetBeatmap() => new Beatmap(); protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4"); diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index ae83a14d61..e90df687e4 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -38,7 +38,7 @@ namespace osu.Game.Beatmaps Mods.ValueChanged += mods => applyRateAdjustments(); - originalBeatmap = new AsyncLazy(populateOriginalBeatmap); + beatmap = new AsyncLazy(populateBeatmap); background = new AsyncLazy(populateBackground, b => b == null || !b.IsDisposed); track = new AsyncLazy(populateTrack); waveform = new AsyncLazy(populateWaveform); @@ -47,31 +47,31 @@ namespace osu.Game.Beatmaps } /// - /// Saves the . + /// Saves the . /// public void Save() { var path = FileSafety.GetTempPath(Guid.NewGuid().ToString().Replace("-", string.Empty) + ".json"); using (var sw = new StreamWriter(path)) - sw.WriteLine(OriginalBeatmap.Serialize()); + sw.WriteLine(Beatmap.Serialize()); Process.Start(path); } - protected abstract IBeatmap GetOriginalBeatmap(); + protected abstract IBeatmap GetBeatmap(); protected abstract Texture GetBackground(); protected abstract Track GetTrack(); protected virtual Skin GetSkin() => new DefaultSkin(); protected virtual Waveform GetWaveform() => new Waveform(); protected virtual Storyboard GetStoryboard() => new Storyboard { BeatmapInfo = BeatmapInfo }; - public bool BeatmapLoaded => originalBeatmap.IsResultAvailable; - public IBeatmap OriginalBeatmap => originalBeatmap.Value.Result; - public async Task GetOriginalBeatmapAsync() => await originalBeatmap.Value; - private readonly AsyncLazy originalBeatmap; + public bool BeatmapLoaded => beatmap.IsResultAvailable; + public IBeatmap Beatmap => beatmap.Value.Result; + public async Task GetBeatmapAsync() => await beatmap.Value; + private readonly AsyncLazy beatmap; - private IBeatmap populateOriginalBeatmap() + private IBeatmap populateBeatmap() { - var b = GetOriginalBeatmap() ?? new Beatmap(); + var b = GetBeatmap() ?? new Beatmap(); // use the database-backed info. b.BeatmapInfo = BeatmapInfo; @@ -80,21 +80,21 @@ namespace osu.Game.Beatmaps } /// - /// Retrieves the resulting from the conversion of to a specific . + /// Retrieves the resulting from the conversion of to a specific . /// All mods have been applied to the returned . /// - /// The to convert to. + /// The to convert to. /// The converted . - /// If could not be converted to . + /// If could not be converted to . public IBeatmap GetBeatmap(RulesetInfo ruleset) { var rulesetInstance = ruleset.CreateInstance(); - IBeatmapConverter converter = rulesetInstance.CreateBeatmapConverter(OriginalBeatmap); + IBeatmapConverter converter = rulesetInstance.CreateBeatmapConverter(Beatmap); // Check if the beatmap can be converted if (!converter.CanConvert) - throw new BeatmapInvalidForRulesetException($"{nameof(Beatmap)} can not be converted for the ruleset (ruleset: {ruleset}, converter: {converter})."); + throw new BeatmapInvalidForRulesetException($"{nameof(Beatmaps.Beatmap)} can not be converted for the ruleset (ruleset: {ruleset}, converter: {converter})."); // Apply conversion mods foreach (var mod in Mods.Value.OfType()) diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index 8d8717a612..bf16af4706 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -38,7 +38,7 @@ namespace osu.Game.Graphics.Containers if (!Beatmap.Value.TrackLoaded || !Beatmap.Value.BeatmapLoaded) return; var track = Beatmap.Value.Track; - var beatmap = Beatmap.Value.OriginalBeatmap; + var beatmap = Beatmap.Value.Beatmap; if (track == null || beatmap == null) return; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index eb88fe0eb4..b4021f2808 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -343,7 +343,7 @@ namespace osu.Game.Overlays // todo: this can likely be replaced with WorkingBeatmap.GetBeatmapAsync() Task.Run(() => { - if (beatmap?.OriginalBeatmap == null) //this is not needed if a placeholder exists + if (beatmap?.Beatmap == null) //this is not needed if a placeholder exists { title.Current = null; title.Text = @"Nothing to play"; diff --git a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs index 3145561001..d5ab856697 100644 --- a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Scoring.Legacy /* score.FileChecksum = */ var beatmapHash = sr.ReadString(); score.Beatmap = beatmaps.QueryBeatmap(b => b.MD5Hash == beatmapHash); - currentBeatmap = beatmaps.GetWorkingBeatmap(score.Beatmap).OriginalBeatmap; + currentBeatmap = beatmaps.GetWorkingBeatmap(score.Beatmap).Beatmap; /* score.PlayerName = */ score.User = new User { Username = sr.ReadString() }; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs index e081897339..1146037004 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected override void LoadBeatmap(WorkingBeatmap beatmap) { base.LoadBeatmap(beatmap); - foreach (var breakPeriod in beatmap.OriginalBeatmap.Breaks) + foreach (var breakPeriod in beatmap.Beatmap.Breaks) Add(new BreakVisualisation(breakPeriod)); } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs index faf090bfd9..4bef22463e 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { base.LoadBeatmap(beatmap); - ControlPointInfo cpi = beatmap.OriginalBeatmap.ControlPointInfo; + ControlPointInfo cpi = beatmap.Beatmap.ControlPointInfo; cpi.TimingPoints.ForEach(addTimingPoint); diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index a9324e3fb0..adb749b492 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -47,7 +47,7 @@ namespace osu.Game.Screens.Edit { // TODO: should probably be done at a RulesetContainer level to share logic with Player. var sourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); - clock = new EditorClock(Beatmap.Value.OriginalBeatmap.ControlPointInfo, beatDivisor) { IsCoupled = false }; + clock = new EditorClock(Beatmap.Value.Beatmap.ControlPointInfo, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); dependencies.CacheAs(clock); diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index bbd50d8f1b..1f2cb915b3 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -87,7 +87,7 @@ namespace osu.Game.Screens.Menu private void updateAmplitudes() { var track = beatmap.Value.TrackLoaded ? beatmap.Value.Track : null; - var effect = beatmap.Value.BeatmapLoaded ? beatmap.Value.OriginalBeatmap.ControlPointInfo.EffectPointAt(track?.CurrentTime ?? Time.Current) : null; + var effect = beatmap.Value.BeatmapLoaded ? beatmap.Value.Beatmap.ControlPointInfo.EffectPointAt(track?.CurrentTime ?? Time.Current) : null; float[] temporalAmplitudes = track?.CurrentAmplitudes.FrequencyAmplitudes ?? new float[256]; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d39b28bf25..f397d0c3d4 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -97,7 +97,7 @@ namespace osu.Game.Screens.Play try { - beatmap = working.OriginalBeatmap; + beatmap = working.Beatmap; if (beatmap == null) throw new InvalidOperationException("Beatmap was not loaded"); diff --git a/osu.Game/Screens/Ranking/ResultsPageScore.cs b/osu.Game/Screens/Ranking/ResultsPageScore.cs index 862f77d219..42d8af07b9 100644 --- a/osu.Game/Screens/Ranking/ResultsPageScore.cs +++ b/osu.Game/Screens/Ranking/ResultsPageScore.cs @@ -88,7 +88,7 @@ namespace osu.Game.Screens.Ranking { RelativeSizeAxes = Axes.Both, Alpha = 0.5f, - Objects = Beatmap.OriginalBeatmap.HitObjects, + Objects = Beatmap.Beatmap.HitObjects, }, scoreCounter = new SlowScoreCounter(6) { diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 2dad5a9008..da82a49f51 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -210,7 +210,7 @@ namespace osu.Game.Screens.Select private InfoLabel[] getInfoLabels() { - var beatmap = working.OriginalBeatmap; + var beatmap = working.Beatmap; var info = working.BeatmapInfo; List labels = new List(); diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index 71893cfe37..37693c99e8 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tests.Beatmaps } private readonly IBeatmap beatmap; - protected override IBeatmap GetOriginalBeatmap() => beatmap; + protected override IBeatmap GetBeatmap() => beatmap; protected override Texture GetBackground() => null; protected override Track GetTrack() diff --git a/osu.Game/Tests/Visual/EditorClockTestCase.cs b/osu.Game/Tests/Visual/EditorClockTestCase.cs index c6a98a4f43..43b20f7021 100644 --- a/osu.Game/Tests/Visual/EditorClockTestCase.cs +++ b/osu.Game/Tests/Visual/EditorClockTestCase.cs @@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual private void beatmapChanged(WorkingBeatmap working) { - Clock.ControlPointInfo = working.OriginalBeatmap.ControlPointInfo; + Clock.ControlPointInfo = working.Beatmap.ControlPointInfo; Clock.ChangeSource((IAdjustableClock)working.Track ?? new StopwatchClock()); Clock.ProcessFrame(); } diff --git a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs index 5d78b95c04..51460ecb6d 100644 --- a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs +++ b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs @@ -250,7 +250,7 @@ namespace osu.Game.Tests.Visual return; lastRequest = new GetScoresRequest(newBeatmap.BeatmapInfo, newBeatmap.BeatmapInfo.Ruleset); - lastRequest.Success += res => res.Scores.ForEach(s => scores.Add(new PerformanceDisplay(s, newBeatmap.OriginalBeatmap))); + lastRequest.Success += res => res.Scores.ForEach(s => scores.Add(new PerformanceDisplay(s, newBeatmap.Beatmap))); api.Queue(lastRequest); } @@ -381,7 +381,7 @@ namespace osu.Game.Tests.Visual var allMods = ruleset.GetAllMods().ToList(); Mod[] activeMods = modFlow.Where(c => c.Current.Value).Select(c => allMods.First(m => m.ShortenedName == c.LabelText)).ToArray(); - var diffCalc = ruleset.CreateDifficultyCalculator(beatmap.OriginalBeatmap, activeMods); + var diffCalc = ruleset.CreateDifficultyCalculator(beatmap.Beatmap, activeMods); if (diffCalc != null) { var categories = new Dictionary(); From db3e48c194ed7a0838b3390dab7152cf37ecde84 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 10:40:30 +0900 Subject: [PATCH 050/229] Rename GetBeatmap() to GetPlayableBeatmap() --- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 15 +++++++++------ osu.Game/Rulesets/UI/RulesetContainer.cs | 2 +- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 2 +- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 71406c6034..400c877d6a 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -30,7 +30,7 @@ namespace osu.Game.Beatmaps this.audioManager = audioManager; } - protected override IBeatmap GetBeatmap() + protected override IBeatmap GetPlayableBeatmap() { try { diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index da52dc7284..2c9d83fe9e 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -40,7 +40,7 @@ namespace osu.Game.Beatmaps this.game = game; } - protected override IBeatmap GetBeatmap() => new Beatmap(); + protected override IBeatmap GetPlayableBeatmap() => new Beatmap(); protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4"); diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index e90df687e4..515b7c2051 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -57,7 +57,7 @@ namespace osu.Game.Beatmaps Process.Start(path); } - protected abstract IBeatmap GetBeatmap(); + protected abstract IBeatmap GetPlayableBeatmap(); protected abstract Texture GetBackground(); protected abstract Track GetTrack(); protected virtual Skin GetSkin() => new DefaultSkin(); @@ -71,7 +71,7 @@ namespace osu.Game.Beatmaps private IBeatmap populateBeatmap() { - var b = GetBeatmap() ?? new Beatmap(); + var b = GetPlayableBeatmap() ?? new Beatmap(); // use the database-backed info. b.BeatmapInfo = BeatmapInfo; @@ -80,13 +80,16 @@ namespace osu.Game.Beatmaps } /// - /// Retrieves the resulting from the conversion of to a specific . - /// All mods have been applied to the returned . + /// Constructs a playable from using the applicable converters for a specific . + /// + /// The returned is in a playable state - all and s + /// have been applied, and s have been fully constructed. + /// /// - /// The to convert to. + /// The to create a playable for. /// The converted . /// If could not be converted to . - public IBeatmap GetBeatmap(RulesetInfo ruleset) + public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset) { var rulesetInstance = ruleset.CreateInstance(); diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 3a2e66505a..e42e74c245 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -212,7 +212,7 @@ namespace osu.Game.Rulesets.UI RelativeSizeAxes = Axes.Both; - Beatmap = (Beatmap)workingBeatmap.GetBeatmap(ruleset.RulesetInfo); + Beatmap = (Beatmap)workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo); KeyBindingInputManager = CreateInputManager(); KeyBindingInputManager.RelativeSizeAxes = Axes.Both; diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index 37693c99e8..fbbe7d5284 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tests.Beatmaps } private readonly IBeatmap beatmap; - protected override IBeatmap GetBeatmap() => beatmap; + protected override IBeatmap GetPlayableBeatmap() => beatmap; protected override Texture GetBackground() => null; protected override Track GetTrack() From 794418432f53b9be47e3495307d0c6fd5a8f4345 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 11:22:25 +0900 Subject: [PATCH 051/229] Fix incorrect method name --- osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 4 ++-- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 400c877d6a..71406c6034 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -30,7 +30,7 @@ namespace osu.Game.Beatmaps this.audioManager = audioManager; } - protected override IBeatmap GetPlayableBeatmap() + protected override IBeatmap GetBeatmap() { try { diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 2c9d83fe9e..da52dc7284 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -40,7 +40,7 @@ namespace osu.Game.Beatmaps this.game = game; } - protected override IBeatmap GetPlayableBeatmap() => new Beatmap(); + protected override IBeatmap GetBeatmap() => new Beatmap(); protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4"); diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 515b7c2051..2a3eb05544 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -57,7 +57,7 @@ namespace osu.Game.Beatmaps Process.Start(path); } - protected abstract IBeatmap GetPlayableBeatmap(); + protected abstract IBeatmap GetBeatmap(); protected abstract Texture GetBackground(); protected abstract Track GetTrack(); protected virtual Skin GetSkin() => new DefaultSkin(); @@ -71,7 +71,7 @@ namespace osu.Game.Beatmaps private IBeatmap populateBeatmap() { - var b = GetPlayableBeatmap() ?? new Beatmap(); + var b = GetBeatmap() ?? new Beatmap(); // use the database-backed info. b.BeatmapInfo = BeatmapInfo; diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index fbbe7d5284..37693c99e8 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tests.Beatmaps } private readonly IBeatmap beatmap; - protected override IBeatmap GetPlayableBeatmap() => beatmap; + protected override IBeatmap GetBeatmap() => beatmap; protected override Texture GetBackground() => null; protected override Track GetTrack() From e20323b5f6408a3bc3e5ba230a7a6e14eec7b18d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 11:23:29 +0900 Subject: [PATCH 052/229] Trim whitespace --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs | 2 +- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index 3b22c47ac8..4a0b120e47 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps : base(beatmap) { } - + protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) }; protected override IEnumerable ConvertHitObject(HitObject obj, IBeatmap beatmap) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index acd289a9e8..c8a7402904 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps : base(beatmap) { IsForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(new ManiaRuleset().RulesetInfo); - + var roundedCircleSize = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.CircleSize); var roundedOverallDifficulty = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty); From 268c14813b826f706de133e96ab6f4129030e01c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 11:38:41 +0900 Subject: [PATCH 053/229] Fix resharper warnings --- osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs | 5 +---- osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs | 2 +- osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index e52fc11518..cf79feb16b 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -18,13 +18,10 @@ namespace osu.Game.Rulesets.Mania.Tests { protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; - private bool isForCurrentRuleset; - [NonParallelizable] [TestCase("basic", false)] - public void Test(string name, bool isForCurrentRuleset) + public new void Test(string name) { - this.isForCurrentRuleset = isForCurrentRuleset; base.Test(name); } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs index dce43f5bbb..ea33ec9ae0 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Osu.Edit { public class OsuEditRulesetContainer : OsuRulesetContainer { - public OsuEditRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) + public OsuEditRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) : base(ruleset, beatmap) { } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 7bf0651443..dce1fc2851 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Edit { } - protected override RulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => new OsuEditRulesetContainer(ruleset, beatmap, true); + protected override RulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => new OsuEditRulesetContainer(ruleset, beatmap); protected override IReadOnlyList CompositionTools => new ICompositionTool[] { From ad2c2a5fe6a3dbc17e1d2267506796ecc2f2f714 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 12:25:21 +0900 Subject: [PATCH 054/229] Restore star difficulty calculation --- osu.Game/Beatmaps/BeatmapManager.cs | 31 +++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 14436fce13..36fde8a319 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -9,7 +9,9 @@ using System.Linq.Expressions; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using osu.Framework.Audio; +using osu.Framework.Audio.Track; using osu.Framework.Extensions; +using osu.Framework.Graphics.Textures; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Beatmaps.Formats; @@ -341,9 +343,16 @@ namespace osu.Game.Beatmaps RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID); - // TODO: this should be done in a better place once we actually need to dynamically update it. beatmap.BeatmapInfo.Ruleset = ruleset; - beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance()?.CreateDifficultyCalculator(beatmap).Calculate() ?? 0; + + if (ruleset != null) + { + // TODO: this should be done in a better place once we actually need to dynamically update it. + var converted = new DummyConversionBeatmap(beatmap).GetPlayableBeatmap(ruleset); + beatmap.BeatmapInfo.StarDifficulty = ruleset.CreateInstance().CreateDifficultyCalculator(converted).Calculate(); + } + else + beatmap.BeatmapInfo.StarDifficulty = 0; beatmapInfos.Add(beatmap.BeatmapInfo); } @@ -351,5 +360,23 @@ namespace osu.Game.Beatmaps return beatmapInfos; } + + /// + /// A dummy WorkingBeatmap for the purpose of retrieving a beatmap for star difficulty calculation. + /// + private class DummyConversionBeatmap : WorkingBeatmap + { + private readonly IBeatmap beatmap; + + public DummyConversionBeatmap(IBeatmap beatmap) + : base(beatmap.BeatmapInfo) + { + this.beatmap = beatmap; + } + + protected override IBeatmap GetBeatmap() => beatmap; + protected override Texture GetBackground() => null; + protected override Track GetTrack() => null; + } } } From 7ee8228a37d31b8b3803328a38a5601c5aae08ec Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 13:28:01 +0900 Subject: [PATCH 055/229] Fix testcases --- osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs | 2 +- osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index cf79feb16b..95a23f65c5 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.Tests protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; [NonParallelizable] - [TestCase("basic", false)] + [TestCase("basic")] public new void Test(string name) { base.Test(name); diff --git a/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs index f67726c022..1bf24a46bc 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.Tests private Container playfieldContainer; [BackgroundDependencyLoader] - private void load(RulesetStore rulesets) + private void load() { AddStep("Hit!", () => addHitJudgement(false)); AddStep("Kiai hit", () => addHitJudgement(true)); @@ -73,6 +73,7 @@ namespace osu.Game.Rulesets.Taiko.Tests Title = @"Sample Beatmap", AuthorString = @"peppy", }, + Ruleset = new TaikoRuleset().RulesetInfo }, ControlPointInfo = controlPointInfo }); @@ -86,7 +87,7 @@ namespace osu.Game.Rulesets.Taiko.Tests RelativeSizeAxes = Axes.X, Height = 768, Clock = new FramedClock(rateAdjustClock), - Children = new[] { rulesetContainer = new TaikoRulesetContainer(rulesets.GetRuleset(1).CreateInstance(), beatmap) } + Children = new[] { rulesetContainer = new TaikoRulesetContainer(new TaikoRuleset(), beatmap) } }); } From 6867886f4c6bda3e43000c023b8fef7eccd80ec2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 14:04:37 +0900 Subject: [PATCH 056/229] Give conversion-tested beatmaps a ruleset --- .../CatchBeatmapConversionTest.cs | 6 +++++- .../ManiaBeatmapConversionTest.cs | 6 +++++- osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs | 6 +++++- .../TaikoBeatmapConversionTest.cs | 6 +++++- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 7 ++++++- 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index a94d29ca2c..d0d623178e 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -14,7 +14,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Catch.Tests { - public class CatchBeatmapConversionTest : BeatmapConversionTest + public class CatchBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Catch"; @@ -64,4 +64,8 @@ namespace osu.Game.Rulesets.Catch.Tests => Precision.AlmostEquals(StartTime, other.StartTime, conversion_lenience) && Precision.AlmostEquals(Position, other.Position, conversion_lenience); } + + public class TestCatchRuleset : CatchRuleset + { + } } diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index 95a23f65c5..f1ee874b88 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -14,7 +14,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Mania.Tests { - public class ManiaBeatmapConversionTest : BeatmapConversionTest + public class ManiaBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; @@ -54,4 +54,8 @@ namespace osu.Game.Rulesets.Mania.Tests && Precision.AlmostEquals(EndTime, other.EndTime, conversion_lenience) && Column == other.Column; } + + public class TestManiaRuleset : ManiaRuleset + { + } } diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index a8f82a112b..aa7de4ed01 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -15,7 +15,7 @@ using OpenTK; namespace osu.Game.Rulesets.Osu.Tests { - public class OsuBeatmapConversionTest : BeatmapConversionTest + public class OsuBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Osu"; @@ -67,4 +67,8 @@ namespace osu.Game.Rulesets.Osu.Tests && Precision.AlmostEquals(EndX, other.EndX, conversion_lenience) && Precision.AlmostEquals(EndY, other.EndY, conversion_lenience); } + + public class TestOsuRuleset : OsuRuleset + { + } } diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs index cbab53fa75..33a5e1772e 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -14,7 +14,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Taiko.Tests { - public class TaikoBeatmapConversionTest : BeatmapConversionTest + public class TaikoBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; @@ -67,4 +67,8 @@ namespace osu.Game.Rulesets.Taiko.Tests && IsSwell == other.IsSwell && IsStrong == other.IsStrong; } + + public class TestTaikoRuleset : TaikoRuleset + { + } } diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 735c0ef76c..2de38d49a9 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -10,12 +10,14 @@ using NUnit.Framework; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; +using osu.Game.Rulesets; using osu.Game.Rulesets.Objects; namespace osu.Game.Tests.Beatmaps { [TestFixture] - public abstract class BeatmapConversionTest + public abstract class BeatmapConversionTest + where TRuleset : Ruleset, new() where TConvertValue : IEquatable { private const string resource_namespace = "Testing.Beatmaps"; @@ -79,6 +81,9 @@ namespace osu.Game.Tests.Beatmaps { var beatmap = getBeatmap(name); + var rulesetInstance = new TRuleset(); + beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo(); + var result = new ConvertResult(); var converter = CreateConverter(beatmap); From 68441f1ef0b7770d3c3754f59024b184bd676a68 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 14:28:30 +0900 Subject: [PATCH 057/229] Output ruleset instantiation info --- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 2a3eb05544..9c389bbb8f 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -97,7 +97,7 @@ namespace osu.Game.Beatmaps // Check if the beatmap can be converted if (!converter.CanConvert) - throw new BeatmapInvalidForRulesetException($"{nameof(Beatmaps.Beatmap)} can not be converted for the ruleset (ruleset: {ruleset}, converter: {converter})."); + throw new BeatmapInvalidForRulesetException($"{nameof(Beatmaps.Beatmap)} can not be converted for the ruleset (ruleset: {ruleset.InstantiationInfo}, converter: {converter})."); // Apply conversion mods foreach (var mod in Mods.Value.OfType()) From 30a3f4f29f2ab4bbd6d6c260382cded231d8b490 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 15:27:45 +0900 Subject: [PATCH 058/229] Fix not being able to convert beatmaps with 0 hitobjects --- osu.Game/Beatmaps/BeatmapConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index 263a4c36ee..b7a454460f 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -32,7 +32,7 @@ namespace osu.Game.Beatmaps /// /// Whether can be converted by this . /// - public bool CanConvert => ValidConversionTypes.All(t => Beatmap.HitObjects.Any(t.IsInstanceOfType)); + public bool CanConvert => !Beatmap.HitObjects.Any() || ValidConversionTypes.All(t => Beatmap.HitObjects.Any(t.IsInstanceOfType)); /// /// Converts . From 9f1efeb19df1d3a9b1c43771ec28c36f0c0ba473 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 15:41:14 +0900 Subject: [PATCH 059/229] Move keybind to last in enum --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 2ae895785c..1658bb4e79 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -76,9 +76,9 @@ namespace osu.Game.Input.Bindings [Description("Quick Retry (Hold)")] QuickRetry, + [Description("Take screenshot")] + TakeScreenshot, [Description("Toggle gameplay mouse buttons")] ToggleGameplayMouseButtons, - [Description("Take screenshot")] - TakeScreenshot } } From 5489976c20cf5d7e15600c8d2f2a53e93f5c3af7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 10:51:17 +0900 Subject: [PATCH 060/229] Implement ruleset-specific beatmap statistics --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs | 45 +++++++++++++++++++ .../Beatmaps/OsuBeatmapConverter.cs | 2 + osu.Game.Rulesets.Osu/OsuRuleset.cs | 33 -------------- osu.Game/Beatmaps/Beatmap.cs | 8 ++++ osu.Game/Rulesets/Ruleset.cs | 2 - osu.Game/Screens/Select/BeatmapInfoWedge.cs | 4 +- 6 files changed, 57 insertions(+), 37 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs new file mode 100644 index 0000000000..68002f73b5 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs @@ -0,0 +1,45 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using System.Linq; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Osu.Objects; + +namespace osu.Game.Rulesets.Osu.Beatmaps +{ + public class OsuBeatmap : Beatmap + { + public override IEnumerable GetStatistics() + { + IEnumerable circles = HitObjects.Where(c => !(c is IHasEndTime)); + IEnumerable sliders = HitObjects.Where(s => s is IHasCurve); + IEnumerable spinners = HitObjects.Where(s => s is IHasEndTime && !(s is IHasCurve)); + + return new[] + { + new BeatmapStatistic + { + Name = @"Circle Count", + Content = circles.Count().ToString(), + Icon = FontAwesome.fa_circle_o + }, + new BeatmapStatistic + { + Name = @"Slider Count", + Content = sliders.Count().ToString(), + Icon = FontAwesome.fa_circle + }, + new BeatmapStatistic + { + Name = @"Spinner Count", + Content = spinners.Count().ToString(), + Icon = FontAwesome.fa_circle + } + }; + } + } +} diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs index 1cd4ec5668..5f3a909488 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs @@ -65,5 +65,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps }; } } + + protected override Beatmap CreateBeatmap() => new OsuBeatmap(); } } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 927ffa2146..69a54fb533 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -9,7 +9,6 @@ using osu.Game.Rulesets.Osu.OsuDifficulty; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; using System.Collections.Generic; -using System.Linq; using osu.Framework.Graphics; using osu.Game.Overlays.Settings; using osu.Framework.Input.Bindings; @@ -17,8 +16,6 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; @@ -40,36 +37,6 @@ namespace osu.Game.Rulesets.Osu new KeyBinding(InputKey.MouseRight, OsuAction.RightButton), }; - public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) - { - IEnumerable hitObjects = beatmap.Beatmap.HitObjects; - IEnumerable circles = hitObjects.Where(c => !(c is IHasEndTime)); - IEnumerable sliders = hitObjects.Where(s => s is IHasCurve); - IEnumerable spinners = hitObjects.Where(s => s is IHasEndTime && !(s is IHasCurve)); - - return new[] - { - new BeatmapStatistic - { - Name = @"Circle Count", - Content = circles.Count().ToString(), - Icon = FontAwesome.fa_circle_o - }, - new BeatmapStatistic - { - Name = @"Slider Count", - Content = sliders.Count().ToString(), - Icon = FontAwesome.fa_circle - }, - new BeatmapStatistic - { - Name = @"Spinner Count", - Content = spinners.Count().ToString(), - Icon = FontAwesome.fa_circle - } - }; - } - public override IEnumerable ConvertLegacyMods(LegacyMods mods) { if (mods.HasFlag(LegacyMods.Nightcore)) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 6a7d2690ff..e323dd0241 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -44,6 +44,12 @@ namespace osu.Game.Beatmaps /// IEnumerable HitObjects { get; } + /// + /// Returns statistics of the contained in this beatmap. + /// + /// + IEnumerable GetStatistics(); + /// /// Creates a shallow-clone of this beatmap and returns it. /// @@ -90,6 +96,8 @@ namespace osu.Game.Beatmaps IEnumerable IBeatmap.HitObjects => HitObjects; + public virtual IEnumerable GetStatistics() => Enumerable.Empty(); + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index d6d1d19628..6883d319f4 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -22,8 +22,6 @@ namespace osu.Game.Rulesets { public readonly RulesetInfo RulesetInfo; - public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { }; - public IEnumerable GetAllMods() => Enum.GetValues(typeof(ModType)).Cast() // Confine all mods of each mod type into a single IEnumerable .SelectMany(GetModsFor) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index da82a49f51..c0370763c0 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -234,8 +234,8 @@ namespace osu.Game.Screens.Select Content = getBPMRange(beatmap), })); - //get statistics from the current ruleset. - labels.AddRange(info.Ruleset.CreateInstance().GetBeatmapStatistics(working).Select(s => new InfoLabel(s))); + //get statistics for the current ruleset. + labels.AddRange(working.GetPlayableBeatmap(info.Ruleset).GetStatistics().Select(s => new InfoLabel(s))); } return labels.ToArray(); From accffda5321fb6314d18665eccdf285e703c0972 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 10:51:30 +0900 Subject: [PATCH 061/229] Add taiko statistics --- .../Beatmaps/TaikoBeatmap.cs | 49 +++++++++++++++++++ .../Beatmaps/TaikoBeatmapConverter.cs | 2 + 2 files changed, 51 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs new file mode 100644 index 0000000000..cbf2270c95 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs @@ -0,0 +1,49 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using System.Linq; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Rulesets.Taiko.Objects; + +namespace osu.Game.Rulesets.Taiko.Beatmaps +{ + public class TaikoBeatmap : Beatmap + { + public override IEnumerable GetStatistics() + { + int drumrolls = HitObjects.Count(s => s is DrumRoll); + int swells = HitObjects.Count(s => s is Swell); + int notes = HitObjects.Count - drumrolls - swells; + + return new[] + { + new BeatmapStatistic + { + Name = @"Object Count", + Content = HitObjects.Count.ToString(), + Icon = FontAwesome.fa_circle + }, + new BeatmapStatistic + { + Name = @"Note Count", + Content = notes.ToString(), + Icon = FontAwesome.fa_circle_o + }, + new BeatmapStatistic + { + Name = @"Drumroll Count", + Content = drumrolls.ToString(), + Icon = FontAwesome.fa_circle + }, + new BeatmapStatistic + { + Name = @"Swell Count", + Content = swells.ToString(), + Icon = FontAwesome.fa_circle + } + }; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index eeb0fa1871..d40e8dc643 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -197,5 +197,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps } } } + + protected override Beatmap CreateBeatmap() => new TaikoBeatmap(); } } From 8a4717d2e9e84875f14f02f318020f8f6949d1cf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 10:57:01 +0900 Subject: [PATCH 062/229] Add catch statistics --- .../Beatmaps/CatchBeatmap.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs new file mode 100644 index 0000000000..1b65a70207 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs @@ -0,0 +1,49 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using System.Linq; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Rulesets.Catch.Objects; + +namespace osu.Game.Rulesets.Catch.Beatmaps +{ + public class CatchBeatmap : Beatmap + { + public override IEnumerable GetStatistics() + { + int juiceStreams = HitObjects.Count(s => s is JuiceStream); + int bananaShowers = HitObjects.Count(s => s is BananaShower); + int fruits = HitObjects.Count - juiceStreams - bananaShowers; + + return new[] + { + new BeatmapStatistic + { + Name = @"Object Count", + Content = HitObjects.Count.ToString(), + Icon = FontAwesome.fa_circle + }, + new BeatmapStatistic + { + Name = @"Fruit Count", + Content = fruits.ToString(), + Icon = FontAwesome.fa_circle_o + }, + new BeatmapStatistic + { + Name = @"Juice Stream Count", + Content = juiceStreams.ToString(), + Icon = FontAwesome.fa_circle + }, + new BeatmapStatistic + { + Name = @"Banana Shower Count", + Content = bananaShowers.ToString(), + Icon = FontAwesome.fa_circle + } + }; + } + } +} From b737644208e0008eae06bdbe3a03b5ff9a527d1a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 10:58:56 +0900 Subject: [PATCH 063/229] Add mania statistics --- .../Beatmaps/ManiaBeatmap.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs index 6af3719f83..22cc57d924 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using osu.Game.Beatmaps; +using osu.Game.Graphics; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.UI; @@ -29,5 +30,33 @@ namespace osu.Game.Rulesets.Mania.Beatmaps { Stages.Add(defaultStage); } + + public override IEnumerable GetStatistics() + { + int holdnotes = HitObjects.Count(s => s is HoldNote); + int notes = HitObjects.Count - holdnotes; + + return new[] + { + new BeatmapStatistic + { + Name = @"Object Count", + Content = HitObjects.Count.ToString(), + Icon = FontAwesome.fa_circle + }, + new BeatmapStatistic + { + Name = @"Note Count", + Content = notes.ToString(), + Icon = FontAwesome.fa_circle_o + }, + new BeatmapStatistic + { + Name = @"Hold Note Count", + Content = holdnotes.ToString(), + Icon = FontAwesome.fa_circle + }, + }; + } } } From 5f74dc2c1746dec30ead8270bf58c1635146653d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 10:59:30 +0900 Subject: [PATCH 064/229] Simplify osu-ruleset statistics --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs index 68002f73b5..7b534deccf 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs @@ -6,7 +6,6 @@ using System.Linq; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Rulesets.Osu.Beatmaps @@ -15,9 +14,9 @@ namespace osu.Game.Rulesets.Osu.Beatmaps { public override IEnumerable GetStatistics() { - IEnumerable circles = HitObjects.Where(c => !(c is IHasEndTime)); - IEnumerable sliders = HitObjects.Where(s => s is IHasCurve); - IEnumerable spinners = HitObjects.Where(s => s is IHasEndTime && !(s is IHasCurve)); + IEnumerable circles = HitObjects.Where(c => c is HitCircle); + IEnumerable sliders = HitObjects.Where(s => s is Slider); + IEnumerable spinners = HitObjects.Where(s => s is Spinner); return new[] { From b9e4b59e46ff589a864de4da71b1fc504a1f95c0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 11:01:09 +0900 Subject: [PATCH 065/229] Actually construct catch beatmaps --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index 4a0b120e47..f40ef67dfb 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -69,5 +69,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps X = positionData.X / CatchPlayfield.BASE_WIDTH }; } + + protected override Beatmap CreateBeatmap() => new CatchBeatmap(); } } From 7eb64ab590ccd828a04328b5b61818e544cb48be Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 11:33:05 +0900 Subject: [PATCH 066/229] Remove object counts from mania/taiko/catch --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs | 8 +------- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs | 8 +------- osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs | 12 +++--------- 3 files changed, 5 insertions(+), 23 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs index 1b65a70207..5b4af6ea8a 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs @@ -13,18 +13,12 @@ namespace osu.Game.Rulesets.Catch.Beatmaps { public override IEnumerable GetStatistics() { + int fruits = HitObjects.Count(s => s is Fruit); int juiceStreams = HitObjects.Count(s => s is JuiceStream); int bananaShowers = HitObjects.Count(s => s is BananaShower); - int fruits = HitObjects.Count - juiceStreams - bananaShowers; return new[] { - new BeatmapStatistic - { - Name = @"Object Count", - Content = HitObjects.Count.ToString(), - Icon = FontAwesome.fa_circle - }, new BeatmapStatistic { Name = @"Fruit Count", diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs index 22cc57d924..ad5f8e447d 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs @@ -33,17 +33,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps public override IEnumerable GetStatistics() { + int notes = HitObjects.Count(s => s is Note); int holdnotes = HitObjects.Count(s => s is HoldNote); - int notes = HitObjects.Count - holdnotes; return new[] { - new BeatmapStatistic - { - Name = @"Object Count", - Content = HitObjects.Count.ToString(), - Icon = FontAwesome.fa_circle - }, new BeatmapStatistic { Name = @"Note Count", diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs index cbf2270c95..36f6df7869 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs @@ -13,22 +13,16 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps { public override IEnumerable GetStatistics() { + int hits = HitObjects.Count(s => s is Hit); int drumrolls = HitObjects.Count(s => s is DrumRoll); int swells = HitObjects.Count(s => s is Swell); - int notes = HitObjects.Count - drumrolls - swells; return new[] { new BeatmapStatistic { - Name = @"Object Count", - Content = HitObjects.Count.ToString(), - Icon = FontAwesome.fa_circle - }, - new BeatmapStatistic - { - Name = @"Note Count", - Content = notes.ToString(), + Name = @"Hit Count", + Content = hits.ToString(), Icon = FontAwesome.fa_circle_o }, new BeatmapStatistic From 251bdfdee8c0232235b8de4f25620ca270946fd6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 11:33:15 +0900 Subject: [PATCH 067/229] Simplify statistics in osu ruleset --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs index 7b534deccf..6d90c2a875 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Linq; using osu.Game.Beatmaps; using osu.Game.Graphics; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Rulesets.Osu.Beatmaps @@ -14,28 +13,28 @@ namespace osu.Game.Rulesets.Osu.Beatmaps { public override IEnumerable GetStatistics() { - IEnumerable circles = HitObjects.Where(c => c is HitCircle); - IEnumerable sliders = HitObjects.Where(s => s is Slider); - IEnumerable spinners = HitObjects.Where(s => s is Spinner); + int circles = HitObjects.Count(c => c is HitCircle); + int sliders = HitObjects.Count(s => s is Slider); + int spinners = HitObjects.Count(s => s is Spinner); return new[] { new BeatmapStatistic { Name = @"Circle Count", - Content = circles.Count().ToString(), + Content = circles.ToString(), Icon = FontAwesome.fa_circle_o }, new BeatmapStatistic { Name = @"Slider Count", - Content = sliders.Count().ToString(), + Content = sliders.ToString(), Icon = FontAwesome.fa_circle }, new BeatmapStatistic { Name = @"Spinner Count", - Content = spinners.Count().ToString(), + Content = spinners.ToString(), Icon = FontAwesome.fa_circle } }; From 6a9f139d9b1fb1fb89a3ef93687e5ef8ae85507b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 11:33:40 +0900 Subject: [PATCH 068/229] Instantiate convertible hitobjects for beatmap info wedge --- osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index efd6c36ce2..a618e44301 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -13,6 +13,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Select; using osu.Game.Tests.Beatmaps; @@ -138,7 +139,7 @@ namespace osu.Game.Tests.Visual { List objects = new List(); for (double i = 0; i < 50000; i += 1000) - objects.Add(new HitObject { StartTime = i }); + objects.Add(new TestHitObject { StartTime = i }); return new Beatmap { @@ -153,7 +154,8 @@ namespace osu.Game.Tests.Visual }, Ruleset = ruleset, StarDifficulty = 6, - Version = $"{ruleset.ShortName}Version" + Version = $"{ruleset.ShortName}Version", + BaseDifficulty = new BeatmapDifficulty() }, HitObjects = objects }; @@ -163,5 +165,12 @@ namespace osu.Game.Tests.Visual { public new BufferedWedgeInfo Info => base.Info; } + + private class TestHitObject : HitObject, IHasPosition + { + public float X { get; } = 0; + public float Y { get; } = 0; + public Vector2 Position { get; } = Vector2.Zero; + } } } From 09c70a93625d4bf3b2f6318b95014a55d0d27f49 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 11:36:51 +0900 Subject: [PATCH 069/229] Add info label tests to TestCaseBeatmapInfoWedge --- .../Visual/TestCaseBeatmapInfoWedge.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index a618e44301..0d3e08154f 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -12,9 +12,12 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets; +using osu.Game.Rulesets.Catch; +using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Taiko; using osu.Game.Screens.Select; using osu.Game.Tests.Beatmaps; @@ -73,13 +76,23 @@ namespace osu.Game.Tests.Visual selectBeatmap(testBeatmap); + testBeatmapLabels(ruleset); + // TODO: adjust cases once more info is shown for other gamemodes switch (ruleset) { - case OsuRuleset osu: - testOsuBeatmap(osu); + case OsuRuleset _: testInfoLabels(5); break; + case TaikoRuleset _: + testInfoLabels(5); + break; + case CatchRuleset _: + testInfoLabels(5); + break; + case ManiaRuleset _: + testInfoLabels(4); + break; default: testInfoLabels(2); break; @@ -89,7 +102,7 @@ namespace osu.Game.Tests.Visual testNullBeatmap(); } - private void testOsuBeatmap(OsuRuleset ruleset) + private void testBeatmapLabels(Ruleset ruleset) { AddAssert("check version", () => infoWedge.Info.VersionLabel.Text == $"{ruleset.ShortName}Version"); AddAssert("check title", () => infoWedge.Info.TitleLabel.Text == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title"); From fbd7ccc03fa732e3d6e4276f75c999538b14097f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 11:59:17 +0900 Subject: [PATCH 070/229] Make BeatmapInfoWedge display properly for converts --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 49 ++++++++++++++++++--- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index c0370763c0..7a8a04bd43 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -4,9 +4,11 @@ using System; using System.Collections.Generic; using System.Linq; +using JetBrains.Annotations; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; @@ -21,6 +23,8 @@ using osu.Game.Rulesets.Objects.Types; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Cursor; using osu.Framework.Localisation; +using osu.Game.Rulesets; +using osu.Game.Rulesets.UI; namespace osu.Game.Screens.Select { @@ -28,6 +32,8 @@ namespace osu.Game.Screens.Select { private static readonly Vector2 wedged_container_shear = new Vector2(0.15f, 0); + private readonly IBindable ruleset = new Bindable(); + protected BufferedWedgeInfo Info; public BeatmapInfoWedge() @@ -46,6 +52,14 @@ namespace osu.Game.Screens.Select }; } + [BackgroundDependencyLoader(true)] + private void load([CanBeNull] OsuGame osuGame) + { + if (osuGame != null) + ruleset.BindTo(osuGame.Ruleset); + ruleset.ValueChanged += updateRuleset; + } + protected override bool BlockPassThroughMouse => false; protected override void PopIn() @@ -62,7 +76,17 @@ namespace osu.Game.Screens.Select this.FadeOut(500, Easing.In); } + private WorkingBeatmap beatmap; + public void UpdateBeatmap(WorkingBeatmap beatmap) + { + this.beatmap = beatmap; + loadBeatmap(); + } + + private void updateRuleset(RulesetInfo ruleset) => loadBeatmap(); + + private void loadBeatmap() { LoadComponentAsync(new BufferedWedgeInfo(beatmap) { @@ -90,14 +114,18 @@ namespace osu.Game.Screens.Select private UnicodeBindableString titleBinding; private UnicodeBindableString artistBinding; + private RulesetInfo ruleset; + public BufferedWedgeInfo(WorkingBeatmap working) { this.working = working; } - [BackgroundDependencyLoader] - private void load(LocalisationEngine localisation) + [BackgroundDependencyLoader(true)] + private void load([NotNull] LocalisationEngine localisation, [CanBeNull] OsuGame osuGame) { + ruleset = osuGame?.Ruleset.Value ?? working.BeatmapInfo.Ruleset; + var beatmapInfo = working.BeatmapInfo; var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); @@ -211,7 +239,6 @@ namespace osu.Game.Screens.Select private InfoLabel[] getInfoLabels() { var beatmap = working.Beatmap; - var info = working.BeatmapInfo; List labels = new List(); @@ -234,8 +261,20 @@ namespace osu.Game.Screens.Select Content = getBPMRange(beatmap), })); - //get statistics for the current ruleset. - labels.AddRange(working.GetPlayableBeatmap(info.Ruleset).GetStatistics().Select(s => new InfoLabel(s))); + IBeatmap playableBeatmap; + + try + { + // Try to get the beatmap with the user's ruleset + playableBeatmap = working.GetPlayableBeatmap(ruleset); + } + catch (BeatmapInvalidForRulesetException) + { + // Can't be converted to the user's ruleset, so use the beatmap's own ruleset + playableBeatmap = working.GetPlayableBeatmap(working.BeatmapInfo.Ruleset); + } + + labels.AddRange(playableBeatmap.GetStatistics().Select(s => new InfoLabel(s))); } return labels.ToArray(); From 674e45d49bb751eef903f7264e05563fa463b23e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 7 May 2018 16:32:15 +0900 Subject: [PATCH 071/229] Fix beatmap/ruleset being changeable while in the editor --- osu.Game/Screens/Edit/Editor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index adb749b492..e4eaee76fc 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -27,6 +27,7 @@ namespace osu.Game.Screens.Edit protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4"); public override bool ShowOverlaysOnEnter => false; + public override bool AllowBeatmapRulesetChange => false; private Box bottomBackground; private Container screenContainer; From c2979a5c48de6b07318bd8c91ecf89d0922d6326 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 May 2018 22:08:45 +0900 Subject: [PATCH 072/229] Update CodeFileSanity --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 15484e4c68..69bc762f4c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,7 +11,7 @@ install: - cmd: git submodule update --init --recursive --depth=5 - cmd: choco install resharper-clt -y - cmd: choco install nvika -y - - cmd: appveyor DownloadFile https://github.com/peppy/CodeFileSanity/releases/download/v0.2.4/CodeFileSanity.exe + - cmd: appveyor DownloadFile https://github.com/peppy/CodeFileSanity/releases/download/v0.2.5/CodeFileSanity.exe before_build: - cmd: CodeFileSanity.exe - cmd: nuget restore -verbosity quiet From 44bbb8700ecc1bdd652c35766bfbaa54310a5855 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Tue, 8 May 2018 00:22:11 +0300 Subject: [PATCH 073/229] Handle mouse back button using OnMouseDown override instead of using GlobalAction --- .../Input/Bindings/GlobalActionContainer.cs | 10 +---- osu.Game/Screens/Loader.cs | 1 + osu.Game/Screens/Menu/ButtonSystem.cs | 44 +++++++------------ osu.Game/Screens/Menu/MainMenu.cs | 1 + osu.Game/Screens/OsuScreen.cs | 28 ++++++++---- osu.Game/Screens/Play/PlayerLoader.cs | 1 - .../Play/ScreenWithBeatmapBackground.cs | 2 + 7 files changed, 43 insertions(+), 44 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 565d530395..dd8f00f6cd 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Input.Bindings { new KeyBinding(InputKey.F8, GlobalAction.ToggleChat), new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial), - new KeyBinding(InputKey.F12, GlobalAction.TakeScreenshot), + new KeyBinding(InputKey.F12,GlobalAction.TakeScreenshot), new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings), new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar), @@ -36,9 +36,6 @@ namespace osu.Game.Input.Bindings new KeyBinding(InputKey.Down, GlobalAction.DecreaseVolume), new KeyBinding(InputKey.MouseWheelDown, GlobalAction.DecreaseVolume), new KeyBinding(InputKey.F4, GlobalAction.ToggleMute), - - new KeyBinding(InputKey.Escape, GlobalAction.Back), - new KeyBinding(InputKey.MouseButton1, GlobalAction.Back) }; public IEnumerable InGameKeyBindings => new[] @@ -79,9 +76,6 @@ namespace osu.Game.Input.Bindings QuickRetry, [Description("Take screenshot")] - TakeScreenshot, - - [Description("Go back")] - Back + TakeScreenshot } } diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index 1d152361df..dc8dbb4421 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -18,6 +18,7 @@ namespace osu.Game.Screens private bool showDisclaimer; public override bool ShowOverlaysOnEnter => false; + protected override bool AllowBackButton => false; public Loader() { diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 8cf0d24f7d..5a1dafe404 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -13,17 +13,15 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input; -using osu.Framework.Input.Bindings; using osu.Framework.Threading; using osu.Game.Graphics; -using osu.Game.Input.Bindings; using OpenTK; using OpenTK.Graphics; using OpenTK.Input; namespace osu.Game.Screens.Menu { - public class ButtonSystem : Container, IStateful, IKeyBindingHandler + public class ButtonSystem : Container, IStateful { public event Action StateChanged; @@ -148,43 +146,35 @@ namespace osu.Game.Screens.Menu case Key.Space: logo?.TriggerOnClick(state); return true; + case Key.Escape: + return handleBack(); } return false; } - public bool OnPressed(GlobalAction action) + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - switch (action) - { - case GlobalAction.Back: - switch (State) - { - case MenuState.TopLevel: - State = MenuState.Initial; - return true; - case MenuState.Play: - backButton.TriggerOnClick(); - return true; - default: - return false; - } - default: - return false; - } + if (state.Mouse.IsPressed(MouseButton.Button1)) + return handleBack(); + + return base.OnMouseDown(state, args); } - public bool OnReleased(GlobalAction action) + private bool handleBack() { - switch (action) + switch (State) { - case GlobalAction.Back: + case MenuState.TopLevel: + State = MenuState.Initial; + return true; + case MenuState.Play: + backButton.TriggerOnClick(); return true; - default: - return false; } - } + return false; + } private void onPlay() { diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index f2ea6d85a8..d91ac099fd 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -25,6 +25,7 @@ namespace osu.Game.Screens.Menu private readonly ButtonSystem buttons; public override bool ShowOverlaysOnEnter => buttons.State != MenuState.Initial; + protected override bool AllowBackButton => false; private readonly BackgroundScreenDefault background; private Screen songSelect; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index fb5d3d12e6..9fa30181a1 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -7,18 +7,18 @@ using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Input.Bindings; +using osu.Framework.Input; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; -using osu.Game.Input.Bindings; using osu.Game.Rulesets; using osu.Game.Screens.Menu; using OpenTK; +using OpenTK.Input; namespace osu.Game.Screens { - public abstract class OsuScreen : Screen, IKeyBindingHandler + public abstract class OsuScreen : Screen { public BackgroundScreen Background { get; private set; } @@ -92,19 +92,31 @@ namespace osu.Game.Screens sampleExit = audio.Sample.Get(@"UI/screen-back"); } - public bool OnPressed(GlobalAction action) + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { - if (action == GlobalAction.Back && AllowBackButton) + if (args.Repeat || !IsCurrentScreen) return false; + + switch (args.Key) + { + case Key.Escape: + Exit(); + return true; + } + + return base.OnKeyDown(state, args); + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + if (AllowBackButton && state.Mouse.IsPressed(MouseButton.Button1)) { Exit(); return true; } - return false; + return base.OnMouseDown(state, args); } - public bool OnReleased(GlobalAction action) => action == GlobalAction.Back && AllowBackButton; - protected override void OnResuming(Screen last) { sampleExit?.Play(); diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 6eb156914e..56fbd7b6e7 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -27,7 +27,6 @@ namespace osu.Game.Screens.Play private bool showOverlays = true; public override bool ShowOverlaysOnEnter => showOverlays; - protected override bool AllowBackButton => false; private Task loadTask; diff --git a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs index 1ccc5e2fe8..30ae6db346 100644 --- a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs +++ b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs @@ -17,6 +17,8 @@ namespace osu.Game.Screens.Play public override bool AllowBeatmapRulesetChange => false; + protected override bool AllowBackButton => false; + protected const float BACKGROUND_FADE_DURATION = 800; protected float BackgroundOpacity => 1 - (float)DimLevel; From c7bc79bce34a9c7f46f738b19d93b80cfbf2dcb4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 9 May 2018 12:40:04 +0900 Subject: [PATCH 074/229] Remove explicit clock in TestCaseBreakOverlay --- osu.Game.Tests/Visual/TestCaseBreakOverlay.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBreakOverlay.cs b/osu.Game.Tests/Visual/TestCaseBreakOverlay.cs index a6a6130a8f..442ca1322a 100644 --- a/osu.Game.Tests/Visual/TestCaseBreakOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseBreakOverlay.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Timing; using osu.Game.Beatmaps.Timing; using System.Collections.Generic; using NUnit.Framework; @@ -16,8 +15,6 @@ namespace osu.Game.Tests.Visual public TestCaseBreakOverlay() { - Clock = new FramedClock(); - Child = breakOverlay = new BreakOverlay(true); AddStep("2s break", () => startBreak(2000)); From 5df9f126d162ea33a8eb1af68746ec5291d4f21d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 10 May 2018 17:07:19 +0900 Subject: [PATCH 075/229] Implement a hold-to-confirm screen when exiting game using escape key --- osu.Game/Overlays/HoldToConfirmOverlay.cs | 59 +++++++++++++++++++++ osu.Game/Screens/Menu/ExitConfirmOverlay.cs | 34 ++++++++++++ osu.Game/Screens/Menu/MainMenu.cs | 4 ++ osu.Game/Screens/Play/HotkeyRetryOverlay.cs | 49 ++--------------- 4 files changed, 101 insertions(+), 45 deletions(-) create mode 100644 osu.Game/Overlays/HoldToConfirmOverlay.cs create mode 100644 osu.Game/Screens/Menu/ExitConfirmOverlay.cs diff --git a/osu.Game/Overlays/HoldToConfirmOverlay.cs b/osu.Game/Overlays/HoldToConfirmOverlay.cs new file mode 100644 index 0000000000..4bc7154ce8 --- /dev/null +++ b/osu.Game/Overlays/HoldToConfirmOverlay.cs @@ -0,0 +1,59 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using OpenTK.Graphics; + +namespace osu.Game.Overlays +{ + /// + /// An overlay which will display a black screen that dims over a period before confirming an exit action. + /// Action is BYO (derived class will need to call and from a user event). + /// + public abstract class HoldToConfirmOverlay : Container + { + public Action Action; + + private Box overlay; + + private const int activate_delay = 400; + private const int fadeout_delay = 200; + + private bool fired; + + [BackgroundDependencyLoader] + private void load() + { + RelativeSizeAxes = Axes.Both; + AlwaysPresent = true; + + Children = new Drawable[] + { + overlay = new Box + { + Alpha = 0, + Colour = Color4.Black, + RelativeSizeAxes = Axes.Both, + } + }; + } + + protected void BeginConfirm() => overlay.FadeIn(activate_delay, Easing.Out); + + protected void AbortConfirm() => overlay.FadeOut(fadeout_delay, Easing.Out); + + protected override void Update() + { + base.Update(); + if (!fired && overlay.Alpha == 1) + { + fired = true; + Action?.Invoke(); + } + } + } +} diff --git a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs new file mode 100644 index 0000000000..62605da5a4 --- /dev/null +++ b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs @@ -0,0 +1,34 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Input; +using osu.Game.Overlays; +using OpenTK.Input; + +namespace osu.Game.Screens.Menu +{ + public class ExitConfirmOverlay : HoldToConfirmOverlay + { + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (args.Key == Key.Escape && !args.Repeat) + { + BeginConfirm(); + return true; + } + + return base.OnKeyDown(state, args); + } + + protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) + { + if (args.Key == Key.Escape) + { + AbortConfirm(); + return true; + } + + return base.OnKeyUp(state, args); + } + } +} diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index f2ea6d85a8..ce5aace50b 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -39,6 +39,10 @@ namespace osu.Game.Screens.Menu Children = new Drawable[] { + new ExitConfirmOverlay + { + Action = Exit, + }, new ParallaxContainer { ParallaxAmount = 0.01f, diff --git a/osu.Game/Screens/Play/HotkeyRetryOverlay.cs b/osu.Game/Screens/Play/HotkeyRetryOverlay.cs index a018a2697a..926a96eb6c 100644 --- a/osu.Game/Screens/Play/HotkeyRetryOverlay.cs +++ b/osu.Game/Screens/Play/HotkeyRetryOverlay.cs @@ -1,50 +1,19 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Allocation; -using System; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Bindings; using osu.Game.Input.Bindings; -using OpenTK.Graphics; +using osu.Game.Overlays; namespace osu.Game.Screens.Play { - public class HotkeyRetryOverlay : Container, IKeyBindingHandler + public class HotkeyRetryOverlay : HoldToConfirmOverlay, IKeyBindingHandler { - public Action Action; - - private Box overlay; - - private const int activate_delay = 400; - private const int fadeout_delay = 200; - - private bool fired; - - [BackgroundDependencyLoader] - private void load() - { - RelativeSizeAxes = Axes.Both; - AlwaysPresent = true; - - Children = new Drawable[] - { - overlay = new Box - { - Alpha = 0, - Colour = Color4.Black, - RelativeSizeAxes = Axes.Both, - } - }; - } - public bool OnPressed(GlobalAction action) { if (action != GlobalAction.QuickRetry) return false; - overlay.FadeIn(activate_delay, Easing.Out); + BeginConfirm(); return true; } @@ -52,18 +21,8 @@ namespace osu.Game.Screens.Play { if (action != GlobalAction.QuickRetry) return false; - overlay.FadeOut(fadeout_delay, Easing.Out); + AbortConfirm(); return true; } - - protected override void Update() - { - base.Update(); - if (!fired && overlay.Alpha == 1) - { - fired = true; - Action?.Invoke(); - } - } } } From 63e10ec3c2d2844e13e7e2b47b86984be5e4547a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 10 May 2018 17:10:42 +0900 Subject: [PATCH 076/229] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 96ef8c43b5..e793a08417 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 96ef8c43b5e6b6ae14b01c3550c480c8d9a78518 +Subproject commit e793a084177f53920645c4f6f70cfef91e7fd19e From fadb1a5e0b44c85b2ff132aa0ab91b9c34285621 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 10 May 2018 17:30:24 +0900 Subject: [PATCH 077/229] Add tests and expand functionality to ensure single fire --- .../Visual/TestCaseHoldToConfirmOverlay.cs | 62 +++++++++++++++++++ osu.Game/Overlays/HoldToConfirmOverlay.cs | 25 +++++--- 2 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseHoldToConfirmOverlay.cs diff --git a/osu.Game.Tests/Visual/TestCaseHoldToConfirmOverlay.cs b/osu.Game.Tests/Visual/TestCaseHoldToConfirmOverlay.cs new file mode 100644 index 0000000000..ef6f44b42e --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseHoldToConfirmOverlay.cs @@ -0,0 +1,62 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Screens.Menu; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseHoldToConfirmOverlay : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] { typeof(ExitConfirmOverlay) }; + + public TestCaseHoldToConfirmOverlay() + { + bool fired = false; + + var abortText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = "Aborted!", + TextSize = 50, + Alpha = 0, + }; + + var overlay = new TestHoldToConfirmOverlay + { + Action = () => + { + fired = true; + abortText.FadeTo(1).Then().FadeOut(1000); + } + }; + + Children = new Drawable[] + { + overlay, + abortText + }; + + AddStep("start confirming", () => overlay.Begin()); + AddStep("abort confirming", () => overlay.Abort()); + + AddAssert("ensure aborted", () => !fired); + + AddStep("start confirming", () => overlay.Begin()); + + AddUntilStep(() => fired, "wait until confirmed"); + } + + private class TestHoldToConfirmOverlay : ExitConfirmOverlay + { + protected override bool AllowMultipleFires => true; + + public void Begin() => BeginConfirm(); + public void Abort() => AbortConfirm(); + } + } +} diff --git a/osu.Game/Overlays/HoldToConfirmOverlay.cs b/osu.Game/Overlays/HoldToConfirmOverlay.cs index 4bc7154ce8..a0e4bf1a39 100644 --- a/osu.Game/Overlays/HoldToConfirmOverlay.cs +++ b/osu.Game/Overlays/HoldToConfirmOverlay.cs @@ -25,6 +25,11 @@ namespace osu.Game.Overlays private bool fired; + /// + /// Whether the overlay should be allowed to return from a fired state. + /// + protected virtual bool AllowMultipleFires => false; + [BackgroundDependencyLoader] private void load() { @@ -42,18 +47,20 @@ namespace osu.Game.Overlays }; } - protected void BeginConfirm() => overlay.FadeIn(activate_delay, Easing.Out); - - protected void AbortConfirm() => overlay.FadeOut(fadeout_delay, Easing.Out); - - protected override void Update() + protected void BeginConfirm() { - base.Update(); - if (!fired && overlay.Alpha == 1) + if (!AllowMultipleFires && fired) return; + overlay.FadeIn(activate_delay * (1 - overlay.Alpha), Easing.Out).OnComplete(_ => { - fired = true; Action?.Invoke(); - } + fired = true; + }); + } + + protected void AbortConfirm() + { + if (!AllowMultipleFires && fired) return; + overlay.FadeOut(fadeout_delay, Easing.Out); } } } From c7443e6b3b5a19795e3b7c38f235b9e9e90c5989 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 10 May 2018 17:10:42 +0900 Subject: [PATCH 078/229] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 96ef8c43b5..e793a08417 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 96ef8c43b5e6b6ae14b01c3550c480c8d9a78518 +Subproject commit e793a084177f53920645c4f6f70cfef91e7fd19e From c03ab9014f1eb2276ec9057bdd1b1a608add5d03 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 10 May 2018 15:49:37 +0900 Subject: [PATCH 079/229] Improve TestCaseOnScreenDisplay Now doesn't rely on framesync. --- .../Visual/TestCaseOnScreenDisplay.cs | 104 +++++++++++++----- osu.Game/Overlays/OnScreenDisplay.cs | 23 ++-- 2 files changed, 90 insertions(+), 37 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseOnScreenDisplay.cs b/osu.Game.Tests/Visual/TestCaseOnScreenDisplay.cs index 233c418d4a..123c1fe055 100644 --- a/osu.Game.Tests/Visual/TestCaseOnScreenDisplay.cs +++ b/osu.Game.Tests/Visual/TestCaseOnScreenDisplay.cs @@ -4,6 +4,8 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Framework.Configuration.Tracking; +using osu.Framework.Graphics; using osu.Game.Overlays; namespace osu.Game.Tests.Visual @@ -11,36 +13,82 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseOnScreenDisplay : OsuTestCase { - private FrameworkConfigManager config; - private Bindable frameSyncMode; - - protected override void LoadComplete() - { - base.LoadComplete(); - - Add(new OnScreenDisplay()); - - frameSyncMode = config.GetBindable(FrameworkSetting.FrameSync); - - FrameSync initial = frameSyncMode.Value; - - AddRepeatStep(@"Change frame limiter", setNextMode, 3); - - AddStep(@"Restore frame limiter", () => frameSyncMode.Value = initial); - } - - private void setNextMode() - { - var nextMode = frameSyncMode.Value + 1; - if (nextMode > FrameSync.Unlimited) - nextMode = FrameSync.VSync; - frameSyncMode.Value = nextMode; - } - [BackgroundDependencyLoader] - private void load(FrameworkConfigManager config) + private void load() { - this.config = config; + var config = new TestConfigManager(); + + var osd = new TestOnScreenDisplay(); + osd.BeginTracking(this, config); + Add(osd); + + AddRepeatStep("Change toggle (no bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingNoKeybind), 2); + AddRepeatStep("Change toggle (with bind)", () => config.ToggleSetting(TestConfigSetting.ToggleSettingWithKeybind), 2); + AddRepeatStep("Change enum (no bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingNoKeybind), 3); + AddRepeatStep("Change enum (with bind)", () => config.IncrementEnumSetting(TestConfigSetting.EnumSettingWithKeybind), 3); + } + + private class TestConfigManager : ConfigManager + { + public TestConfigManager() + { + InitialiseDefaults(); + } + + protected override void InitialiseDefaults() + { + Set(TestConfigSetting.ToggleSettingNoKeybind, false); + Set(TestConfigSetting.EnumSettingNoKeybind, EnumSetting.Setting1); + Set(TestConfigSetting.ToggleSettingWithKeybind, false); + Set(TestConfigSetting.EnumSettingWithKeybind, EnumSetting.Setting1); + + base.InitialiseDefaults(); + } + + public void ToggleSetting(TestConfigSetting setting) => Set(setting, !Get(setting)); + + public void IncrementEnumSetting(TestConfigSetting setting) + { + var nextValue = Get(setting) + 1; + if (nextValue > EnumSetting.Setting4) + nextValue = EnumSetting.Setting1; + Set(setting, nextValue); + } + + public override TrackedSettings CreateTrackedSettings() => new TrackedSettings + { + new TrackedSetting(TestConfigSetting.ToggleSettingNoKeybind, b => new SettingDescription(b, "toggle setting with no keybind", b ? "enabled" : "disabled")), + new TrackedSetting(TestConfigSetting.EnumSettingNoKeybind, v => new SettingDescription(v, "enum setting with no keybind", v.ToString())), + new TrackedSetting(TestConfigSetting.ToggleSettingWithKeybind, b => new SettingDescription(b, "toggle setting with keybind", b ? "enabled" : "disabled", "fake keybind")), + new TrackedSetting(TestConfigSetting.EnumSettingWithKeybind, v => new SettingDescription(v, "enum setting with keybind", v.ToString(), "fake keybind")), + }; + + protected override void PerformLoad() + { + } + + protected override bool PerformSave() => false; + } + + private enum TestConfigSetting + { + ToggleSettingNoKeybind, + EnumSettingNoKeybind, + ToggleSettingWithKeybind, + EnumSettingWithKeybind + } + + private enum EnumSetting + { + Setting1, + Setting2, + Setting3, + Setting4 + } + + private class TestOnScreenDisplay : OnScreenDisplay + { + protected override void Display(Drawable toDisplay) => toDisplay.FadeIn().ResizeHeightTo(110); } } } diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 9882ea01f0..a643080df8 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -102,12 +102,12 @@ namespace osu.Game.Overlays }, textLine3 = new OsuSpriteText { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, Padding = new MarginPadding { Bottom = 15 }, Font = @"Exo2.0-Bold", TextSize = 12, Alpha = 0.3f, - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, }, } } @@ -177,13 +177,7 @@ namespace osu.Game.Overlays textLine2.Text = description.Value; textLine3.Text = description.Shortcut.ToUpper(); - box.Animate( - b => b.FadeIn(500, Easing.OutQuint), - b => b.ResizeHeightTo(height, 500, Easing.OutQuint) - ).Then( - b => b.FadeOutFromOne(1500, Easing.InQuint), - b => b.ResizeHeightTo(height_contracted, 1500, Easing.InQuint) - ); + Display(box); int optionCount = 0; int selectedOption = -1; @@ -215,6 +209,17 @@ namespace osu.Game.Overlays }); } + protected virtual void Display(Drawable toDisplay) + { + toDisplay.Animate( + b => b.FadeIn(500, Easing.OutQuint), + b => b.ResizeHeightTo(height, 500, Easing.OutQuint) + ).Then( + b => b.FadeOutFromOne(1500, Easing.InQuint), + b => b.ResizeHeightTo(height_contracted, 1500, Easing.InQuint) + ); + } + private class OptionLight : Container { private Color4 glowingColour, idleColour; From df604c40ccd33a1b70637a89f09211f6b7de5c87 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 10 May 2018 18:49:19 +0900 Subject: [PATCH 080/229] Keep shortcut padding even when there is no shortut --- osu-framework | 2 +- osu.Game/Overlays/OnScreenDisplay.cs | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/osu-framework b/osu-framework index 0773d895d9..5c135a7360 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 0773d895d9aa0729995cd4a23efc28238e35ceed +Subproject commit 5c135a7360388dc41b1dc4387769a98ee1635d36 diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index a643080df8..8f6bf0f539 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -31,6 +31,7 @@ namespace osu.Game.Overlays private readonly SpriteText textLine3; private const float height = 110; + private const float height_notext = 98; private const float height_contracted = height * 0.9f; private readonly FillFlowContainer optionLights; @@ -100,15 +101,20 @@ namespace osu.Game.Overlays Origin = Anchor.TopCentre, AutoSizeAxes = Axes.Both }, - textLine3 = new OsuSpriteText + new Container { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Padding = new MarginPadding { Bottom = 15 }, - Font = @"Exo2.0-Bold", - TextSize = 12, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Bottom = 15 }, Alpha = 0.3f, - }, + Child = textLine3 = new OsuSpriteText + { + Font = @"Exo2.0-Bold", + TextSize = 12, + AlwaysPresent = true + }, + } } } } From 40c1b24b3db0628bfe8f632640c413062d99562a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 10 May 2018 19:51:40 +0900 Subject: [PATCH 081/229] Move IBeatmap to its own file --- osu.Game/Beatmaps/Beatmap.cs | 39 --------------------------- osu.Game/Beatmaps/IBeatmap.cs | 50 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 39 deletions(-) create mode 100644 osu.Game/Beatmaps/IBeatmap.cs diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 6a7d2690ff..2df0547175 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -12,45 +12,6 @@ using osu.Game.IO.Serialization.Converters; namespace osu.Game.Beatmaps { - public interface IBeatmap : IJsonSerializable - { - /// - /// This beatmap's info. - /// - BeatmapInfo BeatmapInfo { get; set; } - - /// - /// This beatmap's metadata. - /// - BeatmapMetadata Metadata { get; } - - /// - /// The control points in this beatmap. - /// - ControlPointInfo ControlPointInfo { get; } - - /// - /// The breaks in this beatmap. - /// - List Breaks { get; } - - /// - /// Total amount of break time in the beatmap. - /// - double TotalBreakTime { get; } - - /// - /// The hitobjects contained by this beatmap. - /// - IEnumerable HitObjects { get; } - - /// - /// Creates a shallow-clone of this beatmap and returns it. - /// - /// The shallow-cloned beatmap. - IBeatmap Clone(); - } - /// /// A Beatmap containing converted HitObjects. /// diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs new file mode 100644 index 0000000000..4676f056fa --- /dev/null +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Beatmaps.Timing; +using osu.Game.IO.Serialization; +using osu.Game.Rulesets.Objects; + +namespace osu.Game.Beatmaps +{ + public interface IBeatmap : IJsonSerializable + { + /// + /// This beatmap's info. + /// + BeatmapInfo BeatmapInfo { get; set; } + + /// + /// This beatmap's metadata. + /// + BeatmapMetadata Metadata { get; } + + /// + /// The control points in this beatmap. + /// + ControlPointInfo ControlPointInfo { get; } + + /// + /// The breaks in this beatmap. + /// + List Breaks { get; } + + /// + /// Total amount of break time in the beatmap. + /// + double TotalBreakTime { get; } + + /// + /// The hitobjects contained by this beatmap. + /// + IEnumerable HitObjects { get; } + + /// + /// Creates a shallow-clone of this beatmap and returns it. + /// + /// The shallow-cloned beatmap. + IBeatmap Clone(); + } +} From 86430da6d6a2321c588872a11a6c77c8da68d623 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Thu, 10 May 2018 21:08:02 +0300 Subject: [PATCH 082/229] Update CircularProgress.FillTo calls --- osu.Game/Screens/Play/HUD/QuitButton.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index aa6dc388ac..276bffb0a4 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -17,6 +17,7 @@ namespace osu.Game.Screens.Play.HUD public class QuitButton : FillFlowContainer { private readonly Button button; + public Action ExitAction { get => button.ExitAction; @@ -85,7 +86,7 @@ namespace osu.Game.Screens.Play.HUD { icon.ScaleTo(1.5f); text.FadeIn(fade_duration); - progress.FillTo(1, progress_duration).OnComplete(cp => ExitAction()); + progress.FillTo(progress.Current, 1, progress_duration).OnComplete(cp => ExitAction()); return base.OnMouseDown(state, args); } @@ -94,7 +95,7 @@ namespace osu.Game.Screens.Play.HUD { icon.ScaleTo(1f); Scheduler.AddDelayed(() => text.FadeOut(fade_duration), text_display_time); - progress.FillTo(0, progress_duration / 4).OnComplete(cp => progress.Current.SetDefault()); + progress.FillTo(progress.Current, 0, progress_duration / 4).OnComplete(cp => progress.Current.SetDefault()); return base.OnMouseUp(state, args); } From ecb8de29a20138c057fa937ab048dc1cc32f7c2e Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 10 May 2018 20:30:03 -0300 Subject: [PATCH 083/229] Adjust BreadcrumbControl to better match the designs. --- .../UserInterface/BreadcrumbControl.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs index 3f59eeca97..f5017de639 100644 --- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs @@ -14,14 +14,18 @@ namespace osu.Game.Graphics.UserInterface public class BreadcrumbControl : OsuTabControl { private const float padding = 10; + private const float item_chevron_size = 10; - protected override TabItem CreateTabItem(T value) => new BreadcrumbTabItem(value); + protected override TabItem CreateTabItem(T value) => new BreadcrumbTabItem(value) + { + AccentColour = AccentColour, + }; - protected override float StripWidth() => base.StripWidth() - (padding + 8); + protected override float StripWidth() => base.StripWidth() - (padding + item_chevron_size); public BreadcrumbControl() { - Height = 26; + Height = 32; TabContainer.Spacing = new Vector2(padding, 0f); Current.ValueChanged += tab => { @@ -47,6 +51,7 @@ namespace osu.Game.Graphics.UserInterface public override bool HandleKeyboardInput => State == Visibility.Visible; public override bool HandleMouseInput => State == Visibility.Visible; + public override bool IsRemovable => true; private Visibility state; @@ -77,13 +82,14 @@ namespace osu.Game.Graphics.UserInterface public BreadcrumbTabItem(T value) : base(value) { - Text.TextSize = 16; - Padding = new MarginPadding { Right = padding + 8 }; //padding + chevron width + Text.TextSize = 18; + Text.Margin = new MarginPadding { Vertical = 8 }; + Padding = new MarginPadding { Right = padding + item_chevron_size }; Add(Chevron = new SpriteIcon { Anchor = Anchor.CentreRight, Origin = Anchor.CentreLeft, - Size = new Vector2(12), + Size = new Vector2(item_chevron_size), Icon = FontAwesome.fa_chevron_right, Margin = new MarginPadding { Left = padding }, Alpha = 0f, From c35760fdef40981d1830e32e5d2c5d292300f9d8 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 10 May 2018 20:39:05 -0300 Subject: [PATCH 084/229] Rename osu.Game/Screens/Multiplayer to Multi. --- osu.Game.Tests/Visual/TestCaseDrawableRoom.cs | 2 +- osu.Game.Tests/Visual/TestCaseRoomInspector.cs | 2 +- osu.Game/Screens/Menu/MainMenu.cs | 2 +- osu.Game/Screens/Multi/.DS_Store | Bin 0 -> 6148 bytes .../{Multiplayer => Multi}/DrawableGameType.cs | 2 +- .../{Multiplayer => Multi}/DrawableRoom.cs | 2 +- osu.Game/Screens/{Multiplayer => Multi}/Lobby.cs | 2 +- osu.Game/Screens/{Multiplayer => Multi}/Match.cs | 2 +- .../{Multiplayer => Multi}/MatchCreate.cs | 2 +- .../{Multiplayer => Multi}/ModeTypeInfo.cs | 2 +- .../{Multiplayer => Multi}/ParticipantInfo.cs | 2 +- .../{Multiplayer => Multi}/RoomInspector.cs | 2 +- 12 files changed, 11 insertions(+), 11 deletions(-) create mode 100644 osu.Game/Screens/Multi/.DS_Store rename osu.Game/Screens/{Multiplayer => Multi}/DrawableGameType.cs (96%) rename osu.Game/Screens/{Multiplayer => Multi}/DrawableRoom.cs (99%) rename osu.Game/Screens/{Multiplayer => Multi}/Lobby.cs (91%) rename osu.Game/Screens/{Multiplayer => Multi}/Match.cs (96%) rename osu.Game/Screens/{Multiplayer => Multi}/MatchCreate.cs (92%) rename osu.Game/Screens/{Multiplayer => Multi}/ModeTypeInfo.cs (98%) rename osu.Game/Screens/{Multiplayer => Multi}/ParticipantInfo.cs (99%) rename osu.Game/Screens/{Multiplayer => Multi}/RoomInspector.cs (99%) diff --git a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs index 25f8ba06c4..958dbd3c74 100644 --- a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs +++ b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; -using osu.Game.Screens.Multiplayer; +using osu.Game.Screens.Multi; using osu.Game.Users; namespace osu.Game.Tests.Visual diff --git a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs index 88059d2dcf..d0752cfc76 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; -using osu.Game.Screens.Multiplayer; +using osu.Game.Screens.Multi; using osu.Game.Users; namespace osu.Game.Tests.Visual diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index f2ea6d85a8..b09b53063a 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -14,7 +14,7 @@ using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Charts; using osu.Game.Screens.Direct; using osu.Game.Screens.Edit; -using osu.Game.Screens.Multiplayer; +using osu.Game.Screens.Multi; using osu.Game.Screens.Select; using osu.Game.Screens.Tournament; diff --git a/osu.Game/Screens/Multi/.DS_Store b/osu.Game/Screens/Multi/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Thu, 10 May 2018 20:44:24 -0300 Subject: [PATCH 085/229] Move multiplayer screen components to osu.Game/Screens/Multi/Components --- osu.Game.Tests/Visual/TestCaseDrawableRoom.cs | 1 + osu.Game.Tests/Visual/TestCaseRoomInspector.cs | 1 + osu.Game/Screens/Multi/.DS_Store | Bin 6148 -> 0 bytes .../Multi/{ => Components}/DrawableGameType.cs | 2 +- .../Multi/{ => Components}/DrawableRoom.cs | 6 +++--- .../Multi/{ => Components}/ModeTypeInfo.cs | 4 ++-- .../Multi/{ => Components}/ParticipantInfo.cs | 4 ++-- .../Multi/{ => Components}/RoomInspector.cs | 6 +++--- 8 files changed, 13 insertions(+), 11 deletions(-) delete mode 100644 osu.Game/Screens/Multi/.DS_Store rename osu.Game/Screens/Multi/{ => Components}/DrawableGameType.cs (96%) rename osu.Game/Screens/Multi/{ => Components}/DrawableRoom.cs (99%) rename osu.Game/Screens/Multi/{ => Components}/ModeTypeInfo.cs (98%) rename osu.Game/Screens/Multi/{ => Components}/ParticipantInfo.cs (99%) rename osu.Game/Screens/Multi/{ => Components}/RoomInspector.cs (99%) diff --git a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs index 958dbd3c74..3c61efd689 100644 --- a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs +++ b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs @@ -9,6 +9,7 @@ using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; using osu.Game.Screens.Multi; +using osu.Game.Screens.Multi.Components; using osu.Game.Users; namespace osu.Game.Tests.Visual diff --git a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs index d0752cfc76..4cf19924e9 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs @@ -8,6 +8,7 @@ using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; using osu.Game.Screens.Multi; +using osu.Game.Screens.Multi.Components; using osu.Game.Users; namespace osu.Game.Tests.Visual diff --git a/osu.Game/Screens/Multi/.DS_Store b/osu.Game/Screens/Multi/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0. // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; -using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; @@ -17,8 +15,10 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Online.Multiplayer; using osu.Game.Users; +using OpenTK; +using OpenTK.Graphics; -namespace osu.Game.Screens.Multi +namespace osu.Game.Screens.Multi.Components { public class DrawableRoom : OsuClickableContainer { diff --git a/osu.Game/Screens/Multi/ModeTypeInfo.cs b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs similarity index 98% rename from osu.Game/Screens/Multi/ModeTypeInfo.cs rename to osu.Game/Screens/Multi/Components/ModeTypeInfo.cs index 1c175bad44..e3aba685a7 100644 --- a/osu.Game/Screens/Multi/ModeTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs @@ -1,14 +1,14 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Online.Multiplayer; +using OpenTK; -namespace osu.Game.Screens.Multi +namespace osu.Game.Screens.Multi.Components { public class ModeTypeInfo : Container { diff --git a/osu.Game/Screens/Multi/ParticipantInfo.cs b/osu.Game/Screens/Multi/Components/ParticipantInfo.cs similarity index 99% rename from osu.Game/Screens/Multi/ParticipantInfo.cs rename to osu.Game/Screens/Multi/Components/ParticipantInfo.cs index a5d2bcd78a..ab404488f1 100644 --- a/osu.Game/Screens/Multi/ParticipantInfo.cs +++ b/osu.Game/Screens/Multi/Components/ParticipantInfo.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using OpenTK; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -11,8 +10,9 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Users; +using OpenTK; -namespace osu.Game.Screens.Multi +namespace osu.Game.Screens.Multi.Components { public class ParticipantInfo : Container { diff --git a/osu.Game/Screens/Multi/RoomInspector.cs b/osu.Game/Screens/Multi/Components/RoomInspector.cs similarity index 99% rename from osu.Game/Screens/Multi/RoomInspector.cs rename to osu.Game/Screens/Multi/Components/RoomInspector.cs index d8c5d5ea9a..92910e8301 100644 --- a/osu.Game/Screens/Multi/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Components/RoomInspector.cs @@ -2,8 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Linq; -using OpenTK; -using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; @@ -20,8 +18,10 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Online.Multiplayer; using osu.Game.Users; +using OpenTK; +using OpenTK.Graphics; -namespace osu.Game.Screens.Multi +namespace osu.Game.Screens.Multi.Components { public class RoomInspector : Container { From bc9ac8f72a2a281cf43510cd8b81c825a423c27f Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 10 May 2018 20:47:25 -0300 Subject: [PATCH 086/229] Move multiplayer screens to osu.Game/Screens/Multi/Screens --- osu.Game/Screens/Menu/MainMenu.cs | 1 + osu.Game/Screens/Multi/{ => Screens}/Lobby.cs | 2 +- osu.Game/Screens/Multi/{ => Screens}/Match.cs | 6 +++--- osu.Game/Screens/Multi/{ => Screens}/MatchCreate.cs | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) rename osu.Game/Screens/Multi/{ => Screens}/Lobby.cs (90%) rename osu.Game/Screens/Multi/{ => Screens}/Match.cs (96%) rename osu.Game/Screens/Multi/{ => Screens}/MatchCreate.cs (91%) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index b09b53063a..2baa26c676 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -15,6 +15,7 @@ using osu.Game.Screens.Charts; using osu.Game.Screens.Direct; using osu.Game.Screens.Edit; using osu.Game.Screens.Multi; +using osu.Game.Screens.Multi.Screens; using osu.Game.Screens.Select; using osu.Game.Screens.Tournament; diff --git a/osu.Game/Screens/Multi/Lobby.cs b/osu.Game/Screens/Multi/Screens/Lobby.cs similarity index 90% rename from osu.Game/Screens/Multi/Lobby.cs rename to osu.Game/Screens/Multi/Screens/Lobby.cs index 80e682e9f9..dcda40e0d7 100644 --- a/osu.Game/Screens/Multi/Lobby.cs +++ b/osu.Game/Screens/Multi/Screens/Lobby.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; -namespace osu.Game.Screens.Multi +namespace osu.Game.Screens.Multi.Screens { public class Lobby : ScreenWhiteBox { diff --git a/osu.Game/Screens/Multi/Match.cs b/osu.Game/Screens/Multi/Screens/Match.cs similarity index 96% rename from osu.Game/Screens/Multi/Match.cs rename to osu.Game/Screens/Multi/Screens/Match.cs index eee302a115..4ba7fe9f6a 100644 --- a/osu.Game/Screens/Multi/Match.cs +++ b/osu.Game/Screens/Multi/Screens/Match.cs @@ -3,14 +3,14 @@ using System; using System.Collections.Generic; +using osu.Framework.Graphics; using osu.Framework.Screens; using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Play; -using OpenTK.Graphics; using osu.Game.Screens.Select; -using osu.Framework.Graphics; +using OpenTK.Graphics; -namespace osu.Game.Screens.Multi +namespace osu.Game.Screens.Multi.Screens { public class Match : ScreenWhiteBox { diff --git a/osu.Game/Screens/Multi/MatchCreate.cs b/osu.Game/Screens/Multi/Screens/MatchCreate.cs similarity index 91% rename from osu.Game/Screens/Multi/MatchCreate.cs rename to osu.Game/Screens/Multi/Screens/MatchCreate.cs index db528ae2a3..6b4e26d5e5 100644 --- a/osu.Game/Screens/Multi/MatchCreate.cs +++ b/osu.Game/Screens/Multi/Screens/MatchCreate.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; -namespace osu.Game.Screens.Multi +namespace osu.Game.Screens.Multi.Screens { public class MatchCreate : ScreenWhiteBox { From a86843ccc93c1a88d65f527daf011c7b12db1674 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 10 May 2018 20:49:42 -0300 Subject: [PATCH 087/229] Remove unused usings caused by multiplayer folder restructuring. --- osu.Game.Tests/Visual/TestCaseDrawableRoom.cs | 1 - osu.Game.Tests/Visual/TestCaseRoomInspector.cs | 1 - osu.Game/Screens/Menu/MainMenu.cs | 1 - 3 files changed, 3 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs index 3c61efd689..bb5bf93a69 100644 --- a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs +++ b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; -using osu.Game.Screens.Multi; using osu.Game.Screens.Multi.Components; using osu.Game.Users; diff --git a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs index 4cf19924e9..cb1425ca69 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; -using osu.Game.Screens.Multi; using osu.Game.Screens.Multi.Components; using osu.Game.Users; diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 2baa26c676..907ad81111 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -14,7 +14,6 @@ using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Charts; using osu.Game.Screens.Direct; using osu.Game.Screens.Edit; -using osu.Game.Screens.Multi; using osu.Game.Screens.Multi.Screens; using osu.Game.Screens.Select; using osu.Game.Screens.Tournament; From b9adeeb063400477e53e093438c51fb9714d9786 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 10 May 2018 21:35:26 -0300 Subject: [PATCH 088/229] Add ScreenBreadcrumbControl. --- .../Visual/TestCaseScreenBreadcrumbs.cs | 108 ++++++++++++++++++ .../UserInterface/ScreenBreadcrumbControl.cs | 78 +++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs create mode 100644 osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs diff --git a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs new file mode 100644 index 0000000000..5055b0e114 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs @@ -0,0 +1,108 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Screens; +using OpenTK; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseScreenBreadcrumbs : OsuTestCase + { + private readonly ScreenBreadcrumbControl breadcrumbs; + + public TestCaseScreenBreadcrumbs() + { + TestScreen startScreen; + OsuSpriteText titleText; + + Children = new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(10), + Children = new Drawable[] + { + breadcrumbs = new ScreenBreadcrumbControl + { + RelativeSizeAxes = Axes.X, + }, + titleText = new OsuSpriteText(), + }, + }, + startScreen = new TestScreenOne(), + }; + + breadcrumbs.OnScreenChanged += s => titleText.Text = $"Changed to {s.ToString()}"; + breadcrumbs.CurrentScreen = startScreen; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + breadcrumbs.StripColour = colours.Blue; + } + + private abstract class TestScreen : OsuScreen + { + protected abstract string Title { get; } + protected abstract string NextTitle { get; } + protected abstract TestScreen CreateNextScreen(); + + public override string ToString() => Title; + + protected TestScreen() + { + Child = new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(10), + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = Title, + }, + new TriangleButton + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Width = 100, + Text = $"Push {NextTitle}", + Action = () => Push(CreateNextScreen()), + }, + }, + }; + } + } + + private class TestScreenOne : TestScreen + { + protected override string Title => @"Screen One"; + protected override string NextTitle => @"Two"; + protected override TestScreen CreateNextScreen() => new TestScreenTwo(); + } + + private class TestScreenTwo : TestScreen + { + protected override string Title => @"Screen Two"; + protected override string NextTitle => @"One"; + protected override TestScreen CreateNextScreen() => new TestScreenOne(); + } + } +} diff --git a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs new file mode 100644 index 0000000000..fbdb27a81c --- /dev/null +++ b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs @@ -0,0 +1,78 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Screens; + +namespace osu.Game.Graphics.UserInterface +{ + public class ScreenBreadcrumbControl : ScreenBreadcrumbControl + { + } + + public class ScreenBreadcrumbControl : BreadcrumbControl where T : Screen + { + private T currentScreen; + public T CurrentScreen + { + get { return currentScreen; } + set + { + if (value == currentScreen) return; + + if (CurrentScreen != null) + { + CurrentScreen.Exited -= onExited; + CurrentScreen.ModePushed -= onPushed; + } + else + { + // this is the first screen in the stack, so call the initial onPushed + currentScreen = value; + onPushed(CurrentScreen); + } + + currentScreen = value; + + if (CurrentScreen != null) + { + CurrentScreen.Exited += onExited; + CurrentScreen.ModePushed += onPushed; + Current.Value = CurrentScreen; + OnScreenChanged?.Invoke(CurrentScreen); + } + } + } + + public event Action OnScreenChanged; + + public ScreenBreadcrumbControl() + { + Current.ValueChanged += s => + { + if (s != CurrentScreen) + { + CurrentScreen = s; + s.MakeCurrent(); + } + }; + } + + private void onExited(Screen screen) + { + CurrentScreen = screen as T; + } + + private void onPushed(Screen screen) + { + var newScreen = screen as T; + + Items.ToList().SkipWhile(i => i != Current.Value).Skip(1).ForEach(RemoveItem); + AddItem(newScreen); + + CurrentScreen = newScreen; + } + } +} From a294f187ee90a187604d7e3788842f46c2e592fe Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 10 May 2018 21:52:26 -0300 Subject: [PATCH 089/229] Add steps and asserts to TestCaseScreenBreadcrumbs. --- .../Visual/TestCaseScreenBreadcrumbs.cs | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs index 5055b0e114..6bb6b09746 100644 --- a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs +++ b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs @@ -17,6 +17,7 @@ namespace osu.Game.Tests.Visual public class TestCaseScreenBreadcrumbs : OsuTestCase { private readonly ScreenBreadcrumbControl breadcrumbs; + private TestScreen currentScreen, changedScreen = null; public TestCaseScreenBreadcrumbs() { @@ -40,11 +41,29 @@ namespace osu.Game.Tests.Visual titleText = new OsuSpriteText(), }, }, - startScreen = new TestScreenOne(), + currentScreen = startScreen = new TestScreenOne(), }; - breadcrumbs.OnScreenChanged += s => titleText.Text = $"Changed to {s.ToString()}"; - breadcrumbs.CurrentScreen = startScreen; + breadcrumbs.OnScreenChanged += s => + { + titleText.Text = $"Changed to {s.ToString()}"; + changedScreen = s; + }; + + AddStep(@"make start current", () => breadcrumbs.CurrentScreen = startScreen); + assertCurrent(); + pushNext(); + assertCurrent(); + pushNext(); + assertCurrent(); + + AddStep(@"make start current", () => + { + startScreen.MakeCurrent(); + currentScreen = startScreen; + }); + + assertCurrent(); } [BackgroundDependencyLoader] @@ -53,6 +72,9 @@ namespace osu.Game.Tests.Visual breadcrumbs.StripColour = colours.Blue; } + private void pushNext() => AddStep(@"push next screen", () => currentScreen = currentScreen.PushNext()); + private void assertCurrent() => AddAssert(@"assert the current screen is correct", () => currentScreen == changedScreen); + private abstract class TestScreen : OsuScreen { protected abstract string Title { get; } @@ -61,6 +83,14 @@ namespace osu.Game.Tests.Visual public override string ToString() => Title; + public TestScreen PushNext() + { + TestScreen screen = CreateNextScreen(); + Push(screen); + + return screen; + } + protected TestScreen() { Child = new FillFlowContainer @@ -84,7 +114,7 @@ namespace osu.Game.Tests.Visual Origin = Anchor.TopCentre, Width = 100, Text = $"Push {NextTitle}", - Action = () => Push(CreateNextScreen()), + Action = () => PushNext(), }, }, }; From 6f7d0c19efe10356d91a243a08d13ed01112a2a0 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 10 May 2018 22:02:22 -0300 Subject: [PATCH 090/229] Remove redundant default value. --- osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs index 6bb6b09746..3e0dd9e018 100644 --- a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs +++ b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual public class TestCaseScreenBreadcrumbs : OsuTestCase { private readonly ScreenBreadcrumbControl breadcrumbs; - private TestScreen currentScreen, changedScreen = null; + private TestScreen currentScreen, changedScreen; public TestCaseScreenBreadcrumbs() { From d87ac5a1cbb0afb35979f3f1a150eddef7bafb44 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 10 May 2018 22:12:25 -0300 Subject: [PATCH 091/229] Create the drawable hierarchy for DrawableRoom in load. --- osu.Game/Screens/Multiplayer/DrawableRoom.cs | 49 +++++++++----------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/osu.Game/Screens/Multiplayer/DrawableRoom.cs b/osu.Game/Screens/Multiplayer/DrawableRoom.cs index d53100526f..b9f464ff78 100644 --- a/osu.Game/Screens/Multiplayer/DrawableRoom.cs +++ b/osu.Game/Screens/Multiplayer/DrawableRoom.cs @@ -29,11 +29,10 @@ namespace osu.Game.Screens.Multiplayer private const float cover_width = 145; private readonly Box sideStrip; - private readonly Container coverContainer; - private readonly OsuSpriteText name, status, beatmapTitle, beatmapDash, beatmapArtist; - private readonly FillFlowContainer beatmapInfoFlow; - private readonly ParticipantInfo participantInfo; - private readonly ModeTypeInfo modeTypeInfo; + private Container coverContainer; + private OsuSpriteText name, status, beatmapTitle, beatmapDash, beatmapArtist; + private ParticipantInfo participantInfo; + private ModeTypeInfo modeTypeInfo; private readonly Bindable nameBind = new Bindable(); private readonly Bindable hostBind = new Bindable(); @@ -62,6 +61,19 @@ namespace osu.Game.Screens.Multiplayer Radius = 5, }; + sideStrip = new Box + { + RelativeSizeAxes = Axes.Y, + Width = side_strip_width, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours, LocalisationEngine localisation) + { + this.localisation = localisation; + this.colours = colours; + Children = new Drawable[] { new Box @@ -69,11 +81,7 @@ namespace osu.Game.Screens.Multiplayer RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex(@"212121"), }, - sideStrip = new Box - { - RelativeSizeAxes = Axes.Y, - Width = side_strip_width, - }, + sideStrip, new Container { Width = cover_width, @@ -133,10 +141,11 @@ namespace osu.Game.Screens.Multiplayer TextSize = 14, Font = @"Exo2.0-Bold", }, - beatmapInfoFlow = new FillFlowContainer + new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Colour = colours.Gray9, Direction = FillDirection.Horizontal, Children = new[] { @@ -170,7 +179,9 @@ namespace osu.Game.Screens.Multiplayer nameBind.ValueChanged += displayName; hostBind.ValueChanged += displayUser; + statusBind.ValueChanged += displayStatus; typeBind.ValueChanged += displayGameType; + beatmapBind.ValueChanged += displayBeatmap; participantsBind.ValueChanged += displayParticipants; nameBind.BindTo(Room.Name); @@ -181,22 +192,6 @@ namespace osu.Game.Screens.Multiplayer participantsBind.BindTo(Room.Participants); } - [BackgroundDependencyLoader] - private void load(OsuColour colours, LocalisationEngine localisation) - { - this.localisation = localisation; - this.colours = colours; - - beatmapInfoFlow.Colour = colours.Gray9; - - //binded here instead of ctor because dependencies are needed - statusBind.ValueChanged += displayStatus; - beatmapBind.ValueChanged += displayBeatmap; - - statusBind.TriggerChange(); - beatmapBind.TriggerChange(); - } - private void displayName(string value) { name.Text = value; From ec53927d8e77730bd0cc6c820d6287f004018180 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 10 May 2018 22:48:07 -0300 Subject: [PATCH 092/229] Add selection to DrawableRoom. --- osu.Game.Tests/Visual/TestCaseDrawableRoom.cs | 3 + .../Graphics/UserInterface/SelectionState.cs | 11 + osu.Game/Rulesets/Edit/HitObjectMask.cs | 7 +- osu.Game/Screens/Multiplayer/DrawableRoom.cs | 364 +++++++++--------- 4 files changed, 206 insertions(+), 179 deletions(-) create mode 100644 osu.Game/Graphics/UserInterface/SelectionState.cs diff --git a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs index 25f8ba06c4..65e782b828 100644 --- a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs +++ b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; using osu.Game.Screens.Multiplayer; @@ -111,6 +112,7 @@ namespace osu.Game.Tests.Visual } }); + AddStep(@"select", () => first.State = SelectionState.Selected); AddStep(@"change title", () => first.Room.Name.Value = @"I Changed Name"); AddStep(@"change host", () => first.Room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } }); AddStep(@"change status", () => first.Room.Status.Value = new RoomStatusPlaying()); @@ -121,6 +123,7 @@ namespace osu.Game.Tests.Visual new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 1254 } } }, new User { Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 123189 } } }, }); + AddStep(@"deselect", () => first.State = SelectionState.NotSelected); } [BackgroundDependencyLoader] diff --git a/osu.Game/Graphics/UserInterface/SelectionState.cs b/osu.Game/Graphics/UserInterface/SelectionState.cs new file mode 100644 index 0000000000..079ae343eb --- /dev/null +++ b/osu.Game/Graphics/UserInterface/SelectionState.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Graphics.UserInterface +{ + public enum SelectionState + { + NotSelected, + Selected + } +} diff --git a/osu.Game/Rulesets/Edit/HitObjectMask.cs b/osu.Game/Rulesets/Edit/HitObjectMask.cs index ad7c27ad80..61fb700dd3 100644 --- a/osu.Game/Rulesets/Edit/HitObjectMask.cs +++ b/osu.Game/Rulesets/Edit/HitObjectMask.cs @@ -6,6 +6,7 @@ using osu.Framework; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; using osu.Framework.Input; +using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Objects.Drawables; using OpenTK; @@ -137,10 +138,4 @@ namespace osu.Game.Rulesets.Edit /// public virtual Quad SelectionQuad => ScreenSpaceDrawQuad; } - - public enum SelectionState - { - NotSelected, - Selected - } } diff --git a/osu.Game/Screens/Multiplayer/DrawableRoom.cs b/osu.Game/Screens/Multiplayer/DrawableRoom.cs index b9f464ff78..16eb93d3f0 100644 --- a/osu.Game/Screens/Multiplayer/DrawableRoom.cs +++ b/osu.Game/Screens/Multiplayer/DrawableRoom.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using osu.Framework; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; @@ -15,24 +17,23 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Users; namespace osu.Game.Screens.Multiplayer { - public class DrawableRoom : OsuClickableContainer + public class DrawableRoom : OsuClickableContainer, IStateful { + private const float corner_radius = 5; + private const float selection_border_width = 4; private const float transition_duration = 100; private const float content_padding = 10; private const float height = 100; private const float side_strip_width = 5; private const float cover_width = 145; - private readonly Box sideStrip; - private Container coverContainer; - private OsuSpriteText name, status, beatmapTitle, beatmapDash, beatmapArtist; - private ParticipantInfo participantInfo; - private ModeTypeInfo modeTypeInfo; + private readonly Box selectionBox; private readonly Bindable nameBind = new Bindable(); private readonly Bindable hostBind = new Bindable(); @@ -41,148 +42,227 @@ namespace osu.Game.Screens.Multiplayer private readonly Bindable beatmapBind = new Bindable(); private readonly Bindable participantsBind = new Bindable(); - private OsuColour colours; - private LocalisationEngine localisation; - public readonly Room Room; + private SelectionState state; + + public SelectionState State + { + get { return state; } + set + { + if (value == state) return; + state = value; + + if (state == SelectionState.Selected) + selectionBox.FadeIn(transition_duration); + else + selectionBox.FadeOut(transition_duration); + + StateChanged?.Invoke(State); + } + } + + public event Action StateChanged; + public DrawableRoom(Room room) { Room = room; RelativeSizeAxes = Axes.X; - Height = height; - CornerRadius = 5; + Height = height + selection_border_width * 2; + CornerRadius = corner_radius + selection_border_width / 2; Masking = true; - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(40), - Radius = 5, - }; - sideStrip = new Box + // create selectionBox here so State can be set before being loaded + selectionBox = new Box { - RelativeSizeAxes = Axes.Y, - Width = side_strip_width, + RelativeSizeAxes = Axes.Both, + Alpha = 0f, }; } [BackgroundDependencyLoader] private void load(OsuColour colours, LocalisationEngine localisation) { - this.localisation = localisation; - this.colours = colours; + Box sideStrip; + Container coverContainer; + OsuSpriteText name, status, beatmapTitle, beatmapDash, beatmapArtist; + ParticipantInfo participantInfo; + ModeTypeInfo modeTypeInfo; Children = new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"212121"), - }, - sideStrip, - new Container - { - Width = cover_width, - RelativeSizeAxes = Axes.Y, - Masking = true, - Margin = new MarginPadding { Left = side_strip_width }, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }, - coverContainer = new Container - { - RelativeSizeAxes = Axes.Both, - }, - }, - }, + selectionBox, new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding + Padding = new MarginPadding(selection_border_width), + Child = new Container { - Vertical = content_padding, - Left = side_strip_width + cover_width + content_padding, - Right = content_padding, - }, - Children = new Drawable[] - { - new FillFlowContainer + RelativeSizeAxes = Axes.Both, + Masking = true, + CornerRadius = corner_radius, + EdgeEffect = new EdgeEffectParameters { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(5f), - Children = new Drawable[] + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(40), + Radius = 5, + }, + Children = new Drawable[] + { + new Box { - name = new OsuSpriteText - { - TextSize = 18, - }, - participantInfo = new ParticipantInfo(), + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"212121"), }, - }, - new FillFlowContainer - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] + sideStrip = new Box { - status = new OsuSpriteText + RelativeSizeAxes = Axes.Y, + Width = side_strip_width, + }, + new Container + { + Width = cover_width, + RelativeSizeAxes = Axes.Y, + Masking = true, + Margin = new MarginPadding { Left = side_strip_width }, + Children = new Drawable[] { - TextSize = 14, - Font = @"Exo2.0-Bold", - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Colour = colours.Gray9, - Direction = FillDirection.Horizontal, - Children = new[] + new Box { - beatmapTitle = new OsuSpriteText - { - TextSize = 14, - Font = @"Exo2.0-BoldItalic", - }, - beatmapDash = new OsuSpriteText - { - TextSize = 14, - Font = @"Exo2.0-BoldItalic", - }, - beatmapArtist = new OsuSpriteText - { - TextSize = 14, - Font = @"Exo2.0-RegularItalic", - }, + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + coverContainer = new Container + { + RelativeSizeAxes = Axes.Both, + }, + }, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding + { + Vertical = content_padding, + Left = side_strip_width + cover_width + content_padding, + Right = content_padding, + }, + Children = new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(5f), + Children = new Drawable[] + { + name = new OsuSpriteText + { + TextSize = 18, + }, + participantInfo = new ParticipantInfo(), + }, + }, + new FillFlowContainer + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + status = new OsuSpriteText + { + TextSize = 14, + Font = @"Exo2.0-Bold", + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Colour = colours.Gray9, + Direction = FillDirection.Horizontal, + Children = new[] + { + beatmapTitle = new OsuSpriteText + { + TextSize = 14, + Font = @"Exo2.0-BoldItalic", + }, + beatmapDash = new OsuSpriteText + { + TextSize = 14, + Font = @"Exo2.0-BoldItalic", + }, + beatmapArtist = new OsuSpriteText + { + TextSize = 14, + Font = @"Exo2.0-RegularItalic", + }, + }, + }, + }, + }, + modeTypeInfo = new ModeTypeInfo + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, }, }, }, - }, - modeTypeInfo = new ModeTypeInfo - { - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, }, }, }, }; - nameBind.ValueChanged += displayName; - hostBind.ValueChanged += displayUser; - statusBind.ValueChanged += displayStatus; - typeBind.ValueChanged += displayGameType; - beatmapBind.ValueChanged += displayBeatmap; - participantsBind.ValueChanged += displayParticipants; + nameBind.ValueChanged += n => name.Text = n; + hostBind.ValueChanged += h => participantInfo.Host = h; + typeBind.ValueChanged += m => modeTypeInfo.Type = m; + participantsBind.ValueChanged += p => participantInfo.Participants = p; + + statusBind.ValueChanged += s => + { + status.Text = s.Message; + + foreach (Drawable d in new Drawable[] { selectionBox, sideStrip, status }) + d.FadeColour(s.GetAppropriateColour(colours), 100); + }; + + beatmapBind.ValueChanged += b => + { + modeTypeInfo.Beatmap = b; + + if (b != null) + { + coverContainer.FadeIn(transition_duration); + + LoadComponentAsync(new BeatmapSetCover(b.BeatmapSet) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + FillMode = FillMode.Fill, + OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out), + }, coverContainer.Add); + + beatmapTitle.Current = localisation.GetUnicodePreference(b.Metadata.TitleUnicode, b.Metadata.Title); + beatmapDash.Text = @" - "; + beatmapArtist.Current = localisation.GetUnicodePreference(b.Metadata.ArtistUnicode, b.Metadata.Artist); + } + else + { + coverContainer.FadeOut(transition_duration); + + beatmapTitle.Current = null; + beatmapArtist.Current = null; + + beatmapTitle.Text = "Changing map"; + beatmapDash.Text = beatmapArtist.Text = string.Empty; + } + }; nameBind.BindTo(Room.Name); hostBind.BindTo(Room.Host); @@ -191,67 +271,5 @@ namespace osu.Game.Screens.Multiplayer beatmapBind.BindTo(Room.Beatmap); participantsBind.BindTo(Room.Participants); } - - private void displayName(string value) - { - name.Text = value; - } - - private void displayUser(User value) - { - participantInfo.Host = value; - } - - private void displayStatus(RoomStatus value) - { - if (value == null) return; - status.Text = value.Message; - - foreach (Drawable d in new Drawable[] { sideStrip, status }) - d.FadeColour(value.GetAppropriateColour(colours), 100); - } - - private void displayGameType(GameType value) - { - modeTypeInfo.Type = value; - } - - private void displayBeatmap(BeatmapInfo value) - { - modeTypeInfo.Beatmap = value; - - if (value != null) - { - coverContainer.FadeIn(transition_duration); - - LoadComponentAsync(new BeatmapSetCover(value.BeatmapSet) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - FillMode = FillMode.Fill, - OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out), - }, - coverContainer.Add); - - beatmapTitle.Current = localisation.GetUnicodePreference(value.Metadata.TitleUnicode, value.Metadata.Title); - beatmapDash.Text = @" - "; - beatmapArtist.Current = localisation.GetUnicodePreference(value.Metadata.ArtistUnicode, value.Metadata.Artist); - } - else - { - coverContainer.FadeOut(transition_duration); - - beatmapTitle.Current = null; - beatmapArtist.Current = null; - - beatmapTitle.Text = "Changing map"; - beatmapDash.Text = beatmapArtist.Text = string.Empty; - } - } - - private void displayParticipants(User[] value) - { - participantInfo.Participants = value; - } } } From a241ff1c051447338442ae9e30d3b2b402182b0d Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 10 May 2018 22:50:03 -0300 Subject: [PATCH 093/229] Cleanup. --- osu.Game/Screens/Multiplayer/DrawableRoom.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Multiplayer/DrawableRoom.cs b/osu.Game/Screens/Multiplayer/DrawableRoom.cs index 16eb93d3f0..a67ead74a1 100644 --- a/osu.Game/Screens/Multiplayer/DrawableRoom.cs +++ b/osu.Game/Screens/Multiplayer/DrawableRoom.cs @@ -45,7 +45,6 @@ namespace osu.Game.Screens.Multiplayer public readonly Room Room; private SelectionState state; - public SelectionState State { get { return state; } From 2bab08c4373a96360d48a8ed183ff79c1385b3d7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 14:07:17 +0900 Subject: [PATCH 094/229] Fix post-merge errors --- osu-framework | 2 +- osu.Game/Beatmaps/Beatmap.cs | 44 ----------------------------------- osu.Game/Beatmaps/IBeatmap.cs | 6 +++++ 3 files changed, 7 insertions(+), 45 deletions(-) diff --git a/osu-framework b/osu-framework index 0773d895d9..8c4f232694 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 0773d895d9aa0729995cd4a23efc28238e35ceed +Subproject commit 8c4f23269447d9ce21a5dbd3a0fd4f6caae9ab38 diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 9517d44fcd..84897853d8 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -12,50 +12,6 @@ using osu.Game.IO.Serialization.Converters; namespace osu.Game.Beatmaps { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// /// A Beatmap containing converted HitObjects. /// diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index 4676f056fa..fe20bce98a 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -41,6 +41,12 @@ namespace osu.Game.Beatmaps /// IEnumerable HitObjects { get; } + /// + /// Returns statistics for the contained in this beatmap. + /// + /// + IEnumerable GetStatistics(); + /// /// Creates a shallow-clone of this beatmap and returns it. /// From 816ad5c4269c080611156ed6cc798207188fb86a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 14:10:53 +0900 Subject: [PATCH 095/229] Pass down ruleset to the buffered wedge --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 7a8a04bd43..c88e01562f 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -88,7 +88,7 @@ namespace osu.Game.Screens.Select private void loadBeatmap() { - LoadComponentAsync(new BufferedWedgeInfo(beatmap) + LoadComponentAsync(new BufferedWedgeInfo(beatmap, ruleset.Value) { Shear = -Shear, Depth = Info?.Depth + 1 ?? 0, @@ -114,18 +114,18 @@ namespace osu.Game.Screens.Select private UnicodeBindableString titleBinding; private UnicodeBindableString artistBinding; - private RulesetInfo ruleset; + private readonly RulesetInfo ruleset; - public BufferedWedgeInfo(WorkingBeatmap working) + public BufferedWedgeInfo(WorkingBeatmap working, RulesetInfo userRuleset) { this.working = working; + + ruleset = userRuleset ?? working.BeatmapInfo.Ruleset; } [BackgroundDependencyLoader(true)] - private void load([NotNull] LocalisationEngine localisation, [CanBeNull] OsuGame osuGame) + private void load([NotNull] LocalisationEngine localisation) { - ruleset = osuGame?.Ruleset.Value ?? working.BeatmapInfo.Ruleset; - var beatmapInfo = working.BeatmapInfo; var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); From fd9796d08c1c3aa74d7691f8825f353fefeb5b7a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 14:13:52 +0900 Subject: [PATCH 096/229] Remove some unnecessary changes --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index c88e01562f..236b1310e1 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -123,8 +123,8 @@ namespace osu.Game.Screens.Select ruleset = userRuleset ?? working.BeatmapInfo.Ruleset; } - [BackgroundDependencyLoader(true)] - private void load([NotNull] LocalisationEngine localisation) + [BackgroundDependencyLoader] + private void load(LocalisationEngine localisation) { var beatmapInfo = working.BeatmapInfo; var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); From 8216bc311af892c778cad4ae46366755b6fd8bda Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 15:30:26 +0900 Subject: [PATCH 097/229] Restructure HitWindows to allow outside setting --- osu.Game/Rulesets/Objects/HitObject.cs | 25 +++++++++++++++---------- osu.Game/Rulesets/Objects/HitWindows.cs | 4 ++-- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 13fa61f536..70604855e9 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -51,16 +51,10 @@ namespace osu.Game.Rulesets.Objects private float overallDifficulty = BeatmapDifficulty.DEFAULT_DIFFICULTY; - private HitWindows hitWindows; - /// /// The hit windows for this . /// - public HitWindows HitWindows - { - get => hitWindows ?? (hitWindows = new HitWindows(overallDifficulty)); - protected set => hitWindows = value; - } + public HitWindows HitWindows { get; set; } private readonly SortedList nestedHitObjects = new SortedList((h1, h2) => h1.StartTime.CompareTo(h2.StartTime)); @@ -78,7 +72,11 @@ namespace osu.Game.Rulesets.Objects nestedHitObjects.Clear(); CreateNestedHitObjects(); - nestedHitObjects.ForEach(h => h.ApplyDefaults(controlPointInfo, difficulty)); + nestedHitObjects.ForEach(h => + { + h.HitWindows = HitWindows; + h.ApplyDefaults(controlPointInfo, difficulty); + }); } protected virtual void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) @@ -89,8 +87,9 @@ namespace osu.Game.Rulesets.Objects Kiai = effectPoint.KiaiMode; SampleControlPoint = samplePoint; - overallDifficulty = difficulty.OverallDifficulty; - hitWindows = null; + if (HitWindows == null) + HitWindows = CreateHitWindows(); + HitWindows?.SetDifficulty(difficulty.OverallDifficulty); } protected virtual void CreateNestedHitObjects() @@ -98,5 +97,11 @@ namespace osu.Game.Rulesets.Objects } protected void AddNested(HitObject hitObject) => nestedHitObjects.Add(hitObject); + + /// + /// Creates the for this . + /// + /// + protected virtual HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game/Rulesets/Objects/HitWindows.cs b/osu.Game/Rulesets/Objects/HitWindows.cs index bf0878a408..7610593d6a 100644 --- a/osu.Game/Rulesets/Objects/HitWindows.cs +++ b/osu.Game/Rulesets/Objects/HitWindows.cs @@ -63,10 +63,10 @@ namespace osu.Game.Rulesets.Objects public bool AllowsOk; /// - /// Constructs hit windows by fitting a parameter to a 2-part piecewise linear function for each hit window. + /// Sets hit windows with values that correspond to a difficulty parameter. /// /// The parameter. - public HitWindows(double difficulty) + public virtual void SetDifficulty(double difficulty) { Perfect = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Perfect]); Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]); From faa82f17cc1edd90bfa30c6dc53473b55b219335 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 15:30:50 +0900 Subject: [PATCH 098/229] Pass original hitobject HitWindows during conversion --- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 4 +++- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs | 8 +++++--- osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs | 8 +++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index c8a7402904..4f7c52860f 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -59,7 +59,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps protected override Beatmap ConvertBeatmap(IBeatmap original) { - BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty; int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate); @@ -85,7 +84,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps yield break; foreach (ManiaHitObject obj in objects) + { + obj.HitWindows = original.HitWindows; yield return obj; + } } private readonly List prevNoteTimes = new List(max_notes_for_density); diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs index 1cd4ec5668..54720548b4 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs @@ -40,7 +40,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps RepeatSamples = curveData.RepeatSamples, RepeatCount = curveData.RepeatCount, Position = positionData?.Position ?? Vector2.Zero, - NewCombo = comboData?.NewCombo ?? false + NewCombo = comboData?.NewCombo ?? false, + HitWindows = original.HitWindows }; } else if (endTimeData != null) @@ -50,8 +51,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps StartTime = original.StartTime, Samples = original.Samples, EndTime = endTimeData.EndTime, - Position = positionData?.Position ?? OsuPlayfield.BASE_SIZE / 2, + HitWindows = original.HitWindows }; } else @@ -61,7 +62,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps StartTime = original.StartTime, Samples = original.Samples, Position = positionData?.Position ?? Vector2.Zero, - NewCombo = comboData?.NewCombo ?? false + NewCombo = comboData?.NewCombo ?? false, + HitWindows = original.HitWindows }; } } diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index eeb0fa1871..58efc3336d 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -132,7 +132,8 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps { StartTime = j, Samples = currentSamples, - IsStrong = strong + IsStrong = strong, + HitWindows = obj.HitWindows }; } else @@ -142,6 +143,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps StartTime = j, Samples = currentSamples, IsStrong = strong, + HitWindows = obj.HitWindows }; } @@ -157,6 +159,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps IsStrong = strong, Duration = taikoDuration, TickRate = beatmap.BeatmapInfo.BaseDifficulty.SliderTickRate == 3 ? 3 : 4, + HitWindows = obj.HitWindows }; } } @@ -171,6 +174,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps IsStrong = strong, Duration = endTimeData.Duration, RequiredHits = (int)Math.Max(1, endTimeData.Duration / 1000 * hitMultiplier), + HitWindows = obj.HitWindows }; } else @@ -184,6 +188,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps StartTime = obj.StartTime, Samples = obj.Samples, IsStrong = strong, + HitWindows = obj.HitWindows }; } else @@ -193,6 +198,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps StartTime = obj.StartTime, Samples = obj.Samples, IsStrong = strong, + HitWindows = obj.HitWindows }; } } From 9c65d347ba271ff0775b96ca19c6b121681c8261 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 15:31:12 +0900 Subject: [PATCH 099/229] Add convert taiko HitWindows --- .../Objects/Legacy/Taiko/ConvertHit.cs | 2 ++ .../Objects/Legacy/Taiko/ConvertSlider.cs | 2 ++ .../Objects/Legacy/Taiko/ConvertSpinner.cs | 2 ++ .../Legacy/Taiko/ConvertTaikoHitWindows.cs | 28 +++++++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertTaikoHitWindows.cs diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs index 72d18664bf..bdcd1abf3c 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs @@ -11,5 +11,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko internal sealed class ConvertHit : HitObject, IHasCombo { public bool NewCombo { get; set; } + + protected override HitWindows CreateHitWindows() => new ConvertTaikoHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs index e810e687bd..0237ab9619 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs @@ -11,5 +11,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasCombo { public bool NewCombo { get; set; } + + protected override HitWindows CreateHitWindows() => new ConvertTaikoHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs index 193e50aed6..899f383bee 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs @@ -13,5 +13,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko public double EndTime { get; set; } public double Duration => EndTime - StartTime; + + protected override HitWindows CreateHitWindows() => new ConvertTaikoHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertTaikoHitWindows.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertTaikoHitWindows.cs new file mode 100644 index 0000000000..d3e8718307 --- /dev/null +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertTaikoHitWindows.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Objects.Legacy.Taiko +{ + public class ConvertTaikoHitWindows : HitWindows + { + private static readonly IReadOnlyDictionary base_ranges = new Dictionary + { + { HitResult.Great, (100, 70, 40) }, + { HitResult.Good, (240, 160, 100) }, + { HitResult.Meh, (270, 190, 140) }, + { HitResult.Miss, (400, 400, 400) }, + }; + + public override void SetDifficulty(double difficulty) + { + Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]); + Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]); + Meh = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Meh]); + Miss = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Miss]); + } + } +} From c052ee71c10b222a979b4449054f829b4d806f7c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 15:31:36 +0900 Subject: [PATCH 100/229] Add convert osu HitWindows --- .../Rulesets/Objects/Legacy/Osu/ConvertHit.cs | 2 ++ .../Legacy/Osu/ConvertOsuHitWindows.cs | 28 +++++++++++++++++++ .../Objects/Legacy/Osu/ConvertSlider.cs | 2 ++ .../Objects/Legacy/Osu/ConvertSpinner.cs | 2 ++ 4 files changed, 34 insertions(+) create mode 100644 osu.Game/Rulesets/Objects/Legacy/Osu/ConvertOsuHitWindows.cs diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs index f83173f498..bb5b0393e5 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs @@ -18,5 +18,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu public float Y => Position.Y; public bool NewCombo { get; set; } + + protected override HitWindows CreateHitWindows() => new ConvertOsuHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertOsuHitWindows.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertOsuHitWindows.cs new file mode 100644 index 0000000000..07d90f7012 --- /dev/null +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertOsuHitWindows.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Objects.Legacy.Osu +{ + public class ConvertOsuHitWindows : HitWindows + { + private static readonly IReadOnlyDictionary base_ranges = new Dictionary + { + { HitResult.Great, (160, 100, 40) }, + { HitResult.Good, (280, 200, 120) }, + { HitResult.Meh, (400, 300, 200) }, + { HitResult.Miss, (400, 400, 400) }, + }; + + public override void SetDifficulty(double difficulty) + { + Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]); + Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]); + Meh = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Meh]); + Miss = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Miss]); + } + } +} diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs index c6033d482c..cbe044605b 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs @@ -18,5 +18,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu public float Y => Position.Y; public bool NewCombo { get; set; } + + protected override HitWindows CreateHitWindows() => new ConvertOsuHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs index 28aac6862e..b580c5d1b3 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs @@ -20,5 +20,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu public float X => Position.X; public float Y => Position.Y; + + protected override HitWindows CreateHitWindows() => new ConvertOsuHitWindows(); } } From 856329179612d679f3da8f1ae4f34341a8c080d0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 15:32:00 +0900 Subject: [PATCH 101/229] Add convert mania HitWindows --- .../Objects/Legacy/Mania/ConvertHit.cs | 2 ++ .../Objects/Legacy/Mania/ConvertHold.cs | 2 ++ .../Legacy/Mania/ConvertManiaHitWindows.cs | 32 +++++++++++++++++++ .../Objects/Legacy/Mania/ConvertSlider.cs | 2 ++ .../Objects/Legacy/Mania/ConvertSpinner.cs | 2 ++ 5 files changed, 40 insertions(+) create mode 100644 osu.Game/Rulesets/Objects/Legacy/Mania/ConvertManiaHitWindows.cs diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs index 0db5a1dff1..6bf28c5e45 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs @@ -13,5 +13,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public float X { get; set; } public bool NewCombo { get; set; } + + protected override HitWindows CreateHitWindows() => new ConvertManiaHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs index e3b35e2f8e..087e5d5c12 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs @@ -12,5 +12,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public double EndTime { get; set; } public double Duration => EndTime - StartTime; + + protected override HitWindows CreateHitWindows() => new ConvertManiaHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertManiaHitWindows.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertManiaHitWindows.cs new file mode 100644 index 0000000000..072b45dc64 --- /dev/null +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertManiaHitWindows.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Objects.Legacy.Mania +{ + public class ConvertManiaHitWindows : HitWindows + { + private static readonly IReadOnlyDictionary base_ranges = new Dictionary + { + { HitResult.Perfect, (44.8, 38.8, 27.8) }, + { HitResult.Great, (128, 98, 68 ) }, + { HitResult.Good, (194, 164, 134) }, + { HitResult.Ok, (254, 224, 194) }, + { HitResult.Meh, (302, 272, 242) }, + { HitResult.Miss, (376, 346, 316) }, + }; + + public override void SetDifficulty(double difficulty) + { + Perfect = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Perfect]); + Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]); + Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]); + Ok = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Ok]); + Meh = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Meh]); + Miss = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Miss]); + } + } +} diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs index 32fb197c62..08ce465619 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs @@ -13,5 +13,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public float X { get; set; } public bool NewCombo { get; set; } + + protected override HitWindows CreateHitWindows() => new ConvertManiaHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs index c9b3046698..031ba54c59 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs @@ -15,5 +15,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public double Duration => EndTime - StartTime; public float X { get; set; } + + protected override HitWindows CreateHitWindows() => new ConvertManiaHitWindows(); } } From 0cdd39b8b8b06487339891af566d42d43cd36550 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 15:32:13 +0900 Subject: [PATCH 102/229] Add todo because TailNote shouldn't hardcore lenience --- osu.Game.Rulesets.Mania/Objects/HoldNote.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs index 4cf22ccd39..12e3d2de51 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs @@ -103,6 +103,7 @@ namespace osu.Game.Rulesets.Mania.Objects /// /// Lenience of release hit windows. This is to make cases where the hold note release /// is timed alongside presses of other hit objects less awkward. + /// Todo: This shouldn't exist for non-LegacyBeatmapDecoder beatmaps /// private const double release_window_lenience = 1.5; From 5245d2d4268633565006069190bd14776e3d03eb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 15:36:53 +0900 Subject: [PATCH 103/229] Add info about when CreateHitWindows is invoked --- osu.Game/Rulesets/Objects/HitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 70604855e9..d7d827bc97 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -100,8 +100,8 @@ namespace osu.Game.Rulesets.Objects /// /// Creates the for this . + /// This will only be invoked if hasn't been set externally (e.g. from a . /// - /// protected virtual HitWindows CreateHitWindows() => null; } } From bfad101d17ad04d8ee1093e730fa3cc2ce6bff52 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 15:42:34 +0900 Subject: [PATCH 104/229] Standardise naming --- osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs | 2 +- .../Mania/{ConvertManiaHitWindows.cs => ConvertHitWindows.cs} | 2 +- osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs | 2 +- .../Osu/{ConvertOsuHitWindows.cs => ConvertHitWindows.cs} | 2 +- osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs | 2 +- .../Taiko/{ConvertTaikoHitWindows.cs => ConvertHitWindows.cs} | 2 +- osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) rename osu.Game/Rulesets/Objects/Legacy/Mania/{ConvertManiaHitWindows.cs => ConvertHitWindows.cs} (96%) rename osu.Game/Rulesets/Objects/Legacy/Osu/{ConvertOsuHitWindows.cs => ConvertHitWindows.cs} (95%) rename osu.Game/Rulesets/Objects/Legacy/Taiko/{ConvertTaikoHitWindows.cs => ConvertHitWindows.cs} (95%) diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs index 6bf28c5e45..939d3b9c93 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public bool NewCombo { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertManiaHitWindows(); + protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertManiaHitWindows.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitWindows.cs similarity index 96% rename from osu.Game/Rulesets/Objects/Legacy/Mania/ConvertManiaHitWindows.cs rename to osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitWindows.cs index 072b45dc64..131492ea12 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertManiaHitWindows.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitWindows.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Objects.Legacy.Mania { - public class ConvertManiaHitWindows : HitWindows + public class ConvertHitWindows : HitWindows { private static readonly IReadOnlyDictionary base_ranges = new Dictionary { diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs index 087e5d5c12..22abc64b60 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs @@ -13,6 +13,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public double Duration => EndTime - StartTime; - protected override HitWindows CreateHitWindows() => new ConvertManiaHitWindows(); + protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs index 08ce465619..6bca5b717c 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public bool NewCombo { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertManiaHitWindows(); + protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs index 031ba54c59..1dc826af9b 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs @@ -16,6 +16,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public float X { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertManiaHitWindows(); + protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs index bb5b0393e5..23955b2d23 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs @@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu public bool NewCombo { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertOsuHitWindows(); + protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertOsuHitWindows.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitWindows.cs similarity index 95% rename from osu.Game/Rulesets/Objects/Legacy/Osu/ConvertOsuHitWindows.cs rename to osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitWindows.cs index 07d90f7012..fd86173372 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertOsuHitWindows.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitWindows.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Objects.Legacy.Osu { - public class ConvertOsuHitWindows : HitWindows + public class ConvertHitWindows : HitWindows { private static readonly IReadOnlyDictionary base_ranges = new Dictionary { diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs index cbe044605b..35b8c1c7dd 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs @@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu public bool NewCombo { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertOsuHitWindows(); + protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs index b580c5d1b3..73b8369aca 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs @@ -21,6 +21,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu public float Y => Position.Y; - protected override HitWindows CreateHitWindows() => new ConvertOsuHitWindows(); + protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs index bdcd1abf3c..11db086778 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs @@ -12,6 +12,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko { public bool NewCombo { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertTaikoHitWindows(); + protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertTaikoHitWindows.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitWindows.cs similarity index 95% rename from osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertTaikoHitWindows.cs rename to osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitWindows.cs index d3e8718307..6fbf7e122f 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertTaikoHitWindows.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitWindows.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Objects.Legacy.Taiko { - public class ConvertTaikoHitWindows : HitWindows + public class ConvertHitWindows : HitWindows { private static readonly IReadOnlyDictionary base_ranges = new Dictionary { diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs index 0237ab9619..95c69222b5 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs @@ -12,6 +12,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko { public bool NewCombo { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertTaikoHitWindows(); + protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs index 899f383bee..7baea212ea 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko public double Duration => EndTime - StartTime; - protected override HitWindows CreateHitWindows() => new ConvertTaikoHitWindows(); + protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); } } From 97a523584da0b8b686961cccc71763cb8189b50f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 15:52:51 +0900 Subject: [PATCH 105/229] Make HitWindows not return null by default --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 2 ++ osu.Game/Rulesets/Objects/HitObject.cs | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index 95ffd41518..548813fbd2 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -47,6 +47,8 @@ namespace osu.Game.Rulesets.Catch.Objects Scale = 1.0f - 0.7f * (difficulty.CircleSize - 5) / 5; } + + protected override HitWindows CreateHitWindows() => null; } public enum FruitVisualRepresentation diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index d7d827bc97..cd612a5387 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -100,8 +100,11 @@ namespace osu.Game.Rulesets.Objects /// /// Creates the for this . + /// This can be null to indicate that the has no . + /// /// This will only be invoked if hasn't been set externally (e.g. from a . + /// /// - protected virtual HitWindows CreateHitWindows() => null; + protected virtual HitWindows CreateHitWindows() => new HitWindows(); } } From 3e7fa45ad18b168fe3a0268f635143c8bbe9b05e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 16:12:56 +0900 Subject: [PATCH 106/229] Fix tests --- .../TestCaseManiaHitObjects.cs | 16 ++++++++++++---- .../Beatmaps/Formats/OsuJsonDecoderTest.cs | 3 ++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseManiaHitObjects.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseManiaHitObjects.cs index 281c2789af..dd81d015f1 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseManiaHitObjects.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseManiaHitObjects.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; +using osu.Game.Rulesets.Objects; using osu.Game.Tests.Visual; using OpenTK; using OpenTK.Graphics; @@ -17,6 +18,9 @@ namespace osu.Game.Rulesets.Mania.Tests { public TestCaseManiaHitObjects() { + var hitWindows = new HitWindows(); + hitWindows.SetDifficulty(5); + Add(new FillFlowContainer { Anchor = Anchor.Centre, @@ -43,14 +47,14 @@ namespace osu.Game.Rulesets.Mania.Tests RelativeChildSize = new Vector2(1, 10000), Children = new[] { - new DrawableNote(new Note(), ManiaAction.Key1) + new DrawableNote(new Note { HitWindows = hitWindows }, ManiaAction.Key1) { Y = 5000, LifetimeStart = double.MinValue, LifetimeEnd = double.MaxValue, AccentColour = Color4.Red }, - new DrawableNote(new Note(), ManiaAction.Key1) + new DrawableNote(new Note { HitWindows = hitWindows }, ManiaAction.Key1) { Y = 6000, LifetimeStart = double.MinValue, @@ -77,13 +81,17 @@ namespace osu.Game.Rulesets.Mania.Tests RelativeChildSize = new Vector2(1, 10000), Children = new[] { - new DrawableHoldNote(new HoldNote { Duration = 1000 } , ManiaAction.Key1) + new DrawableHoldNote(new HoldNote + { + Duration = 1000, + HitWindows = hitWindows + } , ManiaAction.Key1) { Y = 5000, Height = 1000, LifetimeStart = double.MinValue, LifetimeEnd = double.MaxValue, - AccentColour = Color4.Red + AccentColour = Color4.Red, } } } diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 6e0cf6be2e..489c38c420 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -9,6 +9,7 @@ using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.IO.Serialization; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Tests.Resources; using OpenTK; @@ -117,7 +118,7 @@ namespace osu.Game.Tests.Beatmaps.Formats public void TestParity(string beatmap) { var legacy = decode(beatmap, out Beatmap json); - json.ShouldDeepEqual(legacy); + json.WithDeepEqual(legacy).IgnoreProperty(r => r.DeclaringType == typeof(HitWindows)).Assert(); } /// From fa403e4e2ae4a2a0ad36f5f2261239093994c2d3 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 11 May 2018 04:45:27 -0300 Subject: [PATCH 107/229] Add test step to test pushing after a previous screen is made current. --- osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs | 3 +++ osu.Game/Graphics/UserInterface/BreadcrumbControl.cs | 1 + 2 files changed, 4 insertions(+) diff --git a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs index 3e0dd9e018..f477a0b97e 100644 --- a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs +++ b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -64,6 +65,8 @@ namespace osu.Game.Tests.Visual }); assertCurrent(); + pushNext(); + AddAssert(@"assert there are only 2 items", () => breadcrumbs.Items.Count() == 2); } [BackgroundDependencyLoader] diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs index 3f59eeca97..6b7f235b34 100644 --- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs @@ -47,6 +47,7 @@ namespace osu.Game.Graphics.UserInterface public override bool HandleKeyboardInput => State == Visibility.Visible; public override bool HandleMouseInput => State == Visibility.Visible; + public override bool IsRemovable => true; private Visibility state; From 4fc887b25f1addd4cc08d7cdcb6e93df23c3ad16 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 11 May 2018 21:40:36 +0900 Subject: [PATCH 108/229] Add a pressing effect to make mouse up response feel good --- osu.Game/Overlays/Mods/ModButton.cs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index 3f1541aee3..1d012b1288 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -116,6 +116,7 @@ namespace osu.Game.Overlays.Mods } private Mod mod; + private Container scaleContainer; public Mod Mod { @@ -147,8 +148,16 @@ namespace osu.Game.Overlays.Mods public virtual Mod SelectedMod => Mods.ElementAtOrDefault(selectedIndex); + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + scaleContainer.ScaleTo(0.9f, 800, Easing.Out); + return base.OnMouseDown(state, args); + } + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { + scaleContainer.ScaleTo(1, 500, Easing.OutElastic); + // only trigger the event if we are inside the area of the button if (Contains(ToScreenSpace(state.Mouse.Position - Position))) { @@ -162,6 +171,7 @@ namespace osu.Game.Overlays.Mods break; } } + return true; } @@ -179,7 +189,8 @@ namespace osu.Game.Overlays.Mods start = Mods.Length - 1; for (int i = start; i < Mods.Length && i >= 0; i += direction) - if (SelectAt(i)) return; + if (SelectAt(i)) + return; Deselect(); } @@ -245,8 +256,14 @@ namespace osu.Game.Overlays.Mods Anchor = Anchor.TopCentre, Children = new Drawable[] { - iconsContainer = new Container + scaleContainer = new Container { + Child = iconsContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + }, RelativeSizeAxes = Axes.Both, Origin = Anchor.Centre, Anchor = Anchor.Centre, From 7cb0d328e60fbccc495b419fc69eed730b348881 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 11 May 2018 21:40:48 +0900 Subject: [PATCH 109/229] Make mods screen dynamically testable --- osu.Game.Tests/Visual/TestCaseMods.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseMods.cs b/osu.Game.Tests/Visual/TestCaseMods.cs index dad8fb8fed..d3d21509fd 100644 --- a/osu.Game.Tests/Visual/TestCaseMods.cs +++ b/osu.Game.Tests/Visual/TestCaseMods.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.ComponentModel; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -17,6 +18,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Mania.Mods; +using osu.Game.Rulesets.UI; using OpenTK.Graphics; namespace osu.Game.Tests.Visual @@ -24,6 +26,19 @@ namespace osu.Game.Tests.Visual [Description("mod select and icon display")] public class TestCaseMods : OsuTestCase { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(ModSelectOverlay), + typeof(ModDisplay), + typeof(ModSection), + typeof(ModIcon), + typeof(ModButton), + typeof(ModButtonEmpty), + typeof(DifficultyReductionSection), + typeof(DifficultyIncreaseSection), + typeof(SpecialSection), + }; + private const string unranked_suffix = " (Unranked)"; private RulesetStore rulesets; @@ -66,7 +81,8 @@ namespace osu.Game.Tests.Visual Ruleset ruleset = rulesetInfo.CreateInstance(); AddStep($"switch to {ruleset.Description}", () => modSelect.Ruleset.Value = rulesetInfo); - switch (ruleset) { + switch (ruleset) + { case OsuRuleset or: testOsuMods(or); break; From aa5d5ab2a844c5834134b159c1960b2c3f397dca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 11 May 2018 21:48:35 +0900 Subject: [PATCH 110/229] Fix readonly field --- osu.Game/Overlays/Mods/ModButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Mods/ModButton.cs b/osu.Game/Overlays/Mods/ModButton.cs index 1d012b1288..f4e0e3db04 100644 --- a/osu.Game/Overlays/Mods/ModButton.cs +++ b/osu.Game/Overlays/Mods/ModButton.cs @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.Mods } private Mod mod; - private Container scaleContainer; + private readonly Container scaleContainer; public Mod Mod { From 8ca67f63ece8c3469557ebe6278f67e22d6f5a57 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 20:31:57 +0900 Subject: [PATCH 111/229] Fix score statistics not being read --- .../Scoring/Legacy/LegacyScoreParser.cs | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs index d5ab856697..1cc30afe7b 100644 --- a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs @@ -49,18 +49,21 @@ namespace osu.Game.Rulesets.Scoring.Legacy score.User = new User { Username = sr.ReadString() }; /* var localScoreChecksum = */ sr.ReadString(); - /* score.Count300 = */ - sr.ReadUInt16(); - /* score.Count100 = */ - sr.ReadUInt16(); - /* score.Count50 = */ - sr.ReadUInt16(); - /* score.CountGeki = */ - sr.ReadUInt16(); - /* score.CountKatu = */ - sr.ReadUInt16(); - /* score.CountMiss = */ - sr.ReadUInt16(); + + var count300 = sr.ReadUInt16(); + var count100 = sr.ReadUInt16(); + var count50 = sr.ReadUInt16(); + var countGeki = sr.ReadUInt16(); + var countKatu = sr.ReadUInt16(); + var countMiss = sr.ReadUInt16(); + + score.Statistics[HitResult.Great] = count300; + score.Statistics[HitResult.Good] = count100; + score.Statistics[HitResult.Meh] = count50; + score.Statistics[HitResult.Perfect] = countGeki; + score.Statistics[HitResult.Ok] = countKatu; + score.Statistics[HitResult.Miss] = countMiss; + score.TotalScore = sr.ReadInt32(); score.MaxCombo = sr.ReadUInt16(); /* score.Perfect = */ From 7e7a5f8964972a045cf4f6ef2f47332937a49f82 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 20:32:06 +0900 Subject: [PATCH 112/229] Fix score accuracy not being populated --- .../Scoring/Legacy/LegacyScoreParser.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs index 1cc30afe7b..38873c4df1 100644 --- a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs @@ -84,6 +84,34 @@ namespace osu.Game.Rulesets.Scoring.Legacy /*OnlineId =*/ sr.ReadInt32(); + switch (score.Ruleset.ID) + { + case 0: + { + int totalHits = count50 + count100 + count300 + countMiss; + score.Accuracy = totalHits > 0 ? (double)(count50 * 50 + count100 * 100 + count300 * 300) / (totalHits * 300) : 1; + break; + } + case 1: + { + int totalHits = count50 + count100 + count300 + countMiss; + score.Accuracy = totalHits > 0 ? (double)(count100 * 150 + count300 * 300) / (totalHits * 300) : 1; + break; + } + case 2: + { + int totalHits = count50 + count100 + count300 + countMiss + countKatu; + score.Accuracy = totalHits > 0 ? (double)(count50 + count100 + count300 ) / totalHits : 1; + break; + } + case 3: + { + int totalHits = count50 + count100 + count300 + countMiss + countGeki + countKatu; + score.Accuracy = totalHits > 0 ? (double)(count50 * 50 + count100 * 100 + countKatu * 200 + (count300 + countGeki) * 300) / (totalHits * 300) : 1; + break; + } + } + using (var replayInStream = new MemoryStream(compressedReplay)) { byte[] properties = new byte[5]; From 224f1a0810f75b6d292ee49fa0d0a0c02be60579 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 21:48:10 +0900 Subject: [PATCH 113/229] Fix incorrect osu! difficulty calculator combo count --- osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index 6b9214d9dc..103fdeadea 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Scoring countHitCircles = Beatmap.HitObjects.Count(h => h is HitCircle); beatmapMaxCombo = Beatmap.HitObjects.Count(); - beatmapMaxCombo += Beatmap.HitObjects.OfType().Sum(s => s.NestedHitObjects.Count) + 1; + beatmapMaxCombo += Beatmap.HitObjects.OfType().Count(); } public override double Calculate(Dictionary categoryRatings = null) From a33724899973bd46204dfa981d6bc82ba66f0526 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 11 May 2018 22:06:16 +0900 Subject: [PATCH 114/229] Fix incorrect count --- osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index 103fdeadea..b4324c77fc 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -32,7 +32,8 @@ namespace osu.Game.Rulesets.Osu.Scoring countHitCircles = Beatmap.HitObjects.Count(h => h is HitCircle); beatmapMaxCombo = Beatmap.HitObjects.Count(); - beatmapMaxCombo += Beatmap.HitObjects.OfType().Count(); + // Add the ticks + tail of the slider. 1 is subtracted because the "headcircle" would be counted twice (once for the slider itself in the line above) + beatmapMaxCombo += Beatmap.HitObjects.OfType().Sum(s => s.NestedHitObjects.Count - 1); } public override double Calculate(Dictionary categoryRatings = null) From cfa18bdf1fa2823dd6ead2b9c37a3ce67be4b746 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 11 May 2018 22:09:53 +0900 Subject: [PATCH 115/229] Fix song progress time counters wrapping after an hour Resolves #2466. Supersedes and closes #2487. --- osu.Game/Screens/Play/SongProgressInfo.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/SongProgressInfo.cs b/osu.Game/Screens/Play/SongProgressInfo.cs index 5cc4b30950..b79c212ade 100644 --- a/osu.Game/Screens/Play/SongProgressInfo.cs +++ b/osu.Game/Screens/Play/SongProgressInfo.cs @@ -85,11 +85,13 @@ namespace osu.Game.Screens.Play if (currentSecond != previousSecond && songCurrentTime < songLength) { - timeCurrent.Text = TimeSpan.FromSeconds(currentSecond).ToString(songCurrentTime < 0 ? @"\-m\:ss" : @"m\:ss"); - timeLeft.Text = TimeSpan.FromMilliseconds(endTime - AudioClock.CurrentTime).ToString(@"\-m\:ss"); + timeCurrent.Text = formatTime(TimeSpan.FromSeconds(currentSecond)); + timeLeft.Text = formatTime(TimeSpan.FromMilliseconds(endTime - AudioClock.CurrentTime)); previousSecond = currentSecond; } } + + private string formatTime(TimeSpan timeSpan) => $"{(timeSpan < TimeSpan.Zero ? "-" : "")}{timeSpan.Duration().TotalMinutes:N0}:{timeSpan.Duration().Seconds:D2}"; } } From a14531b9a4d0f4b101d5af1e91df2eb2877bcc1c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 11 May 2018 22:57:36 +0900 Subject: [PATCH 116/229] Fix crash on startup when adjusting volume before volume control loaded --- osu.Game/Overlays/VolumeOverlay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index da63495fec..f922c507f7 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -100,6 +100,8 @@ namespace osu.Game.Overlays public bool Adjust(GlobalAction action) { + if (!IsLoaded) return false; + switch (action) { case GlobalAction.DecreaseVolume: From 41de02fc78e08513e9588a6d02090044155ed32f Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 11 May 2018 13:43:53 -0300 Subject: [PATCH 117/229] Make DrawableRooms select when they are clicked. --- osu.Game/Screens/Multi/Components/DrawableRoom.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Multi/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Components/DrawableRoom.cs index f3ce3dcd8e..994b0e886b 100644 --- a/osu.Game/Screens/Multi/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Components/DrawableRoom.cs @@ -9,6 +9,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; @@ -79,6 +80,8 @@ namespace osu.Game.Screens.Multi.Components RelativeSizeAxes = Axes.Both, Alpha = 0f, }; + + Action += () => State = SelectionState.Selected; } [BackgroundDependencyLoader] From 937ff50a5a4269431973066233d776fc16ace442 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 11 May 2018 13:56:27 -0300 Subject: [PATCH 118/229] Remove unused using. --- osu.Game/Screens/Multi/Components/DrawableRoom.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Components/DrawableRoom.cs index 994b0e886b..88a253d719 100644 --- a/osu.Game/Screens/Multi/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Components/DrawableRoom.cs @@ -9,7 +9,6 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; From 6ebe9f88e78b1c222fcecb6ba4b3ec5f0e003eed Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 12 May 2018 11:11:09 +0900 Subject: [PATCH 119/229] Update framework with upstream fixes --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 8c4f232694..f807997301 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 8c4f23269447d9ce21a5dbd3a0fd4f6caae9ab38 +Subproject commit f8079973011b54e84e5c0e677fe2b56e55947666 From 416ed725977527718f4c5fe744e0a60181c0cd8e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 12 May 2018 15:46:25 +0900 Subject: [PATCH 120/229] Port osu-performance changes into OsuPerformanceCalculator --- osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index 6b9214d9dc..a06e71e20c 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -121,7 +121,7 @@ namespace osu.Game.Rulesets.Osu.Scoring aimValue *= approachRateFactor; if (mods.Any(h => h is OsuModHidden)) - aimValue *= 1.18f; + aimValue *= 1.03f; if (mods.Any(h => h is OsuModFlashlight)) { @@ -152,6 +152,9 @@ namespace osu.Game.Rulesets.Osu.Scoring if (beatmapMaxCombo > 0) speedValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8f) / Math.Pow(beatmapMaxCombo, 0.8f), 1.0f); + if (mods.Any(m => m is OsuModHidden)) + speedValue *= 1.18f; + // Scale the speed value with accuracy _slightly_ speedValue *= 0.5f + accuracy / 2.0f; // It is important to also consider accuracy difficulty when doing that From df43fc6ff8defe26d52b002f19ebd20bb8515a90 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 13 May 2018 01:31:17 +0900 Subject: [PATCH 121/229] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index eaa640972c..fac688633b 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit eaa640972ca9c67f0ea15a942035b5b3a78f1570 +Subproject commit fac688633b8fcf34ae5d0514c26b03e217161eb4 From 8a5bd27c2018e0ae4f980e77aea891f70b1ce562 Mon Sep 17 00:00:00 2001 From: ocboogie Date: Sat, 12 May 2018 16:30:29 -0700 Subject: [PATCH 122/229] Add global key bindings for changing current ruleset --- .../Overlays/Toolbar/ToolbarModeSelector.cs | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 1da51e4a5a..4855c004c4 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -1,11 +1,14 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Caching; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Input.Bindings; using OpenTK; using OpenTK.Graphics; using osu.Framework.Configuration; @@ -14,7 +17,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.Toolbar { - public class ToolbarModeSelector : Container + public class ToolbarModeSelector : KeyBindingContainer { private const float padding = 10; @@ -22,6 +25,7 @@ namespace osu.Game.Overlays.Toolbar private readonly Drawable modeButtonLine; private ToolbarModeButton activeButton; + private int rulesetCount; private readonly Bindable ruleset = new Bindable(); public ToolbarModeSelector() @@ -64,9 +68,50 @@ namespace osu.Game.Overlays.Toolbar }; } + public override IEnumerable DefaultKeyBindings + { + get + { + var keybinds = new List(); + for (int i = 0; i < Math.Min(rulesetCount, 10); i++) + { + InputKey numberKey; + if (i == 9) + numberKey = InputKey.Number0; + else + numberKey = (InputKey)i + 110; + + keybinds.Add(new osu.Framework.Input.Bindings.KeyBinding(new[] { InputKey.Control, numberKey }, i)); + } + return keybinds; + } + } + + private class RulesetSwitcherInputHandler : Container, IKeyBindingHandler + { + private Bindable ruleset; + private RulesetStore rulesets; + + public RulesetSwitcherInputHandler(Bindable ruleset, RulesetStore rulesets) + { + this.ruleset = ruleset; + this.rulesets = rulesets; + } + + public bool OnPressed(int action) + { + ruleset.Value = rulesets.GetRuleset(action); + + return true; + } + + public bool OnReleased(int action) => false; + } + [BackgroundDependencyLoader(true)] private void load(RulesetStore rulesets, OsuGame game) { + this.rulesetCount = rulesets.AvailableRulesets.Count(); foreach (var r in rulesets.AvailableRulesets) { modeButtons.Add(new ToolbarModeButton @@ -85,6 +130,8 @@ namespace osu.Game.Overlays.Toolbar ruleset.BindTo(game.Ruleset); else ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(); + + Add(new RulesetSwitcherInputHandler(ruleset, rulesets)); } public override bool HandleKeyboardInput => !ruleset.Disabled && base.HandleKeyboardInput; From 26f06a9ae1612e19bdc372873fd17ed84f70179e Mon Sep 17 00:00:00 2001 From: ocboogie Date: Sat, 12 May 2018 17:25:15 -0700 Subject: [PATCH 123/229] Resolve linting issues in ToolbarModeSelector.cs --- osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 4855c004c4..889cf8885e 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -89,8 +89,8 @@ namespace osu.Game.Overlays.Toolbar private class RulesetSwitcherInputHandler : Container, IKeyBindingHandler { - private Bindable ruleset; - private RulesetStore rulesets; + private readonly Bindable ruleset; + private readonly RulesetStore rulesets; public RulesetSwitcherInputHandler(Bindable ruleset, RulesetStore rulesets) { @@ -111,7 +111,7 @@ namespace osu.Game.Overlays.Toolbar [BackgroundDependencyLoader(true)] private void load(RulesetStore rulesets, OsuGame game) { - this.rulesetCount = rulesets.AvailableRulesets.Count(); + rulesetCount = rulesets.AvailableRulesets.Count(); foreach (var r in rulesets.AvailableRulesets) { modeButtons.Add(new ToolbarModeButton From db0470243ad2f3e19da40b1f8dcd67d353872173 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 13 May 2018 12:55:54 +0900 Subject: [PATCH 124/229] Fix nullref when changing ruleset at main menu --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 236b1310e1..97f6371cb2 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -88,17 +88,27 @@ namespace osu.Game.Screens.Select private void loadBeatmap() { + void updateState() + { + State = beatmap == null ? Visibility.Hidden : Visibility.Visible; + + Info?.FadeOut(250); + Info?.Expire(); + } + + if (beatmap == null) + { + updateState(); + return; + } + LoadComponentAsync(new BufferedWedgeInfo(beatmap, ruleset.Value) { Shear = -Shear, Depth = Info?.Depth + 1 ?? 0, }, newInfo => { - State = beatmap == null ? Visibility.Hidden : Visibility.Visible; - - Info?.FadeOut(250); - Info?.Expire(); - + updateState(); Add(Info = newInfo); }); } From e1b8a1589bae578864766632fe7d6da7b77b9354 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 11:15:14 +0900 Subject: [PATCH 125/229] Fix TimeRate not being considered for performance calculation --- .../Scoring/OsuPerformanceCalculator.cs | 24 +++++++++++++++---- osu.Game/Beatmaps/DifficultyCalculator.cs | 2 +- .../Rulesets/Scoring/PerformanceCalculator.cs | 15 ++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index a12bdf7f20..aa94572cb4 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -18,7 +18,17 @@ namespace osu.Game.Rulesets.Osu.Scoring private readonly int beatmapMaxCombo; private Mod[] mods; + + /// + /// Approach rate adjusted by mods. + /// private double realApproachRate; + + /// + /// Overall difficulty adjusted by mods. + /// + private double realOverallDifficulty; + private double accuracy; private int scoreMaxCombo; private int count300; @@ -58,9 +68,13 @@ namespace osu.Game.Rulesets.Osu.Scoring ar = Math.Min(10, ar * 1.4); if (mods.Any(m => m is OsuModEasy)) ar = Math.Max(0, ar / 2); - double preEmpt = BeatmapDifficulty.DifficultyRange(ar, 1800, 1200, 450); - realApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5; + double preEmpt = BeatmapDifficulty.DifficultyRange(ar, 1800, 1200, 450) / TimeRate; + double hitWindow300 = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; + + realApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5; + realOverallDifficulty = (80 - 0.5 - hitWindow300) / 6; + // Custom multipliers for NoFail and SpunOut. double multiplier = 1.12f; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things @@ -133,7 +147,7 @@ namespace osu.Game.Rulesets.Osu.Scoring // Scale the aim value with accuracy _slightly_ aimValue *= 0.5f + accuracy / 2.0f; // It is important to also consider accuracy difficulty when doing that - aimValue *= 0.98f + Math.Pow(Beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty, 2) / 2500; + aimValue *= 0.98f + Math.Pow(realOverallDifficulty, 2) / 2500; return aimValue; } @@ -159,7 +173,7 @@ namespace osu.Game.Rulesets.Osu.Scoring // Scale the speed value with accuracy _slightly_ speedValue *= 0.5f + accuracy / 2.0f; // It is important to also consider accuracy difficulty when doing that - speedValue *= 0.98f + Math.Pow(Beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty, 2) / 2500; + speedValue *= 0.98f + Math.Pow(realOverallDifficulty, 2) / 2500; return speedValue; } @@ -181,7 +195,7 @@ namespace osu.Game.Rulesets.Osu.Scoring // Lots of arbitrary values from testing. // Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution - double accuracyValue = Math.Pow(1.52163f, Beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty) * Math.Pow(betterAccuracyPercentage, 24) * 2.83f; + double accuracyValue = Math.Pow(1.52163f, realOverallDifficulty) * Math.Pow(betterAccuracyPercentage, 24) * 2.83f; // Bonus for many hitcircles - it's harder to keep good accuracy up for longer accuracyValue *= Math.Min(1.15f, Math.Pow(amountHitObjectsWithAccuracy / 1000.0f, 0.3f)); diff --git a/osu.Game/Beatmaps/DifficultyCalculator.cs b/osu.Game/Beatmaps/DifficultyCalculator.cs index 37155c09cd..5cac9ed923 100644 --- a/osu.Game/Beatmaps/DifficultyCalculator.cs +++ b/osu.Game/Beatmaps/DifficultyCalculator.cs @@ -14,7 +14,7 @@ namespace osu.Game.Beatmaps protected readonly IBeatmap Beatmap; protected readonly Mod[] Mods; - protected double TimeRate = 1; + protected double TimeRate { get; private set; } = 1; protected DifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) { diff --git a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs b/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs index 5b8f5f0d0f..b23e06e15c 100644 --- a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs +++ b/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs @@ -2,7 +2,11 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Timing; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Scoring { @@ -14,6 +18,8 @@ namespace osu.Game.Rulesets.Scoring protected readonly IBeatmap Beatmap; protected readonly Score Score; + protected double TimeRate { get; private set; } = 1; + protected PerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) { Score = score; @@ -22,6 +28,15 @@ namespace osu.Game.Rulesets.Scoring var diffCalc = ruleset.CreateDifficultyCalculator(beatmap, score.Mods); diffCalc.Calculate(attributes); + + ApplyMods(score.Mods); + } + + protected virtual void ApplyMods(Mod[] mods) + { + var clock = new StopwatchClock(); + mods.OfType().ForEach(m => m.ApplyToClock(clock)); + TimeRate = clock.Rate; } public abstract double Calculate(Dictionary categoryDifficulty = null); From ce6b4cc2d30d60480793d1c94838f0f0e6500680 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 11:15:37 +0900 Subject: [PATCH 126/229] Add more attributes to OsuPerformanceCalculator's output --- osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index aa94572cb4..e927cc946e 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -99,6 +99,9 @@ namespace osu.Game.Rulesets.Osu.Scoring categoryRatings.Add("Aim", aimValue); categoryRatings.Add("Speed", speedValue); categoryRatings.Add("Accuracy", accuracyValue); + categoryRatings.Add("OD", realOverallDifficulty); + categoryRatings.Add("AR", realApproachRate); + categoryRatings.Add("Max Combo", beatmapMaxCombo); } return totalValue; From 8c86f170a928404e63800d552179fff236bb10e9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 11:33:23 +0900 Subject: [PATCH 127/229] Fix mania testcases --- .../TestCaseManiaHitObjects.cs | 22 +++++---- .../TestCaseManiaPlayfield.cs | 47 +++++++++---------- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseManiaHitObjects.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseManiaHitObjects.cs index dd81d015f1..a4109722d4 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseManiaHitObjects.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseManiaHitObjects.cs @@ -4,9 +4,10 @@ using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; -using osu.Game.Rulesets.Objects; using osu.Game.Tests.Visual; using OpenTK; using OpenTK.Graphics; @@ -18,8 +19,13 @@ namespace osu.Game.Rulesets.Mania.Tests { public TestCaseManiaHitObjects() { - var hitWindows = new HitWindows(); - hitWindows.SetDifficulty(5); + Note note1 = new Note(); + Note note2 = new Note(); + HoldNote holdNote = new HoldNote { StartTime = 1000 }; + + note1.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + note2.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + holdNote.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); Add(new FillFlowContainer { @@ -47,14 +53,14 @@ namespace osu.Game.Rulesets.Mania.Tests RelativeChildSize = new Vector2(1, 10000), Children = new[] { - new DrawableNote(new Note { HitWindows = hitWindows }, ManiaAction.Key1) + new DrawableNote(note1, ManiaAction.Key1) { Y = 5000, LifetimeStart = double.MinValue, LifetimeEnd = double.MaxValue, AccentColour = Color4.Red }, - new DrawableNote(new Note { HitWindows = hitWindows }, ManiaAction.Key1) + new DrawableNote(note2, ManiaAction.Key1) { Y = 6000, LifetimeStart = double.MinValue, @@ -81,11 +87,7 @@ namespace osu.Game.Rulesets.Mania.Tests RelativeChildSize = new Vector2(1, 10000), Children = new[] { - new DrawableHoldNote(new HoldNote - { - Duration = 1000, - HitWindows = hitWindows - } , ManiaAction.Key1) + new DrawableHoldNote(holdNote, ManiaAction.Key1) { Y = 5000, Height = 1000, diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseManiaPlayfield.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseManiaPlayfield.cs index 053f478027..dff2b2d56a 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseManiaPlayfield.cs @@ -8,6 +8,8 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Timing; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Configuration; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Configuration; @@ -83,13 +85,16 @@ namespace osu.Game.Rulesets.Mania.Tests int col = rng.Next(0, 4); - var note = new DrawableNote(new Note { Column = col }, ManiaAction.Key1) + var note = new Note { Column = col }; + note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + + var drawableNote = new DrawableNote(note, ManiaAction.Key1) { AccentColour = playfield.Columns.ElementAt(col).AccentColour }; - playfield.OnJudgement(note, new ManiaJudgement { Result = HitResult.Perfect }); - playfield.Columns[col].OnJudgement(note, new ManiaJudgement { Result = HitResult.Perfect }); + playfield.OnJudgement(drawableNote, new ManiaJudgement { Result = HitResult.Perfect }); + playfield.Columns[col].OnJudgement(drawableNote, new ManiaJudgement { Result = HitResult.Perfect }); }); } @@ -162,32 +167,24 @@ namespace osu.Game.Rulesets.Mania.Tests for (double t = start_time; t <= start_time + duration; t += 100) { - playfield.Add(new DrawableNote(new Note - { - StartTime = t, - Column = 0 - }, ManiaAction.Key1)); + var note1 = new Note { StartTime = t, Column = 0 }; + var note2 = new Note { StartTime = t, Column = 3 }; - playfield.Add(new DrawableNote(new Note - { - StartTime = t, - Column = 3 - }, ManiaAction.Key4)); + note1.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + note2.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + + playfield.Add(new DrawableNote(note1, ManiaAction.Key1)); + playfield.Add(new DrawableNote(note2, ManiaAction.Key4)); } - playfield.Add(new DrawableHoldNote(new HoldNote - { - StartTime = start_time, - Duration = duration, - Column = 1 - }, ManiaAction.Key2)); + var holdNote1 = new HoldNote { StartTime = start_time, Duration = duration, Column = 1 }; + var holdNote2 = new HoldNote { StartTime = start_time, Duration = duration, Column = 2 }; - playfield.Add(new DrawableHoldNote(new HoldNote - { - StartTime = start_time, - Duration = duration, - Column = 2 - }, ManiaAction.Key3)); + holdNote1.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + holdNote2.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + + playfield.Add(new DrawableHoldNote(holdNote1, ManiaAction.Key2)); + playfield.Add(new DrawableHoldNote(holdNote2, ManiaAction.Key3)); } } } From 327c7432be72ab79e882a6dc9d8e0c51d310d485 Mon Sep 17 00:00:00 2001 From: ocboogie Date: Sun, 13 May 2018 19:33:52 -0700 Subject: [PATCH 128/229] Use OnKeyDown instead of a IKeyBindingHandler --- .../Overlays/Toolbar/ToolbarModeSelector.cs | 66 ++++++------------- 1 file changed, 21 insertions(+), 45 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 889cf8885e..7286cf3f1c 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -4,12 +4,14 @@ using System; using System.Linq; using System.Collections.Generic; +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Caching; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Input.Bindings; +using osu.Framework.Input; using OpenTK; +using OpenTK.Input; using OpenTK.Graphics; using osu.Framework.Configuration; using osu.Framework.Graphics.Shapes; @@ -17,7 +19,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.Toolbar { - public class ToolbarModeSelector : KeyBindingContainer + public class ToolbarModeSelector : Container { private const float padding = 10; @@ -25,7 +27,7 @@ namespace osu.Game.Overlays.Toolbar private readonly Drawable modeButtonLine; private ToolbarModeButton activeButton; - private int rulesetCount; + private RulesetStore rulesets; private readonly Bindable ruleset = new Bindable(); public ToolbarModeSelector() @@ -68,50 +70,10 @@ namespace osu.Game.Overlays.Toolbar }; } - public override IEnumerable DefaultKeyBindings - { - get - { - var keybinds = new List(); - for (int i = 0; i < Math.Min(rulesetCount, 10); i++) - { - InputKey numberKey; - if (i == 9) - numberKey = InputKey.Number0; - else - numberKey = (InputKey)i + 110; - - keybinds.Add(new osu.Framework.Input.Bindings.KeyBinding(new[] { InputKey.Control, numberKey }, i)); - } - return keybinds; - } - } - - private class RulesetSwitcherInputHandler : Container, IKeyBindingHandler - { - private readonly Bindable ruleset; - private readonly RulesetStore rulesets; - - public RulesetSwitcherInputHandler(Bindable ruleset, RulesetStore rulesets) - { - this.ruleset = ruleset; - this.rulesets = rulesets; - } - - public bool OnPressed(int action) - { - ruleset.Value = rulesets.GetRuleset(action); - - return true; - } - - public bool OnReleased(int action) => false; - } - [BackgroundDependencyLoader(true)] private void load(RulesetStore rulesets, OsuGame game) { - rulesetCount = rulesets.AvailableRulesets.Count(); + this.rulesets = rulesets; foreach (var r in rulesets.AvailableRulesets) { modeButtons.Add(new ToolbarModeButton @@ -130,8 +92,22 @@ namespace osu.Game.Overlays.Toolbar ruleset.BindTo(game.Ruleset); else ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(); + } - Add(new RulesetSwitcherInputHandler(ruleset, rulesets)); + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + base.OnKeyDown(state, args); + if (!state.Keyboard.ControlPressed || args.Repeat || (int)args.Key < 109 || (int)args.Key > 118) { + return false; + } + + RulesetInfo targetRuleset = rulesets.GetRuleset(args.Key == Key.Number0 ? 9 : (int)args.Key - 110); + if (targetRuleset == null || targetRuleset == ruleset.Value) { + return false; + } + + ruleset.Value = targetRuleset; + return true; } public override bool HandleKeyboardInput => !ruleset.Disabled && base.HandleKeyboardInput; From ebd9d1a0376becee8ee0f71e93cca67daf9799e7 Mon Sep 17 00:00:00 2001 From: ocboogie Date: Sun, 13 May 2018 19:43:26 -0700 Subject: [PATCH 129/229] Resolve linting issues in ToolbarModeSelector.cs --- osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 7286cf3f1c..eeaa15d58a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -1,10 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using System.Linq; -using System.Collections.Generic; -using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Caching; using osu.Framework.Graphics; From a81921118dac58379808e0c55a0b281c02ffdf5b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 11:52:22 +0900 Subject: [PATCH 130/229] Strip whitespaces --- .../Scoring/OsuPerformanceCalculator.cs | 12 ++++++------ osu.Game/Rulesets/Scoring/PerformanceCalculator.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index e927cc946e..4942a55004 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -18,17 +18,17 @@ namespace osu.Game.Rulesets.Osu.Scoring private readonly int beatmapMaxCombo; private Mod[] mods; - + /// /// Approach rate adjusted by mods. /// private double realApproachRate; - + /// /// Overall difficulty adjusted by mods. /// private double realOverallDifficulty; - + private double accuracy; private int scoreMaxCombo; private int count300; @@ -70,11 +70,11 @@ namespace osu.Game.Rulesets.Osu.Scoring ar = Math.Max(0, ar / 2); double preEmpt = BeatmapDifficulty.DifficultyRange(ar, 1800, 1200, 450) / TimeRate; - double hitWindow300 = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; - + double hitWindow300 = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; + realApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5; realOverallDifficulty = (80 - 0.5 - hitWindow300) / 6; - + // Custom multipliers for NoFail and SpunOut. double multiplier = 1.12f; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things diff --git a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs b/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs index b23e06e15c..f2c495fa5d 100644 --- a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs +++ b/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Scoring ApplyMods(score.Mods); } - + protected virtual void ApplyMods(Mod[] mods) { var clock = new StopwatchClock(); From 7d027098ec1c0fc5920ba85b8f85797127cf99b0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 14:13:07 +0900 Subject: [PATCH 131/229] Fix drumroll completions always giving GREAT judgements Due to requiredgoodhits/requiredgreathits being calculated prior to nested hitobjects. --- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index 64219c7b52..4c9ec5473b 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -40,6 +40,8 @@ namespace osu.Game.Rulesets.Taiko.Objects /// private double tickSpacing = 100; + private float overallDifficulty = BeatmapDifficulty.DEFAULT_DIFFICULTY; + protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) { base.ApplyDefaultsToSelf(controlPointInfo, difficulty); @@ -47,9 +49,7 @@ namespace osu.Game.Rulesets.Taiko.Objects TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); tickSpacing = timingPoint.BeatLength / TickRate; - - RequiredGoodHits = NestedHitObjects.Count * Math.Min(0.15, 0.05 + 0.10 / 6 * difficulty.OverallDifficulty); - RequiredGreatHits = NestedHitObjects.Count * Math.Min(0.30, 0.10 + 0.20 / 6 * difficulty.OverallDifficulty); + overallDifficulty = difficulty.OverallDifficulty; } protected override void CreateNestedHitObjects() @@ -57,6 +57,9 @@ namespace osu.Game.Rulesets.Taiko.Objects base.CreateNestedHitObjects(); createTicks(); + + RequiredGoodHits = NestedHitObjects.Count * Math.Min(0.15, 0.05 + 0.10 / 6 * overallDifficulty); + RequiredGreatHits = NestedHitObjects.Count * Math.Min(0.30, 0.10 + 0.20 / 6 * overallDifficulty); } private void createTicks() From f5068804d5c2dcf87493cd75bbfd7c929654993a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 15:14:29 +0900 Subject: [PATCH 132/229] Re-enable slider distance overflow Fixes #2467. --- osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs | 24 +++++++++++++++++++ osu.Game/Rulesets/Objects/SliderCurve.cs | 10 ++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs index f7f73f74a5..cb1ea5cc5f 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs @@ -93,12 +93,36 @@ namespace osu.Game.Rulesets.Osu.Tests AddStep("Big Single, Large StackOffset", () => testSimpleBigLargeStackOffset()); AddStep("Big 1 Repeat, Large StackOffset", () => testSimpleBigLargeStackOffset(1)); + + AddStep("Distance Overflow", () => testDistanceOverflow()); + AddStep("Distance Overflow 1 Repeat", () => testDistanceOverflow(1)); } private void testSimpleBig(int repeats = 0) => createSlider(2, repeats: repeats); private void testSimpleBigLargeStackOffset(int repeats = 0) => createSlider(2, repeats: repeats, stackHeight: 10); + private void testDistanceOverflow(int repeats = 0) + { + var slider = new Slider + { + StartTime = Time.Current + 1000, + Position = new Vector2(239, 176), + ControlPoints = new List + { + Vector2.Zero, + new Vector2(154, 28), + new Vector2(52, -34) + }, + Distance = 700, + RepeatCount = repeats, + RepeatSamples = createEmptySamples(repeats), + StackHeight = 10 + }; + + addSlider(slider, 2, 2); + } + private void testSimpleMedium(int repeats = 0) => createSlider(5, repeats: repeats); private void testSimpleSmall(int repeats = 0) => createSlider(7, repeats: repeats); diff --git a/osu.Game/Rulesets/Objects/SliderCurve.cs b/osu.Game/Rulesets/Objects/SliderCurve.cs index 86fe74f9af..3932d8ed9d 100644 --- a/osu.Game/Rulesets/Objects/SliderCurve.cs +++ b/osu.Game/Rulesets/Objects/SliderCurve.cs @@ -99,11 +99,9 @@ namespace osu.Game.Rulesets.Objects cumulativeLength.Add(l); } - //TODO: Figure out if the following code is needed in some cases. Judging by the map - // "Transform" http://osu.ppy.sh/s/484689 it seems like we should _not_ be doing this. // Lengthen slider curves that are too short compared to what's // in the .osu file. - /*if (l < Length && calculatedPath.Count > 1) + if (l < Distance && calculatedPath.Count > 1) { Vector2 diff = calculatedPath[calculatedPath.Count - 1] - calculatedPath[calculatedPath.Count - 2]; double d = diff.Length; @@ -111,9 +109,9 @@ namespace osu.Game.Rulesets.Objects if (d <= 0) return; - calculatedPath[calculatedPath.Count - 1] += diff * (float)((Length - l) / d); - cumulativeLength[calculatedPath.Count - 1] = Length; - }*/ + calculatedPath[calculatedPath.Count - 1] += diff * (float)((Distance - l) / d); + cumulativeLength[calculatedPath.Count - 1] = Distance; + } } public void Calculate() From 43409127b73d3721f7edb5d5b915489ff14dbb8b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 15:36:42 +0900 Subject: [PATCH 133/229] Place break overlay underneath the hud --- osu.Game/Screens/Play/Player.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index f397d0c3d4..af5021a7eb 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -174,6 +174,13 @@ namespace osu.Game.Screens.Play RelativeSizeAxes = Axes.Both, Child = RulesetContainer }, + new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks, scoreProcessor) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + ProcessCustomClock = false, + Breaks = beatmap.Breaks + }, new SkipOverlay(firstObjectTime) { Clock = Clock, // skip button doesn't want to use the audio clock directly @@ -187,13 +194,6 @@ namespace osu.Game.Screens.Play ProcessCustomClock = false, Anchor = Anchor.Centre, Origin = Anchor.Centre - }, - new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks, scoreProcessor) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - ProcessCustomClock = false, - Breaks = beatmap.Breaks } } }, From 64fba5f6d1ed525a1ea4a0f1f844e1e8352f9159 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 15:36:56 +0900 Subject: [PATCH 134/229] Proxy the ruleset cursor above the break overlay --- osu.Game/Screens/Play/Player.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index af5021a7eb..f748d5236d 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -149,6 +149,8 @@ namespace osu.Game.Screens.Play scoreProcessor = RulesetContainer.CreateScoreProcessor(); + Drawable rulesetCursor = RulesetContainer.Cursor?.CreateProxy() ?? new Container(); + Children = new Drawable[] { pauseContainer = new PauseContainer(offsetClock, adjustableClock) @@ -162,7 +164,7 @@ namespace osu.Game.Screens.Play hudOverlay.KeyCounter.IsCounting = pauseContainer.IsPaused; }, OnResume = () => hudOverlay.KeyCounter.IsCounting = true, - Children = new Drawable[] + Children = new[] { storyboardContainer = new Container { @@ -181,6 +183,7 @@ namespace osu.Game.Screens.Play ProcessCustomClock = false, Breaks = beatmap.Breaks }, + rulesetCursor, new SkipOverlay(firstObjectTime) { Clock = Clock, // skip button doesn't want to use the audio clock directly From fe1c1fec0d37ecacbeb5ff328237307b95843706 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 May 2018 15:42:27 +0900 Subject: [PATCH 135/229] Stop overlays from handling DragStart This was causing weird behaviour with the key configuration section and back button in settings. --- .../Containers/OsuFocusedOverlayContainer.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 2a30e0d032..f657c0cae5 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -44,19 +44,6 @@ namespace osu.Game.Graphics.Containers return base.OnClick(state); } - protected override bool OnDragStart(InputState state) - { - if (!base.ReceiveMouseInputAt(state.Mouse.NativeState.Position)) - { - State = Visibility.Hidden; - return true; - } - - return base.OnDragStart(state); - } - - protected override bool OnDrag(InputState state) => State == Visibility.Hidden; - private void onStateChanged(Visibility visibility) { switch (visibility) From 6eb7590ab0151b86a047e157b4369bdf59978691 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 17:41:35 +0900 Subject: [PATCH 136/229] Make MusicController handle all movement to previous/next tracks --- osu.Game/Overlays/Music/PlaylistList.cs | 95 +++++++++------------- osu.Game/Overlays/Music/PlaylistOverlay.cs | 77 +++--------------- osu.Game/Overlays/MusicController.cs | 49 +++++++++-- 3 files changed, 90 insertions(+), 131 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index d63babf3b6..8c8ff89420 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -4,7 +4,8 @@ using System; using System.Collections.Generic; using System.Linq; -using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; @@ -16,7 +17,8 @@ namespace osu.Game.Overlays.Music { public class PlaylistList : CompositeDrawable { - public Action OnSelect; + public Action Selected; + public Action OrderChanged; private readonly ItemsScrollContainer items; @@ -25,7 +27,8 @@ namespace osu.Game.Overlays.Music InternalChild = items = new ItemsScrollContainer { RelativeSizeAxes = Axes.Both, - OnSelect = set => OnSelect?.Invoke(set) + Selected = set => Selected?.Invoke(set), + OrderChanged = (s, i) => OrderChanged?.Invoke(s, i) }; } @@ -35,34 +38,20 @@ namespace osu.Game.Overlays.Music set { base.Padding = value; } } - public IEnumerable BeatmapSets - { - get { return items.Sets; } - set { items.Sets = value; } - } - public BeatmapSetInfo FirstVisibleSet => items.FirstVisibleSet; - public BeatmapSetInfo NextSet => items.NextSet; - public BeatmapSetInfo PreviousSet => items.PreviousSet; - - public BeatmapSetInfo SelectedSet - { - get { return items.SelectedSet; } - set { items.SelectedSet = value; } - } - - public void AddBeatmapSet(BeatmapSetInfo beatmapSet) => items.AddBeatmapSet(beatmapSet); - public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) => items.RemoveBeatmapSet(beatmapSet); public void Filter(string searchTerm) => items.SearchTerm = searchTerm; private class ItemsScrollContainer : OsuScrollContainer { - public Action OnSelect; + public Action Selected; + public Action OrderChanged; private readonly SearchContainer search; private readonly FillFlowContainer items; + private readonly IBindable beatmapBacking = new Bindable(); + public ItemsScrollContainer() { Children = new Drawable[] @@ -83,14 +72,36 @@ namespace osu.Game.Overlays.Music }; } - public IEnumerable Sets + [BackgroundDependencyLoader] + private void load(BeatmapManager beatmaps, OsuGameBase osuGame) { - get { return items.Select(x => x.BeatmapSetInfo).ToList(); } - set - { - items.Clear(); - value.ForEach(AddBeatmapSet); - } + beatmaps.GetAllUsableBeatmapSets().ForEach(addBeatmapSet); + beatmaps.ItemAdded += addBeatmapSet; + beatmaps.ItemRemoved += removeBeatmapSet; + + beatmapBacking.BindTo(osuGame.Beatmap); + beatmapBacking.ValueChanged += _ => updateSelectedSet(); + } + + private void addBeatmapSet(BeatmapSetInfo obj) + { + var newItem = new PlaylistItem(obj) { OnSelect = set => Selected?.Invoke(set) }; + + items.Add(newItem); + items.SetLayoutPosition(newItem, items.Count - 1); + } + + private void removeBeatmapSet(BeatmapSetInfo obj) + { + var itemToRemove = items.FirstOrDefault(i => i.BeatmapSetInfo.ID == obj.ID); + if (itemToRemove != null) + items.Remove(itemToRemove); + } + + private void updateSelectedSet() + { + foreach (PlaylistItem s in items.Children) + s.Selected = s.BeatmapSetInfo.ID == beatmapBacking.Value.BeatmapSetInfo.ID; } public string SearchTerm @@ -99,34 +110,7 @@ namespace osu.Game.Overlays.Music set { search.SearchTerm = value; } } - public void AddBeatmapSet(BeatmapSetInfo beatmapSet) - { - var newItem = new PlaylistItem(beatmapSet) { OnSelect = set => OnSelect?.Invoke(set) }; - - items.Add(newItem); - items.SetLayoutPosition(newItem, items.Count); - } - - public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) - { - var itemToRemove = items.FirstOrDefault(i => i.BeatmapSetInfo.ID == beatmapSet.ID); - if (itemToRemove != null) - items.Remove(itemToRemove); - } - - public BeatmapSetInfo SelectedSet - { - get { return items.FirstOrDefault(i => i.Selected)?.BeatmapSetInfo; } - set - { - foreach (PlaylistItem s in items.Children) - s.Selected = s.BeatmapSetInfo.ID == value?.ID; - } - } - public BeatmapSetInfo FirstVisibleSet => items.FirstOrDefault(i => i.MatchingFilter)?.BeatmapSetInfo; - public BeatmapSetInfo NextSet => (items.SkipWhile(i => !i.Selected).Skip(1).FirstOrDefault() ?? items.FirstOrDefault())?.BeatmapSetInfo; - public BeatmapSetInfo PreviousSet => (items.TakeWhile(i => !i.Selected).LastOrDefault() ?? items.LastOrDefault())?.BeatmapSetInfo; private Vector2 nativeDragPosition; private PlaylistItem draggedItem; @@ -227,6 +211,7 @@ namespace osu.Game.Overlays.Music } items.SetLayoutPosition(draggedItem, dstIndex); + OrderChanged?.Invoke(draggedItem.BeatmapSetInfo, dstIndex); } private class ItemSearchContainer : FillFlowContainer, IHasFilterableChildren diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 3496c044fb..76c2222f8b 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -1,7 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; +using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; @@ -19,18 +19,16 @@ namespace osu.Game.Overlays.Music public class PlaylistOverlay : OverlayContainer { private const float transition_duration = 600; - private const float playlist_height = 510; + public Action OrderChanged; + + private BeatmapManager beatmaps; private FilterControl filter; private PlaylistList list; - private BeatmapManager beatmaps; - private readonly Bindable beatmapBacking = new Bindable(); - public IEnumerable BeatmapSets => list.BeatmapSets; - [BackgroundDependencyLoader] private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours) { @@ -60,7 +58,8 @@ namespace osu.Game.Overlays.Music { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = 95, Bottom = 10, Right = 10 }, - OnSelect = itemSelected, + Selected = itemSelected, + OrderChanged = (s, i) => OrderChanged?.Invoke(s, i) }, filter = new FilterControl { @@ -74,30 +73,16 @@ namespace osu.Game.Overlays.Music }, }; - beatmaps.ItemAdded += handleBeatmapAdded; - beatmaps.ItemRemoved += handleBeatmapRemoved; - - list.BeatmapSets = beatmaps.GetAllUsableBeatmapSets(); - beatmapBacking.BindTo(game.Beatmap); filter.Search.OnCommit = (sender, newText) => { - var beatmap = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); - if (beatmap != null) playSpecified(beatmap); + BeatmapInfo beatmap = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); + if (beatmap != null) + beatmapBacking.Value = beatmaps.GetWorkingBeatmap(beatmap); }; } - protected override void LoadComplete() - { - base.LoadComplete(); - beatmapBacking.ValueChanged += b => list.SelectedSet = b?.BeatmapSetInfo; - beatmapBacking.TriggerChange(); - } - - private void handleBeatmapAdded(BeatmapSetInfo setInfo) => Schedule(() => list.AddBeatmapSet(setInfo)); - private void handleBeatmapRemoved(BeatmapSetInfo setInfo) => Schedule(() => list.RemoveBeatmapSet(setInfo)); - protected override void PopIn() { filter.Search.HoldFocus = true; @@ -123,49 +108,7 @@ namespace osu.Game.Overlays.Music return; } - playSpecified(set.Beatmaps.First()); - } - - public void PlayPrevious() - { - var playable = list.PreviousSet; - - if (playable != null) - { - playSpecified(playable.Beatmaps.First()); - list.SelectedSet = playable; - } - } - - public void PlayNext() - { - var playable = list.NextSet; - - if (playable != null) - { - playSpecified(playable.Beatmaps.First()); - list.SelectedSet = playable; - } - } - - private void playSpecified(BeatmapInfo info) - { - beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking); - - var track = beatmapBacking.Value.Track; - - track.Restart(); - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - if (beatmaps != null) - { - beatmaps.ItemAdded -= handleBeatmapAdded; - beatmaps.ItemRemoved -= handleBeatmapRemoved; - } + beatmapBacking.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First()); } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index b4021f2808..c348a8f7d5 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -50,7 +51,10 @@ namespace osu.Game.Overlays private LocalisationEngine localisation; + private BeatmapManager beatmaps; private readonly Bindable beatmapBacking = new Bindable(); + private List beatmapSets; + private BeatmapSetInfo currentSet; private Container dragContainer; private Container playerContainer; @@ -93,8 +97,9 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuGameBase game, OsuColour colours, LocalisationEngine localisation) + private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation) { + this.beatmaps = beatmaps; this.localisation = localisation; Children = new Drawable[] @@ -111,6 +116,7 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.X, Y = player_height + 10, + OrderChanged = playlistOrderChanged }, playerContainer = new Container { @@ -185,7 +191,7 @@ namespace osu.Game.Overlays { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Action = next, + Action = () => next(), Icon = FontAwesome.fa_step_forward, }, } @@ -214,11 +220,24 @@ namespace osu.Game.Overlays } }; + beatmapSets = beatmaps.GetAllUsableBeatmapSets(); + beatmaps.ItemAdded += handleBeatmapAdded; + beatmaps.ItemRemoved += handleBeatmapRemoved; + beatmapBacking.BindTo(game.Beatmap); playlist.StateChanged += s => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint); } + private void playlistOrderChanged(BeatmapSetInfo beatmapSetInfo, int index) + { + beatmapSets.Remove(beatmapSetInfo); + beatmapSets.Insert(index, beatmapSetInfo); + } + + private void handleBeatmapAdded(BeatmapSetInfo obj) => beatmapSets.Add(obj); + private void handleBeatmapRemoved(BeatmapSetInfo obj) => beatmapSets.RemoveAll(s => s.ID == obj.ID); + protected override void LoadComplete() { beatmapBacking.ValueChanged += beatmapChanged; @@ -257,7 +276,7 @@ namespace osu.Game.Overlays playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; - if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled && playlist.BeatmapSets.Any()) + if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled && beatmapSets.Any()) next(); } else @@ -271,7 +290,7 @@ namespace osu.Game.Overlays if (track == null) { if (!beatmapBacking.Disabled) - playlist.PlayNext(); + next(true); return; } @@ -284,13 +303,25 @@ namespace osu.Game.Overlays private void prev() { queuedDirection = TransformDirection.Prev; - playlist.PlayPrevious(); + + var playable = beatmapSets.TakeWhile(i => i.ID != current.BeatmapSetInfo.ID).LastOrDefault() ?? beatmapSets.LastOrDefault(); + if (playable != null) + playSpecified(playable.Beatmaps.First()); } - private void next() + private void next(bool instant = false) { queuedDirection = TransformDirection.Next; - playlist.PlayNext(); + + var playable = beatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? beatmapSets.FirstOrDefault(); + if (playable != null) + playSpecified(playable.Beatmaps.First()); + } + + private void playSpecified(BeatmapInfo info) + { + beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking); + beatmapBacking.Value.Track.Restart(); } private WorkingBeatmap current; @@ -314,8 +345,8 @@ namespace osu.Game.Overlays else { //figure out the best direction based on order in playlist. - var last = playlist.BeatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count(); - var next = beatmap == null ? -1 : playlist.BeatmapSets.TakeWhile(b => b.ID != beatmap.BeatmapSetInfo?.ID).Count(); + var last = beatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count(); + var next = beatmap == null ? -1 : beatmapSets.TakeWhile(b => b.ID != beatmap.BeatmapSetInfo?.ID).Count(); direction = last > next ? TransformDirection.Prev : TransformDirection.Next; } From 4ceae6ba1f806f4cae2983c32e58c867d74ddad4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 17:45:11 +0900 Subject: [PATCH 137/229] Inline method --- osu.Game/Overlays/MusicController.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index c348a8f7d5..d7884bf53a 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -306,7 +306,10 @@ namespace osu.Game.Overlays var playable = beatmapSets.TakeWhile(i => i.ID != current.BeatmapSetInfo.ID).LastOrDefault() ?? beatmapSets.LastOrDefault(); if (playable != null) - playSpecified(playable.Beatmaps.First()); + { + beatmapBacking.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmapBacking); + beatmapBacking.Value.Track.Restart(); + } } private void next(bool instant = false) @@ -315,13 +318,10 @@ namespace osu.Game.Overlays var playable = beatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? beatmapSets.FirstOrDefault(); if (playable != null) - playSpecified(playable.Beatmaps.First()); - } - - private void playSpecified(BeatmapInfo info) - { - beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking); - beatmapBacking.Value.Track.Restart(); + { + beatmapBacking.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmapBacking); + beatmapBacking.Value.Track.Restart(); + } } private WorkingBeatmap current; From 027f6c3fa4a55e2dafb6b15588d282de465e14eb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 17:47:38 +0900 Subject: [PATCH 138/229] Fix instant movement not doing anything --- osu.Game/Overlays/MusicController.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index d7884bf53a..fb4e278b0c 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -314,7 +314,8 @@ namespace osu.Game.Overlays private void next(bool instant = false) { - queuedDirection = TransformDirection.Next; + if (!instant) + queuedDirection = TransformDirection.Next; var playable = beatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? beatmapSets.FirstOrDefault(); if (playable != null) From 115c2dc239e734d3c6f1c2161c5a80dddc84a22f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 18:02:18 +0900 Subject: [PATCH 139/229] Move hud below the skip button --- osu.Game/Screens/Play/Player.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index f748d5236d..2d7e0e8f9e 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -183,6 +183,13 @@ namespace osu.Game.Screens.Play ProcessCustomClock = false, Breaks = beatmap.Breaks }, + hudOverlay = new HUDOverlay(scoreProcessor, RulesetContainer, working, offsetClock, adjustableClock) + { + Clock = Clock, // hud overlay doesn't want to use the audio clock directly + ProcessCustomClock = false, + Anchor = Anchor.Centre, + Origin = Anchor.Centre + }, rulesetCursor, new SkipOverlay(firstObjectTime) { @@ -191,13 +198,6 @@ namespace osu.Game.Screens.Play AdjustableClock = adjustableClock, FramedClock = offsetClock, }, - hudOverlay = new HUDOverlay(scoreProcessor, RulesetContainer, working, offsetClock, adjustableClock) - { - Clock = Clock, // hud overlay doesn't want to use the audio clock directly - ProcessCustomClock = false, - Anchor = Anchor.Centre, - Origin = Anchor.Centre - } } }, failOverlay = new FailOverlay From 9536c324fa3853bfeff8c29b54d3258ad1998509 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 19:08:00 +0900 Subject: [PATCH 140/229] Rename aborted -> fired --- osu.Game.Tests/Visual/TestCaseHoldToConfirmOverlay.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseHoldToConfirmOverlay.cs b/osu.Game.Tests/Visual/TestCaseHoldToConfirmOverlay.cs index ef6f44b42e..6fa49c4edb 100644 --- a/osu.Game.Tests/Visual/TestCaseHoldToConfirmOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseHoldToConfirmOverlay.cs @@ -17,11 +17,11 @@ namespace osu.Game.Tests.Visual { bool fired = false; - var abortText = new OsuSpriteText + var firedText = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = "Aborted!", + Text = "Fired!", TextSize = 50, Alpha = 0, }; @@ -31,14 +31,14 @@ namespace osu.Game.Tests.Visual Action = () => { fired = true; - abortText.FadeTo(1).Then().FadeOut(1000); + firedText.FadeTo(1).Then().FadeOut(1000); } }; Children = new Drawable[] { overlay, - abortText + firedText }; AddStep("start confirming", () => overlay.Begin()); From 0234bbc37f08354910ed746624e546746b0c3165 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 May 2018 19:14:17 +0900 Subject: [PATCH 141/229] Move definition inline --- osu.Game/Screens/Play/Player.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 2d7e0e8f9e..4a46279d30 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -149,8 +149,6 @@ namespace osu.Game.Screens.Play scoreProcessor = RulesetContainer.CreateScoreProcessor(); - Drawable rulesetCursor = RulesetContainer.Cursor?.CreateProxy() ?? new Container(); - Children = new Drawable[] { pauseContainer = new PauseContainer(offsetClock, adjustableClock) @@ -190,7 +188,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre }, - rulesetCursor, + RulesetContainer.Cursor?.CreateProxy() ?? new Container(), new SkipOverlay(firstObjectTime) { Clock = Clock, // skip button doesn't want to use the audio clock directly From 17861c2a162f1d562aa79fb4bc3e267e96dbe530 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 19:20:53 +0900 Subject: [PATCH 142/229] Display "no key bound" when no shortcut --- osu.Game/Overlays/OnScreenDisplay.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 8f6bf0f539..1c80f2e626 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -101,20 +101,15 @@ namespace osu.Game.Overlays Origin = Anchor.TopCentre, AutoSizeAxes = Axes.Both }, - new Container + textLine3 = new OsuSpriteText { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - AutoSizeAxes = Axes.Both, Margin = new MarginPadding { Bottom = 15 }, + Font = @"Exo2.0-Bold", + TextSize = 12, Alpha = 0.3f, - Child = textLine3 = new OsuSpriteText - { - Font = @"Exo2.0-Bold", - TextSize = 12, - AlwaysPresent = true - }, - } + }, } } } @@ -183,6 +178,9 @@ namespace osu.Game.Overlays textLine2.Text = description.Value; textLine3.Text = description.Shortcut.ToUpper(); + if (string.IsNullOrEmpty(textLine3.Text)) + textLine3.Text = "NO KEY BOUND"; + Display(box); int optionCount = 0; From 47cf4f27fbd800371a531cd396b059c0e27c30fa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 14 May 2018 19:39:23 +0900 Subject: [PATCH 143/229] Fix possibility of test rulesets being discovered from assemblies --- osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs | 6 +++--- osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs | 6 +++--- osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs | 6 +++--- osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs | 6 +++--- osu.Game/Rulesets/RulesetStore.cs | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index d0d623178e..808faa511b 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -14,7 +14,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Catch.Tests { - public class CatchBeatmapConversionTest : BeatmapConversionTest + internal class CatchBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Catch"; @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Catch.Tests protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap); } - public struct ConvertValue : IEquatable + internal struct ConvertValue : IEquatable { /// /// A sane value to account for osu!stable using ints everwhere. @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Catch.Tests && Precision.AlmostEquals(Position, other.Position, conversion_lenience); } - public class TestCatchRuleset : CatchRuleset + internal class TestCatchRuleset : CatchRuleset { } } diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index f1ee874b88..bd67a7d96a 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -14,7 +14,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Mania.Tests { - public class ManiaBeatmapConversionTest : BeatmapConversionTest + internal class ManiaBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Tests protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap); } - public struct ConvertValue : IEquatable + internal struct ConvertValue : IEquatable { /// /// A sane value to account for osu!stable using ints everwhere. @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Mania.Tests && Column == other.Column; } - public class TestManiaRuleset : ManiaRuleset + internal class TestManiaRuleset : ManiaRuleset { } } diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index aa7de4ed01..3d54043027 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -15,7 +15,7 @@ using OpenTK; namespace osu.Game.Rulesets.Osu.Tests { - public class OsuBeatmapConversionTest : BeatmapConversionTest + internal class OsuBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Osu"; @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Tests protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap); } - public struct ConvertValue : IEquatable + internal struct ConvertValue : IEquatable { /// /// A sane value to account for osu!stable using ints everwhere. @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.Tests && Precision.AlmostEquals(EndY, other.EndY, conversion_lenience); } - public class TestOsuRuleset : OsuRuleset + internal class TestOsuRuleset : OsuRuleset { } } diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs index 33a5e1772e..ca4fc3ec57 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -14,7 +14,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Taiko.Tests { - public class TaikoBeatmapConversionTest : BeatmapConversionTest + internal class TaikoBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Taiko.Tests protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap); } - public struct ConvertValue : IEquatable + internal struct ConvertValue : IEquatable { /// /// A sane value to account for osu!stable using ints everwhere. @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Taiko.Tests && IsStrong == other.IsStrong; } - public class TestTaikoRuleset : TaikoRuleset + internal class TestTaikoRuleset : TaikoRuleset { } } diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index 67a9a59d4a..1847b63658 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -112,7 +112,7 @@ namespace osu.Game.Rulesets try { var assembly = Assembly.LoadFrom(file); - loaded_assemblies[assembly] = assembly.GetTypes().First(t => t.IsSubclassOf(typeof(Ruleset))); + loaded_assemblies[assembly] = assembly.GetTypes().First(t => t.IsPublic && t.IsSubclassOf(typeof(Ruleset))); } catch (Exception) { From addb864d1047202af87541763e24a116a4e3cd04 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 May 2018 15:41:31 +0900 Subject: [PATCH 144/229] Allow help text to wrap --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 14 ++++++++------ osu.Game/Overlays/KeyBindingOverlay.cs | 4 ---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 41f23a8cd0..7406a9ec4f 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Input; using OpenTK.Graphics; @@ -43,7 +44,7 @@ namespace osu.Game.Overlays.KeyBinding } private OsuSpriteText text; - private OsuSpriteText pressAKey; + private OsuTextFlowContainer pressAKey; private FillFlowContainer buttons; @@ -95,10 +96,11 @@ namespace osu.Game.Overlays.KeyBinding Anchor = Anchor.TopRight, Origin = Anchor.TopRight }, - pressAKey = new OsuSpriteText + pressAKey = new OsuTextFlowContainer { - Text = "Press a key to change binding, SHIFT+DEL to delete, ESC to cancel.", - Y = height, + Text = "Press a key to change binding, Shift+Delete to delete, Escape to cancel.", + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Margin = new MarginPadding(padding), Alpha = 0, Colour = colours.YellowDark @@ -268,7 +270,7 @@ namespace osu.Game.Overlays.KeyBinding GetContainingInputManager().ChangeFocus(null); pressAKey.FadeOut(300, Easing.OutQuint); - pressAKey.Padding = new MarginPadding { Bottom = -pressAKey.DrawHeight }; + pressAKey.Padding = new MarginPadding { Top = height, Bottom = -pressAKey.DrawHeight }; } protected override void OnFocus(InputState state) @@ -277,7 +279,7 @@ namespace osu.Game.Overlays.KeyBinding AutoSizeEasing = Easing.OutQuint; pressAKey.FadeIn(300, Easing.OutQuint); - pressAKey.Padding = new MarginPadding(); + pressAKey.Padding = new MarginPadding { Top = height }; updateBindTarget(); base.OnFocus(state); diff --git a/osu.Game/Overlays/KeyBindingOverlay.cs b/osu.Game/Overlays/KeyBindingOverlay.cs index bd9c8c20de..06432cfcea 100644 --- a/osu.Game/Overlays/KeyBindingOverlay.cs +++ b/osu.Game/Overlays/KeyBindingOverlay.cs @@ -12,8 +12,6 @@ namespace osu.Game.Overlays { public class KeyBindingOverlay : SettingsOverlay { - protected const float WIDTH = 430; - protected override Drawable CreateHeader() => new SettingsHeader("key configuration", "Customise your keys!"); [BackgroundDependencyLoader(permitNulls: true)] @@ -23,8 +21,6 @@ namespace osu.Game.Overlays foreach (var ruleset in rulesets.AvailableRulesets) AddSection(new RulesetBindingsSection(ruleset)); - - ContentContainer.Width = WIDTH; } public KeyBindingOverlay() From e802b722f053b0f375566eaee81859d07bb98178 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Mon, 14 May 2018 20:27:05 +0300 Subject: [PATCH 145/229] Revert "Handle mouse back button using OnMouseDown override instead of using GlobalAction" This reverts commit 44bbb8700ecc1bdd652c35766bfbaa54310a5855. --- .../Input/Bindings/GlobalActionContainer.cs | 10 +++- osu.Game/Screens/Loader.cs | 1 - osu.Game/Screens/Menu/ButtonSystem.cs | 52 +++++++++++-------- osu.Game/Screens/Menu/MainMenu.cs | 1 - osu.Game/Screens/OsuScreen.cs | 28 +++------- osu.Game/Screens/Play/PlayerLoader.cs | 1 + .../Play/ScreenWithBeatmapBackground.cs | 2 - 7 files changed, 48 insertions(+), 47 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index dd8f00f6cd..565d530395 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Input.Bindings { new KeyBinding(InputKey.F8, GlobalAction.ToggleChat), new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial), - new KeyBinding(InputKey.F12,GlobalAction.TakeScreenshot), + new KeyBinding(InputKey.F12, GlobalAction.TakeScreenshot), new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings), new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar), @@ -36,6 +36,9 @@ namespace osu.Game.Input.Bindings new KeyBinding(InputKey.Down, GlobalAction.DecreaseVolume), new KeyBinding(InputKey.MouseWheelDown, GlobalAction.DecreaseVolume), new KeyBinding(InputKey.F4, GlobalAction.ToggleMute), + + new KeyBinding(InputKey.Escape, GlobalAction.Back), + new KeyBinding(InputKey.MouseButton1, GlobalAction.Back) }; public IEnumerable InGameKeyBindings => new[] @@ -76,6 +79,9 @@ namespace osu.Game.Input.Bindings QuickRetry, [Description("Take screenshot")] - TakeScreenshot + TakeScreenshot, + + [Description("Go back")] + Back } } diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index dc8dbb4421..1d152361df 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -18,7 +18,6 @@ namespace osu.Game.Screens private bool showDisclaimer; public override bool ShowOverlaysOnEnter => false; - protected override bool AllowBackButton => false; public Loader() { diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 5a1dafe404..8cf0d24f7d 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -13,15 +13,17 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input; +using osu.Framework.Input.Bindings; using osu.Framework.Threading; using osu.Game.Graphics; +using osu.Game.Input.Bindings; using OpenTK; using OpenTK.Graphics; using OpenTK.Input; namespace osu.Game.Screens.Menu { - public class ButtonSystem : Container, IStateful + public class ButtonSystem : Container, IStateful, IKeyBindingHandler { public event Action StateChanged; @@ -146,36 +148,44 @@ namespace osu.Game.Screens.Menu case Key.Space: logo?.TriggerOnClick(state); return true; - case Key.Escape: - return handleBack(); } return false; } - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + public bool OnPressed(GlobalAction action) { - if (state.Mouse.IsPressed(MouseButton.Button1)) - return handleBack(); - - return base.OnMouseDown(state, args); - } - - private bool handleBack() - { - switch (State) + switch (action) { - case MenuState.TopLevel: - State = MenuState.Initial; - return true; - case MenuState.Play: - backButton.TriggerOnClick(); - return true; + case GlobalAction.Back: + switch (State) + { + case MenuState.TopLevel: + State = MenuState.Initial; + return true; + case MenuState.Play: + backButton.TriggerOnClick(); + return true; + default: + return false; + } + default: + return false; } - - return false; } + public bool OnReleased(GlobalAction action) + { + switch (action) + { + case GlobalAction.Back: + return true; + default: + return false; + } + } + + private void onPlay() { State = MenuState.Play; diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index d91ac099fd..f2ea6d85a8 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -25,7 +25,6 @@ namespace osu.Game.Screens.Menu private readonly ButtonSystem buttons; public override bool ShowOverlaysOnEnter => buttons.State != MenuState.Initial; - protected override bool AllowBackButton => false; private readonly BackgroundScreenDefault background; private Screen songSelect; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 9fa30181a1..fb5d3d12e6 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -7,18 +7,18 @@ using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Input; +using osu.Framework.Input.Bindings; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; +using osu.Game.Input.Bindings; using osu.Game.Rulesets; using osu.Game.Screens.Menu; using OpenTK; -using OpenTK.Input; namespace osu.Game.Screens { - public abstract class OsuScreen : Screen + public abstract class OsuScreen : Screen, IKeyBindingHandler { public BackgroundScreen Background { get; private set; } @@ -92,31 +92,19 @@ namespace osu.Game.Screens sampleExit = audio.Sample.Get(@"UI/screen-back"); } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + public bool OnPressed(GlobalAction action) { - if (args.Repeat || !IsCurrentScreen) return false; - - switch (args.Key) - { - case Key.Escape: - Exit(); - return true; - } - - return base.OnKeyDown(state, args); - } - - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) - { - if (AllowBackButton && state.Mouse.IsPressed(MouseButton.Button1)) + if (action == GlobalAction.Back && AllowBackButton) { Exit(); return true; } - return base.OnMouseDown(state, args); + return false; } + public bool OnReleased(GlobalAction action) => action == GlobalAction.Back && AllowBackButton; + protected override void OnResuming(Screen last) { sampleExit?.Play(); diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 56fbd7b6e7..6eb156914e 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -27,6 +27,7 @@ namespace osu.Game.Screens.Play private bool showOverlays = true; public override bool ShowOverlaysOnEnter => showOverlays; + protected override bool AllowBackButton => false; private Task loadTask; diff --git a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs index 30ae6db346..1ccc5e2fe8 100644 --- a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs +++ b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs @@ -17,8 +17,6 @@ namespace osu.Game.Screens.Play public override bool AllowBeatmapRulesetChange => false; - protected override bool AllowBackButton => false; - protected const float BACKGROUND_FADE_DURATION = 800; protected float BackgroundOpacity => 1 - (float)DimLevel; From f2f2fb8c73670a02dc6cb877fec342423ff27b9b Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Mon, 14 May 2018 22:09:09 +0300 Subject: [PATCH 146/229] Use both OnKeyDown and GlobalAction.Back --- osu.Game/Screens/Loader.cs | 2 ++ osu.Game/Screens/Menu/MainMenu.cs | 2 ++ osu.Game/Screens/OsuScreen.cs | 16 ++++++++++++++++ .../Screens/Play/ScreenWithBeatmapBackground.cs | 1 + 4 files changed, 21 insertions(+) diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index 1d152361df..555c497d92 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -19,6 +19,8 @@ namespace osu.Game.Screens public override bool ShowOverlaysOnEnter => false; + protected override bool AllowBackButton => false; + public Loader() { ValidForResume = false; diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index f2ea6d85a8..f9f62b764b 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -26,6 +26,8 @@ namespace osu.Game.Screens.Menu public override bool ShowOverlaysOnEnter => buttons.State != MenuState.Initial; + protected override bool AllowBackButton => buttons.State != MenuState.Initial; + private readonly BackgroundScreenDefault background; private Screen songSelect; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index fb5d3d12e6..24945ea347 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -7,6 +7,7 @@ using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Screens; using osu.Game.Beatmaps; @@ -15,6 +16,7 @@ using osu.Game.Input.Bindings; using osu.Game.Rulesets; using osu.Game.Screens.Menu; using OpenTK; +using OpenTK.Input; namespace osu.Game.Screens { @@ -105,6 +107,20 @@ namespace osu.Game.Screens public bool OnReleased(GlobalAction action) => action == GlobalAction.Back && AllowBackButton; + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (args.Repeat || !IsCurrentScreen) return false; + + switch (args.Key) + { + case Key.Escape: + Exit(); + return true; + } + + return base.OnKeyDown(state, args); + } + protected override void OnResuming(Screen last) { sampleExit?.Play(); diff --git a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs index 1ccc5e2fe8..f29f5b328a 100644 --- a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs +++ b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs @@ -16,6 +16,7 @@ namespace osu.Game.Screens.Play protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); public override bool AllowBeatmapRulesetChange => false; + protected override bool AllowBackButton => false; protected const float BACKGROUND_FADE_DURATION = 800; From fe2ea17e7f8a4ef7952409ac82be57c20d42d687 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 11:42:40 +0900 Subject: [PATCH 147/229] Allow subclasses of LegacyScoreParser to specify beatmap/ruleset retrieval --- .../Rulesets/Scoring/Legacy/LegacyScoreParser.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs index 38873c4df1..f7ab9df52a 100644 --- a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs @@ -25,6 +25,10 @@ namespace osu.Game.Rulesets.Scoring.Legacy this.beatmaps = beatmaps; } + protected LegacyScoreParser() + { + } + private IBeatmap currentBeatmap; private Ruleset currentRuleset; @@ -34,16 +38,15 @@ namespace osu.Game.Rulesets.Scoring.Legacy using (SerializationReader sr = new SerializationReader(stream)) { - score = new Score { Ruleset = rulesets.GetRuleset(sr.ReadByte()) }; - currentRuleset = score.Ruleset.CreateInstance(); + currentRuleset = GetRuleset(sr.ReadByte()); + score = new Score { Ruleset = currentRuleset.RulesetInfo }; /* score.Pass = true;*/ var version = sr.ReadInt32(); /* score.FileChecksum = */ - var beatmapHash = sr.ReadString(); - score.Beatmap = beatmaps.QueryBeatmap(b => b.MD5Hash == beatmapHash); - currentBeatmap = beatmaps.GetWorkingBeatmap(score.Beatmap).Beatmap; + currentBeatmap = GetBeatmap(sr.ReadString()).Beatmap; + score.Beatmap = currentBeatmap.BeatmapInfo; /* score.PlayerName = */ score.User = new User { Username = sr.ReadString() }; @@ -181,5 +184,8 @@ namespace osu.Game.Rulesets.Scoring.Legacy return frame; } + + protected virtual Ruleset GetRuleset(int rulesetId) => rulesets.GetRuleset(rulesetId).CreateInstance(); + protected virtual WorkingBeatmap GetBeatmap(string md5Hash) => beatmaps.GetWorkingBeatmap(beatmaps.QueryBeatmap(b => b.MD5Hash == md5Hash)); } } From 10e2f7453802b5166f7cb924924033f15d4ddd75 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 11:53:11 +0900 Subject: [PATCH 148/229] Port osu-performance HD AR fix --- osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index 4942a55004..793060197d 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -138,8 +138,9 @@ namespace osu.Game.Rulesets.Osu.Scoring aimValue *= approachRateFactor; + // We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR. if (mods.Any(h => h is OsuModHidden)) - aimValue *= 1.03f; + aimValue *= 1.02 + (11.0f - realApproachRate) / 50.0; // Gives a 1.04 bonus for AR10, a 1.06 bonus for AR9, a 1.02 bonus for AR11. if (mods.Any(h => h is OsuModFlashlight)) { From 1ee68c1c545662321b8404d899da1136b799991d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 15:27:57 +0900 Subject: [PATCH 149/229] Make LegacyScoreParser abstract --- .../Legacy/DatabasedLegacyScoreParser.cs | 26 ++++++++++++++++ .../Scoring/Legacy/LegacyScoreParser.cs | 30 +++++++++---------- osu.Game/Rulesets/Scoring/ScoreStore.cs | 2 +- 3 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 osu.Game/Rulesets/Scoring/Legacy/DatabasedLegacyScoreParser.cs diff --git a/osu.Game/Rulesets/Scoring/Legacy/DatabasedLegacyScoreParser.cs b/osu.Game/Rulesets/Scoring/Legacy/DatabasedLegacyScoreParser.cs new file mode 100644 index 0000000000..bfb2b7c13b --- /dev/null +++ b/osu.Game/Rulesets/Scoring/Legacy/DatabasedLegacyScoreParser.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps; + +namespace osu.Game.Rulesets.Scoring.Legacy +{ + /// + /// A which retrieves the applicable and + /// for the score from the database. + /// + public class DatabasedLegacyScoreParser : LegacyScoreParser + { + private readonly RulesetStore rulesets; + private readonly BeatmapManager beatmaps; + + public DatabasedLegacyScoreParser(RulesetStore rulesets, BeatmapManager beatmaps) + { + this.rulesets = rulesets; + this.beatmaps = beatmaps; + } + + protected override Ruleset GetRuleset(int rulesetId) => rulesets.GetRuleset(rulesetId).CreateInstance(); + protected override WorkingBeatmap GetBeatmap(string md5Hash) => beatmaps.GetWorkingBeatmap(beatmaps.QueryBeatmap(b => b.MD5Hash == md5Hash)); + } +} diff --git a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs index f7ab9df52a..a90cd79186 100644 --- a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs @@ -14,21 +14,8 @@ using System.Linq; namespace osu.Game.Rulesets.Scoring.Legacy { - public class LegacyScoreParser + public abstract class LegacyScoreParser { - private readonly RulesetStore rulesets; - private readonly BeatmapManager beatmaps; - - public LegacyScoreParser(RulesetStore rulesets, BeatmapManager beatmaps) - { - this.rulesets = rulesets; - this.beatmaps = beatmaps; - } - - protected LegacyScoreParser() - { - } - private IBeatmap currentBeatmap; private Ruleset currentRuleset; @@ -185,7 +172,18 @@ namespace osu.Game.Rulesets.Scoring.Legacy return frame; } - protected virtual Ruleset GetRuleset(int rulesetId) => rulesets.GetRuleset(rulesetId).CreateInstance(); - protected virtual WorkingBeatmap GetBeatmap(string md5Hash) => beatmaps.GetWorkingBeatmap(beatmaps.QueryBeatmap(b => b.MD5Hash == md5Hash)); + /// + /// Retrieves the for a specific id. + /// + /// The id. + /// The . + protected abstract Ruleset GetRuleset(int rulesetId); + + /// + /// Retrieves the corresponding to an MD5 hash. + /// + /// The MD5 hash. + /// The . + protected abstract WorkingBeatmap GetBeatmap(string md5Hash); } } diff --git a/osu.Game/Rulesets/Scoring/ScoreStore.cs b/osu.Game/Rulesets/Scoring/ScoreStore.cs index 957fd037e0..69d25fcb67 100644 --- a/osu.Game/Rulesets/Scoring/ScoreStore.cs +++ b/osu.Game/Rulesets/Scoring/ScoreStore.cs @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Scoring public Score ReadReplayFile(string replayFilename) { using (Stream s = storage.GetStream(Path.Combine(replay_folder, replayFilename))) - return new LegacyScoreParser(rulesets, beatmaps).Parse(s); + return new DatabasedLegacyScoreParser(rulesets, beatmaps).Parse(s); } } } From 9fd972e0a3a3b582fd4d30935c1e7bd8af9ef74c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 17:36:29 +0900 Subject: [PATCH 150/229] Rename OsuDifficulty -> Difficulty --- .../OsuDifficultyCalculator.cs | 6 +++--- .../Preprocessing/OsuDifficultyBeatmap.cs | 2 +- .../Preprocessing/OsuDifficultyHitObject.cs | 4 ++-- .../{OsuDifficulty => Difficulty}/Skills/Aim.cs | 4 ++-- .../{OsuDifficulty => Difficulty}/Skills/Skill.cs | 6 +++--- .../{OsuDifficulty => Difficulty}/Skills/Speed.cs | 4 ++-- .../{OsuDifficulty => Difficulty}/Utils/History.cs | 2 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) rename osu.Game.Rulesets.Osu/{OsuDifficulty => Difficulty}/OsuDifficultyCalculator.cs (93%) rename osu.Game.Rulesets.Osu/{OsuDifficulty => Difficulty}/Preprocessing/OsuDifficultyBeatmap.cs (98%) rename osu.Game.Rulesets.Osu/{OsuDifficulty => Difficulty}/Preprocessing/OsuDifficultyHitObject.cs (98%) rename osu.Game.Rulesets.Osu/{OsuDifficulty => Difficulty}/Skills/Aim.cs (85%) rename osu.Game.Rulesets.Osu/{OsuDifficulty => Difficulty}/Skills/Skill.cs (96%) rename osu.Game.Rulesets.Osu/{OsuDifficulty => Difficulty}/Skills/Speed.cs (93%) rename osu.Game.Rulesets.Osu/{OsuDifficulty => Difficulty}/Utils/History.cs (98%) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs similarity index 93% rename from osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs rename to osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 4853cd66cd..875f1f6097 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -5,11 +5,11 @@ using System; using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; +using osu.Game.Rulesets.Osu.Difficulty.Skills; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; -using osu.Game.Rulesets.Osu.OsuDifficulty.Skills; -namespace osu.Game.Rulesets.Osu.OsuDifficulty +namespace osu.Game.Rulesets.Osu.Difficulty { public class OsuDifficultyCalculator : DifficultyCalculator { diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyBeatmap.cs similarity index 98% rename from osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs rename to osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyBeatmap.cs index 5c8ab0f3d4..e97042a9aa 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyBeatmap.cs @@ -5,7 +5,7 @@ using System.Collections; using System.Collections.Generic; using osu.Game.Rulesets.Osu.Objects; -namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing +namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing { /// /// An enumerable container wrapping input as diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs similarity index 98% rename from osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs rename to osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs index 415f76ced8..f95426466b 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -3,10 +3,10 @@ using System; using System.Linq; -using OpenTK; using osu.Game.Rulesets.Osu.Objects; +using OpenTK; -namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing +namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing { /// /// A wrapper around extending it with additional data required for difficulty calculation. diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs similarity index 85% rename from osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs rename to osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index 5c736d7bb5..0a45c62671 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -2,9 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; +using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; -namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills +namespace osu.Game.Rulesets.Osu.Difficulty.Skills { /// /// Represents the skill required to correctly aim at every object in the map with a uniform CircleSize and normalized distances. diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Skill.cs similarity index 96% rename from osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs rename to osu.Game.Rulesets.Osu/Difficulty/Skills/Skill.cs index 983599432f..47037c1503 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Skill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Skill.cs @@ -3,11 +3,11 @@ using System; using System.Collections.Generic; +using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; +using osu.Game.Rulesets.Osu.Difficulty.Utils; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; -using osu.Game.Rulesets.Osu.OsuDifficulty.Utils; -namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills +namespace osu.Game.Rulesets.Osu.Difficulty.Skills { /// /// Used to processes strain values of s, keep track of strain levels caused by the processed objects diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs similarity index 93% rename from osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs rename to osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index ae3caa1e66..b807f20037 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -1,9 +1,9 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing; +using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; -namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills +namespace osu.Game.Rulesets.Osu.Difficulty.Skills { /// /// Represents the skill required to press keys with regards to keeping up with the speed at which objects need to be hit. diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs b/osu.Game.Rulesets.Osu/Difficulty/Utils/History.cs similarity index 98% rename from osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs rename to osu.Game.Rulesets.Osu/Difficulty/Utils/History.cs index f6933a3e5d..55bd950209 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Utils/History.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Utils/History.cs @@ -5,7 +5,7 @@ using System; using System.Collections; using System.Collections.Generic; -namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils +namespace osu.Game.Rulesets.Osu.Difficulty.Utils { /// /// An indexed stack with Push() only, which disposes items at the bottom after the capacity is full. diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 69a54fb533..b5dc9063af 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -5,7 +5,6 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Rulesets.Osu.OsuDifficulty; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; using System.Collections.Generic; @@ -20,6 +19,7 @@ using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Osu.Beatmaps; +using osu.Game.Rulesets.Osu.Difficulty; namespace osu.Game.Rulesets.Osu { From 995fda9b6f9a9d3bde52c9e943592e376dc6271f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 17:38:04 +0900 Subject: [PATCH 151/229] Move base classes to osu.Game.Rulesets.Difficulty namespace --- osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs | 1 + osu.Game.Rulesets.Catch/CatchRuleset.cs | 1 + osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs | 1 + osu.Game.Rulesets.Mania/ManiaRuleset.cs | 1 + .../Difficulty/OsuDifficultyCalculator.cs | 1 + osu.Game.Rulesets.Osu/OsuRuleset.cs | 1 + osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs | 1 + osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs | 1 + osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 1 + osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 1 + .../Difficulty}/DifficultyCalculator.cs | 7 ++++--- .../{Scoring => Difficulty}/PerformanceCalculator.cs | 3 ++- osu.Game/Rulesets/Ruleset.cs | 1 + 13 files changed, 17 insertions(+), 4 deletions(-) rename osu.Game/{Beatmaps => Rulesets/Difficulty}/DifficultyCalculator.cs (94%) rename osu.Game/Rulesets/{Scoring => Difficulty}/PerformanceCalculator.cs (95%) diff --git a/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs index f47d09fe20..1ea70c54c9 100644 --- a/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs @@ -3,6 +3,7 @@ using osu.Game.Beatmaps; using System.Collections.Generic; +using osu.Game.Rulesets.Difficulty; namespace osu.Game.Rulesets.Catch { diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 15e51fa126..c4342ec4b0 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -14,6 +14,7 @@ using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Catch.Beatmaps; +using osu.Game.Rulesets.Difficulty; namespace osu.Game.Rulesets.Catch { diff --git a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs index 822ba53eeb..d5ae568bc4 100644 --- a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs @@ -7,6 +7,7 @@ using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mods; using System; using System.Collections.Generic; +using osu.Game.Rulesets.Difficulty; namespace osu.Game.Rulesets.Mania { diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index f1d65f855b..2672486460 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -15,6 +15,7 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Mania.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; +using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mania.Beatmaps; namespace osu.Game.Rulesets.Mania diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 875f1f6097..bd8d18af41 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; using osu.Game.Rulesets.Osu.Difficulty.Skills; diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index b5dc9063af..a2423ffbe5 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -18,6 +18,7 @@ using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; +using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Difficulty; diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index 793060197d..938060a664 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Objects; diff --git a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs index f14c53f7ae..1c49118d32 100644 --- a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs @@ -5,6 +5,7 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Taiko.Objects; using System.Collections.Generic; using System; +using osu.Game.Rulesets.Difficulty; namespace osu.Game.Rulesets.Taiko { diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 102de5717f..154b66f4ad 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -13,6 +13,7 @@ using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Taiko.Replays; using osu.Game.Beatmaps.Legacy; +using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Taiko.Beatmaps; namespace osu.Game.Rulesets.Taiko diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index da52dc7284..8094abe5ed 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; using osu.Game.Rulesets; +using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.UI; diff --git a/osu.Game/Beatmaps/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs similarity index 94% rename from osu.Game/Beatmaps/DifficultyCalculator.cs rename to osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index 5cac9ed923..070bc7ddb0 100644 --- a/osu.Game/Beatmaps/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -2,12 +2,13 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using osu.Game.Rulesets.Mods; -using osu.Framework.Timing; using System.Linq; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Timing; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; -namespace osu.Game.Beatmaps +namespace osu.Game.Rulesets.Difficulty { public abstract class DifficultyCalculator { diff --git a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs b/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs similarity index 95% rename from osu.Game/Rulesets/Scoring/PerformanceCalculator.cs rename to osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs index f2c495fa5d..9fd7a0156d 100644 --- a/osu.Game/Rulesets/Scoring/PerformanceCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs @@ -7,8 +7,9 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; -namespace osu.Game.Rulesets.Scoring +namespace osu.Game.Rulesets.Difficulty { public abstract class PerformanceCalculator { diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 6883d319f4..395eeab419 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -15,6 +15,7 @@ using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Beatmaps.Legacy; +using osu.Game.Rulesets.Difficulty; namespace osu.Game.Rulesets { From 803200ff6a724e1c7143c0901776b7a95756b76d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 17:40:19 +0900 Subject: [PATCH 152/229] Apply similar changes to other rulesets --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 1 + .../{ => Difficulty}/CatchDifficultyCalculator.cs | 4 ++-- .../{ => Difficulty}/ManiaDifficultyCalculator.cs | 8 ++++---- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 1 + .../{ => Difficulty}/TaikoDifficultyCalculator.cs | 8 ++++---- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 1 + 6 files changed, 13 insertions(+), 10 deletions(-) rename osu.Game.Rulesets.Catch/{ => Difficulty}/CatchDifficultyCalculator.cs (92%) rename osu.Game.Rulesets.Mania/{ => Difficulty}/ManiaDifficultyCalculator.cs (99%) rename osu.Game.Rulesets.Taiko/{ => Difficulty}/TaikoDifficultyCalculator.cs (99%) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index c4342ec4b0..2325a8cad9 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -14,6 +14,7 @@ using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Catch.Beatmaps; +using osu.Game.Rulesets.Catch.Difficulty; using osu.Game.Rulesets.Difficulty; namespace osu.Game.Rulesets.Catch diff --git a/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs similarity index 92% rename from osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs rename to osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs index 1ea70c54c9..f8351b7519 100644 --- a/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs @@ -1,11 +1,11 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Beatmaps; using System.Collections.Generic; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; -namespace osu.Game.Rulesets.Catch +namespace osu.Game.Rulesets.Catch.Difficulty { public class CatchDifficultyCalculator : DifficultyCalculator { diff --git a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs similarity index 99% rename from osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs rename to osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs index d5ae568bc4..ac45130fd8 100644 --- a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs @@ -1,15 +1,15 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mods; -using System; -using System.Collections.Generic; -using osu.Game.Rulesets.Difficulty; -namespace osu.Game.Rulesets.Mania +namespace osu.Game.Rulesets.Mania.Difficulty { internal class ManiaDifficultyCalculator : DifficultyCalculator { diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 2672486460..b1702de537 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -17,6 +17,7 @@ using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.Difficulty; namespace osu.Game.Rulesets.Mania { diff --git a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs similarity index 99% rename from osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs rename to osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs index 1c49118d32..acff0d286d 100644 --- a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs @@ -1,13 +1,13 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Taiko.Objects; -using System.Collections.Generic; using System; +using System.Collections.Generic; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Taiko.Objects; -namespace osu.Game.Rulesets.Taiko +namespace osu.Game.Rulesets.Taiko.Difficulty { internal class TaikoDifficultyCalculator : DifficultyCalculator { diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 154b66f4ad..35dc17c0e2 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -15,6 +15,7 @@ using osu.Game.Rulesets.Taiko.Replays; using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Taiko.Beatmaps; +using osu.Game.Rulesets.Taiko.Difficulty; namespace osu.Game.Rulesets.Taiko { From 0325b1bd7ac7b9b0af4bc9f2bd210bfe00aa12bf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 May 2018 19:42:30 +0900 Subject: [PATCH 153/229] Remove unused class --- osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs index fbdb27a81c..ae03a06b4f 100644 --- a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs @@ -8,10 +8,6 @@ using osu.Framework.Screens; namespace osu.Game.Graphics.UserInterface { - public class ScreenBreadcrumbControl : ScreenBreadcrumbControl - { - } - public class ScreenBreadcrumbControl : BreadcrumbControl where T : Screen { private T currentScreen; From 28df77e83887d2eae75454bdd6de5b3a8afca46a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 May 2018 21:08:55 +0900 Subject: [PATCH 154/229] Simplify code and remove generic --- ....cs => TestCaseScreenBreadcrumbControl.cs} | 18 ++--- .../UserInterface/ScreenBreadcrumbControl.cs | 75 +++++++------------ 2 files changed, 36 insertions(+), 57 deletions(-) rename osu.Game.Tests/Visual/{TestCaseScreenBreadcrumbs.cs => TestCaseScreenBreadcrumbControl.cs} (89%) diff --git a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs similarity index 89% rename from osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs rename to osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs index f477a0b97e..a64e60dbd6 100644 --- a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbs.cs +++ b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs @@ -6,6 +6,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Screens; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -15,18 +16,19 @@ using OpenTK; namespace osu.Game.Tests.Visual { [TestFixture] - public class TestCaseScreenBreadcrumbs : OsuTestCase + public class TestCaseScreenBreadcrumbControl : OsuTestCase { - private readonly ScreenBreadcrumbControl breadcrumbs; - private TestScreen currentScreen, changedScreen; + private readonly ScreenBreadcrumbControl breadcrumbs; + private Screen currentScreen, changedScreen; - public TestCaseScreenBreadcrumbs() + public TestCaseScreenBreadcrumbControl() { TestScreen startScreen; OsuSpriteText titleText; Children = new Drawable[] { + changedScreen = currentScreen = startScreen = new TestScreenOne(), new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -35,23 +37,21 @@ namespace osu.Game.Tests.Visual Spacing = new Vector2(10), Children = new Drawable[] { - breadcrumbs = new ScreenBreadcrumbControl + breadcrumbs = new ScreenBreadcrumbControl(startScreen) { RelativeSizeAxes = Axes.X, }, titleText = new OsuSpriteText(), }, }, - currentScreen = startScreen = new TestScreenOne(), }; - breadcrumbs.OnScreenChanged += s => + breadcrumbs.Current.ValueChanged += s => { titleText.Text = $"Changed to {s.ToString()}"; changedScreen = s; }; - AddStep(@"make start current", () => breadcrumbs.CurrentScreen = startScreen); assertCurrent(); pushNext(); assertCurrent(); @@ -75,7 +75,7 @@ namespace osu.Game.Tests.Visual breadcrumbs.StripColour = colours.Blue; } - private void pushNext() => AddStep(@"push next screen", () => currentScreen = currentScreen.PushNext()); + private void pushNext() => AddStep(@"push next screen", () => currentScreen = ((TestScreen)currentScreen).PushNext()); private void assertCurrent() => AddAssert(@"assert the current screen is correct", () => currentScreen == changedScreen); private abstract class TestScreen : OsuScreen diff --git a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs index ae03a06b4f..49d854ccd2 100644 --- a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs @@ -8,67 +8,46 @@ using osu.Framework.Screens; namespace osu.Game.Graphics.UserInterface { - public class ScreenBreadcrumbControl : BreadcrumbControl where T : Screen + /// + /// A which follows the active screen (and allows navigation) in a stack. + /// + public class ScreenBreadcrumbControl : BreadcrumbControl { - private T currentScreen; - public T CurrentScreen + private Screen last; + + public ScreenBreadcrumbControl(Screen initialScreen) { - get { return currentScreen; } - set + Current.ValueChanged += newScreen => { - if (value == currentScreen) return; - - if (CurrentScreen != null) - { - CurrentScreen.Exited -= onExited; - CurrentScreen.ModePushed -= onPushed; - } - else - { - // this is the first screen in the stack, so call the initial onPushed - currentScreen = value; - onPushed(CurrentScreen); - } - - currentScreen = value; - - if (CurrentScreen != null) - { - CurrentScreen.Exited += onExited; - CurrentScreen.ModePushed += onPushed; - Current.Value = CurrentScreen; - OnScreenChanged?.Invoke(CurrentScreen); - } - } - } - - public event Action OnScreenChanged; - - public ScreenBreadcrumbControl() - { - Current.ValueChanged += s => - { - if (s != CurrentScreen) - { - CurrentScreen = s; - s.MakeCurrent(); - } + if (last != newScreen && !newScreen.IsCurrentScreen) + newScreen.MakeCurrent(); }; + + onPushed(initialScreen); } - private void onExited(Screen screen) + private void screenChanged(Screen newScreen) { - CurrentScreen = screen as T; + if (last != null) + { + last.Exited -= screenChanged; + last.ModePushed -= onPushed; + } + + last = newScreen; + + newScreen.Exited += screenChanged; + newScreen.ModePushed += onPushed; + + Current.Value = newScreen; } private void onPushed(Screen screen) { - var newScreen = screen as T; - Items.ToList().SkipWhile(i => i != Current.Value).Skip(1).ForEach(RemoveItem); - AddItem(newScreen); + AddItem(screen); - CurrentScreen = newScreen; + screenChanged(screen); } } } From 49c36787d7d1365c6eda1fcae9b4fb5e77b496de Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 21:22:57 +0900 Subject: [PATCH 155/229] Remove triangle pattern and remove not-implemented reading strain --- .../Preprocessing/OsuDifficultyBeatmap.cs | 58 ++----------------- .../Preprocessing/OsuDifficultyHitObject.cs | 19 +++--- 2 files changed, 11 insertions(+), 66 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs index 5c8ab0f3d4..867a11f280 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs @@ -14,7 +14,6 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing public class OsuDifficultyBeatmap : IEnumerable { private readonly IEnumerator difficultyObjects; - private readonly Queue onScreen = new Queue(); /// /// Creates an enumerator, which preprocesses a list of s recieved as input, wrapping them as @@ -30,65 +29,16 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing /// /// Returns an enumerator that enumerates all s in the . - /// The inner loop adds objects that appear on screen into a queue until we need to hit the next object. - /// The outer loop returns objects from this queue one at a time, only after they had to be hit, and should no longer be on screen. - /// This means that we can loop through every object that is on screen at the time when a new one appears, - /// allowing us to determine a reading strain for the object that just appeared. /// - public IEnumerator GetEnumerator() - { - while (true) - { - // Add upcoming objects to the queue until we have at least one object that had been hit and can be dequeued. - // This means there is always at least one object in the queue unless we reached the end of the map. - do - { - if (!difficultyObjects.MoveNext()) - break; // New objects can't be added anymore, but we still need to dequeue and return the ones already on screen. - - OsuDifficultyHitObject latest = difficultyObjects.Current; - // Calculate flow values here - - foreach (OsuDifficultyHitObject h in onScreen) - { - // ReSharper disable once PossibleNullReferenceException (resharper not smart enough to understand IEnumerator.MoveNext()) - h.TimeUntilHit -= latest.DeltaTime; - // Calculate reading strain here - } - - onScreen.Enqueue(latest); - } - while (onScreen.Peek().TimeUntilHit > 0); // Keep adding new objects on screen while there is still time before we have to hit the next one. - - if (onScreen.Count == 0) break; // We have reached the end of the map and enumerated all the objects. - yield return onScreen.Dequeue(); // Remove and return objects one by one that had to be hit before the latest one appeared. - } - } - + public IEnumerator GetEnumerator() => difficultyObjects; IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); private IEnumerator createDifficultyObjectEnumerator(List objects, double timeRate) { - // We will process OsuHitObjects in groups of three to form a triangle, so we can calculate an angle for each object. - OsuHitObject[] triangle = new OsuHitObject[3]; - - // OsuDifficultyHitObject construction requires three components, an extra copy of the first OsuHitObject is used at the beginning. - if (objects.Count > 1) - { - triangle[1] = objects[0]; // This copy will get shifted to the last spot in the triangle. - triangle[0] = objects[0]; // This component corresponds to the real first OsuHitOject. - } - - // The final component of the first triangle will be the second OsuHitOject of the map, which forms the first jump. + // The first jump is formed by the first two hitobjects of the map. // If the map has less than two OsuHitObjects, the enumerator will not return anything. - for (int i = 1; i < objects.Count; ++i) - { - triangle[2] = triangle[1]; - triangle[1] = triangle[0]; - triangle[0] = objects[i]; - - yield return new OsuDifficultyHitObject(triangle, timeRate); - } + for (int i = 1; i < objects.Count; i++) + yield return new OsuDifficultyHitObject(objects[i], objects[i - 1], timeRate); } } } diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs index 415f76ced8..c096e9a464 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -28,26 +28,22 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing /// public double DeltaTime { get; private set; } - /// - /// Number of milliseconds until the has to be hit. - /// - public double TimeUntilHit { get; set; } private const int normalized_radius = 52; + private readonly OsuHitObject lastObject; private readonly double timeRate; - private readonly OsuHitObject[] t; - /// /// Initializes the object calculating extra data required for difficulty calculation. /// - public OsuDifficultyHitObject(OsuHitObject[] triangle, double timeRate) + public OsuDifficultyHitObject(OsuHitObject currentObject, OsuHitObject lastObject, double timeRate) { + this.lastObject = lastObject; this.timeRate = timeRate; - t = triangle; - BaseObject = t[0]; + BaseObject = currentObject; + setDistances(); setTimingValues(); // Calculate angle here @@ -63,10 +59,10 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing scalingFactor *= 1 + smallCircleBonus; } - Vector2 lastCursorPosition = t[1].StackedPosition; + Vector2 lastCursorPosition = lastObject.StackedPosition; float lastTravelDistance = 0; - var lastSlider = t[1] as Slider; + var lastSlider = lastObject as Slider; if (lastSlider != null) { computeSliderCursorPosition(lastSlider); @@ -81,7 +77,6 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing { // Every timing inverval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure. DeltaTime = Math.Max(40, (t[0].StartTime - t[1].StartTime) / timeRate); - TimeUntilHit = 450; // BaseObject.PreEmpt; } private void computeSliderCursorPosition(Slider slider) From 1b5c151e0edf7f528ca344516f47977908f04a75 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 21:25:02 +0900 Subject: [PATCH 156/229] Fix DeltaTime being capped incorrectly --- .../OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs index c096e9a464..d06518df53 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing private void setTimingValues() { // Every timing inverval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure. - DeltaTime = Math.Max(40, (t[0].StartTime - t[1].StartTime) / timeRate); + DeltaTime = Math.Max(50, (BaseObject.StartTime - lastObject.StartTime) / timeRate); } private void computeSliderCursorPosition(Slider slider) From 1acfc1bbabf365c15401b121a6c2f1eab9b46c1f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 21:25:20 +0900 Subject: [PATCH 157/229] Fix ModHardRock not properly clamping Drain/OD --- osu.Game/Rulesets/Mods/ModHardRock.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModHardRock.cs b/osu.Game/Rulesets/Mods/ModHardRock.cs index 090bc737dd..1629945c87 100644 --- a/osu.Game/Rulesets/Mods/ModHardRock.cs +++ b/osu.Game/Rulesets/Mods/ModHardRock.cs @@ -21,8 +21,8 @@ namespace osu.Game.Rulesets.Mods const float ratio = 1.4f; difficulty.CircleSize *= 1.3f; // CS uses a custom 1.3 ratio. difficulty.ApproachRate = Math.Min(difficulty.ApproachRate * ratio, 10.0f); - difficulty.DrainRate *= ratio; - difficulty.OverallDifficulty *= ratio; + difficulty.DrainRate = Math.Min(difficulty.DrainRate * ratio, 10.0f); + difficulty.OverallDifficulty = Math.Min(difficulty.OverallDifficulty * ratio, 10.0f); } } } From bc197a88e17f745344efd688f65e520d1f814565 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 21:25:33 +0900 Subject: [PATCH 158/229] Fix slider length calculation including slider head --- .../OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs index d06518df53..1624b936c8 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -102,7 +102,8 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing } }); - var scoringTimes = slider.NestedHitObjects.Select(t => t.StartTime); + // Skip the head circle + var scoringTimes = slider.NestedHitObjects.Skip(1).Select(t => t.StartTime); foreach (var time in scoringTimes) computeVertex(time); computeVertex(slider.EndTime); From 22f3bee55ae10fa62c0cb7ef9ede89946149529a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 21:26:06 +0900 Subject: [PATCH 159/229] Fix incorrect iteration over difficulty sections --- .../OsuDifficulty/OsuDifficultyCalculator.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs index 4853cd66cd..92cfb77faa 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs @@ -35,18 +35,22 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty new Speed() }; - double sectionEnd = section_length / TimeRate; + double sectionLength = section_length * TimeRate; + + // The first object doesn't generate a strain, so we begin with an incremented section end + double currentSectionEnd = 2 * sectionLength; + foreach (OsuDifficultyHitObject h in beatmap) { - while (h.BaseObject.StartTime > sectionEnd) + while (h.BaseObject.StartTime > currentSectionEnd) { foreach (Skill s in skills) { s.SaveCurrentPeak(); - s.StartNewSectionFrom(sectionEnd); + s.StartNewSectionFrom(currentSectionEnd); } - sectionEnd += section_length; + currentSectionEnd += sectionLength; } foreach (Skill s in skills) From cf08293be15de809bf79c3051278babbd164033b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 21:44:45 +0900 Subject: [PATCH 160/229] Remove extra newline --- .../Difficulty/Preprocessing/OsuDifficultyHitObject.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs index 595e2d7e3e..29de23406b 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -13,6 +13,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing /// public class OsuDifficultyHitObject { + private const int normalized_radius = 52; + /// /// The this refers to. /// @@ -28,9 +30,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing /// public double DeltaTime { get; private set; } - - private const int normalized_radius = 52; - private readonly OsuHitObject lastObject; private readonly double timeRate; From 3f67d044291d081df01a259aa40e57ff3274fb82 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 15 May 2018 21:57:08 +0900 Subject: [PATCH 161/229] Cap CS to 10 also --- osu.Game/Rulesets/Mods/ModHardRock.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModHardRock.cs b/osu.Game/Rulesets/Mods/ModHardRock.cs index 1629945c87..6379be9bfc 100644 --- a/osu.Game/Rulesets/Mods/ModHardRock.cs +++ b/osu.Game/Rulesets/Mods/ModHardRock.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mods public void ApplyToDifficulty(BeatmapDifficulty difficulty) { const float ratio = 1.4f; - difficulty.CircleSize *= 1.3f; // CS uses a custom 1.3 ratio. + difficulty.CircleSize = Math.Min(difficulty.CircleSize * 1.3f, 10.0f); // CS uses a custom 1.3 ratio. difficulty.ApproachRate = Math.Min(difficulty.ApproachRate * ratio, 10.0f); difficulty.DrainRate = Math.Min(difficulty.DrainRate * ratio, 10.0f); difficulty.OverallDifficulty = Math.Min(difficulty.OverallDifficulty * ratio, 10.0f); From c0c449e453d2a71043386cf120a633c40ff2c123 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 May 2018 22:53:33 +0900 Subject: [PATCH 162/229] Remove unused using --- osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs index 49d854ccd2..ba3927b771 100644 --- a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using System.Linq; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Screens; From 4019683f6ce6231c3cf04d437adccc8d48e1b651 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 16 May 2018 01:24:53 +0900 Subject: [PATCH 163/229] Implement osu!mania performance calculation --- .../Difficulty/ManiaDifficultyCalculator.cs | 3 +- .../Difficulty/ManiaPerformanceCalculator.cs | 122 ++++++++++++++++++ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 + 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs index ac45130fd8..8458e63fca 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs @@ -60,7 +60,8 @@ namespace osu.Game.Rulesets.Mania.Difficulty double starRating = calculateDifficulty() * star_scaling_factor; - categoryDifficulty?.Add("Strain", starRating); + if (categoryDifficulty != null) + categoryDifficulty["Strain"] = starRating; return starRating; } diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs new file mode 100644 index 0000000000..1704d924f8 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs @@ -0,0 +1,122 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Mania.Difficulty +{ + public class ManiaPerformanceCalculator : PerformanceCalculator + { + private Mod[] mods; + private int countGeki; + private int countKatu; + private int count300; + private int count100; + private int count50; + private int countMiss; + + public ManiaPerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) + : base(ruleset, beatmap, score) + { + } + + public override double Calculate(Dictionary categoryDifficulty = null) + { + mods = Score.Mods; + countGeki = Convert.ToInt32(Score.Statistics[HitResult.Perfect]); + countKatu = Convert.ToInt32(Score.Statistics[HitResult.Ok]); + count300 = Convert.ToInt32(Score.Statistics[HitResult.Great]); + count100 = Convert.ToInt32(Score.Statistics[HitResult.Good]); + count50 = Convert.ToInt32(Score.Statistics[HitResult.Meh]); + countMiss = Convert.ToInt32(Score.Statistics[HitResult.Miss]); + + if (mods.Any(m => !m.Ranked)) + return 0; + + // Custom multipliers for NoFail + double multiplier = 1.1; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things + + if (mods.Any(m => m is ModNoFail)) + multiplier *= 0.9; + if (mods.Any(m => m is ModEasy)) + multiplier *= 0.5; + + double strainValue = computeStrainValue(); + double accValue = computeAccuracyValue(); + double totalValue = + Math.Pow( + Math.Pow(strainValue, 1.1) + + Math.Pow(accValue, 1.1), 1.0 / 1.1 + ) * multiplier; + + if (categoryDifficulty != null) + { + categoryDifficulty["Strain"] = strainValue; + categoryDifficulty["Accuracy"] = accValue; + + } + + return totalValue; + } + + private double computeStrainValue() + { + IEnumerable scoreIncreaseMods = new ManiaRuleset().GetModsFor(ModType.DifficultyIncrease); + + double scoreMultiplier = 1.0; + foreach (var m in mods.Where(m => !scoreIncreaseMods.Contains(m))) + scoreMultiplier *= m.ScoreMultiplier; + + // Score after being scaled by non-difficulty-increasing mods + double scaledScore = Score.TotalScore; + + // Scale score up, so it's comparable to other keymods + scaledScore *= 1.0 / scoreMultiplier; + + // Obtain strain difficulty + double strainValue = Math.Pow(5 * Math.Max(1, Attributes["Strain"] / 0.0825) - 4.0, 3.0) / 110000.0; + + // Longer maps are worth more + strainValue *= 1.0 + 0.1 * Math.Min(1.0, totalHits / 1500.0); + + if (scaledScore <= 500000) + strainValue = 0; + else if (scaledScore <= 600000) + strainValue *= (scaledScore - 500000) / 100000 * 0.3; + else if (scaledScore <= 700000) + strainValue *= 0.3 + (scaledScore - 600000) / 100000 * 0.35; + else if (scaledScore <= 800000) + strainValue *= 0.65 + (scaledScore - 700000) / 100000 * 0.20; + else if (scaledScore <= 900000) + strainValue *= 0.85 + (scaledScore - 800000) / 100000 * 0.1; + else + strainValue *= 0.95 + (scaledScore - 900000) / 100000 * 0.05; + + return strainValue; + } + + private double computeAccuracyValue() + { + double hitWindow300 = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; + if (hitWindow300 <= 0) + return 0; + + // Lots of arbitrary values from testing. + // Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution + double accuracyValue = Math.Pow(150.0 / hitWindow300 * Math.Pow(Score.Accuracy, 16), 1.8) * 2.5; + + // Bonus for many hitcircles - it's harder to keep good accuracy up for longer + accuracyValue *= Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3)); + + return accuracyValue; + } + + private double totalHits => countGeki + countKatu + count300 + count100 + count50 + countMiss; + } +} diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index b1702de537..02ecb3afda 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -18,6 +18,7 @@ using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Difficulty; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania { @@ -25,6 +26,7 @@ namespace osu.Game.Rulesets.Mania { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) => new ManiaRulesetContainer(this, beatmap); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap); + public override PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => new ManiaPerformanceCalculator(this, beatmap, score); public override IEnumerable ConvertLegacyMods(LegacyMods mods) { From 1fdc77d5791cd03af2e69fe62b1a68c57e1589c0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 16 May 2018 01:34:07 +0900 Subject: [PATCH 164/229] Update with the rebalance changes --- .../Difficulty/ManiaPerformanceCalculator.cs | 51 ++++++++++--------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs index 1704d924f8..3337d4df75 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs @@ -14,6 +14,10 @@ namespace osu.Game.Rulesets.Mania.Difficulty public class ManiaPerformanceCalculator : PerformanceCalculator { private Mod[] mods; + + // Score after being scaled by non-difficulty-increasing mods + private double scaledScore; + private int countGeki; private int countKatu; private int count300; @@ -29,6 +33,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty public override double Calculate(Dictionary categoryDifficulty = null) { mods = Score.Mods; + scaledScore = Score.TotalScore; countGeki = Convert.ToInt32(Score.Statistics[HitResult.Perfect]); countKatu = Convert.ToInt32(Score.Statistics[HitResult.Ok]); count300 = Convert.ToInt32(Score.Statistics[HitResult.Great]); @@ -39,8 +44,18 @@ namespace osu.Game.Rulesets.Mania.Difficulty if (mods.Any(m => !m.Ranked)) return 0; - // Custom multipliers for NoFail - double multiplier = 1.1; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things + IEnumerable scoreIncreaseMods = new ManiaRuleset().GetModsFor(ModType.DifficultyIncrease); + + double scoreMultiplier = 1.0; + foreach (var m in mods.Where(m => !scoreIncreaseMods.Contains(m))) + scoreMultiplier *= m.ScoreMultiplier; + + // Scale score up, so it's comparable to other keymods + scaledScore *= 1.0 / scoreMultiplier; + + // Arbitrary initial value for scaling pp in order to standardize distributions across game modes. + // The specific number has no intrinsic meaning and can be adjusted as needed. + double multiplier = 0.8; if (mods.Any(m => m is ModNoFail)) multiplier *= 0.9; @@ -48,7 +63,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty multiplier *= 0.5; double strainValue = computeStrainValue(); - double accValue = computeAccuracyValue(); + double accValue = computeAccuracyValue(strainValue); double totalValue = Math.Pow( Math.Pow(strainValue, 1.1) + @@ -67,20 +82,8 @@ namespace osu.Game.Rulesets.Mania.Difficulty private double computeStrainValue() { - IEnumerable scoreIncreaseMods = new ManiaRuleset().GetModsFor(ModType.DifficultyIncrease); - - double scoreMultiplier = 1.0; - foreach (var m in mods.Where(m => !scoreIncreaseMods.Contains(m))) - scoreMultiplier *= m.ScoreMultiplier; - - // Score after being scaled by non-difficulty-increasing mods - double scaledScore = Score.TotalScore; - - // Scale score up, so it's comparable to other keymods - scaledScore *= 1.0 / scoreMultiplier; - // Obtain strain difficulty - double strainValue = Math.Pow(5 * Math.Max(1, Attributes["Strain"] / 0.0825) - 4.0, 3.0) / 110000.0; + double strainValue = Math.Pow(5 * Math.Max(1, Attributes["Strain"] / 0.2) - 4.0, 2.2) / 135.0; // Longer maps are worth more strainValue *= 1.0 + 0.1 * Math.Min(1.0, totalHits / 1500.0); @@ -90,18 +93,18 @@ namespace osu.Game.Rulesets.Mania.Difficulty else if (scaledScore <= 600000) strainValue *= (scaledScore - 500000) / 100000 * 0.3; else if (scaledScore <= 700000) - strainValue *= 0.3 + (scaledScore - 600000) / 100000 * 0.35; + strainValue *= 0.3 + (scaledScore - 600000) / 100000 * 0.25; else if (scaledScore <= 800000) - strainValue *= 0.65 + (scaledScore - 700000) / 100000 * 0.20; + strainValue *= 0.55 + (scaledScore - 700000) / 100000 * 0.20; else if (scaledScore <= 900000) - strainValue *= 0.85 + (scaledScore - 800000) / 100000 * 0.1; + strainValue *= 0.75 + (scaledScore - 800000) / 100000 * 0.15; else - strainValue *= 0.95 + (scaledScore - 900000) / 100000 * 0.05; + strainValue *= 0.90 + (scaledScore - 900000) / 100000 * 0.1; return strainValue; } - private double computeAccuracyValue() + private double computeAccuracyValue(double strainValue) { double hitWindow300 = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; if (hitWindow300 <= 0) @@ -109,10 +112,12 @@ namespace osu.Game.Rulesets.Mania.Difficulty // Lots of arbitrary values from testing. // Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution - double accuracyValue = Math.Pow(150.0 / hitWindow300 * Math.Pow(Score.Accuracy, 16), 1.8) * 2.5; + double accuracyValue = Math.Max(0.0, 0.2 - (hitWindow300 - 34) * 0.006667) + * strainValue + * Math.Pow(Math.Max(0.0, scaledScore - 960000) / 40000, 1.1); // Bonus for many hitcircles - it's harder to keep good accuracy up for longer - accuracyValue *= Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3)); + // accuracyValue *= Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3)); return accuracyValue; } From ed902d9325eb6c7435e106224bd517a08ab9aa4c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 16 May 2018 01:36:28 +0900 Subject: [PATCH 165/229] Cleanup --- osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs index 3337d4df75..024362f5d2 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs @@ -74,7 +74,6 @@ namespace osu.Game.Rulesets.Mania.Difficulty { categoryDifficulty["Strain"] = strainValue; categoryDifficulty["Accuracy"] = accValue; - } return totalValue; From de63a1b578d422a1c39b6212018ed3448c806ec5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 16 May 2018 01:43:58 +0900 Subject: [PATCH 166/229] Remove construction of new ruleset --- .../Difficulty/ManiaPerformanceCalculator.cs | 2 +- osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs index 024362f5d2..f5f815d9fb 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty if (mods.Any(m => !m.Ranked)) return 0; - IEnumerable scoreIncreaseMods = new ManiaRuleset().GetModsFor(ModType.DifficultyIncrease); + IEnumerable scoreIncreaseMods = Ruleset.GetModsFor(ModType.DifficultyIncrease); double scoreMultiplier = 1.0; foreach (var m in mods.Where(m => !scoreIncreaseMods.Contains(m))) diff --git a/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs b/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs index 9fd7a0156d..07d9c80061 100644 --- a/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs @@ -16,6 +16,7 @@ namespace osu.Game.Rulesets.Difficulty private readonly Dictionary attributes = new Dictionary(); protected IDictionary Attributes => attributes; + protected readonly Ruleset Ruleset; protected readonly IBeatmap Beatmap; protected readonly Score Score; @@ -23,9 +24,9 @@ namespace osu.Game.Rulesets.Difficulty protected PerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) { - Score = score; - + Ruleset = ruleset; Beatmap = beatmap; + Score = score; var diffCalc = ruleset.CreateDifficultyCalculator(beatmap, score.Mods); diffCalc.Calculate(attributes); From b9d99b5f4049531bcb9c255d78c088652c094b29 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 15 May 2018 19:42:50 -0300 Subject: [PATCH 167/229] Fix nullref when exiting the last screen. --- osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs index ba3927b771..adcf401546 100644 --- a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs @@ -27,6 +27,8 @@ namespace osu.Game.Graphics.UserInterface private void screenChanged(Screen newScreen) { + if (newScreen == null) return; + if (last != null) { last.Exited -= screenChanged; From f67ad7b8e879be7c789e9c763a335f966e4b786a Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 15 May 2018 19:52:28 -0300 Subject: [PATCH 168/229] Add exit test. --- osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs index a64e60dbd6..edd2e9fd11 100644 --- a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs +++ b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs @@ -66,7 +66,9 @@ namespace osu.Game.Tests.Visual assertCurrent(); pushNext(); - AddAssert(@"assert there are only 2 items", () => breadcrumbs.Items.Count() == 2); + AddAssert(@"only 2 items", () => breadcrumbs.Items.Count() == 2); + AddStep(@"exit current", () => changedScreen.Exit()); + AddAssert(@"current screen is first", () => startScreen == changedScreen); } [BackgroundDependencyLoader] @@ -76,7 +78,7 @@ namespace osu.Game.Tests.Visual } private void pushNext() => AddStep(@"push next screen", () => currentScreen = ((TestScreen)currentScreen).PushNext()); - private void assertCurrent() => AddAssert(@"assert the current screen is correct", () => currentScreen == changedScreen); + private void assertCurrent() => AddAssert(@"current screen is correct", () => currentScreen == changedScreen); private abstract class TestScreen : OsuScreen { From dda253758bfb4ade3bc3f6686cb2fccac6e17fc3 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 15 May 2018 19:56:47 -0300 Subject: [PATCH 169/229] Cleanup test step wording. --- osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs index edd2e9fd11..7a743655f4 100644 --- a/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs +++ b/osu.Game.Tests/Visual/TestCaseScreenBreadcrumbControl.cs @@ -28,7 +28,7 @@ namespace osu.Game.Tests.Visual Children = new Drawable[] { - changedScreen = currentScreen = startScreen = new TestScreenOne(), + currentScreen = startScreen = new TestScreenOne(), new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -52,6 +52,8 @@ namespace osu.Game.Tests.Visual changedScreen = s; }; + breadcrumbs.Current.TriggerChange(); + assertCurrent(); pushNext(); assertCurrent(); @@ -78,7 +80,7 @@ namespace osu.Game.Tests.Visual } private void pushNext() => AddStep(@"push next screen", () => currentScreen = ((TestScreen)currentScreen).PushNext()); - private void assertCurrent() => AddAssert(@"current screen is correct", () => currentScreen == changedScreen); + private void assertCurrent() => AddAssert(@"changedScreen correct", () => currentScreen == changedScreen); private abstract class TestScreen : OsuScreen { From 1450bf64f5c57f08ab85bc2900876c904d03c08e Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 15 May 2018 20:34:14 -0300 Subject: [PATCH 170/229] Add multiplayer screen header. --- osu.Game.Tests/Visual/TestCaseMultiHeader.cs | 27 +++++ osu.Game/Screens/Multi/Header.cs | 101 +++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseMultiHeader.cs create mode 100644 osu.Game/Screens/Multi/Header.cs diff --git a/osu.Game.Tests/Visual/TestCaseMultiHeader.cs b/osu.Game.Tests/Visual/TestCaseMultiHeader.cs new file mode 100644 index 0000000000..af51a6221f --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseMultiHeader.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Game.Screens.Multi; +using osu.Game.Screens.Multi.Screens; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseMultiHeader : OsuTestCase + { + public TestCaseMultiHeader() + { + Lobby lobby; + Children = new Drawable[] + { + lobby = new Lobby + { + Padding = new MarginPadding { Top = Header.HEIGHT }, + }, + new Header(lobby), + }; + } + } +} diff --git a/osu.Game/Screens/Multi/Header.cs b/osu.Game/Screens/Multi/Header.cs new file mode 100644 index 0000000000..03996f5309 --- /dev/null +++ b/osu.Game/Screens/Multi/Header.cs @@ -0,0 +1,101 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Screens; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.SearchableList; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Screens.Multi +{ + public class Header : Container + { + public const float HEIGHT = 121; + + private readonly OsuSpriteText screenTitle; + private readonly ScreenBreadcrumbControl breadcrumbs; + + public Header(Screen initialScreen) + { + RelativeSizeAxes = Axes.X; + Height = HEIGHT; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"2f2043"), + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, + Children = new Drawable[] + { + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.BottomLeft, + Position = new Vector2(-35f, 5f), + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10f, 0f), + Children = new Drawable[] + { + new SpriteIcon + { + Size = new Vector2(25), + Icon = FontAwesome.fa_osu_multi, + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new[] + { + new OsuSpriteText + { + Text = "multiplayer ", + TextSize = 25, + }, + screenTitle = new OsuSpriteText + { + TextSize = 25, + Font = @"Exo2.0-Light", + }, + }, + }, + }, + }, + breadcrumbs = new ScreenBreadcrumbControl(initialScreen) + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + }, + }, + }, + }; + + breadcrumbs.OnLoadComplete = d => breadcrumbs.AccentColour = Color4.White; + + breadcrumbs.Current.ValueChanged += s => screenTitle.Text = s.ToString(); + breadcrumbs.Current.TriggerChange(); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + screenTitle.Colour = colours.Yellow; + breadcrumbs.StripColour = colours.Green; + } + } +} From 1a78ac3d10629a12302133f6d26d209c60adfc3d Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 15 May 2018 21:14:10 -0300 Subject: [PATCH 171/229] Add Multiplayer screen. --- osu.Game.Tests/Visual/TestCaseMultiScreen.cs | 17 ++++ osu.Game/Screens/Menu/MainMenu.cs | 4 +- osu.Game/Screens/Multi/Multiplayer.cs | 100 +++++++++++++++++++ 3 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseMultiScreen.cs create mode 100644 osu.Game/Screens/Multi/Multiplayer.cs diff --git a/osu.Game.Tests/Visual/TestCaseMultiScreen.cs b/osu.Game.Tests/Visual/TestCaseMultiScreen.cs new file mode 100644 index 0000000000..2dd3e81ee1 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseMultiScreen.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Game.Screens.Multi; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseMultiScreen : OsuTestCase + { + public TestCaseMultiScreen() + { + Child = new Multiplayer(); + } + } +} diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index e564ab786d..600fad8da5 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -14,7 +14,7 @@ using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Charts; using osu.Game.Screens.Direct; using osu.Game.Screens.Edit; -using osu.Game.Screens.Multi.Screens; +using osu.Game.Screens.Multi; using osu.Game.Screens.Select; using osu.Game.Screens.Tournament; @@ -54,7 +54,7 @@ namespace osu.Game.Screens.Menu OnDirect = delegate { Push(new OnlineListing()); }, OnEdit = delegate { Push(new Editor()); }, OnSolo = delegate { Push(consumeSongSelect()); }, - OnMulti = delegate { Push(new Lobby()); }, + OnMulti = delegate { Push(new Multiplayer()); }, OnExit = Exit, } } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs new file mode 100644 index 0000000000..b3d393209c --- /dev/null +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -0,0 +1,100 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Screens; +using osu.Game.Graphics; +using osu.Game.Graphics.Backgrounds; +using osu.Game.Graphics.Containers; +using osu.Game.Screens.Multi.Screens; + +namespace osu.Game.Screens.Multi +{ + public class Multiplayer : OsuScreen + { + private readonly MultiplayerWaveContainer waves; + + protected override Container Content => waves; + + public Multiplayer() + { + InternalChild = waves = new MultiplayerWaveContainer + { + RelativeSizeAxes = Axes.Both, + }; + + Lobby lobby; + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"3e3a44"), + }, + new Triangles + { + RelativeSizeAxes = Axes.Both, + ColourLight = OsuColour.FromHex(@"3c3842"), + ColourDark = OsuColour.FromHex(@"393540"), + TriangleScale = 5, + }, + }, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = Header.HEIGHT }, + Child = lobby = new Lobby(), + }, + new Header(lobby), + }; + + lobby.Exited += s => Exit(); + } + + protected override void OnEntering(Screen last) + { + base.OnEntering(last); + waves.Show(); + } + + protected override bool OnExiting(Screen next) + { + waves.Hide(); + return base.OnExiting(next); + } + + protected override void OnResuming(Screen last) + { + base.OnResuming(last); + waves.Show(); + } + + protected override void OnSuspending(Screen next) + { + base.OnSuspending(next); + waves.Hide(); + } + + private class MultiplayerWaveContainer : WaveContainer + { + protected override bool StartHidden => true; + + public MultiplayerWaveContainer() + { + FirstWaveColour = OsuColour.FromHex(@"654d8c"); + SecondWaveColour = OsuColour.FromHex(@"554075"); + ThirdWaveColour = OsuColour.FromHex(@"44325e"); + FourthWaveColour = OsuColour.FromHex(@"392850"); + } + } + } +} From 8e053f2166a00f96865713d7c8b1d6a5532972ac Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 15 May 2018 21:20:34 -0300 Subject: [PATCH 172/229] Add multiplayer screen test steps. --- osu.Game.Tests/Visual/TestCaseMultiScreen.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseMultiScreen.cs b/osu.Game.Tests/Visual/TestCaseMultiScreen.cs index 2dd3e81ee1..6c22fb020f 100644 --- a/osu.Game.Tests/Visual/TestCaseMultiScreen.cs +++ b/osu.Game.Tests/Visual/TestCaseMultiScreen.cs @@ -11,7 +11,11 @@ namespace osu.Game.Tests.Visual { public TestCaseMultiScreen() { - Child = new Multiplayer(); + Multiplayer multi = new Multiplayer(); + + AddStep(@"show", () => Add(multi)); + AddWaitStep(5); + AddStep(@"exit", multi.Exit); } } } From edbb3a5a57448e1bde365f7df4a7265d8610c07a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 16 May 2018 12:44:11 +0900 Subject: [PATCH 173/229] Rename to use new hit result namings --- .../Difficulty/ManiaPerformanceCalculator.cs | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs index f5f815d9fb..e6e3028d62 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs @@ -18,11 +18,11 @@ namespace osu.Game.Rulesets.Mania.Difficulty // Score after being scaled by non-difficulty-increasing mods private double scaledScore; - private int countGeki; - private int countKatu; - private int count300; - private int count100; - private int count50; + private int countPerfect; + private int countGreat; + private int countGood; + private int countOk; + private int countMeh; private int countMiss; public ManiaPerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) @@ -34,11 +34,11 @@ namespace osu.Game.Rulesets.Mania.Difficulty { mods = Score.Mods; scaledScore = Score.TotalScore; - countGeki = Convert.ToInt32(Score.Statistics[HitResult.Perfect]); - countKatu = Convert.ToInt32(Score.Statistics[HitResult.Ok]); - count300 = Convert.ToInt32(Score.Statistics[HitResult.Great]); - count100 = Convert.ToInt32(Score.Statistics[HitResult.Good]); - count50 = Convert.ToInt32(Score.Statistics[HitResult.Meh]); + countPerfect = Convert.ToInt32(Score.Statistics[HitResult.Perfect]); + countGreat = Convert.ToInt32(Score.Statistics[HitResult.Great]); + countGood = Convert.ToInt32(Score.Statistics[HitResult.Good]); + countOk = Convert.ToInt32(Score.Statistics[HitResult.Ok]); + countMeh = Convert.ToInt32(Score.Statistics[HitResult.Meh]); countMiss = Convert.ToInt32(Score.Statistics[HitResult.Miss]); if (mods.Any(m => !m.Ranked)) @@ -105,13 +105,13 @@ namespace osu.Game.Rulesets.Mania.Difficulty private double computeAccuracyValue(double strainValue) { - double hitWindow300 = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; - if (hitWindow300 <= 0) + double hitWindowGreat = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; + if (hitWindowGreat <= 0) return 0; // Lots of arbitrary values from testing. // Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution - double accuracyValue = Math.Max(0.0, 0.2 - (hitWindow300 - 34) * 0.006667) + double accuracyValue = Math.Max(0.0, 0.2 - (hitWindowGreat - 34) * 0.006667) * strainValue * Math.Pow(Math.Max(0.0, scaledScore - 960000) / 40000, 1.1); @@ -121,6 +121,6 @@ namespace osu.Game.Rulesets.Mania.Difficulty return accuracyValue; } - private double totalHits => countGeki + countKatu + count300 + count100 + count50 + countMiss; + private double totalHits => countPerfect + countOk + countGreat + countGood + countMeh + countMiss; } } From c1d9fcc140509ec4022f7c6d44449f31d8a0fbab Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 16 May 2018 12:46:31 +0900 Subject: [PATCH 174/229] Make OsuPerformanceCalculator use the new hitresult namings --- .../Scoring/OsuPerformanceCalculator.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs index 938060a664..84a83d331b 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs @@ -32,9 +32,9 @@ namespace osu.Game.Rulesets.Osu.Scoring private double accuracy; private int scoreMaxCombo; - private int count300; - private int count100; - private int count50; + private int countGreat; + private int countGood; + private int countMeh; private int countMiss; public OsuPerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) @@ -52,9 +52,9 @@ namespace osu.Game.Rulesets.Osu.Scoring mods = Score.Mods; accuracy = Score.Accuracy; scoreMaxCombo = Score.MaxCombo; - count300 = Convert.ToInt32(Score.Statistics[HitResult.Great]); - count100 = Convert.ToInt32(Score.Statistics[HitResult.Good]); - count50 = Convert.ToInt32(Score.Statistics[HitResult.Meh]); + countGreat = Convert.ToInt32(Score.Statistics[HitResult.Great]); + countGood = Convert.ToInt32(Score.Statistics[HitResult.Good]); + countMeh = Convert.ToInt32(Score.Statistics[HitResult.Meh]); countMiss = Convert.ToInt32(Score.Statistics[HitResult.Miss]); // Don't count scores made with supposedly unranked mods @@ -71,10 +71,10 @@ namespace osu.Game.Rulesets.Osu.Scoring ar = Math.Max(0, ar / 2); double preEmpt = BeatmapDifficulty.DifficultyRange(ar, 1800, 1200, 450) / TimeRate; - double hitWindow300 = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; + double hitWindowGreat = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; realApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5; - realOverallDifficulty = (80 - 0.5 - hitWindow300) / 6; + realOverallDifficulty = (80 - 0.5 - hitWindowGreat) / 6; // Custom multipliers for NoFail and SpunOut. double multiplier = 1.12f; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things @@ -190,7 +190,7 @@ namespace osu.Game.Rulesets.Osu.Scoring int amountHitObjectsWithAccuracy = countHitCircles; if (amountHitObjectsWithAccuracy > 0) - betterAccuracyPercentage = ((count300 - (totalHits - amountHitObjectsWithAccuracy)) * 6 + count100 * 2 + count50) / (amountHitObjectsWithAccuracy * 6); + betterAccuracyPercentage = ((countGreat - (totalHits - amountHitObjectsWithAccuracy)) * 6 + countGood * 2 + countMeh) / (amountHitObjectsWithAccuracy * 6); else betterAccuracyPercentage = 0; @@ -213,7 +213,7 @@ namespace osu.Game.Rulesets.Osu.Scoring return accuracyValue; } - private double totalHits => count300 + count100 + count50 + countMiss; - private double totalSuccessfulHits => count300 + count100 + count50; + private double totalHits => countGreat + countGood + countMeh + countMiss; + private double totalSuccessfulHits => countGreat + countGood + countMeh; } } From 8d8b7e6fa2d3332575a2280704ddeb493a1f81cc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 16 May 2018 13:09:48 +0900 Subject: [PATCH 175/229] Fix conversion tests for ruleset-specific beatmaps not working TRuleset was a mistake. This resulted in cases that checked whether the beatmap was for the current ruleset (TaikoBeatmapConverter and ManiaBeatmapConverter) failing due to TestXRuleset != XRuleset... --- .../CatchBeatmapConversionTest.cs | 10 ++-------- .../ManiaBeatmapConversionTest.cs | 10 ++-------- .../OsuBeatmapConversionTest.cs | 10 ++-------- .../TaikoBeatmapConversionTest.cs | 10 ++-------- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 9 ++++----- 5 files changed, 12 insertions(+), 37 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index 808faa511b..5b34e46247 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -5,8 +5,6 @@ using System; using System.Collections.Generic; using NUnit.Framework; using osu.Framework.MathUtils; -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Catch.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects; @@ -14,7 +12,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Catch.Tests { - internal class CatchBeatmapConversionTest : BeatmapConversionTest + internal class CatchBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Catch"; @@ -47,7 +45,7 @@ namespace osu.Game.Rulesets.Catch.Tests } } - protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap); + protected override Ruleset CreateRuleset() => new CatchRuleset(); } internal struct ConvertValue : IEquatable @@ -64,8 +62,4 @@ namespace osu.Game.Rulesets.Catch.Tests => Precision.AlmostEquals(StartTime, other.StartTime, conversion_lenience) && Precision.AlmostEquals(Position, other.Position, conversion_lenience); } - - internal class TestCatchRuleset : CatchRuleset - { - } } diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index bd67a7d96a..5ae899f6d6 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -5,8 +5,6 @@ using System; using System.Collections.Generic; using NUnit.Framework; using osu.Framework.MathUtils; -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -14,7 +12,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Mania.Tests { - internal class ManiaBeatmapConversionTest : BeatmapConversionTest + internal class ManiaBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; @@ -35,7 +33,7 @@ namespace osu.Game.Rulesets.Mania.Tests }; } - protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap); + protected override Ruleset CreateRuleset() => new ManiaRuleset(); } internal struct ConvertValue : IEquatable @@ -54,8 +52,4 @@ namespace osu.Game.Rulesets.Mania.Tests && Precision.AlmostEquals(EndTime, other.EndTime, conversion_lenience) && Column == other.Column; } - - internal class TestManiaRuleset : ManiaRuleset - { - } } diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index 3d54043027..386ae5eb05 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -5,17 +5,15 @@ using System; using System.Collections.Generic; using NUnit.Framework; using osu.Framework.MathUtils; -using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Tests.Beatmaps; using OpenTK; namespace osu.Game.Rulesets.Osu.Tests { - internal class OsuBeatmapConversionTest : BeatmapConversionTest + internal class OsuBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Osu"; @@ -42,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Tests }; } - protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap); + protected override Ruleset CreateRuleset() => new OsuRuleset(); } internal struct ConvertValue : IEquatable @@ -67,8 +65,4 @@ namespace osu.Game.Rulesets.Osu.Tests && Precision.AlmostEquals(EndX, other.EndX, conversion_lenience) && Precision.AlmostEquals(EndY, other.EndY, conversion_lenience); } - - internal class TestOsuRuleset : OsuRuleset - { - } } diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs index ca4fc3ec57..93f1b7faf7 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -5,16 +5,14 @@ using System; using System.Collections.Generic; using NUnit.Framework; using osu.Framework.MathUtils; -using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Taiko.Beatmaps; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Taiko.Tests { - internal class TaikoBeatmapConversionTest : BeatmapConversionTest + internal class TaikoBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; @@ -40,7 +38,7 @@ namespace osu.Game.Rulesets.Taiko.Tests }; } - protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap); + protected override Ruleset CreateRuleset() => new TaikoRuleset(); } internal struct ConvertValue : IEquatable @@ -67,8 +65,4 @@ namespace osu.Game.Rulesets.Taiko.Tests && IsSwell == other.IsSwell && IsStrong == other.IsStrong; } - - internal class TestTaikoRuleset : TaikoRuleset - { - } } diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 2de38d49a9..7470f6ebed 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -16,8 +16,7 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Tests.Beatmaps { [TestFixture] - public abstract class BeatmapConversionTest - where TRuleset : Ruleset, new() + public abstract class BeatmapConversionTest where TConvertValue : IEquatable { private const string resource_namespace = "Testing.Beatmaps"; @@ -81,12 +80,12 @@ namespace osu.Game.Tests.Beatmaps { var beatmap = getBeatmap(name); - var rulesetInstance = new TRuleset(); + var rulesetInstance = CreateRuleset(); beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo(); var result = new ConvertResult(); - var converter = CreateConverter(beatmap); + var converter = rulesetInstance.CreateBeatmapConverter(beatmap); converter.ObjectConverted += (orig, converted) => { converted.ForEach(h => h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty)); @@ -130,7 +129,7 @@ namespace osu.Game.Tests.Beatmaps } protected abstract IEnumerable CreateConvertValue(HitObject hitObject); - protected abstract IBeatmapConverter CreateConverter(IBeatmap beatmap); + protected abstract Ruleset CreateRuleset(); private class ConvertMapping { From cf44357bdb1f4f6f6f4bce4e136e3ac872a12a55 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 16 May 2018 13:30:48 +0900 Subject: [PATCH 176/229] Use a stable sort for hitobjects --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 655355913c..7317c7a135 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -56,7 +56,7 @@ namespace osu.Game.Beatmaps.Formats // objects may be out of order *only* if a user has manually edited an .osu file. // unfortunately there are ranked maps in this state (example: https://osu.ppy.sh/s/594828). - this.beatmap.HitObjects.Sort((x, y) => x.StartTime.CompareTo(y.StartTime)); + this.beatmap.HitObjects = this.beatmap.HitObjects.OrderBy(h => h.StartTime).ToList(); foreach (var hitObject in this.beatmap.HitObjects) hitObject.ApplyDefaults(this.beatmap.ControlPointInfo, this.beatmap.BeatmapInfo.BaseDifficulty); From 0f817d18d4cfb1e17ff7a547ad284819cdb4829a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 16 May 2018 13:59:51 +0900 Subject: [PATCH 177/229] Add explanatory comment --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 7317c7a135..2aee419d20 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -54,8 +54,10 @@ namespace osu.Game.Beatmaps.Formats base.ParseStreamInto(stream, beatmap); - // objects may be out of order *only* if a user has manually edited an .osu file. - // unfortunately there are ranked maps in this state (example: https://osu.ppy.sh/s/594828). + // Objects may be out of order *only* if a user has manually edited an .osu file. + // Unfortunately there are ranked maps in this state (example: https://osu.ppy.sh/s/594828). + // OrderBy is used to guarantee that the parsing order of hitobjects with equal start times is maintained (stably-sorted) + // The parsing order of hitobjects matters in mania difficulty calculation this.beatmap.HitObjects = this.beatmap.HitObjects.OrderBy(h => h.StartTime).ToList(); foreach (var hitObject in this.beatmap.HitObjects) From 5aadc35a25ebdd5f9233e7d16c93378fdbfa26df Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 16 May 2018 14:47:28 +0900 Subject: [PATCH 178/229] Stably-sort difficulty hitobjects to prevent future issues --- .../Difficulty/ManiaDifficultyCalculator.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs index ac45130fd8..1483283283 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mania.Beatmaps; @@ -49,11 +50,9 @@ namespace osu.Game.Rulesets.Mania.Difficulty int columnCount = (Beatmap as ManiaBeatmap)?.TotalColumns ?? 7; - foreach (var hitObject in Beatmap.HitObjects) - difficultyHitObjects.Add(new ManiaHitObjectDifficulty((ManiaHitObject)hitObject, columnCount)); - // Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure. - difficultyHitObjects.Sort((a, b) => a.BaseHitObject.StartTime.CompareTo(b.BaseHitObject.StartTime)); + // Note: Stable sort is done so that the ordering of hitobjects with equal start times doesn't change + difficultyHitObjects.AddRange(Beatmap.HitObjects.Select(h => new ManiaHitObjectDifficulty((ManiaHitObject)h, columnCount)).OrderBy(h => h.BaseHitObject.StartTime)); if (!calculateStrainValues()) return 0; From 2fc1939d650f8187d97155455a2dff4350f9a76e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 16 May 2018 19:43:01 +0900 Subject: [PATCH 179/229] Fix hold notes never dying --- .../Judgements/HoldNoteJudgement.cs | 13 +++++++++++++ .../Objects/Drawables/DrawableHoldNote.cs | 13 +++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs new file mode 100644 index 0000000000..9630ba9273 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Mania.Judgements +{ + public class HoldNoteJudgement : ManiaJudgement + { + public override bool AffectsCombo => false; + protected override int NumericResultFor(HitResult result) => 0; + } +} diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index f8b2311a13..3661c0be04 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -99,6 +99,19 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected override void UpdateState(ArmedState state) { + switch (state) + { + case ArmedState.Hit: + // Good enough for now, we just want them to have a lifetime end + this.Delay(2000).Expire(); + break; + } + } + + protected override void CheckForJudgements(bool userTriggered, double timeOffset) + { + if (tail.AllJudged) + AddJudgement(new HoldNoteJudgement { Result = HitResult.Perfect }); } protected override void Update() From c67f37256023dfdef5bfabba951adbac330785a5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 17 May 2018 12:29:33 +0900 Subject: [PATCH 180/229] Don't create nested hitobjects unless absolutely required --- osu.Game/Rulesets/Objects/HitObject.cs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index cd612a5387..15c24e2975 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Collections.Generic; using Newtonsoft.Json; using osu.Framework.Extensions.IEnumerableExtensions; @@ -56,10 +57,10 @@ namespace osu.Game.Rulesets.Objects /// public HitWindows HitWindows { get; set; } - private readonly SortedList nestedHitObjects = new SortedList((h1, h2) => h1.StartTime.CompareTo(h2.StartTime)); + private readonly Lazy> nestedHitObjects = new Lazy>(() => new SortedList((h1, h2) => h1.StartTime.CompareTo(h2.StartTime))); [JsonIgnore] - public IReadOnlyList NestedHitObjects => nestedHitObjects; + public IReadOnlyList NestedHitObjects => nestedHitObjects.Value; /// /// Applies default values to this HitObject. @@ -70,13 +71,19 @@ namespace osu.Game.Rulesets.Objects { ApplyDefaultsToSelf(controlPointInfo, difficulty); - nestedHitObjects.Clear(); + if (nestedHitObjects.IsValueCreated) + nestedHitObjects.Value.Clear(); + CreateNestedHitObjects(); - nestedHitObjects.ForEach(h => + + if (nestedHitObjects.IsValueCreated) { - h.HitWindows = HitWindows; - h.ApplyDefaults(controlPointInfo, difficulty); - }); + nestedHitObjects.Value.ForEach(h => + { + h.HitWindows = HitWindows; + h.ApplyDefaults(controlPointInfo, difficulty); + }); + } } protected virtual void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) @@ -96,7 +103,7 @@ namespace osu.Game.Rulesets.Objects { } - protected void AddNested(HitObject hitObject) => nestedHitObjects.Add(hitObject); + protected void AddNested(HitObject hitObject) => nestedHitObjects.Value.Add(hitObject); /// /// Creates the for this . From 397d93660aad78e1ba4a759c48d28b54ba99d7cd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 17 May 2018 12:59:48 +0900 Subject: [PATCH 181/229] Don't deep-clone beatmapinfo/control points --- .../Beatmaps/TaikoBeatmapConverter.cs | 6 +++--- osu.Game/Beatmaps/Beatmap.cs | 11 ++--------- osu.Game/Beatmaps/BeatmapConverter.cs | 2 -- osu.Game/Beatmaps/BeatmapDifficulty.cs | 5 +++++ osu.Game/Beatmaps/BeatmapInfo.cs | 5 +++++ osu.Game/IO/Serialization/IJsonSerializable.cs | 2 -- .../UI/Scrolling/ScrollingRulesetContainer.cs | 3 +-- 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index b450e4d26c..abb2193235 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -8,7 +8,6 @@ using osu.Game.Rulesets.Taiko.Objects; using System; using System.Collections.Generic; using System.Linq; -using osu.Game.IO.Serialization; using osu.Game.Audio; using osu.Game.Beatmaps.ControlPoints; @@ -51,8 +50,9 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps protected override Beatmap ConvertBeatmap(IBeatmap original) { // Rewrite the beatmap info to add the slider velocity multiplier - BeatmapInfo info = original.BeatmapInfo.DeepClone(); - info.BaseDifficulty.SliderMultiplier *= legacy_velocity_multiplier; + original.BeatmapInfo = original.BeatmapInfo.Clone(); + original.BeatmapInfo.BaseDifficulty = original.BeatmapInfo.BaseDifficulty.Clone(); + original.BeatmapInfo.BaseDifficulty.SliderMultiplier *= legacy_velocity_multiplier; Beatmap converted = base.ConvertBeatmap(original); diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 84897853d8..9aabb434a3 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -6,7 +6,6 @@ using osu.Game.Rulesets.Objects; using System.Collections.Generic; using System.Linq; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.IO.Serialization; using Newtonsoft.Json; using osu.Game.IO.Serialization.Converters; @@ -55,17 +54,11 @@ namespace osu.Game.Beatmaps IBeatmap IBeatmap.Clone() => Clone(); - public Beatmap Clone() - { - var newInstance = (Beatmap)MemberwiseClone(); - newInstance.BeatmapInfo = BeatmapInfo.DeepClone(); - - return newInstance; - } + public Beatmap Clone() => (Beatmap)MemberwiseClone(); } public class Beatmap : Beatmap { - public Beatmap Clone() => (Beatmap)base.Clone(); + public new Beatmap Clone() => (Beatmap)base.Clone(); } } diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index b7a454460f..a1bb70135a 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -53,8 +53,6 @@ namespace osu.Game.Beatmaps { var beatmap = CreateBeatmap(); - // todo: this *must* share logic (or directly use) Beatmap's constructor. - // right now this isn't easily possible due to generic entanglement. beatmap.BeatmapInfo = original.BeatmapInfo; beatmap.ControlPointInfo = original.ControlPointInfo; beatmap.HitObjects = original.HitObjects.SelectMany(h => convert(h, original)).ToList(); diff --git a/osu.Game/Beatmaps/BeatmapDifficulty.cs b/osu.Game/Beatmaps/BeatmapDifficulty.cs index 855e8fe881..508232dbfe 100644 --- a/osu.Game/Beatmaps/BeatmapDifficulty.cs +++ b/osu.Game/Beatmaps/BeatmapDifficulty.cs @@ -32,6 +32,11 @@ namespace osu.Game.Beatmaps public double SliderMultiplier { get; set; } = 1; public double SliderTickRate { get; set; } = 1; + /// + /// Returns a shallow-clone of this . + /// + public BeatmapDifficulty Clone() => (BeatmapDifficulty)MemberwiseClone(); + /// /// Maps a difficulty value [0, 10] to a two-piece linear range of values. /// diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index a1b97afc6c..40d62103a8 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -143,5 +143,10 @@ namespace osu.Game.Beatmaps public bool BackgroundEquals(BeatmapInfo other) => other != null && BeatmapSet != null && other.BeatmapSet != null && BeatmapSet.Hash == other.BeatmapSet.Hash && (Metadata ?? BeatmapSet.Metadata).BackgroundFile == (other.Metadata ?? other.BeatmapSet.Metadata).BackgroundFile; + + /// + /// Returns a shallow-clone of this . + /// + public BeatmapInfo Clone() => (BeatmapInfo)MemberwiseClone(); } } diff --git a/osu.Game/IO/Serialization/IJsonSerializable.cs b/osu.Game/IO/Serialization/IJsonSerializable.cs index c9727725ef..ce6ff7c82d 100644 --- a/osu.Game/IO/Serialization/IJsonSerializable.cs +++ b/osu.Game/IO/Serialization/IJsonSerializable.cs @@ -18,8 +18,6 @@ namespace osu.Game.IO.Serialization public static void DeserializeInto(this string objString, T target) => JsonConvert.PopulateObject(objString, target, CreateGlobalSettings()); - public static T DeepClone(this T obj) where T : IJsonSerializable => Deserialize(Serialize(obj)); - /// /// Creates the default that should be used for all s. /// diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs index efd901240a..3fc67e4e34 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs @@ -8,7 +8,6 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Lists; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.IO.Serialization; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Timing; @@ -104,7 +103,7 @@ namespace osu.Game.Rulesets.UI.Scrolling if (index < 0) return new MultiplierControlPoint(time); - return new MultiplierControlPoint(time, DefaultControlPoints[index].DeepClone()); + return new MultiplierControlPoint(time, DefaultControlPoints[index]); } } } From f67d2635960ac1ca37a7297f02b255b3f47ac413 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 17 May 2018 13:35:06 +0900 Subject: [PATCH 182/229] Move ruleset-specific hitwindows to post-converted hitobjects --- .../Beatmaps/ManiaBeatmapConverter.cs | 3 --- .../Objects/ManiaHitObject.cs | 10 +--------- .../Objects/ManiaHitWindows.cs | 8 ++++++-- .../Beatmaps/OsuBeatmapConverter.cs | 9 +++------ osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 2 ++ .../Objects/OsuHitWindows.cs | 5 +++-- .../Beatmaps/TaikoBeatmapConverter.cs | 18 ++++++------------ .../Objects/TaikoHitObject.cs | 2 ++ .../Objects/TaikoHitWindows.cs | 5 +++-- .../Objects/Legacy/Mania/ConvertHit.cs | 2 +- .../Objects/Legacy/Mania/ConvertHold.cs | 2 +- .../Objects/Legacy/Mania/ConvertSlider.cs | 2 +- .../Objects/Legacy/Mania/ConvertSpinner.cs | 2 +- .../Rulesets/Objects/Legacy/Osu/ConvertHit.cs | 2 +- .../Objects/Legacy/Osu/ConvertSlider.cs | 2 +- .../Objects/Legacy/Osu/ConvertSpinner.cs | 2 +- .../Objects/Legacy/Taiko/ConvertHit.cs | 2 +- .../Objects/Legacy/Taiko/ConvertSlider.cs | 2 +- .../Objects/Legacy/Taiko/ConvertSpinner.cs | 2 +- 19 files changed, 36 insertions(+), 46 deletions(-) rename osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitWindows.cs => osu.Game.Rulesets.Mania/Objects/ManiaHitWindows.cs (88%) rename osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitWindows.cs => osu.Game.Rulesets.Osu/Objects/OsuHitWindows.cs (90%) rename osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitWindows.cs => osu.Game.Rulesets.Taiko/Objects/TaikoHitWindows.cs (90%) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 4f7c52860f..19fef9eb54 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -84,10 +84,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps yield break; foreach (ManiaHitObject obj in objects) - { - obj.HitWindows = original.HitWindows; yield return obj; - } } private readonly List prevNoteTimes = new List(max_notes_for_density); diff --git a/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs index 4f0e02ff0d..e183098a51 100644 --- a/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs @@ -1,8 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Mania.Objects.Types; using osu.Game.Rulesets.Objects; @@ -12,12 +10,6 @@ namespace osu.Game.Rulesets.Mania.Objects { public virtual int Column { get; set; } - protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) - { - base.ApplyDefaultsToSelf(controlPointInfo, difficulty); - - HitWindows.AllowsPerfect = true; - HitWindows.AllowsOk = true; - } + protected override HitWindows CreateHitWindows() => new ManiaHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitWindows.cs b/osu.Game.Rulesets.Mania/Objects/ManiaHitWindows.cs similarity index 88% rename from osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitWindows.cs rename to osu.Game.Rulesets.Mania/Objects/ManiaHitWindows.cs index 131492ea12..063b626af1 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitWindows.cs +++ b/osu.Game.Rulesets.Mania/Objects/ManiaHitWindows.cs @@ -3,11 +3,12 @@ using System.Collections.Generic; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; -namespace osu.Game.Rulesets.Objects.Legacy.Mania +namespace osu.Game.Rulesets.Mania.Objects { - public class ConvertHitWindows : HitWindows + public class ManiaHitWindows : HitWindows { private static readonly IReadOnlyDictionary base_ranges = new Dictionary { @@ -21,6 +22,9 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public override void SetDifficulty(double difficulty) { + AllowsPerfect = true; + AllowsOk = true; + Perfect = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Perfect]); Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]); Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]); diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs index 4369a31b2c..80eb808f6e 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs @@ -40,8 +40,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps RepeatSamples = curveData.RepeatSamples, RepeatCount = curveData.RepeatCount, Position = positionData?.Position ?? Vector2.Zero, - NewCombo = comboData?.NewCombo ?? false, - HitWindows = original.HitWindows + NewCombo = comboData?.NewCombo ?? false }; } else if (endTimeData != null) @@ -51,8 +50,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps StartTime = original.StartTime, Samples = original.Samples, EndTime = endTimeData.EndTime, - Position = positionData?.Position ?? OsuPlayfield.BASE_SIZE / 2, - HitWindows = original.HitWindows + Position = positionData?.Position ?? OsuPlayfield.BASE_SIZE / 2 }; } else @@ -62,8 +60,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps StartTime = original.StartTime, Samples = original.Samples, Position = positionData?.Position ?? Vector2.Zero, - NewCombo = comboData?.NewCombo ?? false, - HitWindows = original.HitWindows + NewCombo = comboData?.NewCombo ?? false }; } } diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index 2b7b7783e2..54126b934f 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -71,5 +71,7 @@ namespace osu.Game.Rulesets.Osu.Objects } public virtual void OffsetPosition(Vector2 offset) => Position += offset; + + protected override HitWindows CreateHitWindows() => new OsuHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitWindows.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitWindows.cs similarity index 90% rename from osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitWindows.cs rename to osu.Game.Rulesets.Osu/Objects/OsuHitWindows.cs index fd86173372..8405498554 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitWindows.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitWindows.cs @@ -3,11 +3,12 @@ using System.Collections.Generic; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; -namespace osu.Game.Rulesets.Objects.Legacy.Osu +namespace osu.Game.Rulesets.Osu.Objects { - public class ConvertHitWindows : HitWindows + public class OsuHitWindows : HitWindows { private static readonly IReadOnlyDictionary base_ranges = new Dictionary { diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index b450e4d26c..a84b1a64a0 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -132,8 +132,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps { StartTime = j, Samples = currentSamples, - IsStrong = strong, - HitWindows = obj.HitWindows + IsStrong = strong }; } else @@ -142,8 +141,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps { StartTime = j, Samples = currentSamples, - IsStrong = strong, - HitWindows = obj.HitWindows + IsStrong = strong }; } @@ -158,8 +156,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps Samples = obj.Samples, IsStrong = strong, Duration = taikoDuration, - TickRate = beatmap.BeatmapInfo.BaseDifficulty.SliderTickRate == 3 ? 3 : 4, - HitWindows = obj.HitWindows + TickRate = beatmap.BeatmapInfo.BaseDifficulty.SliderTickRate == 3 ? 3 : 4 }; } } @@ -173,8 +170,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps Samples = obj.Samples, IsStrong = strong, Duration = endTimeData.Duration, - RequiredHits = (int)Math.Max(1, endTimeData.Duration / 1000 * hitMultiplier), - HitWindows = obj.HitWindows + RequiredHits = (int)Math.Max(1, endTimeData.Duration / 1000 * hitMultiplier) }; } else @@ -187,8 +183,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps { StartTime = obj.StartTime, Samples = obj.Samples, - IsStrong = strong, - HitWindows = obj.HitWindows + IsStrong = strong }; } else @@ -197,8 +192,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps { StartTime = obj.StartTime, Samples = obj.Samples, - IsStrong = strong, - HitWindows = obj.HitWindows + IsStrong = strong }; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs index 63de096238..ffbbe28f2e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs @@ -27,5 +27,7 @@ namespace osu.Game.Rulesets.Taiko.Objects /// Strong hit objects give more points for hitting the hit object with both keys. /// public bool IsStrong; + + protected override HitWindows CreateHitWindows() => new TaikoHitWindows(); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitWindows.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitWindows.cs similarity index 90% rename from osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitWindows.cs rename to osu.Game.Rulesets.Taiko/Objects/TaikoHitWindows.cs index 6fbf7e122f..289f084a45 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitWindows.cs +++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitWindows.cs @@ -3,11 +3,12 @@ using System.Collections.Generic; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; -namespace osu.Game.Rulesets.Objects.Legacy.Taiko +namespace osu.Game.Rulesets.Taiko.Objects { - public class ConvertHitWindows : HitWindows + public class TaikoHitWindows : HitWindows { private static readonly IReadOnlyDictionary base_ranges = new Dictionary { diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs index 939d3b9c93..ea4e7f6907 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHit.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public bool NewCombo { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs index 22abc64b60..86a10fd363 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHold.cs @@ -13,6 +13,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public double Duration => EndTime - StartTime; - protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs index 6bca5b717c..a8d7b23df1 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSlider.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public bool NewCombo { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs index 1dc826af9b..5a443c2ac2 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertSpinner.cs @@ -16,6 +16,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania public float X { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs index 23955b2d23..f015272b2c 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHit.cs @@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu public bool NewCombo { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs index 35b8c1c7dd..ec5a002bbb 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSlider.cs @@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu public bool NewCombo { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs index 73b8369aca..0141785f31 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertSpinner.cs @@ -21,6 +21,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu public float Y => Position.Y; - protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs index 11db086778..5e9786c84a 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHit.cs @@ -12,6 +12,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko { public bool NewCombo { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs index 95c69222b5..8a9a0db0a7 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSlider.cs @@ -12,6 +12,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko { public bool NewCombo { get; set; } - protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); + protected override HitWindows CreateHitWindows() => null; } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs index 7baea212ea..4c8807a1d3 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertSpinner.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko public double Duration => EndTime - StartTime; - protected override HitWindows CreateHitWindows() => new ConvertHitWindows(); + protected override HitWindows CreateHitWindows() => null; } } From 43cdbec0a3f78d612e901b703803abfb67e3e685 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 17 May 2018 13:59:04 +0900 Subject: [PATCH 183/229] Fix hold note hitwindow lenience --- .../Objects/Drawables/DrawableHoldNote.cs | 10 ++++++ osu.Game.Rulesets.Mania/Objects/HoldNote.cs | 22 +----------- osu.Game/Rulesets/Objects/HitWindows.cs | 34 ------------------- 3 files changed, 11 insertions(+), 55 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index f8b2311a13..59808c5643 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -191,6 +191,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// private class DrawableTailNote : DrawableNote { + /// + /// Lenience of release hit windows. This is to make cases where the hold note release + /// is timed alongside presses of other hit objects less awkward. + /// Todo: This shouldn't exist for non-LegacyBeatmapDecoder beatmaps + /// + private const double release_window_lenience = 1.5; + private readonly DrawableHoldNote holdNote; public DrawableTailNote(DrawableHoldNote holdNote, ManiaAction action) @@ -203,6 +210,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected override void CheckForJudgements(bool userTriggered, double timeOffset) { + // Factor in the release lenience + timeOffset /= release_window_lenience; + if (!userTriggered) { if (!HitObject.HitWindows.CanBeHit(timeOffset)) diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs index 12e3d2de51..22fa93a308 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Mania.Objects /// /// The tail note of the hold. /// - public readonly Note Tail = new TailNote(); + public readonly Note Tail = new Note(); /// /// The time between ticks of this hold. @@ -94,25 +94,5 @@ namespace osu.Game.Rulesets.Mania.Objects }); } } - - /// - /// The tail of the hold note. - /// - private class TailNote : Note - { - /// - /// Lenience of release hit windows. This is to make cases where the hold note release - /// is timed alongside presses of other hit objects less awkward. - /// Todo: This shouldn't exist for non-LegacyBeatmapDecoder beatmaps - /// - private const double release_window_lenience = 1.5; - - protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) - { - base.ApplyDefaultsToSelf(controlPointInfo, difficulty); - - HitWindows *= release_window_lenience; - } - } } } diff --git a/osu.Game/Rulesets/Objects/HitWindows.cs b/osu.Game/Rulesets/Objects/HitWindows.cs index 7610593d6a..3717209860 100644 --- a/osu.Game/Rulesets/Objects/HitWindows.cs +++ b/osu.Game/Rulesets/Objects/HitWindows.cs @@ -135,39 +135,5 @@ namespace osu.Game.Rulesets.Objects /// The time offset. /// Whether the can be hit at any point in the future from this time offset. public bool CanBeHit(double timeOffset) => timeOffset <= HalfWindowFor(HitResult.Meh); - - /// - /// Multiplies all hit windows by a value. - /// - /// The hit windows to multiply. - /// The value to multiply each hit window by. - public static HitWindows operator *(HitWindows windows, double value) - { - windows.Perfect *= value; - windows.Great *= value; - windows.Good *= value; - windows.Ok *= value; - windows.Meh *= value; - windows.Miss *= value; - - return windows; - } - - /// - /// Divides all hit windows by a value. - /// - /// The hit windows to divide. - /// The value to divide each hit window by. - public static HitWindows operator /(HitWindows windows, double value) - { - windows.Perfect /= value; - windows.Great /= value; - windows.Good /= value; - windows.Ok /= value; - windows.Meh /= value; - windows.Miss /= value; - - return windows; - } } } From b9ed9769546fd05cb8c1413c480054762042a84f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 17 May 2018 14:44:30 +0900 Subject: [PATCH 184/229] Fix taiko slider multiplier being applied twice --- osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index abb2193235..304fd290fc 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -98,12 +98,12 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps double distance = distanceData.Distance * spans * legacy_velocity_multiplier; // The velocity of the taiko hit object - calculated as the velocity of a drum roll - double taikoVelocity = taiko_base_distance * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * legacy_velocity_multiplier / speedAdjustedBeatLength; + double taikoVelocity = taiko_base_distance * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier / speedAdjustedBeatLength; // The duration of the taiko hit object double taikoDuration = distance / taikoVelocity; // The velocity of the osu! hit object - calculated as the velocity of a slider - double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * legacy_velocity_multiplier / speedAdjustedBeatLength; + double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier / speedAdjustedBeatLength; // The duration of the osu! hit object double osuDuration = distance / osuVelocity; From 532d65f6e8aa5c8383413e3c4726d5200429c1aa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 17 May 2018 15:17:47 +0900 Subject: [PATCH 185/229] Re-enable basic taiko beatmap conversion tests --- osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs index 93f1b7faf7..11586e340b 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -17,8 +17,8 @@ namespace osu.Game.Rulesets.Taiko.Tests protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; [NonParallelizable] - [TestCase("basic", false), Ignore("See: https://github.com/ppy/osu/issues/2152")] - [TestCase("slider-generating-drumroll", false)] + [TestCase("basic")] + [TestCase("slider-generating-drumroll")] public new void Test(string name) { base.Test(name); From eba1d309b674eb42d16486ea603859a4e94174ed Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 17 May 2018 16:58:22 +0900 Subject: [PATCH 186/229] Fix incorrect namespace of OsuPerformanceCalculator --- .../{Scoring => Difficulty}/OsuPerformanceCalculator.cs | 2 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) rename osu.Game.Rulesets.Osu/{Scoring => Difficulty}/OsuPerformanceCalculator.cs (99%) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs similarity index 99% rename from osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs rename to osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs index 84a83d331b..eeb776fa6e 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; -namespace osu.Game.Rulesets.Osu.Scoring +namespace osu.Game.Rulesets.Osu.Difficulty { public class OsuPerformanceCalculator : PerformanceCalculator { diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index a2423ffbe5..c455bb2af6 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics; using osu.Game.Overlays.Settings; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Osu.Edit; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Replays; From d20011ba58a849c0cca543b13149458d03f05f39 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 17 May 2018 17:56:25 +0900 Subject: [PATCH 187/229] Fix an endless feedback loop --- osu.Game/Screens/Select/MatchSongSelect.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 4e252eac75..3ffac591f3 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -7,7 +7,12 @@ namespace osu.Game.Screens.Select { protected override bool OnSelectionFinalised() { - Exit(); + Schedule(() => + { + // needs to be scheduled else we enter an infinite feedback loop. + if (IsCurrentScreen) Exit(); + }); + return true; } } From 450d54eea9ccafce0df2ec8f1ad0c816be4fa6a1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 17 May 2018 17:12:28 +0900 Subject: [PATCH 188/229] Fix taiko difficulty calculator never considering mods --- .../Difficulty/TaikoDifficultyCalculator.cs | 6 ++++++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs index acff0d286d..d33150d739 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Taiko.Objects; namespace osu.Game.Rulesets.Taiko.Difficulty @@ -35,6 +36,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty { } + public TaikoDifficultyCalculator(IBeatmap beatmap, Mod[] mods) + : base(beatmap, mods) + { + } + public override double Calculate(Dictionary categoryDifficulty = null) { // Fill our custom DifficultyHitObject class, that carries additional information diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 35dc17c0e2..04b513866a 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -144,7 +144,7 @@ namespace osu.Game.Rulesets.Taiko public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o }; - public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new TaikoDifficultyCalculator(beatmap); + public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new TaikoDifficultyCalculator(beatmap, mods); public override int? LegacyID => 1; From 3091d3a01450a1185ba346d813f46c0de1658f18 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 17 May 2018 17:40:46 +0900 Subject: [PATCH 189/229] Implement the taiko performance calculator --- .../Difficulty/TaikoDifficultyCalculator.cs | 5 +- .../Difficulty/TaikoPerformanceCalculator.cs | 111 ++++++++++++++++++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 3 + 3 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs index d33150d739..57e1e65064 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs @@ -57,10 +57,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty double starRating = calculateDifficulty() * star_scaling_factor; if (categoryDifficulty != null) - { - categoryDifficulty.Add("Strain", starRating); - categoryDifficulty.Add("Hit window 300", 35 /*HitObjectManager.HitWindow300*/ / TimeRate); - } + categoryDifficulty["Strain"] = starRating; return starRating; } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs new file mode 100644 index 0000000000..9c9cd1f0fb --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -0,0 +1,111 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.Taiko.Objects; + +namespace osu.Game.Rulesets.Taiko.Difficulty +{ + public class TaikoPerformanceCalculator : PerformanceCalculator + { + private readonly int beatmapMaxCombo; + + private Mod[] mods; + private int countGreat; + private int countGood; + private int countMeh; + private int countMiss; + + public TaikoPerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) + : base(ruleset, beatmap, score) + { + beatmapMaxCombo = beatmap.HitObjects.Count(h => h is Hit); + } + + public override double Calculate(Dictionary categoryDifficulty = null) + { + mods = Score.Mods; + countGreat = Convert.ToInt32(Score.Statistics[HitResult.Great]); + countGood = Convert.ToInt32(Score.Statistics[HitResult.Good]); + countMeh = Convert.ToInt32(Score.Statistics[HitResult.Meh]); + countMiss = Convert.ToInt32(Score.Statistics[HitResult.Miss]); + + // Don't count scores made with supposedly unranked mods + if (mods.Any(m => !m.Ranked)) + return 0; + + // Custom multipliers for NoFail and SpunOut. + double multiplier = 1.1; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things + + if (mods.Any(m => m is ModNoFail)) + multiplier *= 0.90; + + if (mods.Any(m => m is ModHidden)) + multiplier *= 1.10; + + double strainValue = computeStrainValue(); + double accuracyValue = computeAccuracyValue(); + double totalValue = + Math.Pow( + Math.Pow(strainValue, 1.1) + + Math.Pow(accuracyValue, 1.1), 1.0 / 1.1 + ) * multiplier; + + if (categoryDifficulty != null) + { + categoryDifficulty["Strain"] = strainValue; + categoryDifficulty["Accuracy"] = accuracyValue; + } + + return totalValue; + } + + private double computeStrainValue() + { + double strainValue = Math.Pow(5.0 * Math.Max(1.0, Attributes["Strain"] / 0.0075) - 4.0, 2.0) / 100000.0; + + // Longer maps are worth more + double lengthBonus = 1 + 0.1f * Math.Min(1.0, totalHits / 1500.0); + strainValue *= lengthBonus; + + // Penalize misses exponentially. This mainly fixes tag4 maps and the likes until a per-hitobject solution is available + strainValue *= Math.Pow(0.985, countMiss); + + // Combo scaling + if (beatmapMaxCombo > 0) + strainValue *= Math.Min(Math.Pow(Score.MaxCombo, 0.5) / Math.Pow(beatmapMaxCombo, 0.5), 1.0); + + if (mods.Any(m => m is ModHidden)) + strainValue *= 1.025; + + if (mods.Any(m => m is ModFlashlight)) + // Apply length bonus again if flashlight is on simply because it becomes a lot harder on longer maps. + strainValue *= 1.05 * lengthBonus; + + // Scale the speed value with accuracy _slightly_ + return strainValue * Score.Accuracy; + } + + private double computeAccuracyValue() + { + double hitWindowGreat = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate; + if (hitWindowGreat <= 0) + return 0; + + // Lots of arbitrary values from testing. + // Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution + double accValue = Math.Pow(150.0 / hitWindowGreat, 1.1) * Math.Pow(Score.Accuracy, 15) * 22.0; + + // Bonus for many hitcircles - it's harder to keep good accuracy up for longer + return accValue * Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3)); + } + + private int totalHits => countGreat + countGood + countMeh + countMiss; + } +} diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 04b513866a..abaa8db597 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -14,6 +14,7 @@ using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Taiko.Replays; using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Beatmaps; using osu.Game.Rulesets.Taiko.Difficulty; @@ -146,6 +147,8 @@ namespace osu.Game.Rulesets.Taiko public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new TaikoDifficultyCalculator(beatmap, mods); + public override PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => new TaikoPerformanceCalculator(this, beatmap, score); + public override int? LegacyID => 1; public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame(); From ebfbe58abb20c13a36ce18cf1b8ba91a9b413400 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 17 May 2018 06:19:55 -0300 Subject: [PATCH 190/229] Move Header breadcrumbs to a subclass. --- osu.Game/Screens/Multi/Header.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Multi/Header.cs b/osu.Game/Screens/Multi/Header.cs index 03996f5309..db8898495f 100644 --- a/osu.Game/Screens/Multi/Header.cs +++ b/osu.Game/Screens/Multi/Header.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Multi public const float HEIGHT = 121; private readonly OsuSpriteText screenTitle; - private readonly ScreenBreadcrumbControl breadcrumbs; + private readonly HeaderBreadcrumbControl breadcrumbs; public Header(Screen initialScreen) { @@ -75,7 +75,7 @@ namespace osu.Game.Screens.Multi }, }, }, - breadcrumbs = new ScreenBreadcrumbControl(initialScreen) + breadcrumbs = new HeaderBreadcrumbControl(initialScreen) { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, @@ -85,8 +85,6 @@ namespace osu.Game.Screens.Multi }, }; - breadcrumbs.OnLoadComplete = d => breadcrumbs.AccentColour = Color4.White; - breadcrumbs.Current.ValueChanged += s => screenTitle.Text = s.ToString(); breadcrumbs.Current.TriggerChange(); } @@ -97,5 +95,18 @@ namespace osu.Game.Screens.Multi screenTitle.Colour = colours.Yellow; breadcrumbs.StripColour = colours.Green; } + + private class HeaderBreadcrumbControl : ScreenBreadcrumbControl + { + public HeaderBreadcrumbControl(Screen initialScreen) : base(initialScreen) + { + } + + protected override void LoadComplete() + { + base.LoadComplete(); + AccentColour = Color4.White; + } + } } } From 17d1759c37f53893dfdb9c1529206b0f0c2c5083 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Fri, 18 May 2018 01:01:54 +0300 Subject: [PATCH 191/229] Get rid of multiple blank lines in a row --- osu.Game/Screens/Menu/ButtonSystem.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 8cf0d24f7d..997002327a 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -185,7 +185,6 @@ namespace osu.Game.Screens.Menu } } - private void onPlay() { State = MenuState.Play; From e2389ad7a4a4e02938bd6eb2157d36cd19e30741 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 May 2018 13:30:36 +0900 Subject: [PATCH 192/229] Allow using back button on PlayerLoader and Replay --- osu.Game/Screens/Play/Player.cs | 2 ++ osu.Game/Screens/Play/PlayerLoader.cs | 1 - osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 4a46279d30..46919e25e1 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -45,6 +45,8 @@ namespace osu.Game.Screens.Play public bool AllowLeadIn { get; set; } = true; public bool AllowResults { get; set; } = true; + protected override bool AllowBackButton => false; + private Bindable mouseWheelDisabled; private Bindable userAudioOffset; diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 6eb156914e..56fbd7b6e7 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -27,7 +27,6 @@ namespace osu.Game.Screens.Play private bool showOverlays = true; public override bool ShowOverlaysOnEnter => showOverlays; - protected override bool AllowBackButton => false; private Task loadTask; diff --git a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs index f29f5b328a..1ccc5e2fe8 100644 --- a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs +++ b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs @@ -16,7 +16,6 @@ namespace osu.Game.Screens.Play protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); public override bool AllowBeatmapRulesetChange => false; - protected override bool AllowBackButton => false; protected const float BACKGROUND_FADE_DURATION = 800; From d75fe4009afd0663ffcf6198014de748e22a9fef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 May 2018 13:40:35 +0900 Subject: [PATCH 193/229] Add back action support to settings back button --- osu.Game/Overlays/MainSettings.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/MainSettings.cs b/osu.Game/Overlays/MainSettings.cs index 09b5be6a85..99a86f19a1 100644 --- a/osu.Game/Overlays/MainSettings.cs +++ b/osu.Game/Overlays/MainSettings.cs @@ -6,9 +6,11 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; +using osu.Framework.Input.Bindings; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Input.Bindings; using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings.Sections; using osu.Game.Screens.Ranking; @@ -96,7 +98,7 @@ namespace osu.Game.Overlays }); } - private class BackButton : OsuClickableContainer + private class BackButton : OsuClickableContainer, IKeyBindingHandler { private AspectContainer aspect; @@ -146,6 +148,20 @@ namespace osu.Game.Overlays aspect.ScaleTo(1, 1000, Easing.OutElastic); return base.OnMouseUp(state, args); } + + public bool OnPressed(GlobalAction action) + { + switch (action) + { + case GlobalAction.Back: + TriggerOnClick(); + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => false; } } } From 67db5391729cb62a3461eb3eb448152dc9bc1580 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Fri, 18 May 2018 07:57:12 +0200 Subject: [PATCH 194/229] prevent Overlays from showing in intro/outro sequences --- .../Graphics/Containers/OsuFocusedOverlayContainer.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index f657c0cae5..c26adc8a3d 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -7,6 +7,7 @@ using osu.Framework.Audio.Sample; using osu.Framework.Graphics.Containers; using osu.Framework.Input; using OpenTK; +using osu.Framework.Configuration; namespace osu.Game.Graphics.Containers { @@ -15,13 +16,17 @@ namespace osu.Game.Graphics.Containers private SampleChannel samplePopIn; private SampleChannel samplePopOut; + protected BindableBool ShowOverlays = new BindableBool(); + [BackgroundDependencyLoader] - private void load(AudioManager audio) + private void load(OsuGame osuGame, AudioManager audio) { samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in"); samplePopOut = audio.Sample.Get(@"UI/overlay-pop-out"); StateChanged += onStateChanged; + + ShowOverlays.BindTo(osuGame.ShowOverlays); } /// @@ -46,6 +51,9 @@ namespace osu.Game.Graphics.Containers private void onStateChanged(Visibility visibility) { + if (!ShowOverlays) + State = Visibility.Hidden; + switch (visibility) { case Visibility.Visible: From e6e37583045e6981b3c63517be44a1bb08338394 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 18 May 2018 18:11:52 +0900 Subject: [PATCH 195/229] Fix HR mod affecting original beatmap difficulty Fixes #2575. --- osu.Game/Beatmaps/WorkingBeatmap.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 9c389bbb8f..66a6206c16 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -107,8 +107,14 @@ namespace osu.Game.Beatmaps IBeatmap converted = converter.Convert(); // Apply difficulty mods - foreach (var mod in Mods.Value.OfType()) - mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty); + if (Mods.Value.Any(m => m is IApplicableToDifficulty)) + { + converted.BeatmapInfo = converted.BeatmapInfo.Clone(); + converted.BeatmapInfo.BaseDifficulty = converted.BeatmapInfo.BaseDifficulty.Clone(); + + foreach (var mod in Mods.Value.OfType()) + mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty); + } // Post-process rulesetInstance.CreateBeatmapProcessor(converted)?.PostProcess(); From 33baaf8243d04efc276e30a006118a78d68332df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 May 2018 18:44:42 +0900 Subject: [PATCH 196/229] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index fac688633b..80e78fd45b 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit fac688633b8fcf34ae5d0514c26b03e217161eb4 +Subproject commit 80e78fd45bb79ca4bc46ecc05deb6058f3879faa From 4b2b2086df821b5889892abe9bae3775f55a2a5e Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Sat, 19 May 2018 01:26:39 -0300 Subject: [PATCH 197/229] Create drawable hierarchy for RoomInspector in load, remove display* methods. --- .../Screens/Multi/Components/RoomInspector.cs | 191 ++++++++---------- 1 file changed, 85 insertions(+), 106 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Components/RoomInspector.cs index 92910e8301..b103624dfb 100644 --- a/osu.Game/Screens/Multi/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Components/RoomInspector.cs @@ -28,14 +28,6 @@ namespace osu.Game.Screens.Multi.Components private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 }; private const float transition_duration = 100; - private readonly Box statusStrip; - private readonly Container coverContainer; - private readonly FillFlowContainer topFlow, participantsFlow; - private readonly ModeTypeInfo modeTypeInfo; - private readonly OsuSpriteText participants, participantsSlash, maxParticipants, name, status, beatmapTitle, beatmapDash, beatmapArtist, beatmapAuthor; - private readonly ParticipantInfo participantInfo; - private readonly ScrollContainer participantsScroll; - private readonly Bindable nameBind = new Bindable(); private readonly Bindable hostBind = new Bindable(); private readonly Bindable statusBind = new Bindable(); @@ -44,11 +36,10 @@ namespace osu.Game.Screens.Multi.Components private readonly Bindable maxParticipantsBind = new Bindable(); private readonly Bindable participantsBind = new Bindable(); - private OsuColour colours; - private LocalisationEngine localisation; + private FillFlowContainer topFlow; + private ScrollContainer participantsScroll; private Room room; - public Room Room { get { return room; } @@ -71,6 +62,17 @@ namespace osu.Game.Screens.Multi.Components { Width = 520; RelativeSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours, LocalisationEngine localisation) + { + Box statusStrip; + Container coverContainer; + FillFlowContainer participantsFlow; + ModeTypeInfo modeTypeInfo; + OsuSpriteText participants, participantsSlash, maxParticipants, name, status, beatmapTitle, beatmapDash, beatmapArtist, beatmapAuthor; + ParticipantInfo participantInfo; Children = new Drawable[] { @@ -229,6 +231,7 @@ namespace osu.Game.Screens.Multi.Components Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, TextSize = 14, + Colour = colours.Gray9, }, }, }, @@ -269,27 +272,83 @@ namespace osu.Game.Screens.Multi.Components }, }; - nameBind.ValueChanged += displayName; - hostBind.ValueChanged += displayUser; - typeBind.ValueChanged += displayGameType; - maxParticipantsBind.ValueChanged += displayMaxParticipants; - participantsBind.ValueChanged += displayParticipants; - } + nameBind.ValueChanged += n => name.Text = n; + hostBind.ValueChanged += h => participantInfo.Host = h; + typeBind.ValueChanged += t => modeTypeInfo.Type = t; - [BackgroundDependencyLoader] - private void load(OsuColour colours, LocalisationEngine localisation) - { - this.localisation = localisation; - this.colours = colours; + statusBind.ValueChanged += s => + { + status.Text = s.Message; - beatmapAuthor.Colour = colours.Gray9; + foreach (Drawable d in new Drawable[] { statusStrip, status }) + d.FadeColour(s.GetAppropriateColour(colours), transition_duration); + }; - //binded here instead of ctor because dependencies are needed - statusBind.ValueChanged += displayStatus; - beatmapBind.ValueChanged += displayBeatmap; + beatmapBind.ValueChanged += b => + { + modeTypeInfo.Beatmap = b; + if (b != null) + { + coverContainer.FadeIn(transition_duration); + + LoadComponentAsync(new BeatmapSetCover(b.BeatmapSet) + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + FillMode = FillMode.Fill, + OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out), + }, + coverContainer.Add); + + beatmapTitle.Current = localisation.GetUnicodePreference(b.Metadata.TitleUnicode, b.Metadata.Title); + beatmapDash.Text = @" - "; + beatmapArtist.Current = localisation.GetUnicodePreference(b.Metadata.ArtistUnicode, b.Metadata.Artist); + beatmapAuthor.Text = $"mapped by {b.Metadata.Author}"; + } + else + { + coverContainer.FadeOut(transition_duration); + + beatmapTitle.Current = null; + beatmapArtist.Current = null; + + beatmapTitle.Text = "Changing map"; + beatmapDash.Text = beatmapArtist.Text = beatmapAuthor.Text = string.Empty; + } + }; + + maxParticipantsBind.ValueChanged += m => + { + if (m == null) + { + participantsSlash.FadeOut(transition_duration); + maxParticipants.FadeOut(transition_duration); + } + else + { + participantsSlash.FadeIn(transition_duration); + maxParticipants.FadeIn(transition_duration); + maxParticipants.Text = m.ToString(); + } + }; + + participantsBind.ValueChanged += p => + { + participants.Text = p.Length.ToString(); + participantInfo.Participants = p; + participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u)); + }; + + // trigger incase a room was set before we were loaded + nameBind.TriggerChange(); + hostBind.TriggerChange(); statusBind.TriggerChange(); + typeBind.TriggerChange(); beatmapBind.TriggerChange(); + maxParticipantsBind.TriggerChange(); + participantsBind.TriggerChange(); } protected override void UpdateAfterChildren() @@ -299,86 +358,6 @@ namespace osu.Game.Screens.Multi.Components participantsScroll.Height = DrawHeight - topFlow.DrawHeight; } - private void displayName(string value) - { - name.Text = value; - } - - private void displayUser(User value) - { - participantInfo.Host = value; - } - - private void displayStatus(RoomStatus value) - { - status.Text = value.Message; - - foreach (Drawable d in new Drawable[] { statusStrip, status }) - d.FadeColour(value.GetAppropriateColour(colours), transition_duration); - } - - private void displayGameType(GameType value) - { - modeTypeInfo.Type = value; - } - - private void displayBeatmap(BeatmapInfo value) - { - modeTypeInfo.Beatmap = value; - - if (value != null) - { - coverContainer.FadeIn(transition_duration); - - LoadComponentAsync(new BeatmapSetCover(value.BeatmapSet) - { - RelativeSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - FillMode = FillMode.Fill, - OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out), - }, - coverContainer.Add); - - beatmapTitle.Current = localisation.GetUnicodePreference(value.Metadata.TitleUnicode, value.Metadata.Title); - beatmapDash.Text = @" - "; - beatmapArtist.Current = localisation.GetUnicodePreference(value.Metadata.ArtistUnicode, value.Metadata.Artist); - beatmapAuthor.Text = $"mapped by {value.Metadata.Author}"; - } - else - { - coverContainer.FadeOut(transition_duration); - - beatmapTitle.Current = null; - beatmapArtist.Current = null; - - beatmapTitle.Text = "Changing map"; - beatmapDash.Text = beatmapArtist.Text = beatmapAuthor.Text = string.Empty; - } - } - - private void displayMaxParticipants(int? value) - { - if (value == null) - { - participantsSlash.FadeOut(transition_duration); - maxParticipants.FadeOut(transition_duration); - } - else - { - participantsSlash.FadeIn(transition_duration); - maxParticipants.FadeIn(transition_duration); - maxParticipants.Text = value.ToString(); - } - } - - private void displayParticipants(User[] value) - { - participants.Text = value.Length.ToString(); - participantInfo.Participants = value; - participantsFlow.ChildrenEnumerable = value.Select(u => new UserTile(u)); - } - private class UserTile : Container, IHasTooltip { private readonly User user; From ad878003f7ef6a83cb88d7e98a3d45f1d4f0aeb2 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Sat, 19 May 2018 02:23:09 -0300 Subject: [PATCH 198/229] Add null room support to RoomInspector. --- .../Visual/TestCaseRoomInspector.cs | 8 +- .../Screens/Multi/Components/RoomInspector.cs | 116 ++++++++++++------ 2 files changed, 81 insertions(+), 43 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs index cb1425ca69..48756c907b 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual { base.LoadComplete(); - var room = new Room + Room room = new Room { Name = { Value = @"My Awesome Room" }, Host = { Value = new User { Username = @"flyte", Id = 3103765, Country = new Country { FlagName = @"JP" } } }, @@ -71,9 +71,11 @@ namespace osu.Game.Tests.Visual { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Room = room, }); + AddStep(@"set room", () => inspector.Room = room); + AddStep(@"null room", () => inspector.Room = null); + AddStep(@"set room", () => inspector.Room = room); AddStep(@"change title", () => room.Name.Value = @"A Better Room Than The Above"); AddStep(@"change host", () => room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } }); AddStep(@"change status", () => room.Status.Value = new RoomStatusPlaying()); @@ -88,7 +90,7 @@ namespace osu.Game.Tests.Visual AddStep(@"change room", () => { - var newRoom = new Room + Room newRoom = new Room { Name = { Value = @"My New, Better Than Ever Room" }, Host = { Value = new User { Username = @"Angelsim", Id = 1777162, Country = new Country { FlagName = @"KR" } } }, diff --git a/osu.Game/Screens/Multi/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Components/RoomInspector.cs index b103624dfb..b3a6d90e39 100644 --- a/osu.Game/Screens/Multi/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Components/RoomInspector.cs @@ -5,6 +5,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -25,9 +26,9 @@ namespace osu.Game.Screens.Multi.Components { public class RoomInspector : Container { - private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 }; private const float transition_duration = 100; + private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 }; private readonly Bindable nameBind = new Bindable(); private readonly Bindable hostBind = new Bindable(); private readonly Bindable statusBind = new Bindable(); @@ -36,8 +37,13 @@ namespace osu.Game.Screens.Multi.Components private readonly Bindable maxParticipantsBind = new Bindable(); private readonly Bindable participantsBind = new Bindable(); - private FillFlowContainer topFlow; + private OsuColour colours; + private Box statusStrip; + private Container coverContainer; + private FillFlowContainer topFlow, participantsFlow, participantNumbersFlow, infoPanelFlow; + private OsuSpriteText name, status; private ScrollContainer participantsScroll; + private ParticipantInfo participantInfo; private Room room; public Room Room @@ -48,13 +54,26 @@ namespace osu.Game.Screens.Multi.Components if (value == room) return; room = value; - nameBind.BindTo(Room.Name); - hostBind.BindTo(Room.Host); - statusBind.BindTo(Room.Status); - typeBind.BindTo(Room.Type); - beatmapBind.BindTo(Room.Beatmap); - maxParticipantsBind.BindTo(Room.MaxParticipants); - participantsBind.BindTo(Room.Participants); + nameBind.UnbindBindings(); + hostBind.UnbindBindings(); + statusBind.UnbindBindings(); + typeBind.UnbindBindings(); + beatmapBind.UnbindBindings(); + maxParticipantsBind.UnbindBindings(); + participantsBind.UnbindBindings(); + + if (Room != null) + { + nameBind.BindTo(Room.Name); + hostBind.BindTo(Room.Host); + statusBind.BindTo(Room.Status); + typeBind.BindTo(Room.Type); + beatmapBind.BindTo(Room.Beatmap); + maxParticipantsBind.BindTo(Room.MaxParticipants); + participantsBind.BindTo(Room.Participants); + } + + updateState(); } } @@ -67,12 +86,10 @@ namespace osu.Game.Screens.Multi.Components [BackgroundDependencyLoader] private void load(OsuColour colours, LocalisationEngine localisation) { - Box statusStrip; - Container coverContainer; - FillFlowContainer participantsFlow; + this.colours = colours; + ModeTypeInfo modeTypeInfo; - OsuSpriteText participants, participantsSlash, maxParticipants, name, status, beatmapTitle, beatmapDash, beatmapArtist, beatmapAuthor; - ParticipantInfo participantInfo; + OsuSpriteText participants, participantsSlash, maxParticipants, beatmapTitle, beatmapDash, beatmapArtist, beatmapAuthor; Children = new Drawable[] { @@ -122,7 +139,7 @@ namespace osu.Game.Screens.Multi.Components Padding = new MarginPadding(20), Children = new Drawable[] { - new FillFlowContainer + participantNumbersFlow = new FillFlowContainer { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, @@ -180,6 +197,7 @@ namespace osu.Game.Screens.Multi.Components RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, + LayoutDuration = transition_duration, Padding = contentPadding, Spacing = new Vector2(0f, 5f), Children = new Drawable[] @@ -189,7 +207,7 @@ namespace osu.Game.Screens.Multi.Components TextSize = 14, Font = @"Exo2.0-Bold", }, - new FillFlowContainer + infoPanelFlow = new FillFlowContainer { AutoSizeAxes = Axes.X, Height = 30, @@ -275,14 +293,7 @@ namespace osu.Game.Screens.Multi.Components nameBind.ValueChanged += n => name.Text = n; hostBind.ValueChanged += h => participantInfo.Host = h; typeBind.ValueChanged += t => modeTypeInfo.Type = t; - - statusBind.ValueChanged += s => - { - status.Text = s.Message; - - foreach (Drawable d in new Drawable[] { statusStrip, status }) - d.FadeColour(s.GetAppropriateColour(colours), transition_duration); - }; + statusBind.ValueChanged += displayStatus; beatmapBind.ValueChanged += b => { @@ -293,14 +304,13 @@ namespace osu.Game.Screens.Multi.Components coverContainer.FadeIn(transition_duration); LoadComponentAsync(new BeatmapSetCover(b.BeatmapSet) - { - RelativeSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - FillMode = FillMode.Fill, - OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out), - }, - coverContainer.Add); + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + FillMode = FillMode.Fill, + OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out), + }, coverContainer.Add); beatmapTitle.Current = localisation.GetUnicodePreference(b.Metadata.TitleUnicode, b.Metadata.Title); beatmapDash.Text = @" - "; @@ -341,14 +351,7 @@ namespace osu.Game.Screens.Multi.Components participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u)); }; - // trigger incase a room was set before we were loaded - nameBind.TriggerChange(); - hostBind.TriggerChange(); - statusBind.TriggerChange(); - typeBind.TriggerChange(); - beatmapBind.TriggerChange(); - maxParticipantsBind.TriggerChange(); - participantsBind.TriggerChange(); + updateState(); } protected override void UpdateAfterChildren() @@ -358,6 +361,33 @@ namespace osu.Game.Screens.Multi.Components participantsScroll.Height = DrawHeight - topFlow.DrawHeight; } + private void displayStatus(RoomStatus s) + { + status.Text = s.Message; + + foreach (Drawable d in new Drawable[] { statusStrip, status }) + d.FadeColour(s.GetAppropriateColour(colours), transition_duration); + } + + private void updateState() + { + if (Room == null) + { + foreach (Drawable d in new Drawable[] { coverContainer, participantsFlow, participantNumbersFlow, infoPanelFlow, name, participantInfo }) + d.FadeOut(transition_duration); + + displayStatus(new RoomStatusNoneSelected()); + } + else + { + foreach (Drawable d in new Drawable[] { participantsFlow, participantNumbersFlow, infoPanelFlow, name, participantInfo }) + d.FadeIn(transition_duration); + + statusBind.TriggerChange(); + beatmapBind.TriggerChange(); + } + } + private class UserTile : Container, IHasTooltip { private readonly User user; @@ -386,5 +416,11 @@ namespace osu.Game.Screens.Multi.Components }; } } + + private class RoomStatusNoneSelected : RoomStatus + { + public override string Message => @"No Room Selected"; + public override Color4 GetAppropriateColour(OsuColour colours) => colours.Gray8; + } } } From 136c57b824d477e3af4370681e987358ed35b5b6 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Sat, 19 May 2018 02:27:33 -0300 Subject: [PATCH 199/229] Don't set size in ctor. --- osu.Game.Tests/Visual/TestCaseRoomInspector.cs | 2 ++ osu.Game/Screens/Multi/Components/RoomInspector.cs | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs index 48756c907b..06b9c4a6f9 100644 --- a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs +++ b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs @@ -71,6 +71,8 @@ namespace osu.Game.Tests.Visual { Anchor = Anchor.Centre, Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Width = 0.5f, }); AddStep(@"set room", () => inspector.Room = room); diff --git a/osu.Game/Screens/Multi/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Components/RoomInspector.cs index b3a6d90e39..3de1611b77 100644 --- a/osu.Game/Screens/Multi/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Components/RoomInspector.cs @@ -79,8 +79,6 @@ namespace osu.Game.Screens.Multi.Components public RoomInspector() { - Width = 520; - RelativeSizeAxes = Axes.Y; } [BackgroundDependencyLoader] From 9cd0ec366e2d003e1f6c1923f414010a7208a821 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Sat, 19 May 2018 02:51:51 -0300 Subject: [PATCH 200/229] Cleanup. --- .../Screens/Multi/Components/RoomInspector.cs | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Components/RoomInspector.cs index 3de1611b77..ea12b5dbde 100644 --- a/osu.Game/Screens/Multi/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Components/RoomInspector.cs @@ -5,7 +5,6 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -77,10 +76,6 @@ namespace osu.Game.Screens.Multi.Components } } - public RoomInspector() - { - } - [BackgroundDependencyLoader] private void load(OsuColour colours, LocalisationEngine localisation) { @@ -363,23 +358,31 @@ namespace osu.Game.Screens.Multi.Components { status.Text = s.Message; - foreach (Drawable d in new Drawable[] { statusStrip, status }) - d.FadeColour(s.GetAppropriateColour(colours), transition_duration); + Color4 c = s.GetAppropriateColour(colours); + statusStrip.FadeColour(c, transition_duration); + status.FadeColour(c, transition_duration); } private void updateState() { if (Room == null) { - foreach (Drawable d in new Drawable[] { coverContainer, participantsFlow, participantNumbersFlow, infoPanelFlow, name, participantInfo }) - d.FadeOut(transition_duration); + coverContainer.FadeOut(transition_duration); + participantsFlow.FadeOut(transition_duration); + participantNumbersFlow.FadeOut(transition_duration); + infoPanelFlow.FadeOut(transition_duration); + name.FadeOut(transition_duration); + participantInfo.FadeOut(transition_duration); displayStatus(new RoomStatusNoneSelected()); } else { - foreach (Drawable d in new Drawable[] { participantsFlow, participantNumbersFlow, infoPanelFlow, name, participantInfo }) - d.FadeIn(transition_duration); + participantsFlow.FadeIn(transition_duration); + participantNumbersFlow.FadeIn(transition_duration); + infoPanelFlow.FadeIn(transition_duration); + name.FadeIn(transition_duration); + participantInfo.FadeIn(transition_duration); statusBind.TriggerChange(); beatmapBind.TriggerChange(); From 4d528c4e6703da6e93418e59f3d11db2b13e8031 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sun, 20 May 2018 10:57:15 +0200 Subject: [PATCH 201/229] fix VisualTests and Samples still playing --- .../Graphics/Containers/OsuFocusedOverlayContainer.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index c26adc8a3d..1005794742 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -16,9 +16,9 @@ namespace osu.Game.Graphics.Containers private SampleChannel samplePopIn; private SampleChannel samplePopOut; - protected BindableBool ShowOverlays = new BindableBool(); + protected BindableBool ShowOverlays = new BindableBool(true); - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(OsuGame osuGame, AudioManager audio) { samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in"); @@ -26,7 +26,8 @@ namespace osu.Game.Graphics.Containers StateChanged += onStateChanged; - ShowOverlays.BindTo(osuGame.ShowOverlays); + if (osuGame != null) + ShowOverlays.BindTo(osuGame.ShowOverlays); } /// @@ -52,7 +53,10 @@ namespace osu.Game.Graphics.Containers private void onStateChanged(Visibility visibility) { if (!ShowOverlays) + { State = Visibility.Hidden; + return; + } switch (visibility) { From aaca7e92b483f847fb8605f203088e76909effb3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 May 2018 03:56:59 +0900 Subject: [PATCH 202/229] Avoid excessive property lookups --- .../Screens/Multi/Components/RoomInspector.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Components/RoomInspector.cs index ea12b5dbde..3bd054b042 100644 --- a/osu.Game/Screens/Multi/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Components/RoomInspector.cs @@ -61,15 +61,15 @@ namespace osu.Game.Screens.Multi.Components maxParticipantsBind.UnbindBindings(); participantsBind.UnbindBindings(); - if (Room != null) + if (room != null) { - nameBind.BindTo(Room.Name); - hostBind.BindTo(Room.Host); - statusBind.BindTo(Room.Status); - typeBind.BindTo(Room.Type); - beatmapBind.BindTo(Room.Beatmap); - maxParticipantsBind.BindTo(Room.MaxParticipants); - participantsBind.BindTo(Room.Participants); + nameBind.BindTo(room.Name); + hostBind.BindTo(room.Host); + statusBind.BindTo(room.Status); + typeBind.BindTo(room.Type); + beatmapBind.BindTo(room.Beatmap); + maxParticipantsBind.BindTo(room.MaxParticipants); + participantsBind.BindTo(room.Participants); } updateState(); From 46c6c1d07e6edd0dc778d22a9ecf4e87c686a0dd Mon Sep 17 00:00:00 2001 From: Joehu Date: Sun, 20 May 2018 20:25:39 -0700 Subject: [PATCH 203/229] Allow drag clicking footer and filter on song select --- osu.Game/Screens/Select/FilterControl.cs | 2 -- osu.Game/Screens/Select/Footer.cs | 2 -- 2 files changed, 4 deletions(-) diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index ee458a13a4..f9f3db3827 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -190,7 +190,5 @@ namespace osu.Game.Screens.Select protected override bool OnMouseMove(InputState state) => true; protected override bool OnClick(InputState state) => true; - - protected override bool OnDragStart(InputState state) => true; } } diff --git a/osu.Game/Screens/Select/Footer.cs b/osu.Game/Screens/Select/Footer.cs index 363249ab63..8f07e0a763 100644 --- a/osu.Game/Screens/Select/Footer.cs +++ b/osu.Game/Screens/Select/Footer.cs @@ -141,7 +141,5 @@ namespace osu.Game.Screens.Select protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => true; protected override bool OnClick(InputState state) => true; - - protected override bool OnDragStart(InputState state) => true; } } From 42519e3723e5abcde81c0c04005dae38a657aeb8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 May 2018 14:45:44 +0900 Subject: [PATCH 204/229] Rewrite code for clarity This also uses the AvailableRulesets list rather than private IDs --- .../Overlays/Toolbar/ToolbarModeSelector.cs | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index eeaa15d58a..3078c44844 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -76,15 +76,13 @@ namespace osu.Game.Overlays.Toolbar modeButtons.Add(new ToolbarModeButton { Ruleset = r, - Action = delegate - { - ruleset.Value = r; - } + Action = delegate { ruleset.Value = r; } }); } ruleset.ValueChanged += rulesetChanged; ruleset.DisabledChanged += disabledChanged; + if (game != null) ruleset.BindTo(game.Ruleset); else @@ -94,17 +92,18 @@ namespace osu.Game.Overlays.Toolbar protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { base.OnKeyDown(state, args); - if (!state.Keyboard.ControlPressed || args.Repeat || (int)args.Key < 109 || (int)args.Key > 118) { - return false; + + if (state.Keyboard.ControlPressed && !args.Repeat && args.Key >= Key.Number1 && args.Key <= Key.Number9) + { + int requested = args.Key - Key.Number1; + + RulesetInfo found = rulesets.AvailableRulesets.Skip(requested).FirstOrDefault(); + if (found != null) + ruleset.Value = found; + return true; } - RulesetInfo targetRuleset = rulesets.GetRuleset(args.Key == Key.Number0 ? 9 : (int)args.Key - 110); - if (targetRuleset == null || targetRuleset == ruleset.Value) { - return false; - } - - ruleset.Value = targetRuleset; - return true; + return false; } public override bool HandleKeyboardInput => !ruleset.Disabled && base.HandleKeyboardInput; From 1482bca147a7e152bd109eaf8094ac16d39ffb51 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Mon, 21 May 2018 09:42:29 +0200 Subject: [PATCH 205/229] Rename for better understanding ShowOverlays -> AllowOverlays ShowOverlaysOnEnter -> HideOverlaysOnEnter --- .../Containers/OsuFocusedOverlayContainer.cs | 33 +++++++++---------- osu.Game/OsuGame.cs | 6 ++-- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Loader.cs | 2 +- osu.Game/Screens/Menu/ButtonSystem.cs | 10 +++--- osu.Game/Screens/Menu/Disclaimer.cs | 2 +- osu.Game/Screens/Menu/Intro.cs | 2 +- osu.Game/Screens/Menu/MainMenu.cs | 2 +- osu.Game/Screens/OsuScreen.cs | 10 +++--- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Play/PlayerLoader.cs | 6 ++-- osu.Game/Screens/Tournament/Drawings.cs | 2 +- 12 files changed, 40 insertions(+), 39 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 1005794742..9c36eb8c18 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -16,18 +16,18 @@ namespace osu.Game.Graphics.Containers private SampleChannel samplePopIn; private SampleChannel samplePopOut; - protected BindableBool ShowOverlays = new BindableBool(true); + protected BindableBool AllowOverlays = new BindableBool(true); [BackgroundDependencyLoader(true)] private void load(OsuGame osuGame, AudioManager audio) { + if (osuGame != null) + AllowOverlays.BindTo(osuGame.AllowOverlays); + samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in"); samplePopOut = audio.Sample.Get(@"UI/overlay-pop-out"); StateChanged += onStateChanged; - - if (osuGame != null) - ShowOverlays.BindTo(osuGame.ShowOverlays); } /// @@ -52,21 +52,20 @@ namespace osu.Game.Graphics.Containers private void onStateChanged(Visibility visibility) { - if (!ShowOverlays) + if (AllowOverlays) { + switch (visibility) + { + case Visibility.Visible: + samplePopIn?.Play(); + break; + case Visibility.Hidden: + samplePopOut?.Play(); + break; + } + } + else State = Visibility.Hidden; - return; - } - - switch (visibility) - { - case Visibility.Visible: - samplePopIn?.Play(); - break; - case Visibility.Hidden: - samplePopOut?.Play(); - break; - } } } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index fe5ca4f278..b3da2831cd 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -77,7 +77,7 @@ namespace osu.Game public float ToolbarOffset => Toolbar.Position.Y + Toolbar.DrawHeight; - public readonly BindableBool ShowOverlays = new BindableBool(); + public readonly BindableBool AllowOverlays = new BindableBool(); private OsuScreen screenStack; @@ -367,9 +367,9 @@ namespace osu.Game settings.StateChanged += _ => updateScreenOffset(); notifications.StateChanged += _ => updateScreenOffset(); - notifications.Enabled.BindTo(ShowOverlays); + notifications.Enabled.BindTo(AllowOverlays); - ShowOverlays.ValueChanged += show => + AllowOverlays.ValueChanged += show => { //central game screen change logic. if (!show) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index e4eaee76fc..8049ea2738 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit { protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4"); - public override bool ShowOverlaysOnEnter => false; + public override bool HideOverlaysOnEnter => true; public override bool AllowBeatmapRulesetChange => false; private Box bottomBackground; diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index 555c497d92..e49fb08087 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens { private bool showDisclaimer; - public override bool ShowOverlaysOnEnter => false; + public override bool HideOverlaysOnEnter => true; protected override bool AllowBackButton => false; diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 997002327a..9ca1a1ce19 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Menu { public event Action StateChanged; - private readonly BindableBool showOverlays = new BindableBool(); + private readonly BindableBool allowOverlays = new BindableBool(); public Action OnEdit; public Action OnExit; @@ -135,7 +135,9 @@ namespace osu.Game.Screens.Menu [BackgroundDependencyLoader(true)] private void load(AudioManager audio, OsuGame game) { - if (game != null) showOverlays.BindTo(game.ShowOverlays); + if (game != null) + allowOverlays.BindTo(game.AllowOverlays); + sampleBack = audio.Sample.Get(@"Menu/button-back-select"); } @@ -322,7 +324,7 @@ namespace osu.Game.Screens.Menu logoDelayedAction = Scheduler.AddDelayed(() => { - showOverlays.Value = false; + allowOverlays.Value = false; logo.ClearTransforms(targetMember: nameof(Position)); logo.RelativePositionAxes = Axes.Both; @@ -351,7 +353,7 @@ namespace osu.Game.Screens.Menu logoTracking = true; logo.Impact(); - showOverlays.Value = true; + allowOverlays.Value = true; }, 200); break; default: diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index 5af634b02d..bd32792f3f 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Menu private readonly SpriteIcon icon; private Color4 iconColour; - public override bool ShowOverlaysOnEnter => false; + public override bool HideOverlaysOnEnter => true; public override bool CursorVisible => false; public Disclaimer() diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index 4de76e530a..019f0432f6 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Menu private SampleChannel welcome; private SampleChannel seeya; - public override bool ShowOverlaysOnEnter => false; + public override bool HideOverlaysOnEnter => true; public override bool CursorVisible => false; protected override BackgroundScreen CreateBackground() => new BackgroundScreenEmpty(); diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 3b519c5259..0dd05fa0ad 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Menu { private readonly ButtonSystem buttons; - public override bool ShowOverlaysOnEnter => buttons.State != MenuState.Initial; + public override bool HideOverlaysOnEnter => buttons.State == MenuState.Initial; protected override bool AllowBackButton => buttons.State != MenuState.Initial; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 24945ea347..f94087869a 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -32,12 +32,12 @@ namespace osu.Game.Screens /// protected virtual BackgroundScreen CreateBackground() => null; - protected BindableBool ShowOverlays = new BindableBool(); + protected BindableBool AllowOverlays = new BindableBool(); /// - /// Whether overlays should be shown when this screen is entered or resumed. + /// Whether overlays should be hidden when this screen is entered or resumed. /// - public virtual bool ShowOverlaysOnEnter => true; + public virtual bool HideOverlaysOnEnter => false; /// /// Whether this allows the cursor to be displayed. @@ -88,7 +88,7 @@ namespace osu.Game.Screens if (osuGame != null) { Ruleset.BindTo(osuGame.Ruleset); - ShowOverlays.BindTo(osuGame.ShowOverlays); + AllowOverlays.BindTo(osuGame.AllowOverlays); } sampleExit = audio.Sample.Get(@"UI/screen-back"); @@ -220,7 +220,7 @@ namespace osu.Game.Screens if (backgroundParallaxContainer != null) backgroundParallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * BackgroundParallaxAmount; - ShowOverlays.Value = ShowOverlaysOnEnter; + AllowOverlays.Value = !HideOverlaysOnEnter; } private void onExitingLogo() diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 46919e25e1..44112609f8 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -35,7 +35,7 @@ namespace osu.Game.Screens.Play { protected override float BackgroundParallaxAmount => 0.1f; - public override bool ShowOverlaysOnEnter => false; + public override bool HideOverlaysOnEnter => true; public Action RestartRequested; diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 56fbd7b6e7..fcb2a19c58 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -25,8 +25,8 @@ namespace osu.Game.Screens.Play private BeatmapMetadataDisplay info; - private bool showOverlays = true; - public override bool ShowOverlaysOnEnter => showOverlays; + private bool allowOverlays = true; + public override bool HideOverlaysOnEnter => !allowOverlays; private Task loadTask; @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Play player.RestartRequested = () => { - showOverlays = false; + allowOverlays = false; ValidForResume = true; }; } diff --git a/osu.Game/Screens/Tournament/Drawings.cs b/osu.Game/Screens/Tournament/Drawings.cs index 1ef0b6cca0..ca806ce73e 100644 --- a/osu.Game/Screens/Tournament/Drawings.cs +++ b/osu.Game/Screens/Tournament/Drawings.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Tournament { private const string results_filename = "drawings_results.txt"; - public override bool ShowOverlaysOnEnter => false; + public override bool HideOverlaysOnEnter => true; protected override BackgroundScreen CreateBackground() => new BackgroundScreenDefault(); From b7e3ea348b15e8cdae2e3963f9b8ee4a405e7ea1 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Mon, 21 May 2018 15:53:50 +0200 Subject: [PATCH 206/229] expose two Bindables with split logic instead of one with mixed logic --- .../Containers/OsuFocusedOverlayContainer.cs | 6 +++--- osu.Game/OsuGame.cs | 9 +++++---- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Loader.cs | 2 +- osu.Game/Screens/Menu/ButtonSystem.cs | 13 ++++++++----- osu.Game/Screens/Menu/Disclaimer.cs | 3 ++- osu.Game/Screens/Menu/Intro.cs | 4 +++- osu.Game/Screens/Menu/MainMenu.cs | 3 ++- osu.Game/Screens/OsuScreen.cs | 17 +++++++++++++---- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Play/PlayerLoader.cs | 6 +++--- osu.Game/Screens/Tournament/Drawings.cs | 2 +- 12 files changed, 43 insertions(+), 26 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 9c36eb8c18..11a2034a8f 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -16,13 +16,13 @@ namespace osu.Game.Graphics.Containers private SampleChannel samplePopIn; private SampleChannel samplePopOut; - protected BindableBool AllowOverlays = new BindableBool(true); + private readonly BindableBool allowOpeningOverlays = new BindableBool(true); [BackgroundDependencyLoader(true)] private void load(OsuGame osuGame, AudioManager audio) { if (osuGame != null) - AllowOverlays.BindTo(osuGame.AllowOverlays); + allowOpeningOverlays.BindTo(osuGame.AllowOpeningOverlays); samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in"); samplePopOut = audio.Sample.Get(@"UI/overlay-pop-out"); @@ -52,7 +52,7 @@ namespace osu.Game.Graphics.Containers private void onStateChanged(Visibility visibility) { - if (AllowOverlays) + if (allowOpeningOverlays) { switch (visibility) { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b3da2831cd..ec93b1ae46 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -77,7 +77,8 @@ namespace osu.Game public float ToolbarOffset => Toolbar.Position.Y + Toolbar.DrawHeight; - public readonly BindableBool AllowOverlays = new BindableBool(); + public readonly BindableBool HideOverlaysOnEnter = new BindableBool(); + public readonly BindableBool AllowOpeningOverlays = new BindableBool(true); private OsuScreen screenStack; @@ -367,12 +368,12 @@ namespace osu.Game settings.StateChanged += _ => updateScreenOffset(); notifications.StateChanged += _ => updateScreenOffset(); - notifications.Enabled.BindTo(AllowOverlays); + notifications.Enabled.BindTo(AllowOpeningOverlays); - AllowOverlays.ValueChanged += show => + HideOverlaysOnEnter.ValueChanged += hide => { //central game screen change logic. - if (!show) + if (hide) { hideAllOverlays(); musicController.State = Visibility.Hidden; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 8049ea2738..b657fe5597 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit { protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4"); - public override bool HideOverlaysOnEnter => true; + protected override bool HideOverlaysOnEnter => true; public override bool AllowBeatmapRulesetChange => false; private Box bottomBackground; diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index e49fb08087..fb5c5ca84b 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens { private bool showDisclaimer; - public override bool HideOverlaysOnEnter => true; + protected override bool HideOverlaysOnEnter => true; protected override bool AllowBackButton => false; diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 9ca1a1ce19..d1d388ae1f 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -27,7 +27,8 @@ namespace osu.Game.Screens.Menu { public event Action StateChanged; - private readonly BindableBool allowOverlays = new BindableBool(); + private readonly BindableBool hideOverlaysOnEnter = new BindableBool(); + private readonly BindableBool allowOpeningOverlays = new BindableBool(); public Action OnEdit; public Action OnExit; @@ -136,7 +137,10 @@ namespace osu.Game.Screens.Menu private void load(AudioManager audio, OsuGame game) { if (game != null) - allowOverlays.BindTo(game.AllowOverlays); + { + hideOverlaysOnEnter.BindTo(game.HideOverlaysOnEnter); + allowOpeningOverlays.BindTo(game.AllowOpeningOverlays); + } sampleBack = audio.Sample.Get(@"Menu/button-back-select"); } @@ -324,8 +328,6 @@ namespace osu.Game.Screens.Menu logoDelayedAction = Scheduler.AddDelayed(() => { - allowOverlays.Value = false; - logo.ClearTransforms(targetMember: nameof(Position)); logo.RelativePositionAxes = Axes.Both; @@ -353,7 +355,8 @@ namespace osu.Game.Screens.Menu logoTracking = true; logo.Impact(); - allowOverlays.Value = true; + hideOverlaysOnEnter.Value = false; + allowOpeningOverlays.Value = true; }, 200); break; default: diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index bd32792f3f..9a671cf780 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -18,7 +18,8 @@ namespace osu.Game.Screens.Menu private readonly SpriteIcon icon; private Color4 iconColour; - public override bool HideOverlaysOnEnter => true; + protected override bool HideOverlaysOnEnter => true; + public override bool CursorVisible => false; public Disclaimer() diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index 019f0432f6..c174e2d470 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -31,7 +31,9 @@ namespace osu.Game.Screens.Menu private SampleChannel welcome; private SampleChannel seeya; - public override bool HideOverlaysOnEnter => true; + protected override bool HideOverlaysOnEnter => true; + protected override bool AllowOpeningOverlays => false; + public override bool CursorVisible => false; protected override BackgroundScreen CreateBackground() => new BackgroundScreenEmpty(); diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 0dd05fa0ad..d5f3b11467 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -24,7 +24,8 @@ namespace osu.Game.Screens.Menu { private readonly ButtonSystem buttons; - public override bool HideOverlaysOnEnter => buttons.State == MenuState.Initial; + protected override bool HideOverlaysOnEnter => buttons.State == MenuState.Initial; + protected override bool AllowOpeningOverlays => buttons.State != MenuState.Initial; protected override bool AllowBackButton => buttons.State != MenuState.Initial; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index f94087869a..4b1562291b 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -32,12 +32,19 @@ namespace osu.Game.Screens /// protected virtual BackgroundScreen CreateBackground() => null; - protected BindableBool AllowOverlays = new BindableBool(); + private readonly BindableBool hideOverlaysOnEnter = new BindableBool(); /// /// Whether overlays should be hidden when this screen is entered or resumed. /// - public virtual bool HideOverlaysOnEnter => false; + protected virtual bool HideOverlaysOnEnter => hideOverlaysOnEnter; + + private readonly BindableBool allowOpeningOverlays = new BindableBool(); + + /// + /// Whether overlays should be able to be opened while this screen is active. + /// + protected virtual bool AllowOpeningOverlays => allowOpeningOverlays; /// /// Whether this allows the cursor to be displayed. @@ -88,7 +95,8 @@ namespace osu.Game.Screens if (osuGame != null) { Ruleset.BindTo(osuGame.Ruleset); - AllowOverlays.BindTo(osuGame.AllowOverlays); + hideOverlaysOnEnter.BindTo(osuGame.HideOverlaysOnEnter); + allowOpeningOverlays.BindTo(osuGame.AllowOpeningOverlays); } sampleExit = audio.Sample.Get(@"UI/screen-back"); @@ -220,7 +228,8 @@ namespace osu.Game.Screens if (backgroundParallaxContainer != null) backgroundParallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * BackgroundParallaxAmount; - AllowOverlays.Value = !HideOverlaysOnEnter; + hideOverlaysOnEnter.Value = HideOverlaysOnEnter; + allowOpeningOverlays.Value = AllowOpeningOverlays; } private void onExitingLogo() diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 44112609f8..ec7a99145e 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -35,7 +35,7 @@ namespace osu.Game.Screens.Play { protected override float BackgroundParallaxAmount => 0.1f; - public override bool HideOverlaysOnEnter => true; + protected override bool HideOverlaysOnEnter => true; public Action RestartRequested; diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index fcb2a19c58..734837a4f1 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -25,8 +25,8 @@ namespace osu.Game.Screens.Play private BeatmapMetadataDisplay info; - private bool allowOverlays = true; - public override bool HideOverlaysOnEnter => !allowOverlays; + private bool hideOverlays; + protected override bool HideOverlaysOnEnter => hideOverlays; private Task loadTask; @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Play player.RestartRequested = () => { - allowOverlays = false; + hideOverlays = true; ValidForResume = true; }; } diff --git a/osu.Game/Screens/Tournament/Drawings.cs b/osu.Game/Screens/Tournament/Drawings.cs index ca806ce73e..29301899d5 100644 --- a/osu.Game/Screens/Tournament/Drawings.cs +++ b/osu.Game/Screens/Tournament/Drawings.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Tournament { private const string results_filename = "drawings_results.txt"; - public override bool HideOverlaysOnEnter => true; + protected override bool HideOverlaysOnEnter => true; protected override BackgroundScreen CreateBackground() => new BackgroundScreenDefault(); From d109522bf790bc9e111ff54df5d8b247199f09d5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 May 2018 23:09:00 +0900 Subject: [PATCH 207/229] Fix escape not working to go backwards in menus before finally exiting the game Resolves #2596. --- osu.Game/Screens/Menu/ButtonSystem.cs | 29 +++++++++++++++++---------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 997002327a..98c1cfbf07 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -148,6 +148,8 @@ namespace osu.Game.Screens.Menu case Key.Space: logo?.TriggerOnClick(state); return true; + case Key.Escape: + return goBack(); } return false; @@ -158,17 +160,22 @@ namespace osu.Game.Screens.Menu switch (action) { case GlobalAction.Back: - switch (State) - { - case MenuState.TopLevel: - State = MenuState.Initial; - return true; - case MenuState.Play: - backButton.TriggerOnClick(); - return true; - default: - return false; - } + return goBack(); + default: + return false; + } + } + + private bool goBack() + { + switch (State) + { + case MenuState.TopLevel: + State = MenuState.Initial; + return true; + case MenuState.Play: + backButton.TriggerOnClick(); + return true; default: return false; } From 3d9d40448ded833eb6ecaf960b047817ca3db5ed Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 00:01:40 +0900 Subject: [PATCH 208/229] Fix incorrect syntax --- osu.Game/Screens/Play/HUD/QuitButton.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index 276bffb0a4..db24400f30 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -86,7 +86,7 @@ namespace osu.Game.Screens.Play.HUD { icon.ScaleTo(1.5f); text.FadeIn(fade_duration); - progress.FillTo(progress.Current, 1, progress_duration).OnComplete(cp => ExitAction()); + progress.FillTo(1, progress_duration).OnComplete(cp => ExitAction()); return base.OnMouseDown(state, args); } @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Play.HUD { icon.ScaleTo(1f); Scheduler.AddDelayed(() => text.FadeOut(fade_duration), text_display_time); - progress.FillTo(progress.Current, 0, progress_duration / 4).OnComplete(cp => progress.Current.SetDefault()); + progress.FillTo(0, progress_duration / 4f).OnComplete(cp => progress.Current.SetDefault()); return base.OnMouseUp(state, args); } From d5afccd610f268096c6fe968213d71ec97fb3aa1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 00:02:03 +0900 Subject: [PATCH 209/229] Make hint text display briefly at initial display, then on hover --- osu.Game/Screens/Play/HUD/QuitButton.cs | 35 ++++++++++++++++++------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index db24400f30..61925108ae 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -16,6 +16,8 @@ namespace osu.Game.Screens.Play.HUD { public class QuitButton : FillFlowContainer { + public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => button.ReceiveMouseInputAt(screenSpacePos); + private readonly Button button; public Action ExitAction @@ -24,28 +26,47 @@ namespace osu.Game.Screens.Play.HUD set => button.ExitAction = value; } + OsuSpriteText text; + public QuitButton() { - OsuSpriteText text; Direction = FillDirection.Horizontal; Spacing = new Vector2(20, 0); + Margin = new MarginPadding(10); Children = new Drawable[] { text = new OsuSpriteText { - Text = "Hold to Quit", + Text = "hold to quit", Font = @"Exo2.0-Bold", Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft }, - button = new Button(text) + button = new Button() }; AutoSizeAxes = Axes.Both; } + protected override void LoadComplete() + { + text.FadeInFromZero(500, Easing.OutQuint).Delay(1500).FadeOut(500, Easing.OutQuint); + base.LoadComplete(); + } + + protected override bool OnHover(InputState state) + { + text.FadeIn(500, Easing.OutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + text.FadeOut(500, Easing.OutQuint); + base.OnHoverLost(state); + } + private class Button : CircularContainer { - private readonly OsuSpriteText text; private SpriteIcon icon; private CircularProgress progress; @@ -53,9 +74,6 @@ namespace osu.Game.Screens.Play.HUD private const int fade_duration = 200; private const int progress_duration = 1000; - private const int text_display_time = 5000; - - public Button(OsuSpriteText text) => this.text = text; [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -79,13 +97,11 @@ namespace osu.Game.Screens.Play.HUD }, progress = new CircularProgress { RelativeSizeAxes = Axes.Both, InnerRadius = 0.1f } }); - Scheduler.AddDelayed(() => text.FadeOut(fade_duration), text_display_time); } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { icon.ScaleTo(1.5f); - text.FadeIn(fade_duration); progress.FillTo(1, progress_duration).OnComplete(cp => ExitAction()); return base.OnMouseDown(state, args); @@ -94,7 +110,6 @@ namespace osu.Game.Screens.Play.HUD protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { icon.ScaleTo(1f); - Scheduler.AddDelayed(() => text.FadeOut(fade_duration), text_display_time); progress.FillTo(0, progress_duration / 4f).OnComplete(cp => progress.Current.SetDefault()); return base.OnMouseUp(state, args); From cee8d21542713dd2e3eadc3983d9c611ddf7dd21 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Mon, 21 May 2018 17:24:57 +0200 Subject: [PATCH 210/229] hide overlays when going back to initial menu state --- osu.Game/Screens/Menu/ButtonSystem.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index d1d388ae1f..2e757c256e 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -328,6 +328,9 @@ namespace osu.Game.Screens.Menu logoDelayedAction = Scheduler.AddDelayed(() => { + hideOverlaysOnEnter.Value = true; + allowOpeningOverlays.Value = false; + logo.ClearTransforms(targetMember: nameof(Position)); logo.RelativePositionAxes = Axes.Both; @@ -355,6 +358,7 @@ namespace osu.Game.Screens.Menu logoTracking = true; logo.Impact(); + hideOverlaysOnEnter.Value = false; allowOpeningOverlays.Value = true; }, 200); From f9c162dee95617e22cd8666cc35d3fe03b6941a0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 00:49:33 +0900 Subject: [PATCH 211/229] Adjust design and feel --- osu.Game/Screens/Play/HUD/QuitButton.cs | 58 +++++++++++++++++++++---- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index 61925108ae..939966f0e5 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; +using osu.Framework.MathUtils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using OpenTK; @@ -26,7 +27,7 @@ namespace osu.Game.Screens.Play.HUD set => button.ExitAction = value; } - OsuSpriteText text; + private readonly OsuSpriteText text; public QuitButton() { @@ -65,15 +66,32 @@ namespace osu.Game.Screens.Play.HUD base.OnHoverLost(state); } + protected override void Update() + { + base.Update(); + + float adjust = Vector2.Distance(GetContainingInputManager().CurrentState.Mouse.NativeState.Position, button.ScreenSpaceDrawQuad.Centre) / 200; + double elapsed = MathHelper.Clamp(Clock.ElapsedFrameTime, 0, 1000); + + bool stayVisible = text.Alpha > 0 || button.Progress > 0 || IsHovered; + + Alpha = stayVisible ? 1 : Interpolation.ValueAt(elapsed, Alpha, MathHelper.Clamp(1 - adjust, 0.04f, 1), 0, 200, Easing.OutQuint); + } + private class Button : CircularContainer { private SpriteIcon icon; private CircularProgress progress; + private Circle innerCircle; + + private bool triggered; public Action ExitAction { get; set; } + public double Progress => progress.Current.Value; + private const int fade_duration = 200; - private const int progress_duration = 1000; + private const int progress_duration = 600; [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -86,31 +104,55 @@ namespace osu.Game.Screens.Play.HUD { RelativeSizeAxes = Axes.Both, Colour = colours.Gray1, - Alpha = 0.8f, + Alpha = 0.5f, + }, + progress = new CircularProgress + { + RelativeSizeAxes = Axes.Both, + InnerRadius = 1 + }, + innerCircle = new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + Size = new Vector2(0.9f), }, icon = new SpriteIcon { + Shadow = false, Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(15), Icon = FontAwesome.fa_close }, - progress = new CircularProgress { RelativeSizeAxes = Axes.Both, InnerRadius = 0.1f } }); } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - icon.ScaleTo(1.5f); - progress.FillTo(1, progress_duration).OnComplete(cp => ExitAction()); + if (state.Mouse.Buttons.Count > 1 || triggered) + return true; + + icon.ScaleTo(1.4f, progress_duration); + progress.FillTo(1, progress_duration, Easing.OutSine).OnComplete(_ => + { + innerCircle.ScaleTo(0, 100).Then().FadeOut().ScaleTo(1).FadeIn(500); + triggered = true; + ExitAction(); + }); return base.OnMouseDown(state, args); } protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { - icon.ScaleTo(1f); - progress.FillTo(0, progress_duration / 4f).OnComplete(cp => progress.Current.SetDefault()); + if (state.Mouse.Buttons.Count > 0 || triggered) + return true; + + icon.ScaleTo(1, 800, Easing.OutElastic); + progress.FillTo(0, progress_duration, Easing.OutQuint).OnComplete(cp => progress.Current.SetDefault()); return base.OnMouseUp(state, args); } From ebda287e8186fea7c7ebf82ac9c1e70175bcd7b4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 01:44:06 +0900 Subject: [PATCH 212/229] Share code with HoldToConfirm implementations elsewhere --- osu-framework | 2 +- osu.Game.Tests/Visual/TestCaseQuitButton.cs | 42 ++++--- .../Containers/HoldToCofirmContainer.cs | 52 ++++++++ osu.Game/Overlays/HoldToConfirmOverlay.cs | 33 +---- osu.Game/Screens/Play/HUD/QuitButton.cs | 116 ++++++++---------- osu.Game/Screens/Play/Player.cs | 2 +- 6 files changed, 135 insertions(+), 112 deletions(-) create mode 100644 osu.Game/Graphics/Containers/HoldToCofirmContainer.cs diff --git a/osu-framework b/osu-framework index fac688633b..b4d5c766f5 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit fac688633b8fcf34ae5d0514c26b03e217161eb4 +Subproject commit b4d5c766f5698540a7b1bbbae7290ac7dafc2813 diff --git a/osu.Game.Tests/Visual/TestCaseQuitButton.cs b/osu.Game.Tests/Visual/TestCaseQuitButton.cs index 545a8ff57b..f0f8d41074 100644 --- a/osu.Game.Tests/Visual/TestCaseQuitButton.cs +++ b/osu.Game.Tests/Visual/TestCaseQuitButton.cs @@ -3,49 +3,55 @@ using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Game.Screens.Play.HUD; +using OpenTK; +using OpenTK.Input; namespace osu.Game.Tests.Visual { [Description("'Hold to Quit' UI element")] - public class TestCaseQuitButton : OsuTestCase + public class TestCaseQuitButton : ManualInputManagerTestCase { - private readonly QuitButton quitButton; - private Drawable innerButton => quitButton.Children.Single(child => child is CircularContainer); private bool exitAction; - public TestCaseQuitButton() + [BackgroundDependencyLoader] + private void load() { + QuitButton quitButton; + Add(quitButton = new QuitButton { Origin = Anchor.BottomRight, Anchor = Anchor.BottomRight, - }); - quitButton.ExitAction = () => exitAction = true; - - var text = quitButton.Children.OfType().Single(); - - AddStep("Trigger text fade in/out", () => - { - exitAction = false; - - innerButton.TriggerOnMouseDown(); - innerButton.TriggerOnMouseUp(); + Action = () => exitAction = true }); + var text = quitButton.Children.OfType().First(); + + // initial display AddUntilStep(() => text.IsPresent && !exitAction, "Text visible"); AddUntilStep(() => !text.IsPresent && !exitAction, "Text is not visible"); + AddStep("Trigger text fade in", () => InputManager.MoveMouseTo(quitButton)); + AddUntilStep(() => text.IsPresent && !exitAction, "Text visible"); + AddStep("Trigger text fade out", () => InputManager.MoveMouseTo(Vector2.One)); + AddUntilStep(() => !text.IsPresent && !exitAction, "Text is not visible"); + AddStep("Trigger exit action", () => { exitAction = false; - innerButton.TriggerOnMouseDown(); + InputManager.MoveMouseTo(quitButton); + InputManager.ButtonDown(MouseButton.Left); }); - AddUntilStep(() => exitAction, $"{nameof(quitButton.ExitAction)} was triggered"); + AddStep("Early release", () => InputManager.ButtonUp(MouseButton.Left)); + AddAssert("action not triggered", () => !exitAction); + + AddStep("Trigger exit action", () => InputManager.ButtonDown(MouseButton.Left)); + AddUntilStep(() => exitAction, $"{nameof(quitButton.Action)} was triggered"); } } } diff --git a/osu.Game/Graphics/Containers/HoldToCofirmContainer.cs b/osu.Game/Graphics/Containers/HoldToCofirmContainer.cs new file mode 100644 index 0000000000..eb2b2ca51b --- /dev/null +++ b/osu.Game/Graphics/Containers/HoldToCofirmContainer.cs @@ -0,0 +1,52 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; + +namespace osu.Game.Graphics.Containers +{ + public abstract class HoldToCofirmContainer : Container + { + public Action Action; + + private const int activate_delay = 400; + private const int fadeout_delay = 200; + + private bool fired; + private bool confirming; + + /// + /// Whether the overlay should be allowed to return from a fired state. + /// + protected virtual bool AllowMultipleFires => false; + + public Bindable Progress = new BindableDouble(); + + protected void BeginConfirm() + { + if (confirming || !AllowMultipleFires && fired) return; + + confirming = true; + + this.TransformBindableTo(Progress, 1, activate_delay * (1 - Progress.Value), Easing.Out).OnComplete(_ => Confirm()); + } + + protected virtual void Confirm() + { + Action?.Invoke(); + fired = true; + } + + protected void AbortConfirm() + { + if (!AllowMultipleFires && fired) return; + + confirming = false; + + this.TransformBindableTo(Progress, 0, fadeout_delay, Easing.Out); + } + } +} diff --git a/osu.Game/Overlays/HoldToConfirmOverlay.cs b/osu.Game/Overlays/HoldToConfirmOverlay.cs index a0e4bf1a39..afd3e2016f 100644 --- a/osu.Game/Overlays/HoldToConfirmOverlay.cs +++ b/osu.Game/Overlays/HoldToConfirmOverlay.cs @@ -1,11 +1,10 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.Containers; using OpenTK.Graphics; namespace osu.Game.Overlays @@ -14,22 +13,10 @@ namespace osu.Game.Overlays /// An overlay which will display a black screen that dims over a period before confirming an exit action. /// Action is BYO (derived class will need to call and from a user event). /// - public abstract class HoldToConfirmOverlay : Container + public abstract class HoldToConfirmOverlay : HoldToCofirmContainer { - public Action Action; - private Box overlay; - private const int activate_delay = 400; - private const int fadeout_delay = 200; - - private bool fired; - - /// - /// Whether the overlay should be allowed to return from a fired state. - /// - protected virtual bool AllowMultipleFires => false; - [BackgroundDependencyLoader] private void load() { @@ -45,22 +32,8 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.Both, } }; - } - protected void BeginConfirm() - { - if (!AllowMultipleFires && fired) return; - overlay.FadeIn(activate_delay * (1 - overlay.Alpha), Easing.Out).OnComplete(_ => - { - Action?.Invoke(); - fired = true; - }); - } - - protected void AbortConfirm() - { - if (!AllowMultipleFires && fired) return; - overlay.FadeOut(fadeout_delay, Easing.Out); + Progress.ValueChanged += v => overlay.Alpha = (float)v; } } } diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index 939966f0e5..867558ad93 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; using osu.Framework.MathUtils; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using OpenTK; @@ -21,10 +22,9 @@ namespace osu.Game.Screens.Play.HUD private readonly Button button; - public Action ExitAction + public Action Action { - get => button.ExitAction; - set => button.ExitAction = value; + set => button.Action = value; } private readonly OsuSpriteText text; @@ -73,88 +73,80 @@ namespace osu.Game.Screens.Play.HUD float adjust = Vector2.Distance(GetContainingInputManager().CurrentState.Mouse.NativeState.Position, button.ScreenSpaceDrawQuad.Centre) / 200; double elapsed = MathHelper.Clamp(Clock.ElapsedFrameTime, 0, 1000); - bool stayVisible = text.Alpha > 0 || button.Progress > 0 || IsHovered; + bool stayVisible = text.Alpha > 0 || button.Progress.Value > 0 || IsHovered; Alpha = stayVisible ? 1 : Interpolation.ValueAt(elapsed, Alpha, MathHelper.Clamp(1 - adjust, 0.04f, 1), 0, 200, Easing.OutQuint); } - private class Button : CircularContainer + private class Button : HoldToCofirmContainer { private SpriteIcon icon; private CircularProgress progress; private Circle innerCircle; - private bool triggered; - - public Action ExitAction { get; set; } - - public double Progress => progress.Current.Value; - - private const int fade_duration = 200; - private const int progress_duration = 600; - [BackgroundDependencyLoader] private void load(OsuColour colours) { - Masking = true; Size = new Vector2(60); - AddRange(new Drawable[] + + Child = new CircularContainer { - new Box + Masking = true, + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = colours.Gray1, - Alpha = 0.5f, - }, - progress = new CircularProgress - { - RelativeSizeAxes = Axes.Both, - InnerRadius = 1 - }, - innerCircle = new Circle - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Colour = colours.Gray1, - Size = new Vector2(0.9f), - }, - icon = new SpriteIcon - { - Shadow = false, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(15), - Icon = FontAwesome.fa_close - }, - }); + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + Alpha = 0.5f, + }, + progress = new CircularProgress + { + RelativeSizeAxes = Axes.Both, + InnerRadius = 1 + }, + innerCircle = new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + Size = new Vector2(0.9f), + }, + icon = new SpriteIcon + { + Shadow = false, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(15), + Icon = FontAwesome.fa_close + }, + } + }; + + Progress.BindTo(progress.Current); + Progress.ValueChanged += v => icon.Scale = new Vector2(1 + (float)v * 0.4f); + } + + protected override void Confirm() + { + base.Confirm(); + innerCircle.ScaleTo(0, 100).Then().FadeOut().ScaleTo(1).FadeIn(500); } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - if (state.Mouse.Buttons.Count > 1 || triggered) - return true; - - icon.ScaleTo(1.4f, progress_duration); - progress.FillTo(1, progress_duration, Easing.OutSine).OnComplete(_ => - { - innerCircle.ScaleTo(0, 100).Then().FadeOut().ScaleTo(1).FadeIn(500); - triggered = true; - ExitAction(); - }); - - return base.OnMouseDown(state, args); + if (state.Mouse.Buttons.Count == 1) + BeginConfirm(); + return true; } protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { - if (state.Mouse.Buttons.Count > 0 || triggered) - return true; - - icon.ScaleTo(1, 800, Easing.OutElastic); - progress.FillTo(0, progress_duration, Easing.OutQuint).OnComplete(cp => progress.Current.SetDefault()); - - return base.OnMouseUp(state, args); + if (state.Mouse.Buttons.Count == 0) + AbortConfirm(); + return true; } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 5fb3fb778c..37176aa327 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -219,7 +219,7 @@ namespace osu.Game.Screens.Play } }; - hudOverlay.HoldToQuit.ExitAction = Exit; + hudOverlay.HoldToQuit.Action = Exit; if (ShowStoryboard) initializeStoryboard(false); From 946a75ddb273bd84a71b1f3bce73dfed9dea7fe8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 02:05:08 +0900 Subject: [PATCH 213/229] Block hover to use UI cursor instead of gameplay cursor --- osu.Game/Screens/Play/HUD/QuitButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index 867558ad93..1533f6a9af 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Play.HUD protected override bool OnHover(InputState state) { text.FadeIn(500, Easing.OutQuint); - return base.OnHover(state); + return true; } protected override void OnHoverLost(InputState state) From 156d7fb25a15458e23fa8458a717fd33a856c359 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 02:08:21 +0900 Subject: [PATCH 214/229] Change depth of HUD Yes, this is intentional. --- osu.Game/Screens/Play/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 37176aa327..0150d76251 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -183,6 +183,7 @@ namespace osu.Game.Screens.Play ProcessCustomClock = false, Breaks = beatmap.Breaks }, + RulesetContainer.Cursor?.CreateProxy() ?? new Container(), hudOverlay = new HUDOverlay(scoreProcessor, RulesetContainer, working, offsetClock, adjustableClock) { Clock = Clock, // hud overlay doesn't want to use the audio clock directly @@ -190,7 +191,6 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre }, - RulesetContainer.Cursor?.CreateProxy() ?? new Container(), new SkipOverlay(firstObjectTime) { Clock = Clock, // skip button doesn't want to use the audio clock directly From 323aa189b63269329f5f32db31893859bf90e1ac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 02:08:44 +0900 Subject: [PATCH 215/229] Make on-confirmation animation more robust --- osu.Game/Screens/Play/HUD/QuitButton.cs | 31 +++++++++++++++++++++---- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index 1533f6a9af..d6060e01a3 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -81,9 +81,11 @@ namespace osu.Game.Screens.Play.HUD private class Button : HoldToCofirmContainer { private SpriteIcon icon; - private CircularProgress progress; + private CircularProgress circularProgress; private Circle innerCircle; + protected override bool AllowMultipleFires => true; + [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -101,7 +103,7 @@ namespace osu.Game.Screens.Play.HUD Colour = colours.Gray1, Alpha = 0.5f, }, - progress = new CircularProgress + circularProgress = new CircularProgress { RelativeSizeAxes = Axes.Both, InnerRadius = 1 @@ -125,19 +127,38 @@ namespace osu.Game.Screens.Play.HUD } }; - Progress.BindTo(progress.Current); + bind(); + } + + private void bind() + { + circularProgress.Current.BindTo(Progress); Progress.ValueChanged += v => icon.Scale = new Vector2(1 + (float)v * 0.4f); } + private bool pendingAnimation; + protected override void Confirm() { base.Confirm(); - innerCircle.ScaleTo(0, 100).Then().FadeOut().ScaleTo(1).FadeIn(500); + + // temporarily unbind as to not look weird during flash animation. + Progress.UnbindAll(); + pendingAnimation = true; + + innerCircle.ScaleTo(0, 100) + .Then().FadeOut().ScaleTo(1).FadeIn(500) + .OnComplete(a => circularProgress.FadeOut(100).OnComplete(_ => + { + bind(); + circularProgress.FadeIn(); + pendingAnimation = false; + })); } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - if (state.Mouse.Buttons.Count == 1) + if (!pendingAnimation && state.Mouse.Buttons.Count == 1) BeginConfirm(); return true; } From 5a892e4d082fa8042b053d2a870bd851226198af Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 02:09:52 +0900 Subject: [PATCH 216/229] This quit button don't quit --- osu.Game/Screens/Play/HUD/QuitButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index d6060e01a3..e829d26aab 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -38,7 +38,7 @@ namespace osu.Game.Screens.Play.HUD { text = new OsuSpriteText { - Text = "hold to quit", + Text = "hold for menu", Font = @"Exo2.0-Bold", Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft From 2ce2bd9788aabec4ca0db917a057c710f1ba9719 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 15:58:00 +0900 Subject: [PATCH 217/229] Add comment for pendingAnimation --- osu.Game/Screens/Play/HUD/QuitButton.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index e829d26aab..a26e0a2aae 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -144,6 +144,8 @@ namespace osu.Game.Screens.Play.HUD // temporarily unbind as to not look weird during flash animation. Progress.UnbindAll(); + + // avoid starting a new confirm call until we finish animating. pendingAnimation = true; innerCircle.ScaleTo(0, 100) From ef55c3c1971de6e7ed8e329223673c9bd11d701c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 15:58:17 +0900 Subject: [PATCH 218/229] Fix icon scale not resetting due to no implicit triggering --- osu.Game/Screens/Play/HUD/QuitButton.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index a26e0a2aae..defaf002b8 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -133,7 +133,9 @@ namespace osu.Game.Screens.Play.HUD private void bind() { circularProgress.Current.BindTo(Progress); + Progress.ValueChanged += v => icon.Scale = new Vector2(1 + (float)v * 0.4f); + Progress.TriggerChange(); } private bool pendingAnimation; From 58ae54574701520ce54cbc8065f254549a02c233 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 15:59:53 +0900 Subject: [PATCH 219/229] innerCircle -> overlayCircle --- osu.Game/Screens/Play/HUD/QuitButton.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index defaf002b8..2ee1b97136 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -82,7 +82,7 @@ namespace osu.Game.Screens.Play.HUD { private SpriteIcon icon; private CircularProgress circularProgress; - private Circle innerCircle; + private Circle overlayCircle; protected override bool AllowMultipleFires => true; @@ -108,7 +108,7 @@ namespace osu.Game.Screens.Play.HUD RelativeSizeAxes = Axes.Both, InnerRadius = 1 }, - innerCircle = new Circle + overlayCircle = new Circle { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -150,7 +150,7 @@ namespace osu.Game.Screens.Play.HUD // avoid starting a new confirm call until we finish animating. pendingAnimation = true; - innerCircle.ScaleTo(0, 100) + overlayCircle.ScaleTo(0, 100) .Then().FadeOut().ScaleTo(1).FadeIn(500) .OnComplete(a => circularProgress.FadeOut(100).OnComplete(_ => { From 8fbda9d57ea02add62558f60571a5e00f1442620 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 16:04:07 +0900 Subject: [PATCH 220/229] Improve comment --- osu.Game/Screens/Play/HUD/QuitButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index 2ee1b97136..bbd6075332 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -144,7 +144,7 @@ namespace osu.Game.Screens.Play.HUD { base.Confirm(); - // temporarily unbind as to not look weird during flash animation. + // temporarily unbind as to not look weird if releasing during confirm animation (can see the unwind of progress). Progress.UnbindAll(); // avoid starting a new confirm call until we finish animating. From 5f8eb6d8231cd2ab53f8d2031d372606406720eb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 16:04:36 +0900 Subject: [PATCH 221/229] Fix class name --- .../{HoldToCofirmContainer.cs => HoldToConfirmContainer.cs} | 2 +- osu.Game/Overlays/HoldToConfirmOverlay.cs | 2 +- osu.Game/Screens/Play/HUD/QuitButton.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename osu.Game/Graphics/Containers/{HoldToCofirmContainer.cs => HoldToConfirmContainer.cs} (95%) diff --git a/osu.Game/Graphics/Containers/HoldToCofirmContainer.cs b/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs similarity index 95% rename from osu.Game/Graphics/Containers/HoldToCofirmContainer.cs rename to osu.Game/Graphics/Containers/HoldToConfirmContainer.cs index eb2b2ca51b..adfc258f61 100644 --- a/osu.Game/Graphics/Containers/HoldToCofirmContainer.cs +++ b/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Graphics.Containers { - public abstract class HoldToCofirmContainer : Container + public abstract class HoldToConfirmContainer : Container { public Action Action; diff --git a/osu.Game/Overlays/HoldToConfirmOverlay.cs b/osu.Game/Overlays/HoldToConfirmOverlay.cs index afd3e2016f..7e2f6f5891 100644 --- a/osu.Game/Overlays/HoldToConfirmOverlay.cs +++ b/osu.Game/Overlays/HoldToConfirmOverlay.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays /// An overlay which will display a black screen that dims over a period before confirming an exit action. /// Action is BYO (derived class will need to call and from a user event). /// - public abstract class HoldToConfirmOverlay : HoldToCofirmContainer + public abstract class HoldToConfirmOverlay : HoldToConfirmContainer { private Box overlay; diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index bbd6075332..924c8d35ee 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -78,7 +78,7 @@ namespace osu.Game.Screens.Play.HUD Alpha = stayVisible ? 1 : Interpolation.ValueAt(elapsed, Alpha, MathHelper.Clamp(1 - adjust, 0.04f, 1), 0, 200, Easing.OutQuint); } - private class Button : HoldToCofirmContainer + private class Button : HoldToConfirmContainer { private SpriteIcon icon; private CircularProgress circularProgress; From babb7d5158d860123b00bb76c58d0a0d395df8c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 16:23:05 +0900 Subject: [PATCH 222/229] Fix white ring flash when holding button post-confirmation --- osu.Game/Screens/Play/HUD/QuitButton.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index 924c8d35ee..9f59d4164f 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -151,13 +151,16 @@ namespace osu.Game.Screens.Play.HUD pendingAnimation = true; overlayCircle.ScaleTo(0, 100) - .Then().FadeOut().ScaleTo(1).FadeIn(500) - .OnComplete(a => circularProgress.FadeOut(100).OnComplete(_ => - { - bind(); - circularProgress.FadeIn(); - pendingAnimation = false; - })); + .Then().FadeOut().ScaleTo(1).FadeIn(500) + .OnComplete(a => circularProgress.FadeOut(100).OnComplete(_ => + { + Progress.Value = 0; + + bind(); + + circularProgress.FadeIn(); + pendingAnimation = false; + })); } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) From 7b770d03c5b99a83434e636dc37ae08f71abb41b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 16:26:11 +0900 Subject: [PATCH 223/229] Use OnMouseMove instead of Update logic --- osu.Game/Screens/Play/HUD/QuitButton.cs | 47 ++++++++++++++++--------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index 9f59d4164f..8c59427edb 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Play.HUD { public class QuitButton : FillFlowContainer { - public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => button.ReceiveMouseInputAt(screenSpacePos); + public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true; private readonly Button button; @@ -43,7 +43,11 @@ namespace osu.Game.Screens.Play.HUD Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft }, - button = new Button() + button = new Button + { + HoverGained = () => text.FadeIn(500, Easing.OutQuint), + HoverLost = () => text.FadeOut(500, Easing.OutQuint) + } }; AutoSizeAxes = Axes.Both; } @@ -54,28 +58,24 @@ namespace osu.Game.Screens.Play.HUD base.LoadComplete(); } - protected override bool OnHover(InputState state) - { - text.FadeIn(500, Easing.OutQuint); - return true; - } + private float positionalAdjust; - protected override void OnHoverLost(InputState state) + protected override bool OnMouseMove(InputState state) { - text.FadeOut(500, Easing.OutQuint); - base.OnHoverLost(state); + positionalAdjust = Vector2.Distance(state.Mouse.NativeState.Position, button.ScreenSpaceDrawQuad.Centre) / 200; + return base.OnMouseMove(state); } protected override void Update() { base.Update(); - float adjust = Vector2.Distance(GetContainingInputManager().CurrentState.Mouse.NativeState.Position, button.ScreenSpaceDrawQuad.Centre) / 200; - double elapsed = MathHelper.Clamp(Clock.ElapsedFrameTime, 0, 1000); - - bool stayVisible = text.Alpha > 0 || button.Progress.Value > 0 || IsHovered; - - Alpha = stayVisible ? 1 : Interpolation.ValueAt(elapsed, Alpha, MathHelper.Clamp(1 - adjust, 0.04f, 1), 0, 200, Easing.OutQuint); + if (text.Alpha > 0 || button.Progress.Value > 0 || button.IsHovered) + Alpha = 1; + else + Alpha = Interpolation.ValueAt( + MathHelper.Clamp(Clock.ElapsedFrameTime, 0, 1000), + Alpha, MathHelper.Clamp(1 - positionalAdjust, 0.04f, 1), 0, 200, Easing.OutQuint); } private class Button : HoldToConfirmContainer @@ -86,6 +86,9 @@ namespace osu.Game.Screens.Play.HUD protected override bool AllowMultipleFires => true; + public Action HoverGained; + public Action HoverLost; + [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -163,6 +166,18 @@ namespace osu.Game.Screens.Play.HUD })); } + protected override bool OnHover(InputState state) + { + HoverGained?.Invoke(); + return true; + } + + protected override void OnHoverLost(InputState state) + { + HoverLost?.Invoke(); + base.OnHoverLost(state); + } + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { if (!pendingAnimation && state.Mouse.Buttons.Count == 1) From 436067c01f52c8a3f91c48637d86caef65f936d4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 16:44:37 +0900 Subject: [PATCH 224/229] Handle scale back in a nicer way --- osu.Game/Screens/Play/HUD/QuitButton.cs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index 8c59427edb..43a24a3ba8 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -136,9 +136,7 @@ namespace osu.Game.Screens.Play.HUD private void bind() { circularProgress.Current.BindTo(Progress); - - Progress.ValueChanged += v => icon.Scale = new Vector2(1 + (float)v * 0.4f); - Progress.TriggerChange(); + Progress.ValueChanged += v => icon.Scale = new Vector2(1 + (float)v * 0.2f); } private bool pendingAnimation; @@ -155,15 +153,19 @@ namespace osu.Game.Screens.Play.HUD overlayCircle.ScaleTo(0, 100) .Then().FadeOut().ScaleTo(1).FadeIn(500) - .OnComplete(a => circularProgress.FadeOut(100).OnComplete(_ => + .OnComplete(a => { - Progress.Value = 0; + icon.ScaleTo(1, 100); + circularProgress.FadeOut(100).OnComplete(_ => + { + Progress.Value = 0; - bind(); + bind(); - circularProgress.FadeIn(); - pendingAnimation = false; - })); + circularProgress.FadeIn(); + pendingAnimation = false; + }); + }); } protected override bool OnHover(InputState state) From d43e4af8ea2136d0b1a0be3f6edb3c5ac9c502cb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 16:45:42 +0900 Subject: [PATCH 225/229] Fix overlap between quit button at key input overlay --- osu.Game/Screens/Play/HUDOverlay.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index cba5c94266..f920b20649 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -52,15 +52,26 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { - KeyCounter = CreateKeyCounter(), ComboCounter = CreateComboCounter(), ScoreCounter = CreateScoreCounter(), AccuracyCounter = CreateAccuracyCounter(), HealthDisplay = CreateHealthDisplay(), Progress = CreateProgress(), - HoldToQuit = CreateQuitButton(), ModDisplay = CreateModsContainer(), - PlayerSettingsOverlay = CreatePlayerSettingsOverlay() + PlayerSettingsOverlay = CreatePlayerSettingsOverlay(), + new FillFlowContainer + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + Position = -new Vector2(5, TwoLayerButton.SIZE_RETRACTED.Y), + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + KeyCounter = CreateKeyCounter(), + HoldToQuit = CreateQuitButton(), + } + } } }); @@ -189,7 +200,6 @@ namespace osu.Game.Screens.Play Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, Margin = new MarginPadding(10), - Y = -TwoLayerButton.SIZE_RETRACTED.Y, }; protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6) @@ -211,7 +221,6 @@ namespace osu.Game.Screens.Play { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, - Position = new Vector2(-5, -70) }; protected virtual ModDisplay CreateModsContainer() => new ModDisplay From 39de807445eeb353a8843b93dfd6fc72c640ccd7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 May 2018 16:46:55 +0900 Subject: [PATCH 226/229] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index b4d5c766f5..eb076a3301 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit b4d5c766f5698540a7b1bbbae7290ac7dafc2813 +Subproject commit eb076a3301231eb73917073499051e49a9b12978 From 0e122468dba15da4f5932d224249b303cea07ea5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 22 May 2018 18:06:40 +0900 Subject: [PATCH 227/229] Fix progress easing to 0 if aborting after confirmation --- osu.Game/Screens/Play/HUD/QuitButton.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/QuitButton.cs b/osu.Game/Screens/Play/HUD/QuitButton.cs index 43a24a3ba8..d0aa0dad92 100644 --- a/osu.Game/Screens/Play/HUD/QuitButton.cs +++ b/osu.Game/Screens/Play/HUD/QuitButton.cs @@ -151,6 +151,8 @@ namespace osu.Game.Screens.Play.HUD // avoid starting a new confirm call until we finish animating. pendingAnimation = true; + Progress.Value = 0; + overlayCircle.ScaleTo(0, 100) .Then().FadeOut().ScaleTo(1).FadeIn(500) .OnComplete(a => @@ -158,8 +160,6 @@ namespace osu.Game.Screens.Play.HUD icon.ScaleTo(1, 100); circularProgress.FadeOut(100).OnComplete(_ => { - Progress.Value = 0; - bind(); circularProgress.FadeIn(); From 76fbc656a18587d3299c04b858a91b155c79eb99 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 22 May 2018 17:53:36 +0200 Subject: [PATCH 228/229] fix disclaimer allowing notifications --- osu.Game/Screens/Menu/Disclaimer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index 9a671cf780..b8cb7f2a4a 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -19,6 +19,7 @@ namespace osu.Game.Screens.Menu private Color4 iconColour; protected override bool HideOverlaysOnEnter => true; + protected override bool AllowOpeningOverlays => false; public override bool CursorVisible => false; From 0c0f86fe26ec1785b67d52d50d9ad4fa9d62c8d7 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Wed, 23 May 2018 16:23:03 +0200 Subject: [PATCH 229/229] fix incorrect default values keeping overlays in wrong state --- osu.Game/Screens/OsuScreen.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 4b1562291b..a188b7aa64 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -37,14 +37,14 @@ namespace osu.Game.Screens /// /// Whether overlays should be hidden when this screen is entered or resumed. /// - protected virtual bool HideOverlaysOnEnter => hideOverlaysOnEnter; + protected virtual bool HideOverlaysOnEnter => false; private readonly BindableBool allowOpeningOverlays = new BindableBool(); /// /// Whether overlays should be able to be opened while this screen is active. /// - protected virtual bool AllowOpeningOverlays => allowOpeningOverlays; + protected virtual bool AllowOpeningOverlays => true; /// /// Whether this allows the cursor to be displayed.