From f6e0e0bc38197ba9086b0e44a89e9da7f015dd42 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sat, 3 Jun 2017 19:21:21 +0200 Subject: [PATCH 001/483] add caps lock warning --- .../UserInterface/OsuPasswordTextBox.cs | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index 904aa14aa7..8ad3febf19 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -1,11 +1,14 @@ // Copyright (c) 2007-2017 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.Sprites; using OpenTK; using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Sprites; +using System; namespace osu.Game.Graphics.UserInterface { @@ -15,6 +18,14 @@ namespace osu.Game.Graphics.UserInterface public override bool AllowClipboardExport => false; + public OsuPasswordTextBox() + { + Add(new CapsWarning + { + TextSize = 20, + }); + } + public class PasswordMaskChar : Container { private readonly CircularContainer circle; @@ -51,5 +62,36 @@ namespace osu.Game.Graphics.UserInterface circle.ResizeTo(new Vector2(0.8f), 500, EasingTypes.OutQuint); } } + + private class CapsWarning : TextAwesome, IHasTooltip + { + public string TooltipText => Console.CapsLock ? @"Caps lock is active" : string.Empty; + + public override bool HandleInput => true; + + public CapsWarning() + { + Icon = FontAwesome.fa_warning; + Origin = Anchor.CentreRight; + Anchor = Anchor.CentreRight; + Margin = new MarginPadding { Right = 10 }; + AlwaysPresent = true; + Alpha = 0; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + Colour = colour.YellowLight; + } + + protected override void Update() + { + base.Update(); + updateVisibility(); + } + + private void updateVisibility() => FadeTo(Console.CapsLock ? 1 : 0, 250, EasingTypes.OutQuint); + } } } From a95ee7494f54b36929dbc7574b893adc199b47a8 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 8 Aug 2017 16:01:18 +0900 Subject: [PATCH 002/483] Initial conversion of taiko to use ScrollingPlayfield. --- .../Visual/TestCaseTaikoPlayfield.cs | 12 ++----- .../Objects/Drawables/DrawableBarLine.cs | 29 +++++---------- .../Objects/Drawables/DrawableDrumRoll.cs | 36 ++++++++----------- .../Objects/Drawables/DrawableDrumRollTick.cs | 5 --- .../Objects/Drawables/DrawableSwell.cs | 13 +++---- .../Drawables/DrawableTaikoHitObject.cs | 18 +--------- .../Drawables/Pieces/ElongatedCirclePiece.cs | 12 +------ osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 1 - .../Objects/TaikoHitObject.cs | 14 -------- .../UI/TaikoHitRenderer.cs | 4 +-- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 20 ++++------- 11 files changed, 41 insertions(+), 123 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs index 45be9e800d..f6ee2a5bf3 100644 --- a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs @@ -151,13 +151,9 @@ namespace osu.Desktop.Tests.Visual private void addBarLine(bool major, double delay = scroll_time) { - BarLine bl = new BarLine - { - StartTime = playfield.Time.Current + delay, - ScrollTime = scroll_time - }; + BarLine bl = new BarLine { StartTime = playfield.Time.Current + delay }; - playfield.AddBarLine(major ? new DrawableBarLineMajor(bl) : new DrawableBarLine(bl)); + playfield.Add(major ? new DrawableBarLineMajor(bl) : new DrawableBarLine(bl)); } private void addSwell(double duration = default_duration) @@ -166,7 +162,6 @@ namespace osu.Desktop.Tests.Visual { StartTime = playfield.Time.Current + scroll_time, Duration = duration, - ScrollTime = scroll_time })); } @@ -180,7 +175,6 @@ namespace osu.Desktop.Tests.Visual StartTime = playfield.Time.Current + scroll_time, IsStrong = strong, Duration = duration, - ScrollTime = scroll_time, }; playfield.Add(new DrawableDrumRoll(d)); @@ -191,7 +185,6 @@ namespace osu.Desktop.Tests.Visual Hit h = new Hit { StartTime = playfield.Time.Current + scroll_time, - ScrollTime = scroll_time, IsStrong = strong }; @@ -206,7 +199,6 @@ namespace osu.Desktop.Tests.Visual Hit h = new Hit { StartTime = playfield.Time.Current + scroll_time, - ScrollTime = scroll_time, IsStrong = strong }; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index 7507ee600e..f6959fb426 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -5,13 +5,16 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using OpenTK; +using osu.Game.Rulesets.Objects.Drawables; +using System; +using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { /// /// A line that scrolls alongside hit objects in the playfield and visualises control points. /// - public class DrawableBarLine : Container + public class DrawableBarLine : DrawableTaikoHitObject { /// /// The width of the line tracker. @@ -34,15 +37,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected readonly BarLine BarLine; public DrawableBarLine(BarLine barLine) + : base(barLine) { BarLine = barLine; - Anchor = Anchor.CentreLeft; - Origin = Anchor.Centre; - - RelativePositionAxes = Axes.X; RelativeSizeAxes = Axes.Y; - Width = tracker_width; Children = new[] @@ -56,24 +55,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Alpha = 0.75f } }; - - LifetimeStart = BarLine.StartTime - BarLine.ScrollTime * 2; - LifetimeEnd = BarLine.StartTime + BarLine.ScrollTime; } - protected override void LoadComplete() + protected override TaikoPiece CreateMainPiece() => new TaikoPiece(); + + protected override void UpdateState(ArmedState state) { - base.LoadComplete(); - this.Delay(BarLine.StartTime - Time.Current).FadeOut(base_fadeout_time * BarLine.ScrollTime / 1000); - } - - private void updateScrollPosition(double time) => this.MoveToX((float)((BarLine.StartTime - time) / BarLine.ScrollTime)); - - protected override void Update() - { - base.Update(); - - updateScrollPosition(Time.Current); } } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 74f0f2326d..e9c50dacf8 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -11,6 +11,7 @@ using OpenTK; using OpenTK.Graphics; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -34,27 +35,29 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables RelativeSizeAxes = Axes.Y; AutoSizeAxes = Axes.X; + Width = (float)HitObject.Duration; + + Container tickContainer; + MainPiece.Add(tickContainer = new Container + { + RelativeSizeAxes = Axes.Both, + RelativeChildOffset = new Vector2((float)HitObject.StartTime, 0), + RelativeChildSize = new Vector2((float)HitObject.Duration, 1) + }); + foreach (var tick in drumRoll.Ticks) { - var newTick = new DrawableDrumRollTick(tick) - { - X = (float)((tick.StartTime - HitObject.StartTime) / HitObject.Duration) - }; - + var newTick = new DrawableDrumRollTick(tick) { X = (float)tick.StartTime }; newTick.OnJudgement += onTickJudgement; AddNested(newTick); - MainPiece.Add(newTick); + tickContainer.Add(newTick); } } protected override TaikoJudgement CreateJudgement() => new TaikoJudgement { SecondHit = HitObject.IsStrong }; - protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece - { - Length = (float)(HitObject.Duration / HitObject.ScrollTime), - PlayfieldLengthReference = () => Parent.DrawSize.X - }; + protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece(); [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -63,17 +66,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables accentDarkColour = colours.YellowDarker; } - protected override void LoadComplete() - { - base.LoadComplete(); - - // This is naive, however it's based on the reasoning that the hit target - // is further than mid point of the play field, so the time taken to scroll in should always - // be greater than the time taken to scroll out to the left of the screen. - // Thus, using PreEmpt here is enough for the drum roll to completely scroll out. - LifetimeEnd = HitObject.EndTime + HitObject.ScrollTime; - } - private void onTickJudgement(DrawableHitObject obj) { if (obj.Judgement.Result == HitResult.Hit) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 0e1cd05de3..ad065395b9 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -47,11 +47,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } - protected override void UpdateScrollPosition(double time) - { - // Ticks don't move - } - protected override bool HandleKeyPress(Key key) { return Judgement.Result == HitResult.None && UpdateJudgement(true); diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index e861af03cf..f704879f1a 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -118,7 +118,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables }); MainPiece.Add(symbol = new SwellSymbolPiece()); - } [BackgroundDependencyLoader] @@ -189,20 +188,22 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Expire(); } - protected override void UpdateScrollPosition(double time) + protected override void Update() { - // Make the swell stop at the hit target - double t = Math.Min(HitObject.StartTime, time); + base.Update(); + // Make the swell stop at the hit target + X = (float)Math.Max(Time.Current, HitObject.StartTime); + + double t = Math.Min(HitObject.StartTime, Time.Current); if (t == HitObject.StartTime && !hasStarted) { OnStart?.Invoke(); hasStarted = true; } - - base.UpdateScrollPosition(t); } + protected override bool HandleKeyPress(Key key) { if (Judgement.Result != HitResult.None) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 510994ed70..caae70fe05 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -12,7 +12,7 @@ using OpenTK.Input; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public abstract class DrawableTaikoHitObject : DrawableHitObject + public abstract class DrawableTaikoHitObject : DrawableScrollingHitObject where TaikoHitType : TaikoHitObject { /// @@ -38,30 +38,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables RelativeSizeAxes = Axes.Both; Size = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE); - RelativePositionAxes = Axes.X; - Add(MainPiece = CreateMainPiece()); MainPiece.KiaiMode = HitObject.Kiai; - - LifetimeStart = HitObject.StartTime - HitObject.ScrollTime * 2; } protected override TaikoJudgement CreateJudgement() => new TaikoJudgement(); protected virtual TaikoPiece CreateMainPiece() => new CirclePiece(); - /// - /// Sets the scroll position of the DrawableHitObject relative to the offset between - /// a time value and the HitObject's StartTime. - /// - /// - protected virtual void UpdateScrollPosition(double time) => X = (float)((HitObject.StartTime - time) / HitObject.ScrollTime); - - protected override void Update() - { - UpdateScrollPosition(Time.Current); - } - protected virtual bool HandleKeyPress(Key key) => false; protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs index 2f5b4eefd6..d3786a4324 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs @@ -8,16 +8,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces { public class ElongatedCirclePiece : CirclePiece { - /// - /// As we are being used to define the absolute size of hits, we need to be given a relative reference of our containing playfield container. - /// - public Func PlayfieldLengthReference; - - /// - /// The length of this piece as a multiple of the value returned by - /// - public float Length; - public ElongatedCirclePiece() { RelativeSizeAxes = Axes.Y; @@ -35,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces Right = padding, }; - Width = (PlayfieldLengthReference?.Invoke() ?? 0) * Length + DrawHeight; + Width = Parent.DrawSize.X + DrawHeight; } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index fd9daa269c..526d23f51a 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -80,7 +80,6 @@ namespace osu.Game.Rulesets.Taiko.Objects ret.Add(new DrumRollTick { FirstTick = first, - ScrollTime = ScrollTime, TickSpacing = tickSpacing, StartTime = t, IsStrong = IsStrong, diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs index 7e7dc3662f..f1c0afc675 100644 --- a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs @@ -24,16 +24,6 @@ namespace osu.Game.Rulesets.Taiko.Objects /// public const float DEFAULT_STRONG_SIZE = DEFAULT_SIZE * STRONG_SCALE; - /// - /// The time taken from the initial (off-screen) spawn position to the centre of the hit target for a of 1000ms. - /// - private const double scroll_time = 6000; - - /// - /// Our adjusted taking into consideration local and other speed multipliers. - /// - public double ScrollTime; - /// /// Whether this HitObject is a "strong" type. /// Strong hit objects give more points for hitting the hit object with both keys. @@ -49,12 +39,8 @@ namespace osu.Game.Rulesets.Taiko.Objects { base.ApplyDefaults(controlPointInfo, difficulty); - TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); - DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime); EffectControlPoint effectPoint = controlPointInfo.EffectPointAt(StartTime); - ScrollTime = scroll_time * (timingPoint.BeatLength * difficultyPoint.SpeedMultiplier / 1000) / difficulty.SliderMultiplier; - Kiai |= effectPoint.KiaiMode; } } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoHitRenderer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoHitRenderer.cs index 570b4be488..9c9c71ab46 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoHitRenderer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoHitRenderer.cs @@ -21,7 +21,7 @@ using System.Linq; namespace osu.Game.Rulesets.Taiko.UI { - public class TaikoHitRenderer : HitRenderer + public class TaikoHitRenderer : ScrollingHitRenderer { public TaikoHitRenderer(WorkingBeatmap beatmap, bool isForCurrentRuleset) : base(beatmap, isForCurrentRuleset) @@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Taiko.UI barLine.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.Difficulty); bool isMajor = currentBeat % (int)currentPoint.TimeSignature == 0; - taikoPlayfield.AddBarLine(isMajor ? new DrawableBarLineMajor(barLine) : new DrawableBarLine(barLine)); + taikoPlayfield.Add(isMajor ? new DrawableBarLineMajor(barLine) : new DrawableBarLine(barLine)); double bl = currentPoint.BeatLength; if (bl < 800) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index dca339f734..d94b69f141 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -18,7 +18,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.UI { - public class TaikoPlayfield : Playfield + public class TaikoPlayfield : ScrollingPlayfield { /// /// Default height of a when inside a . @@ -35,14 +35,14 @@ namespace osu.Game.Rulesets.Taiko.UI /// private const float left_area_size = 240; - protected override Container Content => hitObjectContainer; private readonly Container hitExplosionContainer; private readonly Container kiaiExplosionContainer; - private readonly Container barLineContainer; private readonly Container judgementContainer; - private readonly Container hitObjectContainer; + protected override Container Content => content; + private readonly Container content; + private readonly Container topLevelHitContainer; private readonly Container overlayBackgroundContainer; @@ -52,6 +52,7 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Box background; public TaikoPlayfield() + : base(Axes.X) { AddRangeInternal(new Drawable[] { @@ -96,10 +97,6 @@ namespace osu.Game.Rulesets.Taiko.UI FillMode = FillMode.Fit, BlendingMode = BlendingMode.Additive, }, - barLineContainer = new Container - { - RelativeSizeAxes = Axes.Both, - }, new HitTarget { Anchor = Anchor.CentreLeft, @@ -107,7 +104,7 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit }, - hitObjectContainer = new Container + content = new Container { RelativeSizeAxes = Axes.Both, }, @@ -205,11 +202,6 @@ namespace osu.Game.Rulesets.Taiko.UI swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy()); } - public void AddBarLine(DrawableBarLine barLine) - { - barLineContainer.Add(barLine); - } - public override void OnJudgement(DrawableHitObject judgedObject) { bool wasHit = judgedObject.Judgement.Result == HitResult.Hit; From 3d4db427ff36912220337fbc90bb440d4215b2d5 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Tue, 8 Aug 2017 17:17:53 +0200 Subject: [PATCH 003/483] Pass RuleSet to ScoreStore, compute and store MD5 for legacy replays compatibility --- osu.Game/Beatmaps/BeatmapInfo.cs | 2 ++ osu.Game/Beatmaps/BeatmapManager.cs | 1 + osu.Game/OsuGameBase.cs | 2 +- osu.Game/Rulesets/Scoring/ScoreStore.cs | 2 +- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index ec90cabf02..578b37ea17 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -52,6 +52,8 @@ namespace osu.Game.Beatmaps [JsonProperty("file_md5")] public string Hash { get; set; } + public string MD5Hash { get; set; } + // General public int AudioLeadIn { get; set; } public bool Countdown { get; set; } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index bbb6c975d0..51c1b698ce 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -367,6 +367,7 @@ namespace osu.Game.Beatmaps beatmap.BeatmapInfo.Path = name; beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash(); + beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash(); // TODO: Diff beatmap metadata with set metadata and leave it here if necessary beatmap.BeatmapInfo.Metadata = null; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 0dec4228de..2855c75ef1 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -103,7 +103,7 @@ namespace osu.Game dependencies.Cache(RulesetStore = new RulesetStore(connection)); dependencies.Cache(FileStore = new FileStore(connection, Host.Storage)); dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host)); - dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager)); + dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager, RulesetStore)); dependencies.Cache(new OsuColour()); //this completely overrides the framework default. will need to change once we make a proper FontStore. diff --git a/osu.Game/Rulesets/Scoring/ScoreStore.cs b/osu.Game/Rulesets/Scoring/ScoreStore.cs index e69fec4b54..c6421522b4 100644 --- a/osu.Game/Rulesets/Scoring/ScoreStore.cs +++ b/osu.Game/Rulesets/Scoring/ScoreStore.cs @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Scoring var version = sr.ReadInt32(); /* score.FileChecksum = */ var beatmapHash = sr.ReadString(); - score.Beatmap = beatmaps.QueryBeatmap(b => b.Hash == beatmapHash); + score.Beatmap = beatmaps.QueryBeatmap(b => b.MD5Hash == beatmapHash); /* score.PlayerName = */ sr.ReadString(); /* var localScoreChecksum = */ From 27e63eb7c4d2947e8acec044b189349102593bd4 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 9 Aug 2017 10:54:00 +0900 Subject: [PATCH 004/483] Fix up sizing issues. --- osu-framework | 2 +- .../Objects/Drawables/DrawableBarLine.cs | 8 ++++++-- .../Objects/Drawables/DrawableDrumRoll.cs | 3 --- .../Objects/Drawables/DrawableDrumRollTick.cs | 8 ++++++++ osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs | 8 ++++++++ .../Objects/Drawables/DrawableSwell.cs | 8 ++++++++ 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/osu-framework b/osu-framework index dd0daafcfc..3b858d078c 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit dd0daafcfc0d625bb588c8e12d7db58bc00c255e +Subproject commit 3b858d078cf54465d9af8e2bb9e1a144bcfcdbf4 diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index f6959fb426..28f0af4aba 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -8,13 +8,14 @@ using OpenTK; using osu.Game.Rulesets.Objects.Drawables; using System; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; +using osu.Game.Rulesets.Taiko.Judgements; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { /// /// A line that scrolls alongside hit objects in the playfield and visualises control points. /// - public class DrawableBarLine : DrawableTaikoHitObject + public class DrawableBarLine : DrawableScrollingHitObject { /// /// The width of the line tracker. @@ -41,6 +42,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { BarLine = barLine; + Anchor = Anchor.CentreLeft; + Origin = Anchor.Centre; + RelativeSizeAxes = Axes.Y; Width = tracker_width; @@ -57,7 +61,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables }; } - protected override TaikoPiece CreateMainPiece() => new TaikoPiece(); + protected override TaikoJudgement CreateJudgement() => new TaikoJudgement(); protected override void UpdateState(ArmedState state) { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index e9c50dacf8..425f87752f 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -32,9 +32,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public DrawableDrumRoll(DrumRoll drumRoll) : base(drumRoll) { - RelativeSizeAxes = Axes.Y; - AutoSizeAxes = Axes.X; - Width = (float)HitObject.Duration; Container tickContainer; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index ad065395b9..5a6abd24b1 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -18,6 +18,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables FillMode = FillMode.Fit; } + protected override void LoadComplete() + { + base.LoadComplete(); + + // We need to set this here because RelativeSizeAxes won't/can't set our size by default with a different RelativeChildSize + Width *= Parent.RelativeChildSize.X; + } + protected override TaikoPiece CreateMainPiece() => new TickPiece { Filled = HitObject.FirstTick diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 5a17355cdb..0666d75083 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -29,6 +29,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables FillMode = FillMode.Fit; } + protected override void LoadComplete() + { + base.LoadComplete(); + + // We need to set this here because RelativeSizeAxes won't/can't set our size by default with a different RelativeChildSize + Width *= Parent.RelativeChildSize.X; + } + protected override void CheckJudgement(bool userTriggered) { if (!userTriggered) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index f704879f1a..2b1ed07da7 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -128,6 +128,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables targetRing.BorderColour = colours.YellowDark.Opacity(0.25f); } + protected override void LoadComplete() + { + base.LoadComplete(); + + // We need to set this here because RelativeSizeAxes won't/can't set our size by default with a different RelativeChildSize + Width *= Parent.RelativeChildSize.X; + } + protected override void CheckJudgement(bool userTriggered) { if (userTriggered) From a751c19cf73d8915fb551ceb9d6fbb90ff9721a3 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Wed, 9 Aug 2017 08:36:15 +0200 Subject: [PATCH 005/483] Moved JsonProperty file_md5 and added file_sha2 --- osu.Game/Beatmaps/BeatmapInfo.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 578b37ea17..432da57a5c 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -49,9 +49,10 @@ namespace osu.Game.Beatmaps public string Path { get; set; } - [JsonProperty("file_md5")] + [JsonProperty("file_sha2")] public string Hash { get; set; } + [JsonProperty("file_md5")] public string MD5Hash { get; set; } // General From d83c218e08155add50e570246f09e84ebdf0d6a5 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 9 Aug 2017 16:19:09 +0900 Subject: [PATCH 006/483] Remove various scrolling container optimisations (removing when not alive). --- .../Drawables/DrawableScrollingHitObject.cs | 2 ++ osu.Game/Rulesets/Timing/ScrollingContainer.cs | 2 ++ .../Rulesets/Timing/SpeedAdjustmentContainer.cs | 2 ++ osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 17 +++++++++-------- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs index f67dd4dfea..a7c4dd0333 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs @@ -32,6 +32,8 @@ namespace osu.Game.Rulesets.Objects.Drawables } } + public override bool RemoveWhenNotAlive => false; + protected DrawableScrollingHitObject(TObject hitObject) : base(hitObject) { diff --git a/osu.Game/Rulesets/Timing/ScrollingContainer.cs b/osu.Game/Rulesets/Timing/ScrollingContainer.cs index 843f307d0d..9bb32ead77 100644 --- a/osu.Game/Rulesets/Timing/ScrollingContainer.cs +++ b/osu.Game/Rulesets/Timing/ScrollingContainer.cs @@ -27,6 +27,8 @@ namespace osu.Game.Rulesets.Timing /// internal Axes ScrollingAxes; + public override bool RemoveWhenNotAlive => false; + /// /// The control point that defines the speed adjustments for this container. This is set by the . /// diff --git a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs index 9d5f49e155..5d6c03b9de 100644 --- a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs +++ b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs @@ -34,6 +34,8 @@ namespace osu.Game.Rulesets.Timing /// public Axes ScrollingAxes { get; internal set; } + public override bool RemoveWhenNotAlive => false; + /// /// The that defines the speed adjustments. /// diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 66ca2dd7c4..f8e090d613 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -7,6 +7,7 @@ using System.Linq; using OpenTK.Input; using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Transforms; using osu.Framework.Input; using osu.Framework.MathUtils; @@ -154,7 +155,7 @@ namespace osu.Game.Rulesets.UI /// Hit objects that are to be re-processed on the next update. /// private readonly List queuedHitObjects = new List(); - private readonly List speedAdjustments = new List(); + private readonly Container speedAdjustments; private readonly Axes scrollingAxes; @@ -165,6 +166,8 @@ namespace osu.Game.Rulesets.UI public ScrollingHitObjectContainer(Axes scrollingAxes) { this.scrollingAxes = scrollingAxes; + + AddInternal(speedAdjustments = new Container { RelativeSizeAxes = Axes.Both }); } /// @@ -176,9 +179,7 @@ namespace osu.Game.Rulesets.UI speedAdjustment.ScrollingAxes = scrollingAxes; speedAdjustment.VisibleTimeRange.BindTo(VisibleTimeRange); speedAdjustment.Reversed.BindTo(Reversed); - speedAdjustments.Add(speedAdjustment); - AddInternal(speedAdjustment); } public override IEnumerable Objects => speedAdjustments.SelectMany(s => s.Children); @@ -210,11 +211,11 @@ namespace osu.Game.Rulesets.UI var hitObject = queuedHitObjects[i]; var target = adjustmentContainerFor(hitObject); - if (target != null) - { - target.Add(hitObject); - queuedHitObjects.RemoveAt(i); - } + if (target == null) + continue; + + target.Add(hitObject); + queuedHitObjects.RemoveAt(i); } } From 88cefa77bd69ec637afbfaf6dddf1614e9fd9e8d Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 9 Aug 2017 16:19:20 +0900 Subject: [PATCH 007/483] Make TestCaseTaikoPlayfield work again. --- .../Visual/TestCaseTaikoPlayfield.cs | 64 +++++++++++++------ 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs index f6ee2a5bf3..1589ca8f9b 100644 --- a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs @@ -14,6 +14,9 @@ using osu.Game.Rulesets.Taiko.UI; using OpenTK; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps; +using osu.Desktop.Tests.Beatmaps; +using System.Collections.Generic; +using osu.Game.Rulesets.Objects; namespace osu.Desktop.Tests.Visual { @@ -27,7 +30,7 @@ namespace osu.Desktop.Tests.Visual protected override double TimePerAction => default_duration * 2; private readonly Random rng = new Random(1337); - private readonly TaikoPlayfield playfield; + private readonly TaikoRulesetContainer rulesetContainer; private readonly Container playfieldContainer; public TestCaseTaikoPlayfield() @@ -51,7 +54,29 @@ namespace osu.Desktop.Tests.Visual AddStep("Height test 5", () => changePlayfieldSize(5)); AddStep("Reset height", () => changePlayfieldSize(6)); - var rateAdjustClock = new StopwatchClock(true) { Rate = 1 }; + var controlPointInfo = new ControlPointInfo(); + controlPointInfo.TimingPoints.Add(new TimingControlPoint + { + BeatLength = 200 + }); + + WorkingBeatmap beatmap = new TestWorkingBeatmap(new Beatmap + { + HitObjects = new List { new CentreHit() }, + BeatmapInfo = new BeatmapInfo + { + Difficulty = new BeatmapDifficulty(), + Metadata = new BeatmapMetadata + { + Artist = @"Unknown", + Title = @"Sample Beatmap", + Author = @"peppy", + }, + }, + ControlPointInfo = controlPointInfo + }); + + var rateAdjustClock = new StopwatchClock(true) { Rate = 0.1 }; Add(playfieldContainer = new Container { @@ -60,10 +85,7 @@ namespace osu.Desktop.Tests.Visual RelativeSizeAxes = Axes.X, Height = TaikoPlayfield.DEFAULT_HEIGHT, Clock = new FramedClock(rateAdjustClock), - Children = new[] - { - playfield = new TaikoPlayfield() - } + Children = new[] { rulesetContainer = new TaikoRulesetContainer(null, beatmap, true) } }); } @@ -128,18 +150,18 @@ namespace osu.Desktop.Tests.Visual } }; - playfield.OnJudgement(h); + rulesetContainer.Playfield.OnJudgement(h); if (RNG.Next(10) == 0) { h.Judgement.SecondHit = true; - playfield.OnJudgement(h); + rulesetContainer.Playfield.OnJudgement(h); } } private void addMissJudgement() { - playfield.OnJudgement(new DrawableTestHit(new Hit()) + rulesetContainer.Playfield.OnJudgement(new DrawableTestHit(new Hit()) { Judgement = new TaikoJudgement { @@ -151,16 +173,16 @@ namespace osu.Desktop.Tests.Visual private void addBarLine(bool major, double delay = scroll_time) { - BarLine bl = new BarLine { StartTime = playfield.Time.Current + delay }; + BarLine bl = new BarLine { StartTime = rulesetContainer.Playfield.Time.Current + delay }; - playfield.Add(major ? new DrawableBarLineMajor(bl) : new DrawableBarLine(bl)); + rulesetContainer.Playfield.Add(major ? new DrawableBarLineMajor(bl) : new DrawableBarLine(bl)); } private void addSwell(double duration = default_duration) { - playfield.Add(new DrawableSwell(new Swell + rulesetContainer.Playfield.Add(new DrawableSwell(new Swell { - StartTime = playfield.Time.Current + scroll_time, + StartTime = rulesetContainer.Playfield.Time.Current + scroll_time, Duration = duration, })); } @@ -172,40 +194,40 @@ namespace osu.Desktop.Tests.Visual var d = new DrumRoll { - StartTime = playfield.Time.Current + scroll_time, + StartTime = rulesetContainer.Playfield.Time.Current + scroll_time, IsStrong = strong, Duration = duration, }; - playfield.Add(new DrawableDrumRoll(d)); + rulesetContainer.Playfield.Add(new DrawableDrumRoll(d)); } private void addCentreHit(bool strong) { Hit h = new Hit { - StartTime = playfield.Time.Current + scroll_time, + StartTime = rulesetContainer.Playfield.Time.Current + scroll_time, IsStrong = strong }; if (strong) - playfield.Add(new DrawableCentreHitStrong(h)); + rulesetContainer.Playfield.Add(new DrawableCentreHitStrong(h)); else - playfield.Add(new DrawableCentreHit(h)); + rulesetContainer.Playfield.Add(new DrawableCentreHit(h)); } private void addRimHit(bool strong) { Hit h = new Hit { - StartTime = playfield.Time.Current + scroll_time, + StartTime = rulesetContainer.Playfield.Time.Current + scroll_time, IsStrong = strong }; if (strong) - playfield.Add(new DrawableRimHitStrong(h)); + rulesetContainer.Playfield.Add(new DrawableRimHitStrong(h)); else - playfield.Add(new DrawableRimHit(h)); + rulesetContainer.Playfield.Add(new DrawableRimHit(h)); } private class DrawableTestHit : DrawableHitObject From 8b4f28318f5e45a365f27efaad51e79ff39bc438 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 9 Aug 2017 16:19:31 +0900 Subject: [PATCH 008/483] Fix drum roll ticks. --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs | 2 +- .../Objects/Drawables/DrawableDrumRollTick.cs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 425f87752f..8f81368a2c 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables foreach (var tick in drumRoll.Ticks) { - var newTick = new DrawableDrumRollTick(tick) { X = (float)tick.StartTime }; + var newTick = new DrawableDrumRollTick(tick); newTick.OnJudgement += onTickJudgement; AddNested(newTick); diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 5a6abd24b1..6e916aa9d5 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -15,6 +15,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public DrawableDrumRollTick(DrumRollTick tick) : base(tick) { + // Because ticks aren't added by the ScrollingPlayfield, we need to set the following properties ourselves + RelativePositionAxes = Axes.X; + X = (float)tick.StartTime; + FillMode = FillMode.Fit; } From 7237f834c4e1144bef0c38627cc6b2d02dc49922 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 9 Aug 2017 16:39:19 +0900 Subject: [PATCH 009/483] Update framework. --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 67d89a3601..9bad670471 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 67d89a36016f98c0ede576b859a2ccafe114fce8 +Subproject commit 9bad670471a03e299760315fd9d3fa9a726f6233 From 2334c109e5262514970e54ab34a626d94d0aff52 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 9 Aug 2017 16:46:08 +0900 Subject: [PATCH 010/483] Set better TaikoPlayfield default VisibleTimeRange. --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index e2823ccdfe..da86c31123 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -178,6 +178,8 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, } }); + + VisibleTimeRange.Value = 6000; } [BackgroundDependencyLoader] From 0c1b68d7111a2e5da1d4bb073db1f3ccf374b2ff Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 9 Aug 2017 16:46:22 +0900 Subject: [PATCH 011/483] Fix up TestCaseTaikoPlayfield. --- osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs index 1589ca8f9b..43148da512 100644 --- a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs @@ -55,10 +55,7 @@ namespace osu.Desktop.Tests.Visual AddStep("Reset height", () => changePlayfieldSize(6)); var controlPointInfo = new ControlPointInfo(); - controlPointInfo.TimingPoints.Add(new TimingControlPoint - { - BeatLength = 200 - }); + controlPointInfo.TimingPoints.Add(new TimingControlPoint()); WorkingBeatmap beatmap = new TestWorkingBeatmap(new Beatmap { @@ -76,14 +73,14 @@ namespace osu.Desktop.Tests.Visual ControlPointInfo = controlPointInfo }); - var rateAdjustClock = new StopwatchClock(true) { Rate = 0.1 }; + var rateAdjustClock = new StopwatchClock(true) { Rate = 1 }; Add(playfieldContainer = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.X, - Height = TaikoPlayfield.DEFAULT_HEIGHT, + Height = 768, Clock = new FramedClock(rateAdjustClock), Children = new[] { rulesetContainer = new TaikoRulesetContainer(null, beatmap, true) } }); From e9a98358b3d47ad6708e39a9ad9f0ea71adf7030 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 9 Aug 2017 17:26:59 +0900 Subject: [PATCH 012/483] Don't move completed drum rolls above the playfield. --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index da86c31123..eb9e41f771 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -224,7 +224,7 @@ namespace osu.Game.Rulesets.Taiko.UI if (!secondHit) { - if (judgedObject.X >= -0.05f && !(judgedObject is DrawableSwell)) + if (judgedObject.X >= -0.05f && judgedObject is DrawableHit) { // If we're far enough away from the left stage, we should bring outselves in front of it topLevelHitContainer.Add(judgedObject.CreateProxy()); From bb8c5338022cd6d1313ec64750930917cccb523e Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 9 Aug 2017 17:34:09 +0900 Subject: [PATCH 013/483] Fix CI issues. --- .../Objects/Drawables/DrawableBarLine.cs | 3 --- .../Objects/Drawables/Pieces/ElongatedCirclePiece.cs | 1 - osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs | 7 +------ 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index 28f0af4aba..06702e8141 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -2,12 +2,9 @@ // 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 OpenTK; using osu.Game.Rulesets.Objects.Drawables; -using System; -using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using osu.Game.Rulesets.Taiko.Judgements; namespace osu.Game.Rulesets.Taiko.Objects.Drawables diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs index d3786a4324..4642e318c4 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using osu.Framework.Graphics; namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index 36ee0c2a1d..723af3e4e9 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -36,11 +36,6 @@ namespace osu.Game.Rulesets.Taiko.UI private void loadBarLines() { - var taikoPlayfield = Playfield as TaikoPlayfield; - - if (taikoPlayfield == null) - return; - TaikoHitObject lastObject = Beatmap.HitObjects[Beatmap.HitObjects.Count - 1]; double lastHitTime = 1 + (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime; @@ -72,7 +67,7 @@ namespace osu.Game.Rulesets.Taiko.UI barLine.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.Difficulty); bool isMajor = currentBeat % (int)currentPoint.TimeSignature == 0; - taikoPlayfield.Add(isMajor ? new DrawableBarLineMajor(barLine) : new DrawableBarLine(barLine)); + Playfield.Add(isMajor ? new DrawableBarLineMajor(barLine) : new DrawableBarLine(barLine)); double bl = currentPoint.BeatLength; if (bl < 800) From c0642ad6d3b438761412e28649fa5437ea8d2bb5 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Wed, 9 Aug 2017 10:54:03 +0200 Subject: [PATCH 014/483] Added database migration --- osu-framework | 2 +- osu-resources | 2 +- osu.Game/Beatmaps/BeatmapStore.cs | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/osu-framework b/osu-framework index 107c551767..9bad670471 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 107c5517670ca88dbe8c83a97e37e99ac5742ee6 +Subproject commit 9bad670471a03e299760315fd9d3fa9a726f6233 diff --git a/osu-resources b/osu-resources index 76656c51f2..f6042e1cb3 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit 76656c51f281e7934159e9ed4414378fef24d130 +Subproject commit f6042e1cb37cfad6c879d0e1245f7880c7fcd5f5 diff --git a/osu.Game/Beatmaps/BeatmapStore.cs b/osu.Game/Beatmaps/BeatmapStore.cs index 2ec9a7d759..d717a46a24 100644 --- a/osu.Game/Beatmaps/BeatmapStore.cs +++ b/osu.Game/Beatmaps/BeatmapStore.cs @@ -20,7 +20,7 @@ namespace osu.Game.Beatmaps /// The current version of this store. Used for migrations (see ). /// The initial version is 1. /// - protected override int StoreVersion => 2; + protected override int StoreVersion => 3; public BeatmapStore(SQLiteConnection connection) : base(connection) @@ -77,6 +77,10 @@ namespace osu.Game.Beatmaps // cannot migrate; breaking underlying changes. Reset(); break; + case 3: + // Added MD5Hash column to BeatmapInfo + Connection.CreateCommand("ALTER TABLE BeatmapInfo ADD COLUMN MD5Hash varchar").ExecuteNonQuery(); + break; } } } From 8dd4f513e717ebf638ca46b3c6139643f0557f36 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Wed, 9 Aug 2017 11:55:36 +0200 Subject: [PATCH 015/483] Symplified migration using MigrateTable<> instead of commands --- osu.Game/Beatmaps/BeatmapStore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapStore.cs b/osu.Game/Beatmaps/BeatmapStore.cs index d717a46a24..8212712bf9 100644 --- a/osu.Game/Beatmaps/BeatmapStore.cs +++ b/osu.Game/Beatmaps/BeatmapStore.cs @@ -79,7 +79,7 @@ namespace osu.Game.Beatmaps break; case 3: // Added MD5Hash column to BeatmapInfo - Connection.CreateCommand("ALTER TABLE BeatmapInfo ADD COLUMN MD5Hash varchar").ExecuteNonQuery(); + Connection.MigrateTable(); break; } } From e48c5898bd8f59f98e95b92f28cd9a699ce56370 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 11 Aug 2017 17:26:30 +0930 Subject: [PATCH 016/483] Ensure the Track for the selected beatmap is added to the TrackManager. Fixes the problem where a beatmap would be stuck at 100% if it is replayed. --- osu.Game/Screens/Select/SongSelect.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 8f545240c8..f8423a90ed 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -372,6 +372,7 @@ namespace osu.Game.Screens.Select if (!track.IsRunning) { + Game.Audio.Track.AddItemToList(track); if (preview) track.Seek(Beatmap.Value.Metadata.PreviewTime); track.Start(); } From 096e5744012fad381b3fbfa3d7b1fc9e64317765 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Sat, 12 Aug 2017 19:52:09 +0930 Subject: [PATCH 017/483] Selecting a beatmap set no longer updates the ruleset to the first map of that set (since it causes the carousel to refilter) --- osu.Game/Screens/Select/SongSelect.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 8f545240c8..6414365853 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -253,8 +253,6 @@ namespace osu.Game.Screens.Select } else { - Ruleset.Value = beatmap.Ruleset; - if (beatmap.BeatmapSetInfoID == beatmapNoDebounce?.BeatmapSetInfoID) sampleChangeDifficulty.Play(); else From d19c8f56be69c913c95b72334b6cea5e9e7e71bf Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Sun, 13 Aug 2017 15:03:01 +0930 Subject: [PATCH 018/483] Make RulesetInfo implement IEquatable since EqualityComparer was sometimes giving false negatives and causing Bindable observers to fire --- osu.Game/Rulesets/RulesetInfo.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index bc23649ede..059f93645f 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -6,7 +6,7 @@ using SQLite.Net.Attributes; namespace osu.Game.Rulesets { - public class RulesetInfo + public class RulesetInfo : IEquatable { [PrimaryKey, AutoIncrement] public int? ID { get; set; } @@ -21,5 +21,10 @@ namespace osu.Game.Rulesets public bool Available { get; set; } public virtual Ruleset CreateInstance() => (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo), this); + + public bool Equals(RulesetInfo other) + { + return this.ID == other.ID && this.Available == other.Available && this.Name == other.Name && this.InstantiationInfo == other.InstantiationInfo; + } } } \ No newline at end of file From 4c2d7bf343999b55213b8d8900b62aee79d56276 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 17:41:13 +0200 Subject: [PATCH 019/483] Parse the mods of a leaderboard's score --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 18 +++++++++ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 30 +++++++++++++++ osu.Game.Rulesets.Mania/Mods/ManiaMod.cs | 4 ++ .../Mods/ManiaModGravity.cs | 1 + osu.Game.Rulesets.Osu/Mods/OsuMod.cs | 3 ++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 21 ++++++++++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 18 +++++++++ osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 + osu.Game/Rulesets/Mods/Mod.cs | 5 +++ osu.Game/Rulesets/Mods/ModAutoplay.cs | 1 + osu.Game/Rulesets/Mods/ModCinema.cs | 1 + osu.Game/Rulesets/Mods/ModDaycore.cs | 1 + osu.Game/Rulesets/Mods/ModDoubleTime.cs | 1 + osu.Game/Rulesets/Mods/ModEasy.cs | 1 + osu.Game/Rulesets/Mods/ModFlashlight.cs | 1 + osu.Game/Rulesets/Mods/ModHalfTime.cs | 1 + osu.Game/Rulesets/Mods/ModHardRock.cs | 1 + osu.Game/Rulesets/Mods/ModHidden.cs | 1 + osu.Game/Rulesets/Mods/ModNightcore.cs | 1 + osu.Game/Rulesets/Mods/ModNoFail.cs | 1 + osu.Game/Rulesets/Mods/ModPerfect.cs | 1 + osu.Game/Rulesets/Mods/ModRelax.cs | 1 + osu.Game/Rulesets/Mods/ModSuddenDeath.cs | 1 + osu.Game/Rulesets/Mods/MultiMod.cs | 1 + osu.Game/Rulesets/Ruleset.cs | 15 +++++++- osu.Game/Rulesets/Scoring/Score.cs | 38 ++++++++++++++++++- .../Select/Leaderboards/Leaderboard.cs | 6 ++- .../Select/Leaderboards/LeaderboardScore.cs | 19 +++++++++- 28 files changed, 188 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 8d45ea8fa2..69f22f7121 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -20,6 +20,24 @@ namespace osu.Game.Rulesets.Catch { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IEnumerable GetAllMods() => new Mod[] + { + new CatchModEasy(), + new CatchModNoFail(), + new CatchModHalfTime(), + new CatchModDaycore(), + new CatchModHardRock(), + new CatchModSuddenDeath(), + new CatchModPerfect(), + new CatchModDoubleTime(), + new CatchModNightcore(), + new CatchModHidden(), + new CatchModFlashlight(), + new CatchModRelax(), + new ModAutoplay(), + new ModCinema() + }; + public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 50ad6960ae..3a7c072604 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -19,6 +19,36 @@ namespace osu.Game.Rulesets.Mania { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new ManiaRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IEnumerable GetAllMods() => new Mod[] + { + new ManiaModEasy(), + new ManiaModNoFail(), + new ManiaModHalfTime(), + new ManiaModDaycore(), + new ManiaModHardRock(), + new ManiaModSuddenDeath(), + new ManiaModPerfect(), + new ManiaModDoubleTime(), + new ManiaModNightcore(), + new ManiaModFadeIn(), + new ManiaModHidden(), + new ManiaModFlashlight(), + new ManiaModKey4(), + new ManiaModKey5(), + new ManiaModKey6(), + new ManiaModKey7(), + new ManiaModKey8(), + new ManiaModKey9(), + new ManiaModKey1(), + new ManiaModKey2(), + new ManiaModKey3(), + new ManiaModRandom(), + new ManiaModKeyCoop(), + new ModAutoplay(), + new ModCinema(), + new ManiaModGravity() + }; + public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs index f44ad6fd60..12aa9b0886 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs @@ -68,6 +68,7 @@ namespace osu.Game.Rulesets.Mania.Mods public class ManiaModFadeIn : Mod { public override string Name => "FadeIn"; + public override string ShortenedName => "FI"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden; public override ModType Type => ModType.DifficultyIncrease; public override double ScoreMultiplier => 1; @@ -78,12 +79,14 @@ namespace osu.Game.Rulesets.Mania.Mods public class ManiaModRandom : Mod { public override string Name => "Random"; + public override string ShortenedName => "RD"; public override string Description => @"Shuffle around the notes!"; public override double ScoreMultiplier => 1; } public abstract class ManiaKeyMod : Mod { + 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; @@ -146,6 +149,7 @@ namespace osu.Game.Rulesets.Mania.Mods public class ManiaModKeyCoop : Mod { public override string Name => "KeyCoop"; + public override string ShortenedName => "CO"; public override string Description => @"Double the key amount, double the fun!"; public override double ScoreMultiplier => 1; public override bool Ranked => true; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs index a054e0db56..132c49ab31 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs @@ -15,6 +15,7 @@ namespace osu.Game.Rulesets.Mania.Mods public class ManiaModGravity : Mod, IGenerateSpeedAdjustments { public override string Name => "Gravity"; + public override string ShortenedName => "GR"; public override double ScoreMultiplier => 0; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs index 3b0cfc1ef1..649e6cfb3c 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs @@ -78,6 +78,7 @@ namespace osu.Game.Rulesets.Osu.Mods public class OsuModSpunOut : Mod { public override string Name => "Spun Out"; + public override string ShortenedName => "SO"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_spunout; public override string Description => @"Spinners will be automatically completed"; public override double ScoreMultiplier => 0.9; @@ -88,6 +89,7 @@ namespace osu.Game.Rulesets.Osu.Mods public class OsuModAutopilot : Mod { public override string Name => "Autopilot"; + public override string ShortenedName => "AP"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot; public override string Description => @"Automatic cursor movement - just follow the rhythm."; public override double ScoreMultiplier => 0; @@ -108,6 +110,7 @@ namespace osu.Game.Rulesets.Osu.Mods public class OsuModTarget : Mod { public override string Name => "Target"; + public override string ShortenedName => "TP"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_target; public override string Description => @""; public override double ScoreMultiplier => 1; diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 212c634aaf..fbcb5e3abf 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -24,6 +24,27 @@ namespace osu.Game.Rulesets.Osu { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new OsuRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IEnumerable GetAllMods() => new Mod[] + { + new OsuModEasy(), + new OsuModNoFail(), + new OsuModHalfTime(), + new OsuModDaycore(), + new OsuModHardRock(), + new OsuModSuddenDeath(), + new OsuModPerfect(), + new OsuModDoubleTime(), + new OsuModNightcore(), + new OsuModHidden(), + new OsuModFlashlight(), + new OsuModRelax(), + new OsuModAutopilot(), + new OsuModSpunOut(), + new OsuModAutoplay(), + new ModCinema(), + new OsuModTarget(), + }; + public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new[] { new BeatmapStatistic diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 4d4bbb7bc5..3e126cec4e 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -20,6 +20,24 @@ namespace osu.Game.Rulesets.Taiko { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new TaikoRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IEnumerable GetAllMods() => new Mod[] + { + new TaikoModEasy(), + new TaikoModNoFail(), + new TaikoModHalfTime(), + new TaikoModDaycore(), + new TaikoModHardRock(), + new TaikoModSuddenDeath(), + new TaikoModPerfect(), + new TaikoModDoubleTime(), + new TaikoModNightcore(), + new TaikoModHidden(), + new TaikoModFlashlight(), + new TaikoModRelax(), + new TaikoModAutoplay(), + new ModCinema() + }; + public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 2fb9a568f8..f807b5828f 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -58,6 +58,8 @@ namespace osu.Game.Beatmaps private class DummyRuleset : Ruleset { + public override IEnumerable GetAllMods() => new Mod[] { }; + public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; public override Mod GetAutoplayMod() => new ModAutoplay(); diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index f54267af29..7b0034863e 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -16,6 +16,11 @@ namespace osu.Game.Rulesets.Mods /// public abstract string Name { get; } + /// + /// The shortened name of this mod. + /// + public abstract string ShortenedName { get; } + /// /// The icon of this mod. /// diff --git a/osu.Game/Rulesets/Mods/ModAutoplay.cs b/osu.Game/Rulesets/Mods/ModAutoplay.cs index ca120e446e..2b10d098f3 100644 --- a/osu.Game/Rulesets/Mods/ModAutoplay.cs +++ b/osu.Game/Rulesets/Mods/ModAutoplay.cs @@ -24,6 +24,7 @@ namespace osu.Game.Rulesets.Mods public class ModAutoplay : Mod { public override string Name => "Autoplay"; + public override string ShortenedName => "AT"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_auto; public override string Description => "Watch a perfect automated play through the song"; public override double ScoreMultiplier => 0; diff --git a/osu.Game/Rulesets/Mods/ModCinema.cs b/osu.Game/Rulesets/Mods/ModCinema.cs index 332bd2c5ac..581fbc5e3a 100644 --- a/osu.Game/Rulesets/Mods/ModCinema.cs +++ b/osu.Game/Rulesets/Mods/ModCinema.cs @@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mods public class ModCinema : ModAutoplay { public override string Name => "Cinema"; + public override string ShortenedName => "CN"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_cinema; } } \ No newline at end of file diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs index 3e878d7104..cbad224316 100644 --- a/osu.Game/Rulesets/Mods/ModDaycore.cs +++ b/osu.Game/Rulesets/Mods/ModDaycore.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModDaycore : ModHalfTime { public override string Name => "Daycore"; + public override string ShortenedName => "DC"; public override FontAwesome Icon => FontAwesome.fa_question; public override string Description => "whoaaaaa"; diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index 1aab56a9fc..d8aa5ea1d2 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods public class ModDoubleTime : Mod, IApplicableToClock { public override string Name => "Double Time"; + public override string ShortenedName => "DT"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_doubletime; public override ModType Type => ModType.DifficultyIncrease; public override string Description => "Zoooooooooom"; diff --git a/osu.Game/Rulesets/Mods/ModEasy.cs b/osu.Game/Rulesets/Mods/ModEasy.cs index 075a62b0d7..aaf083fd9e 100644 --- a/osu.Game/Rulesets/Mods/ModEasy.cs +++ b/osu.Game/Rulesets/Mods/ModEasy.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModEasy : Mod, IApplicableToDifficulty { public override string Name => "Easy"; + public override string ShortenedName => "EZ"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_easy; public override ModType Type => ModType.DifficultyReduction; public override string Description => "Reduces overall difficulty - larger circles, more forgiving HP drain, less accuracy required."; diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index b5ad859172..b7499e624a 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModFlashlight : Mod { public override string Name => "Flashlight"; + public override string ShortenedName => "FL"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_flashlight; public override ModType Type => ModType.DifficultyIncrease; public override string Description => "Restricted view area."; diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index 14aede0809..a9e49bb4b0 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModHalfTime : Mod, IApplicableToClock { public override string Name => "Half Time"; + public override string ShortenedName => "HT"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_halftime; public override ModType Type => ModType.DifficultyReduction; public override string Description => "Less zoom"; diff --git a/osu.Game/Rulesets/Mods/ModHardRock.cs b/osu.Game/Rulesets/Mods/ModHardRock.cs index f33f46a207..36d82362e3 100644 --- a/osu.Game/Rulesets/Mods/ModHardRock.cs +++ b/osu.Game/Rulesets/Mods/ModHardRock.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModHardRock : Mod, IApplicableToDifficulty { public override string Name => "Hard Rock"; + public override string ShortenedName => "HR"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_hardrock; public override ModType Type => ModType.DifficultyIncrease; public override string Description => "Everything just got a bit harder..."; diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index 89b9b3b62d..25f6ad024d 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModHidden : Mod { public override string Name => "Hidden"; + public override string ShortenedName => "HD"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden; public override ModType Type => ModType.DifficultyIncrease; public override bool Ranked => true; diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs index d04643fb8b..5cefd89023 100644 --- a/osu.Game/Rulesets/Mods/ModNightcore.cs +++ b/osu.Game/Rulesets/Mods/ModNightcore.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModNightcore : ModDoubleTime { public override string Name => "Nightcore"; + public override string ShortenedName => "NC"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_nightcore; public override string Description => "uguuuuuuuu"; diff --git a/osu.Game/Rulesets/Mods/ModNoFail.cs b/osu.Game/Rulesets/Mods/ModNoFail.cs index d41c4e3956..3a3878d77e 100644 --- a/osu.Game/Rulesets/Mods/ModNoFail.cs +++ b/osu.Game/Rulesets/Mods/ModNoFail.cs @@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModNoFail : Mod { public override string Name => "NoFail"; + public override string ShortenedName => "NF"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail; public override ModType Type => ModType.DifficultyReduction; public override string Description => "You can't fail, no matter what."; diff --git a/osu.Game/Rulesets/Mods/ModPerfect.cs b/osu.Game/Rulesets/Mods/ModPerfect.cs index 35217c8305..082370ea5d 100644 --- a/osu.Game/Rulesets/Mods/ModPerfect.cs +++ b/osu.Game/Rulesets/Mods/ModPerfect.cs @@ -6,6 +6,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModPerfect : ModSuddenDeath { public override string Name => "Perfect"; + public override string ShortenedName => "PF"; public override string Description => "SS or quit."; } } \ No newline at end of file diff --git a/osu.Game/Rulesets/Mods/ModRelax.cs b/osu.Game/Rulesets/Mods/ModRelax.cs index 5491f8fc58..a3f38e4ff6 100644 --- a/osu.Game/Rulesets/Mods/ModRelax.cs +++ b/osu.Game/Rulesets/Mods/ModRelax.cs @@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModRelax : Mod { public override string Name => "Relax"; + public override string ShortenedName => "RX"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_relax; public override double ScoreMultiplier => 0; public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModNoFail), typeof(ModSuddenDeath) }; diff --git a/osu.Game/Rulesets/Mods/ModSuddenDeath.cs b/osu.Game/Rulesets/Mods/ModSuddenDeath.cs index 2bf0278046..999cb40f89 100644 --- a/osu.Game/Rulesets/Mods/ModSuddenDeath.cs +++ b/osu.Game/Rulesets/Mods/ModSuddenDeath.cs @@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods public abstract class ModSuddenDeath : Mod { public override string Name => "Sudden Death"; + public override string ShortenedName => "SD"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_suddendeath; public override ModType Type => ModType.DifficultyIncrease; public override string Description => "Miss a note and fail."; diff --git a/osu.Game/Rulesets/Mods/MultiMod.cs b/osu.Game/Rulesets/Mods/MultiMod.cs index c5fac250d0..c40d107bda 100644 --- a/osu.Game/Rulesets/Mods/MultiMod.cs +++ b/osu.Game/Rulesets/Mods/MultiMod.cs @@ -6,6 +6,7 @@ namespace osu.Game.Rulesets.Mods public class MultiMod : Mod { public override string Name => string.Empty; + public override string ShortenedName => string.Empty; public override string Description => string.Empty; public override double ScoreMultiplier => 0.0; diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index ba040403ba..b6bcd48562 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -1,12 +1,12 @@ // Copyright (c) 2007-2017 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.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; -using System.Collections.Generic; using osu.Framework.Graphics; using osu.Game.Rulesets.Scoring; using osu.Game.Overlays.Settings; @@ -19,8 +19,21 @@ namespace osu.Game.Rulesets public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { }; + public abstract IEnumerable GetAllMods(); + public abstract IEnumerable GetModsFor(ModType type); + public Mod GetModByShortenedName(string shortenedName) + { + foreach(Mod mod in GetAllMods()) + { + if (string.Equals(mod.ShortenedName, shortenedName)) + return mod; + } + + return null; + } + public abstract Mod GetAutoplayMod(); protected Ruleset(RulesetInfo rulesetInfo) diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 6169bb7380..8377b95cb2 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Reflection; using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; @@ -27,10 +28,31 @@ namespace osu.Game.Rulesets.Scoring public int Combo { get; set; } + private string[] modStrings; [JsonProperty(@"mods")] - protected string[] ModStrings { get; set; } //todo: parse to Mod objects + protected string[] ModStrings { + get { return modStrings; } + set + { + modStrings = value; - public RulesetInfo Ruleset { get; set; } + if (ruleset != null) + handleModString(); + } + } + + private RulesetInfo ruleset; + public RulesetInfo Ruleset + { + get { return ruleset; } + set + { + ruleset = value; + + if (modStrings != null) + handleModString(); + } + } public Mod[] Mods { get; set; } @@ -80,5 +102,17 @@ namespace osu.Game.Rulesets.Scoring } public Dictionary Statistics = new Dictionary(); + + private void handleModString() + { + List modList = new List(); + + Ruleset rulesetInstance = Ruleset.CreateInstance(); + + foreach (string modShortenedName in modStrings) + modList.Add(rulesetInstance.GetModByShortenedName(modShortenedName)); + + Mods = modList.ToArray(); + } } } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 5a375e55d4..341e24baf0 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -1,15 +1,15 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Collections.Generic; using OpenTK; using OpenTK.Graphics; +using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; -using System; -using osu.Framework.Allocation; using osu.Framework.Threading; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; @@ -55,6 +55,8 @@ namespace osu.Game.Screens.Select.Leaderboards i = 0; foreach (var s in scores) { + s.Ruleset = beatmap.Ruleset; + var ls = new LeaderboardScore(s, 1 + i) { AlwaysPresent = true, diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index ac3b0b5c3b..993186ffdf 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -256,8 +256,23 @@ namespace osu.Game.Screens.Select.Leaderboards { foreach (Mod mod in Score.Mods) { - // TODO: Get actual mod colours - modsContainer.Add(new ScoreModIcon(mod.Icon, OsuColour.FromHex(@"ffcc22"))); + Color4 modColor; + + switch (mod.Type) + { + default: + case ModType.DifficultyIncrease: + modColor = OsuColour.FromHex(@"ffcc22"); + break; + case ModType.DifficultyReduction: + modColor = OsuColour.FromHex(@"88b300"); + break; + case ModType.Special: + modColor = OsuColour.FromHex(@"66ccff"); + break; + } + + modsContainer.Add(new ScoreModIcon(mod.Icon, modColor)); } } } From 997d0c9053c0b7cd641fa7047c0508203dac3744 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 17:45:46 +0200 Subject: [PATCH 020/483] CI fix --- osu.Game/Rulesets/Scoring/Score.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 8377b95cb2..0200e883ba 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Reflection; using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; From e1e4eb78e324b972241d3ae57161f3da631f23aa Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 18:00:53 +0200 Subject: [PATCH 021/483] Fix nullref in the leaderboard's test case --- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 341e24baf0..740dc90586 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Select.Leaderboards i = 0; foreach (var s in scores) { - s.Ruleset = beatmap.Ruleset; + s.Ruleset = beatmap?.Ruleset; var ls = new LeaderboardScore(s, 1 + i) { From d9c26f98c7d132a8109f37174cfcbc791b7ac9ab Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 19:54:07 +0200 Subject: [PATCH 022/483] Suggested changes --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 18 ----- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 30 --------- osu.Game.Rulesets.Osu/OsuRuleset.cs | 21 ------ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 18 ----- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 - osu.Game/Rulesets/Ruleset.cs | 28 +++++--- osu.Game/Rulesets/Scoring/Score.cs | 10 +-- osu.Game/Rulesets/UI/ModIcon.cs | 6 +- .../Select/Leaderboards/LeaderboardScore.cs | 67 ++++--------------- 9 files changed, 38 insertions(+), 162 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 69f22f7121..8d45ea8fa2 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -20,24 +20,6 @@ namespace osu.Game.Rulesets.Catch { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchRulesetContainer(this, beatmap, isForCurrentRuleset); - public override IEnumerable GetAllMods() => new Mod[] - { - new CatchModEasy(), - new CatchModNoFail(), - new CatchModHalfTime(), - new CatchModDaycore(), - new CatchModHardRock(), - new CatchModSuddenDeath(), - new CatchModPerfect(), - new CatchModDoubleTime(), - new CatchModNightcore(), - new CatchModHidden(), - new CatchModFlashlight(), - new CatchModRelax(), - new ModAutoplay(), - new ModCinema() - }; - public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 3a7c072604..50ad6960ae 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -19,36 +19,6 @@ namespace osu.Game.Rulesets.Mania { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new ManiaRulesetContainer(this, beatmap, isForCurrentRuleset); - public override IEnumerable GetAllMods() => new Mod[] - { - new ManiaModEasy(), - new ManiaModNoFail(), - new ManiaModHalfTime(), - new ManiaModDaycore(), - new ManiaModHardRock(), - new ManiaModSuddenDeath(), - new ManiaModPerfect(), - new ManiaModDoubleTime(), - new ManiaModNightcore(), - new ManiaModFadeIn(), - new ManiaModHidden(), - new ManiaModFlashlight(), - new ManiaModKey4(), - new ManiaModKey5(), - new ManiaModKey6(), - new ManiaModKey7(), - new ManiaModKey8(), - new ManiaModKey9(), - new ManiaModKey1(), - new ManiaModKey2(), - new ManiaModKey3(), - new ManiaModRandom(), - new ManiaModKeyCoop(), - new ModAutoplay(), - new ModCinema(), - new ManiaModGravity() - }; - public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index fbcb5e3abf..212c634aaf 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -24,27 +24,6 @@ namespace osu.Game.Rulesets.Osu { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new OsuRulesetContainer(this, beatmap, isForCurrentRuleset); - public override IEnumerable GetAllMods() => new Mod[] - { - new OsuModEasy(), - new OsuModNoFail(), - new OsuModHalfTime(), - new OsuModDaycore(), - new OsuModHardRock(), - new OsuModSuddenDeath(), - new OsuModPerfect(), - new OsuModDoubleTime(), - new OsuModNightcore(), - new OsuModHidden(), - new OsuModFlashlight(), - new OsuModRelax(), - new OsuModAutopilot(), - new OsuModSpunOut(), - new OsuModAutoplay(), - new ModCinema(), - new OsuModTarget(), - }; - public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new[] { new BeatmapStatistic diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 3e126cec4e..4d4bbb7bc5 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -20,24 +20,6 @@ namespace osu.Game.Rulesets.Taiko { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new TaikoRulesetContainer(this, beatmap, isForCurrentRuleset); - public override IEnumerable GetAllMods() => new Mod[] - { - new TaikoModEasy(), - new TaikoModNoFail(), - new TaikoModHalfTime(), - new TaikoModDaycore(), - new TaikoModHardRock(), - new TaikoModSuddenDeath(), - new TaikoModPerfect(), - new TaikoModDoubleTime(), - new TaikoModNightcore(), - new TaikoModHidden(), - new TaikoModFlashlight(), - new TaikoModRelax(), - new TaikoModAutoplay(), - new ModCinema() - }; - public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index f807b5828f..2fb9a568f8 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -58,8 +58,6 @@ namespace osu.Game.Beatmaps private class DummyRuleset : Ruleset { - public override IEnumerable GetAllMods() => new Mod[] { }; - public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; public override Mod GetAutoplayMod() => new ModAutoplay(); diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index b6bcd48562..56a255eda5 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2017 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.Game.Beatmaps; using osu.Game.Graphics; @@ -19,19 +21,29 @@ namespace osu.Game.Rulesets public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { }; - public abstract IEnumerable GetAllMods(); + public IEnumerable GetAllMods() + { + List modList = new List(); + + foreach (ModType type in Enum.GetValues(typeof(ModType))) + modList.AddRange(GetModsFor(type).SelectMany(mod => + { + var multiMod = mod as MultiMod; + + if (multiMod != null) + return multiMod.Mods; + + return new Mod[] { mod }; + })); + + return modList.ToArray(); + } public abstract IEnumerable GetModsFor(ModType type); public Mod GetModByShortenedName(string shortenedName) { - foreach(Mod mod in GetAllMods()) - { - if (string.Equals(mod.ShortenedName, shortenedName)) - return mod; - } - - return null; + return GetAllMods().First(mod => mod.ShortenedName == shortenedName); } public abstract Mod GetAutoplayMod(); diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 0200e883ba..b9fe54677d 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Linq; using System.Collections.Generic; using Newtonsoft.Json; using osu.Game.Beatmaps; @@ -104,14 +105,7 @@ namespace osu.Game.Rulesets.Scoring private void handleModString() { - List modList = new List(); - - Ruleset rulesetInstance = Ruleset.CreateInstance(); - - foreach (string modShortenedName in modStrings) - modList.Add(rulesetInstance.GetModByShortenedName(modShortenedName)); - - Mods = modList.ToArray(); + Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); } } } diff --git a/osu.Game/Rulesets/UI/ModIcon.cs b/osu.Game/Rulesets/UI/ModIcon.cs index 986d8c92dc..47a39d4644 100644 --- a/osu.Game/Rulesets/UI/ModIcon.cs +++ b/osu.Game/Rulesets/UI/ModIcon.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.UI private readonly SpriteIcon modIcon; private readonly SpriteIcon background; - private const float icon_size = 80; + private const float background_size = 80; public FontAwesome Icon { @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.UI { Origin = Anchor.Centre, Anchor = Anchor.Centre, - Size = new Vector2(icon_size), + Size = new Vector2(background_size), Icon = FontAwesome.fa_osu_mod_bg, Shadow = true, }, @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.UI Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Colour = OsuColour.Gray(84), - Size = new Vector2(icon_size - 35), + Size = new Vector2(background_size - 35), Y = 25, Icon = mod.Icon }, diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index 993186ffdf..fcd87363d6 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -3,17 +3,18 @@ using OpenTK; using OpenTK.Graphics; +using osu.Framework; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Framework.Extensions.Color4Extensions; -using osu.Game.Rulesets.Mods; -using osu.Game.Users; -using osu.Framework; -using osu.Game.Rulesets.Scoring; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; +using osu.Game.Users; namespace osu.Game.Screens.Select.Leaderboards { @@ -38,7 +39,7 @@ namespace osu.Game.Screens.Select.Leaderboards private readonly ScoreComponentLabel maxCombo; private readonly ScoreComponentLabel accuracy; private readonly Container flagBadgeContainer; - private readonly FillFlowContainer modsContainer; + private readonly FillFlowContainer modsContainer; private Visibility state; public Visibility State @@ -239,7 +240,7 @@ namespace osu.Game.Screens.Select.Leaderboards }, }, }, - modsContainer = new FillFlowContainer + modsContainer = new FillFlowContainer { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, @@ -256,23 +257,11 @@ namespace osu.Game.Screens.Select.Leaderboards { foreach (Mod mod in Score.Mods) { - Color4 modColor; - - switch (mod.Type) + modsContainer.Add(new ModIcon(mod) { - default: - case ModType.DifficultyIncrease: - modColor = OsuColour.FromHex(@"ffcc22"); - break; - case ModType.DifficultyReduction: - modColor = OsuColour.FromHex(@"88b300"); - break; - case ModType.Special: - modColor = OsuColour.FromHex(@"66ccff"); - break; - } - - modsContainer.Add(new ScoreModIcon(mod.Icon, modColor)); + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.375f) + }); } } } @@ -341,36 +330,6 @@ namespace osu.Game.Screens.Select.Leaderboards } } - private class ScoreModIcon : Container - { - public ScoreModIcon(FontAwesome icon, Color4 colour) - { - AutoSizeAxes = Axes.Both; - - Children = new[] - { - new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Icon = FontAwesome.fa_osu_mod_bg, - Colour = colour, - Shadow = true, - Size = new Vector2(30), - }, - new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Icon = icon, - Colour = OsuColour.Gray(84), - Size = new Vector2(18), - Position = new Vector2(0f, 2f), - }, - }; - } - } - private class ScoreComponentLabel : Container { public ScoreComponentLabel(FontAwesome icon, string value) From 81289db33b3a9f9d219ce930359e78222cdc234d Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 20:12:01 +0200 Subject: [PATCH 023/483] CI fix, fixed nullref and removed abstraction of GetAutoplayMod --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 -- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 -- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 -- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 -- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 -- osu.Game/Rulesets/Ruleset.cs | 6 +++--- 6 files changed, 3 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 8d45ea8fa2..a5c9cf67b3 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -84,8 +84,6 @@ namespace osu.Game.Rulesets.Catch } } - public override Mod GetAutoplayMod() => new ModAutoplay(); - public override string Description => "osu!catch"; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o }; diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 50ad6960ae..90732df1f2 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -105,8 +105,6 @@ namespace osu.Game.Rulesets.Mania } } - public override Mod GetAutoplayMod() => new ModAutoplay(); - public override string Description => "osu!mania"; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o }; diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 212c634aaf..92cfbf8afa 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -105,8 +105,6 @@ namespace osu.Game.Rulesets.Osu } } - public override Mod GetAutoplayMod() => new OsuModAutoplay(); - public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_osu_o }; public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new OsuDifficultyCalculator(beatmap); diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 4d4bbb7bc5..7fa053161d 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -84,8 +84,6 @@ namespace osu.Game.Rulesets.Taiko } } - public override Mod GetAutoplayMod() => new TaikoModAutoplay(); - public override string Description => "osu!taiko"; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o }; diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 2fb9a568f8..22ad4f38ff 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -60,8 +60,6 @@ namespace osu.Game.Beatmaps { public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; - public override Mod GetAutoplayMod() => new ModAutoplay(); - public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) { throw new NotImplementedException(); diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 56a255eda5..46ab53a7d2 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -26,14 +26,14 @@ namespace osu.Game.Rulesets List modList = new List(); foreach (ModType type in Enum.GetValues(typeof(ModType))) - modList.AddRange(GetModsFor(type).SelectMany(mod => + modList.AddRange(GetModsFor(type).Where(mod => mod != null).SelectMany(mod => { var multiMod = mod as MultiMod; if (multiMod != null) return multiMod.Mods; - return new Mod[] { mod }; + return new[] { mod }; })); return modList.ToArray(); @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets return GetAllMods().First(mod => mod.ShortenedName == shortenedName); } - public abstract Mod GetAutoplayMod(); + public Mod GetAutoplayMod() => GetAllMods().First(mod => mod is ModAutoplay); protected Ruleset(RulesetInfo rulesetInfo) { From 2f89fc432b3ed495a239170b2261aac6b3470a10 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 20:28:30 +0200 Subject: [PATCH 024/483] Removed unused function --- osu.Game/Rulesets/Ruleset.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 46ab53a7d2..cd4480bbb9 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -41,11 +41,6 @@ namespace osu.Game.Rulesets public abstract IEnumerable GetModsFor(ModType type); - public Mod GetModByShortenedName(string shortenedName) - { - return GetAllMods().First(mod => mod.ShortenedName == shortenedName); - } - public Mod GetAutoplayMod() => GetAllMods().First(mod => mod is ModAutoplay); protected Ruleset(RulesetInfo rulesetInfo) From e54f659916c4a897fb2ca5e51f13805923a1bb9e Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sun, 13 Aug 2017 22:37:39 +0200 Subject: [PATCH 025/483] Suggested changes --- osu.Game.Rulesets.Mania/Mods/ManiaMod.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 2 +- osu.Game/Rulesets/Scoring/Score.cs | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs index 12aa9b0886..bb11a05fc8 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs @@ -149,7 +149,7 @@ namespace osu.Game.Rulesets.Mania.Mods public class ManiaModKeyCoop : Mod { public override string Name => "KeyCoop"; - public override string ShortenedName => "CO"; + public override string ShortenedName => "2P"; public override string Description => @"Double the key amount, double the fun!"; public override double ScoreMultiplier => 1; public override bool Ranked => true; diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index cd4480bbb9..bb08850af9 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets return new[] { mod }; })); - return modList.ToArray(); + return modList; } public abstract IEnumerable GetModsFor(ModType type); diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index b9fe54677d..399a805bcc 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -30,7 +30,8 @@ namespace osu.Game.Rulesets.Scoring private string[] modStrings; [JsonProperty(@"mods")] - protected string[] ModStrings { + protected string[] ModStrings + { get { return modStrings; } set { From 6b1184e8aff6f4de5fabe58a430595e0e1e19b02 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 14 Aug 2017 00:27:54 +0200 Subject: [PATCH 026/483] General formatting --- .../Select/Leaderboards/LeaderboardScore.cs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index fcd87363d6..2971600a74 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -8,6 +8,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.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -253,16 +254,13 @@ namespace osu.Game.Screens.Select.Leaderboards }, }; - if (Score.Mods != null) + foreach (Mod mod in Score.Mods) { - foreach (Mod mod in Score.Mods) + modsContainer.Add(new ModIcon(mod) { - modsContainer.Add(new ModIcon(mod) - { - AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.375f) - }); - } + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.375f) + }); } } @@ -271,13 +269,13 @@ namespace osu.Game.Screens.Select.Leaderboards public override void Hide() => State = Visibility.Hidden; public override void Show() => State = Visibility.Visible; - protected override bool OnHover(Framework.Input.InputState state) + protected override bool OnHover(InputState state) { background.FadeTo(0.5f, 300, Easing.OutQuint); return base.OnHover(state); } - protected override void OnHoverLost(Framework.Input.InputState state) + protected override void OnHoverLost(InputState state) { background.FadeTo(background_alpha, 200, Easing.OutQuint); base.OnHoverLost(state); @@ -307,8 +305,8 @@ namespace osu.Game.Screens.Select.Leaderboards Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = font, - TextSize = textSize, FixedWidth = true, + TextSize = textSize, Text = text, Colour = glowColour, Shadow = false, From 718eefa362e326efdb07331d2a6a2e7c52d53e1f Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 14 Aug 2017 01:16:19 +0200 Subject: [PATCH 027/483] Fixed wrong test case accuracy format --- .../Visual/TestCaseLeaderboard.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs b/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs index 5f8ee8795c..2386881d24 100644 --- a/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs +++ b/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs @@ -24,7 +24,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.XH, - Accuracy = 100, + Accuracy = 1, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -42,7 +42,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.X, - Accuracy = 100, + Accuracy = 1, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -60,7 +60,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.SH, - Accuracy = 100, + Accuracy = 1, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -78,7 +78,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.S, - Accuracy = 100, + Accuracy = 1, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -96,7 +96,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.A, - Accuracy = 100, + Accuracy = 1, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -114,7 +114,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.B, - Accuracy = 98.26, + Accuracy = 0.9826, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -132,7 +132,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.C, - Accuracy = 96.54, + Accuracy = 0.9654, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -150,7 +150,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.F, - Accuracy = 60.25, + Accuracy = 0.6025, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -168,7 +168,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.F, - Accuracy = 51.40, + Accuracy = 0.5140, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, @@ -186,7 +186,7 @@ namespace osu.Desktop.Tests.Visual new Score { Rank = ScoreRank.F, - Accuracy = 42.22, + Accuracy = 0.4222, MaxCombo = 244, TotalScore = 1707827, Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), }, From 2ae3ce8b91e03e201efbb88cb13a862830d3d148 Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 3 Aug 2017 20:55:52 +0530 Subject: [PATCH 028/483] Add ability to close chat tabs. --- osu.Game/Overlays/Chat/ChatTabControl.cs | 45 +++++++++++++++++++++--- osu.Game/Overlays/ChatOverlay.cs | 12 +++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 4ff9169877..b44d50e936 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -16,15 +16,16 @@ using osu.Game.Online.Chat; using OpenTK; using OpenTK.Graphics; using osu.Framework.Configuration; +using System; namespace osu.Game.Overlays.Chat { public class ChatTabControl : OsuTabControl { - protected override TabItem CreateTabItem(Channel value) => new ChannelTabItem(value); - private const float shear_width = 10; + public Action OnRequestLeave; + public readonly Bindable ChannelSelectorActive = new Bindable(); private readonly ChannelTabItem.ChannelSelectorTabItem selectorTab; @@ -49,6 +50,14 @@ namespace osu.Game.Overlays.Chat ChannelSelectorActive.BindTo(selectorTab.Active); } + protected override TabItem CreateTabItem(Channel value) + { + ChannelTabItem tab = new ChannelTabItem(value); + tab.OnRequestClose = () => OnRequestLeave?.Invoke(value); + + return tab; + } + protected override void SelectTab(TabItem tab) { if (tab is ChannelTabItem.ChannelSelectorTabItem) @@ -68,12 +77,17 @@ namespace osu.Game.Overlays.Chat private Color4 backgroundHover; private Color4 backgroundActive; + protected override bool isClosable => !Pinned; + private readonly SpriteText text; private readonly SpriteText textBold; + private readonly Button closeButton; private readonly Box box; private readonly Box highlightBox; private readonly SpriteIcon icon; + public Action OnRequestClose; + private void updateState() { if (Active) @@ -88,6 +102,7 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1.1f), transition_length, Easing.OutQuint); + closeButton?.MoveToX(-5f, 0.5f, EasingTypes.OutElastic); box.FadeColour(backgroundActive, transition_length, Easing.OutQuint); highlightBox.FadeIn(transition_length, Easing.OutQuint); @@ -99,6 +114,7 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1), transition_length, Easing.OutQuint); + closeButton?.MoveToX(5f, 0.5f, EasingTypes.InElastic); box.FadeColour(backgroundInactive, transition_length, Easing.OutQuint); highlightBox.FadeOut(transition_length, Easing.OutQuint); @@ -108,6 +124,8 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(InputState state) { + closeButton?.FadeIn(1f, EasingTypes.InBounce); + if (!Active) box.FadeColour(backgroundHover, transition_length, Easing.OutQuint); return true; @@ -115,6 +133,7 @@ namespace osu.Game.Overlays.Chat protected override void OnHoverLost(InputState state) { + closeButton?.FadeOut(1f, EasingTypes.OutBounce); updateState(); } @@ -204,13 +223,31 @@ namespace osu.Game.Overlays.Chat Font = @"Exo2.0-Bold", TextSize = 18, }, - } - } + }, + }, }; + + if (isClosable) + { + Add(closeButton = new Button + { + Alpha = 0, + Width = 20, + Height = 20, + Margin = new MarginPadding { Right = 10 }, + Origin = Anchor.CentreRight, + Anchor = Anchor.CentreRight, + Text = @"x", + BackgroundColour = Color4.Transparent, + Action = () => OnRequestClose?.Invoke(), + }); + } } public class ChannelSelectorTabItem : ChannelTabItem { + protected override bool isClosable => false; + public ChannelSelectorTabItem(Channel value) : base(value) { Depth = float.MaxValue; diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 29b7548ada..cc4177edc6 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -160,6 +160,7 @@ namespace osu.Game.Overlays channelTabs = new ChatTabControl { RelativeSizeAxes = Axes.Both, + OnRequestLeave = removeChannel, }, } }, @@ -305,6 +306,7 @@ namespace osu.Game.Overlays addChannel(channels.Find(c => c.Name == @"#lobby")); channelSelection.OnRequestJoin = addChannel; + channelSelection.OnRequestLeave = removeChannel; channelSelection.Sections = new[] { new ChannelSection @@ -391,6 +393,16 @@ namespace osu.Game.Overlays channel.Joined.Value = true; } + private void removeChannel(Channel channel) + { + if (channel == null) return; + + careChannels.Remove(channel); + channelTabs.RemoveItem(channel); + + channel.Joined.Value = false; + } + private void fetchInitialMessages(Channel channel) { var req = new GetMessagesRequest(new List { channel }, null); From 3b6ffadcc7207c24a081df017d64686752bb9893 Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 3 Aug 2017 22:02:25 +0530 Subject: [PATCH 029/483] Renaming to match framework changes. - IsClosable -> IsRemovable - EasingTypes -> Easing - Also remove all messages on a channel being un-joined --- osu.Game/Overlays/Chat/ChatTabControl.cs | 14 +++++++------- osu.Game/Overlays/Chat/DrawableChannel.cs | 7 +++++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index b44d50e936..735a37e334 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Chat private Color4 backgroundHover; private Color4 backgroundActive; - protected override bool isClosable => !Pinned; + protected override bool IsRemovable => !Pinned; private readonly SpriteText text; private readonly SpriteText textBold; @@ -102,7 +102,7 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1.1f), transition_length, Easing.OutQuint); - closeButton?.MoveToX(-5f, 0.5f, EasingTypes.OutElastic); + closeButton?.MoveToX(-5f, 0.5f, Easing.OutElastic); box.FadeColour(backgroundActive, transition_length, Easing.OutQuint); highlightBox.FadeIn(transition_length, Easing.OutQuint); @@ -114,7 +114,7 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1), transition_length, Easing.OutQuint); - closeButton?.MoveToX(5f, 0.5f, EasingTypes.InElastic); + closeButton?.MoveToX(5f, 0.5f, Easing.InElastic); box.FadeColour(backgroundInactive, transition_length, Easing.OutQuint); highlightBox.FadeOut(transition_length, Easing.OutQuint); @@ -124,7 +124,7 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(InputState state) { - closeButton?.FadeIn(1f, EasingTypes.InBounce); + closeButton?.FadeIn(1f, Easing.InBounce); if (!Active) box.FadeColour(backgroundHover, transition_length, Easing.OutQuint); @@ -133,7 +133,7 @@ namespace osu.Game.Overlays.Chat protected override void OnHoverLost(InputState state) { - closeButton?.FadeOut(1f, EasingTypes.OutBounce); + closeButton?.FadeOut(1f, Easing.OutBounce); updateState(); } @@ -227,7 +227,7 @@ namespace osu.Game.Overlays.Chat }, }; - if (isClosable) + if (IsRemovable) { Add(closeButton = new Button { @@ -246,7 +246,7 @@ namespace osu.Game.Overlays.Chat public class ChannelSelectorTabItem : ChannelTabItem { - protected override bool isClosable => false; + protected override bool IsRemovable => false; public ChannelSelectorTabItem(Channel value) : base(value) { diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 8a2fa95ed1..3736a97981 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -46,6 +46,7 @@ namespace osu.Game.Overlays.Chat }; channel.NewMessagesArrived += newMessagesArrived; + channel.Joined.ValueChanged += channelJoinStatusChanged; } [BackgroundDependencyLoader] @@ -64,6 +65,7 @@ namespace osu.Game.Overlays.Chat { base.Dispose(isDisposing); Channel.NewMessagesArrived -= newMessagesArrived; + Channel.Joined.ValueChanged -= channelJoinStatusChanged; } private void newMessagesArrived(IEnumerable newMessages) @@ -90,6 +92,11 @@ namespace osu.Game.Overlays.Chat } } + private void channelJoinStatusChanged(bool joined) + { + if (!joined) flow.Clear(); + } + private void scrollToEnd() => ScheduleAfterChildren(() => scroll.ScrollToEnd()); } } From 8dbbc623c73e1b3731fcfe4c6e7d870e95691793 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 5 Aug 2017 10:22:06 +0530 Subject: [PATCH 030/483] Add next tab selection logic in game, make IsRemovable public. - Don't clear DrawableChannel when unjoined --- osu.Game/Overlays/Chat/ChatTabControl.cs | 21 ++++++++++++++++++--- osu.Game/Overlays/Chat/DrawableChannel.cs | 7 ------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 735a37e334..baa6fb3ab6 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -53,7 +53,7 @@ namespace osu.Game.Overlays.Chat protected override TabItem CreateTabItem(Channel value) { ChannelTabItem tab = new ChannelTabItem(value); - tab.OnRequestClose = () => OnRequestLeave?.Invoke(value); + tab.OnRequestClose = () => onTabClose(tab); return tab; } @@ -71,13 +71,28 @@ namespace osu.Game.Overlays.Chat base.SelectTab(tab); } + private void onTabClose(TabItem tab) + { + int totalTabs = TabContainer.Children.Count - 1; // account for selectorTab + int currentIndex = MathHelper.Clamp(TabContainer.IndexOf(tab), 1, totalTabs); + + if (tab == SelectedTab && totalTabs > 1) + // Select the tab after tab-to-be-removed's index, or the tab before if current == last + SelectTab(TabContainer.Children[currentIndex == totalTabs ? currentIndex - 1 : currentIndex + 1]); + else if (totalTabs == 1 && !selectorTab.Active) + // Open channel selection overlay if all channel tabs will be closed after removing this tab + SelectTab(selectorTab); + + OnRequestLeave?.Invoke(tab.Value); + } + private class ChannelTabItem : TabItem { private Color4 backgroundInactive; private Color4 backgroundHover; private Color4 backgroundActive; - protected override bool IsRemovable => !Pinned; + public override bool IsRemovable => !Pinned; private readonly SpriteText text; private readonly SpriteText textBold; @@ -246,7 +261,7 @@ namespace osu.Game.Overlays.Chat public class ChannelSelectorTabItem : ChannelTabItem { - protected override bool IsRemovable => false; + public override bool IsRemovable => false; public ChannelSelectorTabItem(Channel value) : base(value) { diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 3736a97981..8a2fa95ed1 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -46,7 +46,6 @@ namespace osu.Game.Overlays.Chat }; channel.NewMessagesArrived += newMessagesArrived; - channel.Joined.ValueChanged += channelJoinStatusChanged; } [BackgroundDependencyLoader] @@ -65,7 +64,6 @@ namespace osu.Game.Overlays.Chat { base.Dispose(isDisposing); Channel.NewMessagesArrived -= newMessagesArrived; - Channel.Joined.ValueChanged -= channelJoinStatusChanged; } private void newMessagesArrived(IEnumerable newMessages) @@ -92,11 +90,6 @@ namespace osu.Game.Overlays.Chat } } - private void channelJoinStatusChanged(bool joined) - { - if (!joined) flow.Clear(); - } - private void scrollToEnd() => ScheduleAfterChildren(() => scroll.ScrollToEnd()); } } From 381c709639ec9f3bbac4d93a4b3e1dc962be5b4a Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 11 Aug 2017 10:10:55 +0530 Subject: [PATCH 031/483] Fix selectorTab Depth if it's wonky when new tabs are added. --- osu.Game/Overlays/Chat/ChatTabControl.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index baa6fb3ab6..ef4760d166 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -50,6 +50,15 @@ namespace osu.Game.Overlays.Chat ChannelSelectorActive.BindTo(selectorTab.Active); } + protected override void AddTabItem(TabItem item, bool addToDropdown = true) + { + if (selectorTab.Depth < float.MaxValue) + // performTabSort might've made selectorTab's position wonky, fix it + TabContainer.ChangeChildDepth(selectorTab, float.MaxValue); + + base.AddTabItem(item, addToDropdown); + } + protected override TabItem CreateTabItem(Channel value) { ChannelTabItem tab = new ChannelTabItem(value); From 920710e7d0b3e37f027becbe059394f8e1345eb2 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 14 Aug 2017 13:30:54 +0200 Subject: [PATCH 032/483] Assign a score's beatmap and cleanup to the Score class --- osu.Game/Rulesets/Scoring/Score.cs | 23 ++++--------------- .../Select/Leaderboards/Leaderboard.cs | 1 + 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 399a805bcc..15217352d0 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -28,19 +28,8 @@ namespace osu.Game.Rulesets.Scoring public int Combo { get; set; } - private string[] modStrings; [JsonProperty(@"mods")] - protected string[] ModStrings - { - get { return modStrings; } - set - { - modStrings = value; - - if (ruleset != null) - handleModString(); - } - } + protected string[] ModStrings { get; set; } private RulesetInfo ruleset; public RulesetInfo Ruleset @@ -50,8 +39,9 @@ namespace osu.Game.Rulesets.Scoring { ruleset = value; - if (modStrings != null) - handleModString(); + // Handle the mod strings if they are assigned + if (ModStrings != null) + Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => ModStrings.Contains(mod.ShortenedName)).ToArray(); } } @@ -103,10 +93,5 @@ namespace osu.Game.Rulesets.Scoring } public Dictionary Statistics = new Dictionary(); - - private void handleModString() - { - Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); - } } } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 740dc90586..5ec76a59ac 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -55,6 +55,7 @@ namespace osu.Game.Screens.Select.Leaderboards i = 0; foreach (var s in scores) { + s.Beatmap = beatmap; s.Ruleset = beatmap?.Ruleset; var ls = new LeaderboardScore(s, 1 + i) From 5ed717ef861d15e02a7319127dcc060fd0cad1a3 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 14 Aug 2017 15:16:22 +0200 Subject: [PATCH 033/483] Shortened GetAllMods() using LINQ --- osu.Game/Rulesets/Ruleset.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index bb08850af9..af51a2cd3f 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -4,14 +4,14 @@ using System; using System.Linq; using System.Collections.Generic; +using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; -using osu.Framework.Graphics; -using osu.Game.Rulesets.Scoring; -using osu.Game.Overlays.Settings; namespace osu.Game.Rulesets { @@ -23,10 +23,9 @@ namespace osu.Game.Rulesets public IEnumerable GetAllMods() { - List modList = new List(); - - foreach (ModType type in Enum.GetValues(typeof(ModType))) - modList.AddRange(GetModsFor(type).Where(mod => mod != null).SelectMany(mod => + return Enum.GetValues(typeof(ModType)).Cast().SelectMany(type => + { + return GetModsFor(type).Where(mod => mod != null).SelectMany(mod => { var multiMod = mod as MultiMod; @@ -34,9 +33,8 @@ namespace osu.Game.Rulesets return multiMod.Mods; return new[] { mod }; - })); - - return modList; + }); + }); } public abstract IEnumerable GetModsFor(ModType type); From e908a3675ee2ac024abce62243a1261539a1956d Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Mon, 14 Aug 2017 18:24:54 +0200 Subject: [PATCH 034/483] Formatted the GetAllMods() function --- osu.Game/Rulesets/Ruleset.cs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index af51a2cd3f..b875dff44f 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -21,21 +21,7 @@ namespace osu.Game.Rulesets public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { }; - public IEnumerable GetAllMods() - { - return Enum.GetValues(typeof(ModType)).Cast().SelectMany(type => - { - return GetModsFor(type).Where(mod => mod != null).SelectMany(mod => - { - var multiMod = mod as MultiMod; - - if (multiMod != null) - return multiMod.Mods; - - return new[] { mod }; - }); - }); - } + public IEnumerable GetAllMods() => Enum.GetValues(typeof(ModType)).Cast().SelectMany(type => GetModsFor(type).Where(mod => mod != null).SelectMany(mod => (mod as MultiMod)?.Mods ?? new[] { mod })); public abstract IEnumerable GetModsFor(ModType type); From 9e5deb63d1bc7d8a409012d1c93f362e39caca09 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Tue, 15 Aug 2017 16:42:26 +0930 Subject: [PATCH 035/483] Fix spinner not handling left/right action bindings --- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index cd808abe9d..99c287f6fb 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -5,13 +5,14 @@ using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; +using osu.Framework.Input.Bindings; using osu.Game.Graphics; using OpenTK; using OpenTK.Graphics; namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { - public class SpinnerDisc : CircularContainer, IHasAccentColour + public class SpinnerDisc : CircularContainer, IHasAccentColour, IKeyBindingHandler { private readonly Spinner spinner; @@ -66,26 +67,53 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } } + private void updateTracking() + { + Tracking = mouseHasMainButtonPressed || actionLeftButtonPressed || actionRightButtonPressed; + } + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - Tracking |= state.Mouse.HasMainButtonPressed; + mouseHasMainButtonPressed |= state.Mouse.HasMainButtonPressed; + updateTracking(); return base.OnMouseDown(state, args); } protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { - Tracking &= state.Mouse.HasMainButtonPressed; + mouseHasMainButtonPressed &= state.Mouse.HasMainButtonPressed; + updateTracking(); return base.OnMouseUp(state, args); } protected override bool OnMouseMove(InputState state) { - Tracking |= state.Mouse.HasMainButtonPressed; + mouseHasMainButtonPressed |= state.Mouse.HasMainButtonPressed; mousePosition = Parent.ToLocalSpace(state.Mouse.NativeState.Position); + updateTracking(); return base.OnMouseMove(state); } + public bool OnPressed(OsuAction action) + { + actionLeftButtonPressed |= action == OsuAction.LeftButton; + actionRightButtonPressed |= action == OsuAction.RightButton; + updateTracking(); + return false; + } + + public bool OnReleased(OsuAction action) + { + actionLeftButtonPressed &= action == OsuAction.LeftButton; + actionRightButtonPressed &= action == OsuAction.RightButton; + updateTracking(); + return false; + } + private Vector2 mousePosition; + private bool mouseHasMainButtonPressed; + private bool actionLeftButtonPressed; + private bool actionRightButtonPressed; private float lastAngle; private float currentRotation; From 21ced322976ddf9d0892f2d939858fe782d82d97 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Tue, 15 Aug 2017 12:03:43 +0200 Subject: [PATCH 036/483] Formatted and commented the GetAllMods() function --- osu.Game/Rulesets/Ruleset.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index b875dff44f..65cc6199f0 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -21,7 +21,14 @@ namespace osu.Game.Rulesets public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { }; - public IEnumerable GetAllMods() => Enum.GetValues(typeof(ModType)).Cast().SelectMany(type => GetModsFor(type).Where(mod => mod != null).SelectMany(mod => (mod as MultiMod)?.Mods ?? new[] { mod })); + public IEnumerable GetAllMods() => Enum.GetValues(typeof(ModType)).Cast() + //Get all mod types as an IEnumerable + .SelectMany(type => GetModsFor(type)) + // Confine all mods of each mod type into a single IEnumerable + .Where(mod => mod != null) + // Filter out all null mods + .SelectMany(mod => (mod as MultiMod)?.Mods ?? new[] { mod }); + // Resolve MultiMods as their .Mods property public abstract IEnumerable GetModsFor(ModType type); From 2c287e13486419e771572fadd682d73d870c2261 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Tue, 15 Aug 2017 12:27:51 +0200 Subject: [PATCH 037/483] CI and comment fix --- osu.Game/Rulesets/Ruleset.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 65cc6199f0..fa12199a58 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -22,8 +22,8 @@ namespace osu.Game.Rulesets public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { }; public IEnumerable GetAllMods() => Enum.GetValues(typeof(ModType)).Cast() - //Get all mod types as an IEnumerable - .SelectMany(type => GetModsFor(type)) + // Get all mod types as an IEnumerable + .SelectMany(GetModsFor) // Confine all mods of each mod type into a single IEnumerable .Where(mod => mod != null) // Filter out all null mods From 105048500ad9a30f173d04892c5dd56ec28e5cdc Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Tue, 15 Aug 2017 15:30:53 +0200 Subject: [PATCH 038/483] Made modString private and moved the beatmap assignment inside GetScoresRequest --- osu.Game/Online/API/Requests/GetScoresRequest.cs | 11 +++++++++++ osu.Game/Rulesets/Scoring/Score.cs | 6 +++--- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 3 --- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index 966049429e..a902c8c807 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -16,6 +16,17 @@ namespace osu.Game.Online.API.Requests public GetScoresRequest(BeatmapInfo beatmap) { this.beatmap = beatmap; + + Success += onSuccess; + } + + private void onSuccess(GetScoresResponse r) + { + foreach (Score score in r.Scores) + { + score.Beatmap = beatmap; + score.Ruleset = beatmap.Ruleset; + } } protected override WebRequest CreateWebRequest() diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 15217352d0..e42c3b2df0 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Scoring public int Combo { get; set; } [JsonProperty(@"mods")] - protected string[] ModStrings { get; set; } + private string[] modStrings { get; set; } private RulesetInfo ruleset; public RulesetInfo Ruleset @@ -40,8 +40,8 @@ namespace osu.Game.Rulesets.Scoring ruleset = value; // Handle the mod strings if they are assigned - if (ModStrings != null) - Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => ModStrings.Contains(mod.ShortenedName)).ToArray(); + if (modStrings != null) + Mods = ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); } } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 5ec76a59ac..0506784614 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -55,9 +55,6 @@ namespace osu.Game.Screens.Select.Leaderboards i = 0; foreach (var s in scores) { - s.Beatmap = beatmap; - s.Ruleset = beatmap?.Ruleset; - var ls = new LeaderboardScore(s, 1 + i) { AlwaysPresent = true, From 9448e2f192bfee608ad6b620c495fcef2c22e09b Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Wed, 16 Aug 2017 17:25:48 +0930 Subject: [PATCH 039/483] Remove unnecessary OnMouseDown/Up from SpinnerDisc --- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 26 ++----------------- 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 99c287f6fb..eda6334b7a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -67,30 +67,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces } } - private void updateTracking() - { - Tracking = mouseHasMainButtonPressed || actionLeftButtonPressed || actionRightButtonPressed; - } - - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) - { - mouseHasMainButtonPressed |= state.Mouse.HasMainButtonPressed; - updateTracking(); - return base.OnMouseDown(state, args); - } - - protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) - { - mouseHasMainButtonPressed &= state.Mouse.HasMainButtonPressed; - updateTracking(); - return base.OnMouseUp(state, args); - } - protected override bool OnMouseMove(InputState state) { - mouseHasMainButtonPressed |= state.Mouse.HasMainButtonPressed; mousePosition = Parent.ToLocalSpace(state.Mouse.NativeState.Position); - updateTracking(); return base.OnMouseMove(state); } @@ -98,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { actionLeftButtonPressed |= action == OsuAction.LeftButton; actionRightButtonPressed |= action == OsuAction.RightButton; - updateTracking(); + Tracking = actionLeftButtonPressed || actionRightButtonPressed; return false; } @@ -106,12 +85,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { actionLeftButtonPressed &= action == OsuAction.LeftButton; actionRightButtonPressed &= action == OsuAction.RightButton; - updateTracking(); + Tracking = actionLeftButtonPressed || actionRightButtonPressed; return false; } private Vector2 mousePosition; - private bool mouseHasMainButtonPressed; private bool actionLeftButtonPressed; private bool actionRightButtonPressed; From b1abf83fee82bfb3bdb6ab1d0a538d67b5f242ca Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Wed, 16 Aug 2017 17:50:24 +0930 Subject: [PATCH 040/483] Change spinner action checks to switches --- .../Objects/Drawables/Pieces/SpinnerDisc.cs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index eda6334b7a..1e56a2559a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -75,16 +75,30 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces public bool OnPressed(OsuAction action) { - actionLeftButtonPressed |= action == OsuAction.LeftButton; - actionRightButtonPressed |= action == OsuAction.RightButton; + switch (action) + { + case OsuAction.LeftButton: + actionLeftButtonPressed = true; + break; + case OsuAction.RightButton: + actionRightButtonPressed = true; + break; + } Tracking = actionLeftButtonPressed || actionRightButtonPressed; return false; } public bool OnReleased(OsuAction action) { - actionLeftButtonPressed &= action == OsuAction.LeftButton; - actionRightButtonPressed &= action == OsuAction.RightButton; + switch (action) + { + case OsuAction.LeftButton: + actionLeftButtonPressed = false; + break; + case OsuAction.RightButton: + actionRightButtonPressed = false; + break; + } Tracking = actionLeftButtonPressed || actionRightButtonPressed; return false; } From 94d664a626c5e368d1e00b67e676f2dcf854cafd Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Wed, 16 Aug 2017 17:00:30 +0200 Subject: [PATCH 041/483] Swap the order of the social and chat toolbar buttons --- osu.Game/Overlays/Toolbar/Toolbar.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 1ecfe90aa1..aca1051c7c 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -60,8 +60,8 @@ namespace osu.Game.Overlays.Toolbar AutoSizeAxes = Axes.X, Children = new Drawable[] { - new ToolbarSocialButton(), new ToolbarChatButton(), + new ToolbarSocialButton(), new ToolbarMusicButton(), new ToolbarButton { From 4f7ae1ed8b6ecc2bee77d24b269b980031a0a7dc Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 17 Aug 2017 08:20:44 +0530 Subject: [PATCH 042/483] Clear messages when the current channel is removed. - Stop using TabContainer.Children --- osu.Game/Overlays/Chat/ChatTabControl.cs | 4 ++-- osu.Game/Overlays/ChatOverlay.cs | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index ef4760d166..5f8db6fa71 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -82,12 +82,12 @@ namespace osu.Game.Overlays.Chat private void onTabClose(TabItem tab) { - int totalTabs = TabContainer.Children.Count - 1; // account for selectorTab + int totalTabs = TabContainer.Count - 1; // account for selectorTab int currentIndex = MathHelper.Clamp(TabContainer.IndexOf(tab), 1, totalTabs); if (tab == SelectedTab && totalTabs > 1) // Select the tab after tab-to-be-removed's index, or the tab before if current == last - SelectTab(TabContainer.Children[currentIndex == totalTabs ? currentIndex - 1 : currentIndex + 1]); + SelectTab(TabContainer[currentIndex == totalTabs ? currentIndex - 1 : currentIndex + 1]); else if (totalTabs == 1 && !selectorTab.Active) // Open channel selection overlay if all channel tabs will be closed after removing this tab SelectTab(selectorTab); diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index cc4177edc6..855fb5a1d6 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -397,7 +397,11 @@ namespace osu.Game.Overlays { if (channel == null) return; + if (channel == CurrentChannel) + currentChannelContainer.Clear(false); + careChannels.Remove(channel); + loadedChannels.Remove(loadedChannels.Find(c => c.Channel == channel)); channelTabs.RemoveItem(channel); channel.Joined.Value = false; From 586a652b08ea3591a7c237f193afebafb9f6d268 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Thu, 17 Aug 2017 12:24:22 +0200 Subject: [PATCH 043/483] Changed Mods to be a property --- .../Visual/TestCaseLeaderboard.cs | 2 +- osu.Game/Rulesets/Scoring/Score.cs | 24 ++++++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs b/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs index 2386881d24..f67db2f41a 100644 --- a/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs +++ b/osu.Desktop.Tests/Visual/TestCaseLeaderboard.cs @@ -1,13 +1,13 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using OpenTK; using osu.Framework.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Select.Leaderboards; using osu.Game.Users; -using OpenTK; namespace osu.Desktop.Tests.Visual { diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index e42c3b2df0..e83cb916bb 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -31,22 +31,28 @@ namespace osu.Game.Rulesets.Scoring [JsonProperty(@"mods")] private string[] modStrings { get; set; } - private RulesetInfo ruleset; - public RulesetInfo Ruleset + public RulesetInfo Ruleset; + + private Mod[] mods; + public Mod[] Mods { - get { return ruleset; } + get + { + // Evaluate the mod strings + if (mods == null) + mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); + + return mods; + } set { - ruleset = value; + mods = value; - // Handle the mod strings if they are assigned - if (modStrings != null) - Mods = ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); + // Assign the mod strings + modStrings = mods.Select(mod => mod.ShortenedName).ToArray(); } } - public Mod[] Mods { get; set; } - [JsonProperty(@"user")] public User User; From df683d911480b987660233c11f322afd4d6b3832 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Thu, 17 Aug 2017 23:28:26 +0930 Subject: [PATCH 044/483] Fix multiple difficulty control points sharing the same time and thus confusing slider velocity calculations --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 46cbad2487..82f48d4361 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using OpenTK.Graphics; using osu.Game.Beatmaps.Timing; using osu.Game.Beatmaps.Legacy; @@ -331,6 +332,7 @@ namespace osu.Game.Beatmaps.Formats if (speedMultiplier != difficultyPoint.SpeedMultiplier) { + beatmap.ControlPointInfo.DifficultyPoints.RemoveAll(x => x.Time == time); beatmap.ControlPointInfo.DifficultyPoints.Add(new DifficultyControlPoint { Time = time, From 61182092004e43ac597ef1492e29a7bc0acaf63a Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Thu, 17 Aug 2017 18:46:16 +0200 Subject: [PATCH 045/483] Fix unlit initial state of the OnScreenDisplay --- osu.Game/Overlays/OnScreenDisplay.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 746b6dd50f..dcab942522 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -258,7 +258,10 @@ namespace osu.Game.Overlays Type = EdgeEffectType.Glow, Radius = 8, }; + } + protected override void LoadComplete() + { updateGlow(); FinishTransforms(true); } From cc39aad7f8d05fc8f678d1763b998cb1abcab41c Mon Sep 17 00:00:00 2001 From: PoULkY Date: Fri, 18 Aug 2017 01:23:44 +0700 Subject: [PATCH 046/483] Fix OsuButton doesn't implement IFilterable --- osu.Game/Graphics/UserInterface/OsuButton.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 3c454f2af2..5650fc6f48 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -7,6 +7,7 @@ using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; @@ -16,7 +17,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { - public class OsuButton : Button + public class OsuButton : Button, IFilterable { private Box hover; @@ -108,5 +109,15 @@ namespace osu.Game.Graphics.UserInterface Content.ScaleTo(1, 1000, Easing.OutElastic); return base.OnMouseUp(state, args); } + + public string[] FilterTerms => new[] { Text }; + + public bool MatchingFilter + { + set + { + this.FadeTo(value ? 1 : 0); + } + } } } \ No newline at end of file From e4b832e8a6be6ba801cec5d8e2d6228e86e7f9ed Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Aug 2017 10:48:35 +0900 Subject: [PATCH 047/483] Fix a possible nullref when login fails --- osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index 3f8b6186c4..7ae45159d9 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -171,7 +171,7 @@ namespace osu.Game.Overlays.Settings.Sections.General break; } - if (form != null) GetContainingInputManager().ChangeFocus(form); + if (form != null) GetContainingInputManager()?.ChangeFocus(form); } public override bool AcceptsFocus => true; From 243a6ca7745f59e256b531ca5034059ca55e644c Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 18 Aug 2017 13:27:16 +0900 Subject: [PATCH 048/483] Update OsuLegacyDecoder.cs --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 82f48d4361..093f607e0d 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Globalization; using System.IO; -using System.Linq; using OpenTK.Graphics; using osu.Game.Beatmaps.Timing; using osu.Game.Beatmaps.Legacy; From a47b6526a2b7810d51adb2cc2f6d035b8e6d5cad Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 18 Aug 2017 14:40:36 +0900 Subject: [PATCH 049/483] Fix CI issues. --- osu.Game/Rulesets/RulesetInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index 059f93645f..8d19b28a81 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets public bool Equals(RulesetInfo other) { - return this.ID == other.ID && this.Available == other.Available && this.Name == other.Name && this.InstantiationInfo == other.InstantiationInfo; + return ID == other?.ID && Available == other?.Available && Name == other?.Name && InstantiationInfo == other?.InstantiationInfo; } } -} \ No newline at end of file +} From 90885a31ae8f172fa89fa50279e2cde01ed3f9e7 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 18 Aug 2017 15:09:54 +0900 Subject: [PATCH 050/483] Round 2 of CI fixes. --- osu.Game/Rulesets/RulesetInfo.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index 8d19b28a81..740369b1b6 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -22,9 +22,6 @@ namespace osu.Game.Rulesets public virtual Ruleset CreateInstance() => (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo), this); - public bool Equals(RulesetInfo other) - { - return ID == other?.ID && Available == other?.Available && Name == other?.Name && InstantiationInfo == other?.InstantiationInfo; - } + public bool Equals(RulesetInfo other) => other != null && ID == other.ID && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo; } } From 306c00e593089589c98ddeea266ffc87d4871037 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 18 Aug 2017 16:26:48 +0930 Subject: [PATCH 051/483] Update framework to include PR #977 --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 5c22092e59..03b7608f21 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 5c22092e590d589927962b8d0173dae5f9b1405c +Subproject commit 03b7608f210b35dbcd3a811bda002e7a9334d081 From 9c6ca2d15928742fb2dbae1b56333d3656a2a7a9 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 18 Aug 2017 16:34:01 +0930 Subject: [PATCH 052/483] Add lazy weak property to DrawableOsuHitObject to find and cache the containing OsuInputManager, if it exists --- .../Objects/Drawables/DrawableOsuHitObject.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index ca1b44e1c7..c5d75f076b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.ComponentModel; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Judgements; @@ -51,6 +52,19 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected virtual void UpdateCurrentState(ArmedState state) { } + + private WeakReference osuActionInputManager = new WeakReference(null); + internal OsuInputManager OsuActionInputManager + { + get + { + OsuInputManager target = null; + if (osuActionInputManager.TryGetTarget(out target)) return target; + target = GetContainingInputManager() as OsuInputManager; + osuActionInputManager.SetTarget(target); + return target; + } + } } public enum ComboResult From 9628c0b6d656a2a63a62b46f649344a80399a08b Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 18 Aug 2017 16:46:00 +0930 Subject: [PATCH 053/483] Change spinner to check currently pressed actions rather than implementing IKeyBindingHandler --- .../Objects/Drawables/DrawableSpinner.cs | 8 +++++ .../Objects/Drawables/Pieces/SpinnerDisc.cs | 34 +------------------ 2 files changed, 9 insertions(+), 33 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 4a0b8422f1..307ef5d636 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; @@ -165,6 +166,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables glow.Colour = colours.BlueDark; } + protected override void Update() + { + disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton); + + base.Update(); + } + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 1e56a2559a..80d4391718 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -12,7 +12,7 @@ using OpenTK.Graphics; namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { - public class SpinnerDisc : CircularContainer, IHasAccentColour, IKeyBindingHandler + public class SpinnerDisc : CircularContainer, IHasAccentColour { private readonly Spinner spinner; @@ -73,39 +73,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces return base.OnMouseMove(state); } - public bool OnPressed(OsuAction action) - { - switch (action) - { - case OsuAction.LeftButton: - actionLeftButtonPressed = true; - break; - case OsuAction.RightButton: - actionRightButtonPressed = true; - break; - } - Tracking = actionLeftButtonPressed || actionRightButtonPressed; - return false; - } - - public bool OnReleased(OsuAction action) - { - switch (action) - { - case OsuAction.LeftButton: - actionLeftButtonPressed = false; - break; - case OsuAction.RightButton: - actionRightButtonPressed = false; - break; - } - Tracking = actionLeftButtonPressed || actionRightButtonPressed; - return false; - } - private Vector2 mousePosition; - private bool actionLeftButtonPressed; - private bool actionRightButtonPressed; private float lastAngle; private float currentRotation; From 90dacd9861809f715151bbcae699afc758914a3b Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 18 Aug 2017 16:49:10 +0930 Subject: [PATCH 054/483] Trim whitespace --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 307ef5d636..8473cc2453 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -169,7 +169,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void Update() { disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton); - + base.Update(); } From 529732ea473093a5a7bbd4fcd27f94b09872fb83 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 18 Aug 2017 16:58:01 +0930 Subject: [PATCH 055/483] More CI fixes --- .../Objects/Drawables/DrawableOsuHitObject.cs | 4 ++-- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index c5d75f076b..cca91925f0 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -53,12 +53,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { } - private WeakReference osuActionInputManager = new WeakReference(null); + private readonly WeakReference osuActionInputManager = new WeakReference(null); internal OsuInputManager OsuActionInputManager { get { - OsuInputManager target = null; + OsuInputManager target; if (osuActionInputManager.TryGetTarget(out target)) return target; target = GetContainingInputManager() as OsuInputManager; osuActionInputManager.SetTarget(target); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs index 80d4391718..6577c7fd50 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs @@ -5,7 +5,6 @@ using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; -using osu.Framework.Input.Bindings; using osu.Game.Graphics; using OpenTK; using OpenTK.Graphics; From 7ad4c046dbe06f30a2b564db87d46f8fc1c8e8a7 Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 18 Aug 2017 13:35:48 +0530 Subject: [PATCH 056/483] Make current value behaviour between channels and tabs consistent. - Trim whitespace --- osu.Game/Overlays/Chat/ChatTabControl.cs | 5 ++++- osu.Game/Overlays/ChatOverlay.cs | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 5f8db6fa71..c11e474b76 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -57,6 +57,9 @@ namespace osu.Game.Overlays.Chat TabContainer.ChangeChildDepth(selectorTab, float.MaxValue); base.AddTabItem(item, addToDropdown); + + if (SelectedTab == null) + SelectTab(item); } protected override TabItem CreateTabItem(Channel value) @@ -149,7 +152,7 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(InputState state) { closeButton?.FadeIn(1f, Easing.InBounce); - + if (!Active) box.FadeColour(backgroundHover, transition_length, Easing.OutQuint); return true; diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 855fb5a1d6..6f8bf69779 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -398,7 +398,10 @@ namespace osu.Game.Overlays if (channel == null) return; if (channel == CurrentChannel) + { + currentChannel = null; currentChannelContainer.Clear(false); + } careChannels.Remove(channel); loadedChannels.Remove(loadedChannels.Find(c => c.Channel == channel)); From 4901ac9e35f7c0cd4f23b15c30461e2593ea43df Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 18 Aug 2017 18:01:18 +0930 Subject: [PATCH 057/483] Add some comments explaining why the Track is being forcefully added to the TrackManager --- osu.Game/Screens/Select/SongSelect.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index e20ddf1c09..aa554152f9 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -370,6 +370,8 @@ namespace osu.Game.Screens.Select if (!track.IsRunning) { + // Ensure the track is added to the TrackManager, since it is removed after the player finishes the map. + // Using AddItemToList rather than AddItem so that it doesn't attempt to register adjustment dependencies more than once. Game.Audio.Track.AddItemToList(track); if (preview) track.Seek(Beatmap.Value.Metadata.PreviewTime); track.Start(); From 44feef78f14f4d13c7cd173cef22af6980e34bb9 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 18 Aug 2017 19:32:08 +0930 Subject: [PATCH 058/483] Simplify OsuActionInputManager property --- .../Objects/Drawables/DrawableOsuHitObject.cs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index cca91925f0..409244998e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -53,18 +53,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { } - private readonly WeakReference osuActionInputManager = new WeakReference(null); - internal OsuInputManager OsuActionInputManager - { - get - { - OsuInputManager target; - if (osuActionInputManager.TryGetTarget(out target)) return target; - target = GetContainingInputManager() as OsuInputManager; - osuActionInputManager.SetTarget(target); - return target; - } - } + private OsuInputManager osuActionInputManager; + internal OsuInputManager OsuActionInputManager => osuActionInputManager ?? (osuActionInputManager = GetContainingInputManager() as OsuInputManager); } public enum ComboResult From 9558d2a16185c5e1b3b2dd8e96f779970df100a9 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 18 Aug 2017 19:39:28 +0930 Subject: [PATCH 059/483] Remove unnecessary using --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 409244998e..b3043d18f6 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using System.ComponentModel; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Judgements; From 7e0fe6cbcbafbe0fce0bd6ebaf1d814b5423f9e6 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 18 Aug 2017 20:19:23 +0930 Subject: [PATCH 060/483] Fix slider tracking to use pressed actions rather than directly querying the mouse buttons --- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index dbfd9b291b..bdf67a48cc 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -118,7 +119,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces base.Update(); if (Time.Current < slider.EndTime) - Tracking = canCurrentlyTrack && lastState != null && ReceiveMouseInputAt(lastState.Mouse.NativeState.Position) && lastState.Mouse.HasMainButtonPressed; + Tracking = canCurrentlyTrack && lastState != null && ReceiveMouseInputAt(lastState.Mouse.NativeState.Position) && ((Parent as DrawableSlider)?.OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false); } public void UpdateProgress(double progress, int repeat) From d6249e7a633a4df5d504728c7af5404fd8d284d1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Aug 2017 18:22:00 +0900 Subject: [PATCH 061/483] Add support for binding mouse buttons to actions --- osu-framework | 2 +- osu.Game.Rulesets.Catch/CatchRuleset.cs | 12 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 8 +- .../Bindings/GlobalKeyBindingInputManager.cs | 17 ++- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 126 ++++++++++++------ .../Overlays/KeyBinding/KeyBindingsSection.cs | 5 +- 6 files changed, 111 insertions(+), 59 deletions(-) diff --git a/osu-framework b/osu-framework index 03b7608f21..825505e788 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 03b7608f210b35dbcd3a811bda002e7a9334d081 +Subproject commit 825505e788c4f093b269c61b485d38d50cd68096 diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index b486566b7d..f7662030fc 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -23,12 +23,12 @@ namespace osu.Game.Rulesets.Catch public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] { - new KeyBinding(Key.Z, CatchAction.MoveLeft), - new KeyBinding(Key.Left, CatchAction.MoveLeft), - new KeyBinding(Key.X, CatchAction.MoveRight), - new KeyBinding(Key.Right, CatchAction.MoveRight), - new KeyBinding(Key.LShift, CatchAction.Dash), - new KeyBinding(Key.RShift, CatchAction.Dash), + new KeyBinding(InputKey.Z, CatchAction.MoveLeft), + new KeyBinding(InputKey.Left, CatchAction.MoveLeft), + new KeyBinding(InputKey.X, CatchAction.MoveRight), + new KeyBinding(InputKey.Right, CatchAction.MoveRight), + new KeyBinding(InputKey.Shift, CatchAction.Dash), + new KeyBinding(InputKey.Shift, CatchAction.Dash), }; public override IEnumerable GetModsFor(ModType type) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 75b7be01a4..aaa1dff820 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -27,10 +27,10 @@ namespace osu.Game.Rulesets.Osu public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] { - new KeyBinding(Key.Z, OsuAction.LeftButton), - new KeyBinding(Key.X, OsuAction.RightButton), - new KeyBinding(Key.LastKey + 1, OsuAction.LeftButton), - new KeyBinding(Key.LastKey + 2, OsuAction.RightButton), + new KeyBinding(InputKey.Z, OsuAction.LeftButton), + new KeyBinding(InputKey.X, OsuAction.RightButton), + new KeyBinding(InputKey.LastKey + 1, OsuAction.LeftButton), + new KeyBinding(InputKey.LastKey + 2, OsuAction.RightButton), }; public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new[] diff --git a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs index 31be2e6adc..5ea66fa600 100644 --- a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK.Input; using System.Collections.Generic; using System.ComponentModel; using System.Linq; @@ -22,16 +21,16 @@ namespace osu.Game.Input.Bindings public override IEnumerable DefaultKeyBindings => new[] { - new KeyBinding(Key.F8, GlobalAction.ToggleChat), - new KeyBinding(Key.F9, GlobalAction.ToggleSocial), - new KeyBinding(new[] { Key.LControl, Key.LAlt, Key.R }, GlobalAction.ResetInputSettings), - new KeyBinding(new[] { Key.LControl, Key.T }, GlobalAction.ToggleToolbar), - new KeyBinding(new[] { Key.LControl, Key.O }, GlobalAction.ToggleSettings), - new KeyBinding(new[] { Key.LControl, Key.D }, GlobalAction.ToggleDirect), + new KeyBinding(InputKey.F8, GlobalAction.ToggleChat), + new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial), + new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings), + new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar), + new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings), + new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.ToggleDirect), }; - protected override IEnumerable GetKeyboardInputQueue() => - handler == null ? base.GetKeyboardInputQueue() : new[] { handler }.Concat(base.GetKeyboardInputQueue()); + protected override IEnumerable KeyBindingInputQueue => + handler == null ? base.KeyBindingInputQueue : new[] { handler }.Concat(base.KeyBindingInputQueue); } public enum GlobalAction diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 44aee0e666..a3361743a1 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -11,6 +11,7 @@ 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.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Input; @@ -123,46 +124,74 @@ namespace osu.Game.Overlays.KeyBinding base.OnHoverLost(state); } - public override bool AcceptsFocus => true; + public override bool AcceptsFocus => bindTarget == null; private KeyButton bindTarget; - protected override void OnFocus(InputState state) - { - AutoSizeDuration = 500; - AutoSizeEasing = Easing.OutQuint; - - pressAKey.FadeIn(300, Easing.OutQuint); - pressAKey.Padding = new MarginPadding(); - - base.OnFocus(state); - } + public bool AllowMainMouseButtons; private bool isModifier(Key k) => k < Key.F1; - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - switch (args.Key) - { - case Key.Escape: - GetContainingInputManager().ChangeFocus(null); - return true; - case Key.Delete: - bindTarget.UpdateKeyCombination(Key.Unknown); - store.Update(bindTarget.KeyBinding); - GetContainingInputManager().ChangeFocus(null); - return true; - } + protected override bool OnClick(InputState state) => true; + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { if (HasFocus) { - bindTarget.UpdateKeyCombination(state.Keyboard.Keys.ToArray()); - if (!isModifier(args.Key)) + if (bindTarget.IsHovered) + { + if (!AllowMainMouseButtons) + { + switch (args.Button) + { + case MouseButton.Left: + case MouseButton.Right: + return true; + } + } + + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(state)); + return true; + } + } + + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + if (HasFocus && !state.Mouse.Buttons.Any()) + { + if (bindTarget.IsHovered) finalise(); + else + updateBindTarget(); return true; } - return base.OnKeyDown(state, args); + return base.OnMouseUp(state, args); + } + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (!HasFocus) + return false; + + switch (args.Key) + { + case Key.Escape: + finalise(); + return true; + case Key.Delete: + bindTarget.UpdateKeyCombination(InputKey.None); + finalise(); + return true; + } + + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(state)); + if (!isModifier(args.Key)) finalise(); + + return true; } protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) @@ -178,27 +207,48 @@ namespace osu.Game.Overlays.KeyBinding private void finalise() { - store.Update(bindTarget.KeyBinding); - GetContainingInputManager().ChangeFocus(null); + if (bindTarget != null) + { + store.Update(bindTarget.KeyBinding); + + bindTarget.IsBinding = false; + Schedule(() => + { + // schedule to ensure we don't instantly get focus back on next OnMouseClick (see AcceptFocus impl.) + bindTarget = null; + }); + } + + if (HasFocus) + GetContainingInputManager().ChangeFocus(null); + + pressAKey.FadeOut(300, Easing.OutQuint); + pressAKey.Padding = new MarginPadding { Bottom = -pressAKey.DrawHeight }; + } + + protected override void OnFocus(InputState state) + { + AutoSizeDuration = 500; + AutoSizeEasing = Easing.OutQuint; + + pressAKey.FadeIn(300, Easing.OutQuint); + pressAKey.Padding = new MarginPadding(); + + updateBindTarget(); + base.OnFocus(state); } protected override void OnFocusLost(InputState state) { - bindTarget.IsBinding = false; - bindTarget = null; - - pressAKey.FadeOut(300, Easing.OutQuint); - pressAKey.Padding = new MarginPadding { Bottom = -pressAKey.DrawHeight }; + finalise(); base.OnFocusLost(state); } - protected override bool OnClick(InputState state) + private void updateBindTarget() { if (bindTarget != null) bindTarget.IsBinding = false; bindTarget = buttons.FirstOrDefault(b => b.IsHovered) ?? buttons.FirstOrDefault(); if (bindTarget != null) bindTarget.IsBinding = true; - - return bindTarget != null; } private class KeyButton : Container @@ -296,7 +346,7 @@ namespace osu.Game.Overlays.KeyBinding } } - public void UpdateKeyCombination(params Key[] newCombination) + public void UpdateKeyCombination(KeyCombination newCombination) { KeyBinding.KeyCombination = newCombination; Text.Text = KeyBinding.KeyCombination.ReadableString(); diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs index 19baeca771..44c28ee9c8 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs @@ -40,7 +40,10 @@ namespace osu.Game.Overlays.KeyBinding foreach (Enum v in Enum.GetValues(enumType)) // one row per valid action. - Add(new KeyBindingRow(v, bindings.Where(b => b.Action.Equals((int)(object)v)))); + Add(new KeyBindingRow(v, bindings.Where(b => b.Action.Equals((int)(object)v))) + { + AllowMainMouseButtons = Ruleset != null + }); } } } \ No newline at end of file From f831832c59b0b015abd22fe2e5d529f962b4196c Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Sat, 19 Aug 2017 00:13:06 +0200 Subject: [PATCH 062/483] CI fix --- osu.Game/Rulesets/Scoring/Score.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index e83cb916bb..154188a2fa 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -38,11 +38,8 @@ namespace osu.Game.Rulesets.Scoring { get { - // Evaluate the mod strings - if (mods == null) - mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); - - return mods; + // Evaluate the mod strings if necessary + return mods ?? (mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray()); } set { From f829caf197c7565bf8d4995073d1eae17c183579 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 19 Aug 2017 07:21:20 +0900 Subject: [PATCH 063/483] Fix custom logic still existing in OsuInputManager --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index a29b128e07..0c4384c006 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -2,13 +2,8 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.ComponentModel; -using System.Linq; -using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Game.Input.Bindings; -using OpenTK.Input; -using KeyboardState = osu.Framework.Input.KeyboardState; -using MouseState = osu.Framework.Input.MouseState; namespace osu.Game.Rulesets.Osu { @@ -16,22 +11,6 @@ namespace osu.Game.Rulesets.Osu { public OsuInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique) { - - } - protected override void TransformState(InputState state) - { - base.TransformState(state); - - var mouse = state.Mouse as MouseState; - var keyboard = state.Keyboard as KeyboardState; - - if (mouse != null && keyboard != null) - { - if (mouse.IsPressed(MouseButton.Left)) - keyboard.Keys = keyboard.Keys.Concat(new[] { Key.LastKey + 1 }); - if (mouse.IsPressed(MouseButton.Right)) - keyboard.Keys = keyboard.Keys.Concat(new[] { Key.LastKey + 2 }); - } } } From 51af233d66f5cf54449d1252e0d6c5de260bc099 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Sat, 19 Aug 2017 12:19:37 +0930 Subject: [PATCH 064/483] Fix sliders not checking the correct cursor position once it moves out of the follow circle --- .../Objects/Drawables/Pieces/SliderBall.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index bdf67a48cc..9b5862e739 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input; +using OpenTK; using OpenTK.Graphics; namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces @@ -97,6 +98,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces return base.OnMouseMove(state); } + public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) + { + // If the current time is between the start and end of the slider, we should track mouse input regardless of the cursor position. + return canCurrentlyTrack || base.ReceiveMouseInputAt(screenSpacePos); + } + private bool tracking; public bool Tracking { @@ -118,8 +125,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { base.Update(); + // Make sure to use the base version of ReceiveMouseInputAt so that we correctly check the position. if (Time.Current < slider.EndTime) - Tracking = canCurrentlyTrack && lastState != null && ReceiveMouseInputAt(lastState.Mouse.NativeState.Position) && ((Parent as DrawableSlider)?.OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false); + Tracking = canCurrentlyTrack && lastState != null && base.ReceiveMouseInputAt(lastState.Mouse.NativeState.Position) && ((Parent as DrawableSlider)?.OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false); } public void UpdateProgress(double progress, int repeat) From 1e6d99a4ef1e0787b9863cc72545e69286db332f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 19 Aug 2017 07:31:03 +0900 Subject: [PATCH 065/483] Update paths --- osu.Desktop.Deploy/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Desktop.Deploy/Program.cs b/osu.Desktop.Deploy/Program.cs index 37776b329f..644987ce5a 100644 --- a/osu.Desktop.Deploy/Program.cs +++ b/osu.Desktop.Deploy/Program.cs @@ -17,8 +17,8 @@ namespace osu.Desktop.Deploy { internal static class Program { - private const string nuget_path = @"packages\NuGet.CommandLine.3.5.0\tools\NuGet.exe"; - private const string squirrel_path = @"packages\squirrel.windows.1.5.2\tools\Squirrel.exe"; + private const string nuget_path = @"packages\NuGet.CommandLine.4.1.0\tools\NuGet.exe"; + private const string squirrel_path = @"packages\squirrel.windows.1.7.5\tools\Squirrel.exe"; private const string msbuild_path = @"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe"; public static string StagingFolder = ConfigurationManager.AppSettings["StagingFolder"]; From 3ea7be1ccfef8643fcc94597d9b542dbb43d0909 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Sat, 19 Aug 2017 12:26:54 +0900 Subject: [PATCH 066/483] Fix selecting unranked beatmaps in song select crashing the game. Fixes #1134. --- osu.Game/Graphics/UserInterface/BarGraph.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index 87b4ab9e40..1a980e6bd5 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -44,19 +44,31 @@ namespace osu.Game.Graphics.UserInterface { List bars = Children.ToList(); foreach (var bar in value.Select((length, index) => new { Value = length, Bar = bars.Count > index ? bars[index] : null })) + { + float length = MaxValue ?? value.Max(); + if (length != 0) + length = bar.Value / length; + + float size = value.Count(); + if (size != 0) + size = 1.0f / size; + if (bar.Bar != null) { - bar.Bar.Length = bar.Value / (MaxValue ?? value.Max()); - bar.Bar.Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, 1.0f / value.Count()) : new Vector2(1.0f / value.Count(), 1); + bar.Bar.Length = length; + bar.Bar.Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, size) : new Vector2(size, 1); } else + { Add(new Bar { RelativeSizeAxes = Axes.Both, - Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, 1.0f / value.Count()) : new Vector2(1.0f / value.Count(), 1), - Length = bar.Value / (MaxValue ?? value.Max()), + Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, size) : new Vector2(size, 1), + Length = length, Direction = Direction, }); + } + } //I'm using ToList() here because Where() returns an Enumerable which can change it's elements afterwards RemoveRange(Children.Where((bar, index) => index >= value.Count()).ToList()); } From 9bebb9f5b0ec5c087801504fce2eaee06850dc4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Sat, 19 Aug 2017 16:09:32 +0200 Subject: [PATCH 067/483] Remove now unused SliderBar class --- .../Visual/TestCaseKeyCounter.cs | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs b/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs index 1861a77a3a..e8b6e6378e 100644 --- a/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs +++ b/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs @@ -41,38 +41,5 @@ namespace osu.Desktop.Tests.Visual Add(kc); } - private class TestSliderBar : SliderBar where T : struct - { - public Color4 Color - { - get { return Box.Colour; } - set { Box.Colour = value; } - } - - public Color4 SelectionColor - { - get { return SelectionBox.Colour; } - set { SelectionBox.Colour = value; } - } - - protected readonly Box SelectionBox; - protected readonly Box Box; - - public TestSliderBar() - { - Children = new Drawable[] - { - Box = new Box { RelativeSizeAxes = Axes.Both }, - SelectionBox = new Box { RelativeSizeAxes = Axes.Both } - }; - } - - protected override void UpdateValue(float value) - { - SelectionBox.ScaleTo( - new Vector2(value, 1), - 300, Easing.OutQuint); - } - } } } From bae1340b5063a9bb72fe2c31f31cf88048c0e782 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sat, 19 Aug 2017 17:00:01 +0200 Subject: [PATCH 068/483] mask the settings overlay --- osu.Game/Overlays/SettingsOverlay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index f9ec2f68b5..ddef5d1001 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -79,6 +79,7 @@ namespace osu.Game.Overlays }, SectionsContainer = new SettingsSectionsContainer { + Masking = true, RelativeSizeAxes = Axes.Both, ExpandableHeader = CreateHeader(), FixedHeader = searchTextBox = new SearchTextBox From 7e1df7907febed0cab5d5d423a0f917e7ddc6df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Sat, 19 Aug 2017 17:43:02 +0200 Subject: [PATCH 069/483] Remove now unnecessary usings --- osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs b/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs index e8b6e6378e..ffe37c83a6 100644 --- a/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs +++ b/osu.Desktop.Tests/Visual/TestCaseKeyCounter.cs @@ -2,12 +2,8 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.UserInterface; using osu.Framework.MathUtils; using osu.Game.Screens.Play; -using OpenTK; -using OpenTK.Graphics; using OpenTK.Input; namespace osu.Desktop.Tests.Visual From 9b20da94e7cc0d1c27819b8bbb6d7bd4fc546302 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Sat, 19 Aug 2017 22:07:03 +0200 Subject: [PATCH 070/483] change Query to AllRulesets --- osu.Game/Input/KeyBindingStore.cs | 2 +- osu.Game/Overlays/KeyBindingOverlay.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Input/KeyBindingStore.cs b/osu.Game/Input/KeyBindingStore.cs index f50acb4802..56302acafe 100644 --- a/osu.Game/Input/KeyBindingStore.cs +++ b/osu.Game/Input/KeyBindingStore.cs @@ -18,7 +18,7 @@ namespace osu.Game.Input public KeyBindingStore(SQLiteConnection connection, RulesetStore rulesets, Storage storage = null) : base(connection, storage) { - foreach (var info in rulesets.Query()) + foreach (var info in rulesets.AllRulesets) { var ruleset = info.CreateInstance(); foreach (var variant in ruleset.AvailableVariants) diff --git a/osu.Game/Overlays/KeyBindingOverlay.cs b/osu.Game/Overlays/KeyBindingOverlay.cs index 7d6ef7ffa6..827d361099 100644 --- a/osu.Game/Overlays/KeyBindingOverlay.cs +++ b/osu.Game/Overlays/KeyBindingOverlay.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays { AddSection(new GlobalKeyBindingsSection(global, "Global")); - foreach (var ruleset in rulesets.Query()) + foreach (var ruleset in rulesets.AllRulesets) AddSection(new RulesetBindingsSection(ruleset)); } From 71ddbd22a1b74c28ed7dc182396939d942fb6cfa Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Sun, 20 Aug 2017 14:00:53 +0930 Subject: [PATCH 071/483] Convert ReceiveMouseInputAt override to lambda syntax, and make Tracking property private set --- .../Objects/Drawables/Pieces/SliderBall.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index 9b5862e739..0bcb8a4986 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -98,17 +98,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces return base.OnMouseMove(state); } - public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) - { - // If the current time is between the start and end of the slider, we should track mouse input regardless of the cursor position. - return canCurrentlyTrack || base.ReceiveMouseInputAt(screenSpacePos); - } + // If the current time is between the start and end of the slider, we should track mouse input regardless of the cursor position. + public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => canCurrentlyTrack || base.ReceiveMouseInputAt(screenSpacePos); private bool tracking; public bool Tracking { get { return tracking; } - set + private set { if (value == tracking) return; From ff84eb219bfdbf954da4046dadbd5d48f7a6eb7b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 20 Aug 2017 21:18:21 +0900 Subject: [PATCH 072/483] Add action support to taiko --- .../Objects/Drawables/DrawableCentreHit.cs | 3 +- .../Drawables/DrawableCentreHitStrong.cs | 3 +- .../Objects/Drawables/DrawableDrumRoll.cs | 2 + .../Objects/Drawables/DrawableDrumRollTick.cs | 3 +- .../Objects/Drawables/DrawableHit.cs | 7 ++-- .../Objects/Drawables/DrawableHitStrong.cs | 30 +++++++------- .../Objects/Drawables/DrawableRimHit.cs | 3 +- .../Objects/Drawables/DrawableRimHitStrong.cs | 3 +- .../Objects/Drawables/DrawableSwell.cs | 16 ++++---- .../Drawables/DrawableTaikoHitObject.cs | 41 ++++++++----------- 10 files changed, 50 insertions(+), 61 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHit.cs index 8bb78669ca..26aa20f1af 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHit.cs @@ -4,13 +4,12 @@ using osu.Framework.Allocation; using osu.Game.Graphics; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; -using OpenTK.Input; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { public class DrawableCentreHit : DrawableHit { - protected override Key[] HitKeys { get; } = { Key.F, Key.J }; + protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftCentre, TaikoAction.RightCentre }; public DrawableCentreHit(Hit hit) : base(hit) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs index 434fb9377f..1dbab408de 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs @@ -4,13 +4,12 @@ using osu.Framework.Allocation; using osu.Game.Graphics; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; -using OpenTK.Input; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { public class DrawableCentreHitStrong : DrawableHitStrong { - protected override Key[] HitKeys { get; } = { Key.F, Key.J }; + protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftCentre, TaikoAction.RightCentre }; public DrawableCentreHitStrong(Hit hit) : base(hit) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 8f81368a2c..5d6ea8f51e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -56,6 +56,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece(); + public override bool OnPressed(TaikoAction action) => false; + [BackgroundDependencyLoader] private void load(OsuColour colours) { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 6e916aa9d5..e94886df16 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -5,7 +5,6 @@ using System; using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Judgements; -using OpenTK.Input; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; namespace osu.Game.Rulesets.Taiko.Objects.Drawables @@ -59,7 +58,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } - protected override bool HandleKeyPress(Key key) + public override bool OnPressed(TaikoAction action) { return Judgement.Result == HitResult.None && UpdateJudgement(true); } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 0666d75083..5fcae7d0f4 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; -using OpenTK.Input; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -16,7 +15,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// /// A list of keys which can result in hits for this HitObject. /// - protected abstract Key[] HitKeys { get; } + protected abstract TaikoAction[] HitActions { get; } /// /// Whether the last key pressed is a valid hit key. @@ -62,12 +61,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Judgement.Result = HitResult.Miss; } - protected override bool HandleKeyPress(Key key) + public override bool OnPressed(TaikoAction action) { if (Judgement.Result != HitResult.None) return false; - validKeyPressed = HitKeys.Contains(key); + validKeyPressed = HitActions.Contains(action); return UpdateJudgement(true); } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs index 57e7eea470..f419bacfa1 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs @@ -6,7 +6,6 @@ using System.Linq; using osu.Framework.Input; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Judgements; -using OpenTK.Input; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -20,7 +19,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables private double firstHitTime; private bool firstKeyHeld; - private Key firstHitKey; + private TaikoAction firstHitAction; protected DrawableHitStrong(Hit hit) : base(hit) @@ -46,18 +45,26 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Judgement.SecondHit = true; } - protected override bool HandleKeyPress(Key key) + public override bool OnReleased(TaikoAction action) + { + if (action == firstHitAction) + firstKeyHeld = false; + return base.OnReleased(action); + } + + public override bool OnPressed(TaikoAction action) { // Check if we've handled the first key if (Judgement.Result == HitResult.None) { // First key hasn't been handled yet, attempt to handle it - bool handled = base.HandleKeyPress(key); + bool handled = base.OnPressed(action); if (handled) { firstHitTime = Time.Current; - firstHitKey = key; + firstHitAction = action; + firstKeyHeld = true; } return handled; @@ -68,22 +75,15 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return false; // Don't handle represses of the first key - if (firstHitKey == key) + if (firstHitAction == action) return false; - // Don't handle invalid hit key presses - if (!HitKeys.Contains(key)) + // Don't handle invalid hit action presses + if (!HitActions.Contains(action)) return false; // Assume the intention was to hit the strong hit with both keys only if the first key is still being held down return firstKeyHeld && UpdateJudgement(true); } - - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - firstKeyHeld = state.Keyboard.Keys.Contains(firstHitKey); - - return base.OnKeyDown(state, args); - } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHit.cs index 20e8d36105..9f0cd3e061 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHit.cs @@ -4,13 +4,12 @@ using osu.Framework.Allocation; using osu.Game.Graphics; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; -using OpenTK.Input; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { public class DrawableRimHit : DrawableHit { - protected override Key[] HitKeys { get; } = { Key.D, Key.K }; + protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftRim, TaikoAction.RightRim }; public DrawableRimHit(Hit hit) : base(hit) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHitStrong.cs index 4b1bb62bab..294198f3ee 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHitStrong.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHitStrong.cs @@ -4,13 +4,12 @@ using osu.Framework.Allocation; using osu.Game.Graphics; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; -using OpenTK.Input; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { public class DrawableRimHitStrong : DrawableHitStrong { - protected override Key[] HitKeys { get; } = { Key.D, Key.K }; + protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftRim, TaikoAction.RightRim }; public DrawableRimHitStrong(Hit hit) : base(hit) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 2b1ed07da7..fc3bc82520 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -13,7 +13,6 @@ using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using OpenTK; using OpenTK.Graphics; -using OpenTK.Input; using osu.Framework.Graphics.Shapes; namespace osu.Game.Rulesets.Taiko.Objects.Drawables @@ -35,9 +34,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables private readonly CircularContainer targetRing; private readonly CircularContainer expandingRing; - private readonly Key[] rimKeys = { Key.D, Key.K }; - private readonly Key[] centreKeys = { Key.F, Key.J }; - private Key[] lastKeySet; + private readonly TaikoAction[] rimActions = { TaikoAction.LeftRim, TaikoAction.RightRim }; + private readonly TaikoAction[] centreActions = { TaikoAction.LeftCentre, TaikoAction.RightCentre }; + private TaikoAction[] lastAction; /// /// The amount of times the user has hit this swell. @@ -211,8 +210,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } - - protected override bool HandleKeyPress(Key key) + public override bool OnPressed(TaikoAction action) { if (Judgement.Result != HitResult.None) return false; @@ -222,12 +220,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return false; // Find the keyset which this key corresponds to - var keySet = rimKeys.Contains(key) ? rimKeys : centreKeys; + var keySet = rimActions.Contains(action) ? rimActions : centreActions; // Ensure alternating keysets - if (keySet == lastKeySet) + if (keySet == lastAction) return false; - lastKeySet = keySet; + lastAction = keySet; UpdateJudgement(true); diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index caae70fe05..44b371f710 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -1,26 +1,21 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; +using System.ComponentModel; using osu.Framework.Graphics; -using osu.Framework.Input; +using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using OpenTK; -using OpenTK.Input; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public abstract class DrawableTaikoHitObject : DrawableScrollingHitObject + public abstract class DrawableTaikoHitObject : + DrawableScrollingHitObject, + IKeyBindingHandler where TaikoHitType : TaikoHitObject { - /// - /// A list of keys which this hit object will accept. These are the standard Taiko keys for now. - /// These should be moved to bindings later. - /// - private readonly List validKeys = new List(new[] { Key.D, Key.F, Key.J, Key.K }); - public override Vector2 OriginPosition => new Vector2(DrawHeight / 2); protected readonly TaikoPiece MainPiece; @@ -46,20 +41,20 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected virtual TaikoPiece CreateMainPiece() => new CirclePiece(); - protected virtual bool HandleKeyPress(Key key) => false; + public abstract bool OnPressed(TaikoAction action); - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - // Make sure we don't handle held-down keys - if (args.Repeat) - return false; + public virtual bool OnReleased(TaikoAction action) => false; + } - // Check if we've pressed a valid taiko key - if (!validKeys.Contains(args.Key)) - return false; - - // Handle it! - return HandleKeyPress(args.Key); - } + public enum TaikoAction + { + [Description("Left (Rim)")] + LeftRim, + [Description("Left (Centre)")] + LeftCentre, + [Description("Right (Centre)")] + RightCentre, + [Description("Right (Rim)")] + RightRim } } From 59fc6cbed7b2c207ecfff3353f253ca97785cacb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 20 Aug 2017 21:51:56 +0900 Subject: [PATCH 073/483] Add action support to InputDrum --- .../Objects/Drawables/DrawableHitStrong.cs | 1 - osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 29 +++++++++---------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs index f419bacfa1..256c50d33a 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs @@ -3,7 +3,6 @@ using System; using System.Linq; -using osu.Framework.Input; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Judgements; diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 0255171284..9cabf2cd2b 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -3,14 +3,14 @@ using System; using OpenTK; -using OpenTK.Input; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Framework.Input; +using osu.Framework.Input.Bindings; using osu.Game.Graphics; +using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.UI { @@ -36,8 +36,8 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, RelativePositionAxes = Axes.X, X = -middle_split / 2, - RimKey = Key.D, - CentreKey = Key.F + RimAction = TaikoAction.LeftRim, + CentreAction = TaikoAction.LeftCentre }, new TaikoHalfDrum(true) { @@ -47,8 +47,8 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, RelativePositionAxes = Axes.X, X = middle_split / 2, - RimKey = Key.K, - CentreKey = Key.J + RimAction = TaikoAction.RightRim, + CentreAction = TaikoAction.RightCentre } }; } @@ -56,17 +56,17 @@ namespace osu.Game.Rulesets.Taiko.UI /// /// A half-drum. Contains one centre and one rim hit. /// - private class TaikoHalfDrum : Container + private class TaikoHalfDrum : Container, IKeyBindingHandler { /// /// The key to be used for the rim of the half-drum. /// - public Key RimKey; + public TaikoAction RimAction; /// /// The key to be used for the centre of the half-drum. /// - public Key CentreKey; + public TaikoAction CentreAction; private readonly Sprite rim; private readonly Sprite rimHit; @@ -124,20 +124,17 @@ namespace osu.Game.Rulesets.Taiko.UI centreHit.Colour = colours.Pink; } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + public bool OnPressed(TaikoAction action) { - if (args.Repeat) - return false; - Drawable target = null; Drawable back = null; - if (args.Key == CentreKey) + if (action == CentreAction) { target = centreHit; back = centre; } - else if (args.Key == RimKey) + else if (action == RimAction) { target = rimHit; back = rim; @@ -166,6 +163,8 @@ namespace osu.Game.Rulesets.Taiko.UI return false; } + + public bool OnReleased(TaikoAction action) => false; } } } From 09b5eef26e8ae1852cfc6a5e1e14f0464e482bb2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 20 Aug 2017 21:56:28 +0900 Subject: [PATCH 074/483] Fix incorrect osu! defaults --- osu.Game.Rulesets.Osu/OsuRuleset.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index aaa1dff820..49848cb67c 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -29,8 +29,8 @@ namespace osu.Game.Rulesets.Osu { new KeyBinding(InputKey.Z, OsuAction.LeftButton), new KeyBinding(InputKey.X, OsuAction.RightButton), - new KeyBinding(InputKey.LastKey + 1, OsuAction.LeftButton), - new KeyBinding(InputKey.LastKey + 2, OsuAction.RightButton), + new KeyBinding(InputKey.MouseLeft, OsuAction.LeftButton), + new KeyBinding(InputKey.MouseRight, OsuAction.RightButton), }; public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new[] From ec08b2940d8fe1a028b208e4d6d6fd0db3275105 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 20 Aug 2017 21:56:37 +0900 Subject: [PATCH 075/483] Add taiko default keys --- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 4d4bbb7bc5..892c8a1705 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -13,6 +13,8 @@ using System.Collections.Generic; using osu.Framework.Graphics; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Scoring; +using osu.Framework.Input.Bindings; +using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko { @@ -20,6 +22,14 @@ namespace osu.Game.Rulesets.Taiko { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new TaikoRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[] + { + new KeyBinding(InputKey.D, TaikoAction.LeftRim), + new KeyBinding(InputKey.F, TaikoAction.LeftCentre), + new KeyBinding(InputKey.J, TaikoAction.RightCentre), + new KeyBinding(InputKey.K, TaikoAction.RightRim), + }; + public override IEnumerable GetModsFor(ModType type) { switch (type) From a18b2bd5f05106b25e0ce2f832e8da892ced0ae5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 20 Aug 2017 22:21:16 +0900 Subject: [PATCH 076/483] Hook everything up --- .../Visual/TestCaseTaikoPlayfield.cs | 11 ++++--- .../Drawables/DrawableTaikoHitObject.cs | 13 --------- osu.Game.Rulesets.Taiko/TaikoInputManager.cs | 29 +++++++++++++++++++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 1 - osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 1 - .../UI/TaikoRulesetContainer.cs | 3 ++ .../osu.Game.Rulesets.Taiko.csproj | 1 + 7 files changed, 40 insertions(+), 19 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/TaikoInputManager.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs index 43148da512..681805ced0 100644 --- a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs @@ -16,6 +16,8 @@ using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps; using osu.Desktop.Tests.Beatmaps; using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Game.Rulesets; using osu.Game.Rulesets.Objects; namespace osu.Desktop.Tests.Visual @@ -30,10 +32,11 @@ namespace osu.Desktop.Tests.Visual protected override double TimePerAction => default_duration * 2; private readonly Random rng = new Random(1337); - private readonly TaikoRulesetContainer rulesetContainer; - private readonly Container playfieldContainer; + private TaikoRulesetContainer rulesetContainer; + private Container playfieldContainer; - public TestCaseTaikoPlayfield() + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets) { AddStep("Hit!", () => addHitJudgement(false)); AddStep("Kiai hit", () => addHitJudgement(true)); @@ -82,7 +85,7 @@ namespace osu.Desktop.Tests.Visual RelativeSizeAxes = Axes.X, Height = 768, Clock = new FramedClock(rateAdjustClock), - Children = new[] { rulesetContainer = new TaikoRulesetContainer(null, beatmap, true) } + Children = new[] { rulesetContainer = new TaikoRulesetContainer(rulesets.GetRuleset(1).CreateInstance(), beatmap, true) } }); } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 44b371f710..8d7a14b683 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.ComponentModel; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; @@ -45,16 +44,4 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public virtual bool OnReleased(TaikoAction action) => false; } - - public enum TaikoAction - { - [Description("Left (Rim)")] - LeftRim, - [Description("Left (Centre)")] - LeftCentre, - [Description("Right (Centre)")] - RightCentre, - [Description("Right (Rim)")] - RightRim - } } diff --git a/osu.Game.Rulesets.Taiko/TaikoInputManager.cs b/osu.Game.Rulesets.Taiko/TaikoInputManager.cs new file mode 100644 index 0000000000..ad3b25d088 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/TaikoInputManager.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.ComponentModel; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; + +namespace osu.Game.Rulesets.Taiko +{ + public class TaikoInputManager : DatabasedKeyBindingInputManager + { + public TaikoInputManager(RulesetInfo ruleset) + : base(ruleset, 0, SimultaneousBindingMode.Unique) + { + } + } + + public enum TaikoAction + { + [Description("Left (Rim)")] + LeftRim, + [Description("Left (Centre)")] + LeftCentre, + [Description("Right (Centre)")] + RightCentre, + [Description("Right (Rim)")] + RightRim + } +} diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 892c8a1705..3a85df43fe 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -14,7 +14,6 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Scoring; using osu.Framework.Input.Bindings; -using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko { diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 9cabf2cd2b..659f421ebe 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Input.Bindings; using osu.Game.Graphics; -using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.UI { diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index 723af3e4e9..4b1c3d7f16 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -18,6 +18,7 @@ using osu.Game.Rulesets.Taiko.Replays; using OpenTK; using osu.Game.Rulesets.Beatmaps; using System.Linq; +using osu.Framework.Input; namespace osu.Game.Rulesets.Taiko.UI { @@ -92,6 +93,8 @@ namespace osu.Game.Rulesets.Taiko.UI protected override BeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter(); + public override PassThroughInputManager CreateKeyBindingInputManager() => new TaikoInputManager(Ruleset?.RulesetInfo); + protected override Playfield CreatePlayfield() => new TaikoPlayfield { Anchor = Anchor.CentreLeft, diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 59c6f4db0a..33748a267f 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -86,6 +86,7 @@ + From 325eaa8671f53adc2c2d47cb72a65d5329a81232 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 20 Aug 2017 22:26:33 +0900 Subject: [PATCH 077/483] Add mouse buttons defaults for taiko --- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 3a85df43fe..41b8ff78a9 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -27,6 +27,10 @@ namespace osu.Game.Rulesets.Taiko new KeyBinding(InputKey.F, TaikoAction.LeftCentre), new KeyBinding(InputKey.J, TaikoAction.RightCentre), new KeyBinding(InputKey.K, TaikoAction.RightRim), + new KeyBinding(InputKey.MouseLeft, TaikoAction.LeftCentre), + new KeyBinding(InputKey.MouseLeft, TaikoAction.RightCentre), + new KeyBinding(InputKey.MouseRight, TaikoAction.LeftRim), + new KeyBinding(InputKey.MouseRight, TaikoAction.RightRim), }; public override IEnumerable GetModsFor(ModType type) From 83643396176e4e085ef5f1cf10f4aac2aad6d213 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 20 Aug 2017 23:47:07 +0900 Subject: [PATCH 078/483] Adjust with proposed formatting --- .../Objects/Drawables/DrawableTaikoHitObject.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 8d7a14b683..765002fb34 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -10,10 +10,9 @@ using OpenTK; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public abstract class DrawableTaikoHitObject : - DrawableScrollingHitObject, - IKeyBindingHandler - where TaikoHitType : TaikoHitObject + public abstract class DrawableTaikoHitObject + : DrawableScrollingHitObject, IKeyBindingHandler + where TaikoHitType : TaikoHitObject { public override Vector2 OriginPosition => new Vector2(DrawHeight / 2); From 6a7b410bc3f9616d8d9fb2e952e1f2f9f49cfb52 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 21 Aug 2017 11:45:57 +0900 Subject: [PATCH 079/483] Make DifficultyControlPoint.SpeedMultiplier actually increase with an increasing speed. Fixes #1147 --- .../Patterns/Legacy/DistanceObjectPatternGenerator.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 +- osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs | 4 ++-- osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs | 2 +- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- osu.Game/Rulesets/Timing/MultiplierControlPoint.cs | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 7e9615a703..c03a8438ae 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy // The true distance, accounting for any repeats double distance = (distanceData?.Distance ?? 0) * repeatCount; // The velocity of the osu! hit object - calculated as the velocity of a slider - double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.Difficulty.SliderMultiplier / (timingPoint.BeatLength * difficultyPoint.SpeedMultiplier); + double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.Difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / timingPoint.BeatLength; // The duration of the osu! hit object double osuDuration = distance / osuVelocity; diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 4d8c030ede..056bde4005 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Osu.Objects TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime); - double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier / difficultyPoint.SpeedMultiplier; + double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier; Velocity = scoringDistance / timingPoint.BeatLength; TickDistance = scoringDistance / difficulty.SliderTickRate; diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 44f61e2074..b6d87c745f 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps DifficultyControlPoint difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(obj.StartTime); double speedAdjustment = difficultyPoint.SpeedMultiplier; - double speedAdjustedBeatLength = timingPoint.BeatLength * speedAdjustment; + double speedAdjustedBeatLength = timingPoint.BeatLength / speedAdjustment; // The true distance, accounting for any repeats. This ends up being the drum roll distance later double distance = distanceData.Distance * repeats * legacy_velocity_multiplier; @@ -94,7 +94,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps // For some reason, old osu! always uses speedAdjustment to determine the taiko velocity, but // only uses it to determine osu! velocity if beatmap version < 8. Let's account for that here. if (beatmap.BeatmapInfo.BeatmapVersion >= 8) - speedAdjustedBeatLength /= speedAdjustment; + speedAdjustedBeatLength *= speedAdjustment; // The velocity of the osu! hit object - calculated as the velocity of a slider double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.Difficulty.SliderMultiplier * legacy_velocity_multiplier / speedAdjustedBeatLength; diff --git a/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs index 30c7884334..c622d5310c 100644 --- a/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/DifficultyControlPoint.cs @@ -10,4 +10,4 @@ namespace osu.Game.Beatmaps.ControlPoints /// public double SpeedMultiplier = 1; } -} \ No newline at end of file +} diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 093f607e0d..b51ea607dd 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -280,7 +280,7 @@ namespace osu.Game.Beatmaps.Formats double time = double.Parse(split[0].Trim(), NumberFormatInfo.InvariantInfo); double beatLength = double.Parse(split[1].Trim(), NumberFormatInfo.InvariantInfo); - double speedMultiplier = beatLength < 0 ? -beatLength / 100.0 : 1; + double speedMultiplier = beatLength < 0 ? 100.0 / -beatLength : 1; TimeSignatures timeSignature = TimeSignatures.SimpleQuadruple; if (split.Length >= 3) diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index ffe40e4f2e..479cacc52b 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Objects.Legacy TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime); - double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier / difficultyPoint.SpeedMultiplier; + double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier; Velocity = scoringDistance / timingPoint.BeatLength; } diff --git a/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs b/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs index 3b9b8d2d57..4f1a85cf2d 100644 --- a/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs +++ b/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Timing /// /// The multiplier which this provides. /// - public double Multiplier => 1000 / TimingPoint.BeatLength / DifficultyPoint.SpeedMultiplier; + public double Multiplier => 1000 / TimingPoint.BeatLength * DifficultyPoint.SpeedMultiplier; /// /// The that provides the timing information for this . @@ -62,4 +62,4 @@ namespace osu.Game.Rulesets.Timing public int CompareTo(MultiplierControlPoint other) => StartTime.CompareTo(other?.StartTime); } -} \ No newline at end of file +} From 0970439e34d6c33c0747f83049835dd47f6edf0e Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 21 Aug 2017 12:04:58 +0900 Subject: [PATCH 080/483] Fix TaikoBeatmapConverter attempting to convert taiko-specific drum rolls to hits. Fixes #1149 --- osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 44f61e2074..a72ba1fa55 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -39,10 +39,14 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps /// private const float taiko_base_distance = 100; + private bool isForCurrentRuleset; + protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(HitObject) }; protected override Beatmap ConvertBeatmap(Beatmap original, bool isForCurrentRuleset) { + this.isForCurrentRuleset = isForCurrentRuleset; + // Rewrite the beatmap info to add the slider velocity multiplier BeatmapInfo info = original.BeatmapInfo.DeepClone(); info.Difficulty.SliderMultiplier *= legacy_velocity_multiplier; @@ -104,7 +108,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps // If the drum roll is to be split into hit circles, assume the ticks are 1/8 spaced within the duration of one beat double tickSpacing = Math.Min(speedAdjustedBeatLength / beatmap.BeatmapInfo.Difficulty.SliderTickRate, taikoDuration / repeats); - if (tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength) + if (!isForCurrentRuleset && tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength) { List allSamples = curveData != null ? curveData.RepeatSamples : new List(new[] { samples }); From 16e96888abc044955288fdfedf5a33fc968c672b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Aug 2017 12:31:21 +0900 Subject: [PATCH 081/483] Update KeyCounterCollection to support action-based buttons --- .../Visual/TestCaseScrollingPlayfield.cs | 3 ++ osu.Game.Rulesets.Catch/CatchInputManager.cs | 4 +- osu.Game.Rulesets.Catch/CatchRuleset.cs | 9 ---- .../UI/CatchRulesetContainer.cs | 2 +- osu.Game.Rulesets.Mania/ManiaInputManager.cs | 21 +++++++++ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 3 -- .../UI/ManiaRulesetContainer.cs | 3 ++ .../osu.Game.Rulesets.Mania.csproj | 1 + osu.Game.Rulesets.Osu/OsuInputManager.cs | 4 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 10 ----- .../UI/OsuRulesetContainer.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoInputManager.cs | 4 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 10 ----- .../UI/TaikoRulesetContainer.cs | 2 +- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 3 -- osu.Game/Rulesets/Ruleset.cs | 3 -- osu.Game/Rulesets/UI/RulesetContainer.cs | 16 ++++--- osu.Game/Rulesets/UI/RulesetInputManager.cs | 44 +++++++++++++++++++ osu.Game/Screens/Play/HUDOverlay.cs | 2 +- osu.Game/Screens/Play/KeyCounterAction.cs | 30 +++++++++++++ osu.Game/Screens/Play/KeyCounterCollection.cs | 22 +++++++--- osu.Game/Screens/Play/Player.cs | 5 +-- osu.Game/osu.Game.csproj | 2 + 23 files changed, 140 insertions(+), 65 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/ManiaInputManager.cs create mode 100644 osu.Game/Rulesets/UI/RulesetInputManager.cs create mode 100644 osu.Game/Screens/Play/KeyCounterAction.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs index 43bd921cfc..e9c29d36c2 100644 --- a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs @@ -8,6 +8,7 @@ using osu.Desktop.Tests.Beatmaps; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets.Beatmaps; @@ -77,6 +78,8 @@ namespace osu.Desktop.Tests.Visual public override ScoreProcessor CreateScoreProcessor() => new TestScoreProcessor(); + public override PassThroughInputManager CreateInputManager() => new PassThroughInputManager(); + protected override BeatmapConverter CreateBeatmapConverter() => new TestBeatmapConverter(); protected override Playfield CreatePlayfield() => new TestPlayfield(scrollingAxes); diff --git a/osu.Game.Rulesets.Catch/CatchInputManager.cs b/osu.Game.Rulesets.Catch/CatchInputManager.cs index 2a913a77d3..47e9b9905a 100644 --- a/osu.Game.Rulesets.Catch/CatchInputManager.cs +++ b/osu.Game.Rulesets.Catch/CatchInputManager.cs @@ -3,11 +3,11 @@ using System.ComponentModel; using osu.Framework.Input.Bindings; -using osu.Game.Input.Bindings; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Catch { - public class CatchInputManager : DatabasedKeyBindingInputManager + public class CatchInputManager : RulesetInputManager { public CatchInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index f7662030fc..96f8a8df9b 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -1,14 +1,12 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets.Catch.Mods; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Play; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Scoring; @@ -101,13 +99,6 @@ namespace osu.Game.Rulesets.Catch public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o }; - public override IEnumerable CreateGameplayKeys() => new KeyCounter[] - { - new KeyCounterKeyboard(Key.ShiftLeft), - new KeyCounterMouse(MouseButton.Left), - new KeyCounterMouse(MouseButton.Right) - }; - public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new CatchDifficultyCalculator(beatmap); public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(); diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index 1d037deaef..f8f74af6c9 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.UI protected override Playfield CreatePlayfield() => new CatchPlayfield(); - public override PassThroughInputManager CreateKeyBindingInputManager() => new CatchInputManager(Ruleset?.RulesetInfo); + public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo); protected override DrawableHitObject GetVisualRepresentation(CatchBaseHit h) { diff --git a/osu.Game.Rulesets.Mania/ManiaInputManager.cs b/osu.Game.Rulesets.Mania/ManiaInputManager.cs new file mode 100644 index 0000000000..b608e4d8d6 --- /dev/null +++ b/osu.Game.Rulesets.Mania/ManiaInputManager.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Input.Bindings; +using osu.Game.Rulesets.UI; + +namespace osu.Game.Rulesets.Mania +{ + public class ManiaInputManager : RulesetInputManager + { + public ManiaInputManager(RulesetInfo ruleset) + : base(ruleset, 0, SimultaneousBindingMode.Unique) + { + } + } + + public enum ManiaAction + { + // placeholder + } +} diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 50ad6960ae..c7809f83ed 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -6,7 +6,6 @@ using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Play; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Game.Graphics; @@ -111,8 +110,6 @@ namespace osu.Game.Rulesets.Mania public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o }; - public override IEnumerable CreateGameplayKeys() => new KeyCounter[] { /* Todo: Should be keymod specific */ }; - public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new ManiaDifficultyCalculator(beatmap); public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(); diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 7f6b19f3bd..9584dc34b8 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -10,6 +10,7 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; +using osu.Framework.Input; using osu.Framework.Lists; using osu.Framework.MathUtils; using osu.Game.Beatmaps; @@ -92,6 +93,8 @@ namespace osu.Game.Rulesets.Mania.UI public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this); + public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo); + protected override BeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter(); protected override DrawableHitObject GetVisualRepresentation(ManiaHitObject h) diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index fb0b2d907f..890c9116cf 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -79,6 +79,7 @@ + diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index 0c4384c006..a65d28cec0 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -3,11 +3,11 @@ using System.ComponentModel; using osu.Framework.Input.Bindings; -using osu.Game.Input.Bindings; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu { - public class OsuInputManager : DatabasedKeyBindingInputManager + public class OsuInputManager : RulesetInputManager { public OsuInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique) { diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 49848cb67c..00413331e0 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; @@ -10,7 +9,6 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.OsuDifficulty; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Play; using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; @@ -122,14 +120,6 @@ namespace osu.Game.Rulesets.Osu public override string Description => "osu!"; - public override IEnumerable CreateGameplayKeys() => new KeyCounter[] - { - new KeyCounterKeyboard(Key.Z), - new KeyCounterKeyboard(Key.X), - new KeyCounterMouse(MouseButton.Left), - new KeyCounterMouse(MouseButton.Right) - }; - public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor(); public override SettingsSubsection CreateSettings() => new OsuSettings(); diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs index 917322de44..083f11945c 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.UI protected override Playfield CreatePlayfield() => new OsuPlayfield(); - public override PassThroughInputManager CreateKeyBindingInputManager() => new OsuInputManager(Ruleset?.RulesetInfo); + public override PassThroughInputManager CreateInputManager() => new OsuInputManager(Ruleset.RulesetInfo); protected override DrawableHitObject GetVisualRepresentation(OsuHitObject h) { diff --git a/osu.Game.Rulesets.Taiko/TaikoInputManager.cs b/osu.Game.Rulesets.Taiko/TaikoInputManager.cs index ad3b25d088..1e3c0fbcf2 100644 --- a/osu.Game.Rulesets.Taiko/TaikoInputManager.cs +++ b/osu.Game.Rulesets.Taiko/TaikoInputManager.cs @@ -3,11 +3,11 @@ using System.ComponentModel; using osu.Framework.Input.Bindings; -using osu.Game.Input.Bindings; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Taiko { - public class TaikoInputManager : DatabasedKeyBindingInputManager + public class TaikoInputManager : RulesetInputManager { public TaikoInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique) diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 41b8ff78a9..f457732085 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -1,14 +1,12 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Taiko.Mods; using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Play; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Game.Rulesets.Scoring; @@ -103,14 +101,6 @@ namespace osu.Game.Rulesets.Taiko public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o }; - public override IEnumerable CreateGameplayKeys() => new KeyCounter[] - { - new KeyCounterKeyboard(Key.D), - new KeyCounterKeyboard(Key.F), - new KeyCounterKeyboard(Key.J), - new KeyCounterKeyboard(Key.K) - }; - public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new TaikoDifficultyCalculator(beatmap); public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index 4b1c3d7f16..1ecd699a8e 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Taiko.UI protected override BeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter(); - public override PassThroughInputManager CreateKeyBindingInputManager() => new TaikoInputManager(Ruleset?.RulesetInfo); + public override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo); protected override Playfield CreatePlayfield() => new TaikoPlayfield { diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 2fb9a568f8..479f274efb 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -10,7 +10,6 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Play; namespace osu.Game.Beatmaps { @@ -76,8 +75,6 @@ namespace osu.Game.Beatmaps public override string Description => "dummy"; - public override IEnumerable CreateGameplayKeys() => new List(); - public DummyRuleset(RulesetInfo rulesetInfo) : base(rulesetInfo) { diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index e5fa7117f3..32d958b462 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -5,7 +5,6 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Play; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; @@ -46,8 +45,6 @@ namespace osu.Game.Rulesets public abstract string Description { get; } - public abstract IEnumerable CreateGameplayKeys(); - public virtual SettingsSubsection CreateSettings() => null; /// diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 8512d4b5e1..1e294827ab 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.UI /// /// The key conversion input manager for this RulesetContainer. /// - protected readonly PassThroughInputManager KeyConversionInputManager; + public readonly PassThroughInputManager KeyBindingInputManager; /// /// Whether we are currently providing the local user a gameplay cursor. @@ -76,8 +76,10 @@ namespace osu.Game.Rulesets.UI internal RulesetContainer(Ruleset ruleset) { Ruleset = ruleset; - KeyConversionInputManager = CreateKeyBindingInputManager(); - KeyConversionInputManager.RelativeSizeAxes = Axes.Both; + KeyBindingInputManager = CreateInputManager(); + if (!(KeyBindingInputManager is ICanAttachKeyCounter)) + throw new InvalidOperationException($"Rulesets should create input managers of type {nameof(ICanAttachKeyCounter)}"); + KeyBindingInputManager.RelativeSizeAxes = Axes.Both; } /// @@ -92,10 +94,10 @@ namespace osu.Game.Rulesets.UI public abstract ScoreProcessor CreateScoreProcessor(); /// - /// Creates a key conversion input manager. + /// Creates a key conversion input manager. An exception will be thrown if a valid is not returned. /// /// The input manager. - public virtual PassThroughInputManager CreateKeyBindingInputManager() => new PassThroughInputManager(); + public abstract PassThroughInputManager CreateInputManager(); protected virtual FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new FramedReplayInputHandler(replay); @@ -253,7 +255,7 @@ namespace osu.Game.Rulesets.UI InputManager.Add(content = new Container { RelativeSizeAxes = Axes.Both, - Children = new[] { KeyConversionInputManager } + Children = new[] { KeyBindingInputManager } }); AddInternal(InputManager); @@ -262,7 +264,7 @@ namespace osu.Game.Rulesets.UI [BackgroundDependencyLoader] private void load() { - KeyConversionInputManager.Add(Playfield = CreatePlayfield()); + KeyBindingInputManager.Add(Playfield = CreatePlayfield()); loadObjects(); diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs new file mode 100644 index 0000000000..6d22b2e91e --- /dev/null +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Linq; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; +using osu.Game.Screens.Play; + +namespace osu.Game.Rulesets.UI +{ + public abstract class RulesetInputManager : DatabasedKeyBindingInputManager, ICanAttachKeyCounter + where T : struct + { + protected RulesetInputManager(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) : base(ruleset, variant, unique) + { + } + + public void Attach(KeyCounterCollection keyCounter) + { + var receptor = new ActionReceptor(keyCounter); + Add(receptor); + keyCounter.SetReceptor(receptor); + + keyCounter.AddRange(DefaultKeyBindings.Select(b => b.GetAction()).Distinct().Select(b => new KeyCounterAction(b))); + } + + public class ActionReceptor : KeyCounterCollection.Receptor, IKeyBindingHandler + { + public ActionReceptor(KeyCounterCollection target) + : base(target) + { + } + + public bool OnPressed(T action) => Target.Children.OfType>().Any(c => c.OnPressed(action)); + + public bool OnReleased(T action) => Target.Children.OfType>().Any(c => c.OnReleased(action)); + } + } + + public interface ICanAttachKeyCounter + { + void Attach(KeyCounterCollection keyCounter); + } +} \ No newline at end of file diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index cf6bc03c60..ddcf031bd4 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -92,7 +92,7 @@ namespace osu.Game.Screens.Play public virtual void BindRulesetContainer(RulesetContainer rulesetContainer) { - rulesetContainer.InputManager.Add(KeyCounter.GetReceptor()); + (rulesetContainer.KeyBindingInputManager as ICanAttachKeyCounter)?.Attach(KeyCounter); replayLoaded = rulesetContainer.HasReplayLoaded; diff --git a/osu.Game/Screens/Play/KeyCounterAction.cs b/osu.Game/Screens/Play/KeyCounterAction.cs new file mode 100644 index 0000000000..a6baeeafb6 --- /dev/null +++ b/osu.Game/Screens/Play/KeyCounterAction.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Input.Bindings; + +namespace osu.Game.Screens.Play +{ + public class KeyCounterAction : KeyCounter, IKeyBindingHandler + where T : struct + { + public T Action { get; } + + public KeyCounterAction(T action) : base($"B{(int)(object)action + 1}") + { + Action = action; + } + + public bool OnPressed(T action) + { + if (action.Equals(Action)) IsLit = true; + return false; + } + + public bool OnReleased(T action) + { + if (action.Equals(Action)) IsLit = false; + return false; + } + } +} \ No newline at end of file diff --git a/osu.Game/Screens/Play/KeyCounterCollection.cs b/osu.Game/Screens/Play/KeyCounterCollection.cs index 63c29a8f78..0f6c5984c4 100644 --- a/osu.Game/Screens/Play/KeyCounterCollection.cs +++ b/osu.Game/Screens/Play/KeyCounterCollection.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -117,27 +118,36 @@ namespace osu.Game.Screens.Play return receptor ?? (receptor = new Receptor(this)); } + public void SetReceptor(Receptor receptor) + { + if (this.receptor != null) + throw new InvalidOperationException("Cannot set a new receptor when one is already active"); + + this.receptor = receptor; + } + public class Receptor : Drawable { - private readonly KeyCounterCollection target; + protected readonly KeyCounterCollection Target; public Receptor(KeyCounterCollection target) { RelativeSizeAxes = Axes.Both; - this.target = target; + Depth = float.MinValue; + Target = target; } public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true; public override bool HandleInput => true; - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) => target.Children.Any(c => c.TriggerOnKeyDown(state, args)); + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) => Target.Children.Any(c => c.TriggerOnKeyDown(state, args)); - protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) => target.Children.Any(c => c.TriggerOnKeyUp(state, args)); + protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) => Target.Children.Any(c => c.TriggerOnKeyUp(state, args)); - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => target.Children.Any(c => c.TriggerOnMouseDown(state, args)); + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => Target.Children.Any(c => c.TriggerOnMouseDown(state, args)); - protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) => target.Children.Any(c => c.TriggerOnMouseUp(state, args)); + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) => Target.Children.Any(c => c.TriggerOnMouseUp(state, args)); } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 00f1bd1b6b..3f399d69e6 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -76,8 +76,6 @@ namespace osu.Game.Screens.Play sampleRestart = audio.Sample.Get(@"Gameplay/restart"); - Ruleset rulesetInstance; - WorkingBeatmap working = Beatmap.Value; Beatmap beatmap; @@ -89,7 +87,7 @@ namespace osu.Game.Screens.Play throw new InvalidOperationException("Beatmap was not loaded"); ruleset = osu?.Ruleset.Value ?? beatmap.BeatmapInfo.Ruleset; - rulesetInstance = ruleset.CreateInstance(); + var rulesetInstance = ruleset.CreateInstance(); try { @@ -192,7 +190,6 @@ namespace osu.Game.Screens.Play scoreProcessor = RulesetContainer.CreateScoreProcessor(); - hudOverlay.KeyCounter.AddRange(rulesetInstance.CreateGameplayKeys()); hudOverlay.BindProcessor(scoreProcessor); hudOverlay.BindRulesetContainer(RulesetContainer); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 07ab58bffc..e35bc44c43 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -128,6 +128,8 @@ + + From a63923a4971f133635a1a50d56c48705e1d5e05b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Aug 2017 12:50:48 +0900 Subject: [PATCH 082/483] Remove type check for now --- osu.Game/Rulesets/UI/RulesetContainer.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 1e294827ab..50fcaa128c 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -77,8 +77,6 @@ namespace osu.Game.Rulesets.UI { Ruleset = ruleset; KeyBindingInputManager = CreateInputManager(); - if (!(KeyBindingInputManager is ICanAttachKeyCounter)) - throw new InvalidOperationException($"Rulesets should create input managers of type {nameof(ICanAttachKeyCounter)}"); KeyBindingInputManager.RelativeSizeAxes = Axes.Both; } From e7c9aec1b18891f02fccd7437b07fca6b5eb92b8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Aug 2017 13:05:06 +0900 Subject: [PATCH 083/483] Ensure the sqlite connection is correctly closed before the game ends Hopefully fixes CI race conditions between consecutive tests. --- osu.Game/OsuGameBase.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index a5600d1ef7..022b3e9fc3 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -94,13 +94,15 @@ namespace osu.Game protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + private SQLiteConnection connection; + [BackgroundDependencyLoader] private void load() { dependencies.Cache(this); dependencies.Cache(LocalConfig); - SQLiteConnection connection = Host.Storage.GetDatabase(@"client"); + connection = Host.Storage.GetDatabase(@"client"); connection.CreateTable(); @@ -237,6 +239,8 @@ namespace osu.Game LocalConfig.Save(); } + connection.Dispose(); + base.Dispose(isDisposing); } } From 7a5708ce9279c94116a4bee0f98fe60d9dc5392c Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 21 Aug 2017 15:35:16 +0900 Subject: [PATCH 084/483] Further support for null judgements. --- osu-framework | 2 +- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs | 4 ++-- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu-framework b/osu-framework index 825505e788..aba135ff83 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 825505e788c4f093b269c61b485d38d50cd68096 +Subproject commit aba135ff83feabd9ca2e8e8075b811b64a9006ad diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index 06702e8141..9df1b41a8b 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -58,10 +58,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables }; } - protected override TaikoJudgement CreateJudgement() => new TaikoJudgement(); + protected override TaikoJudgement CreateJudgement() => null; protected override void UpdateState(ArmedState state) { } } -} \ No newline at end of file +} diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 8cfedc9599..3fba168216 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -106,6 +106,9 @@ namespace osu.Game.Rulesets.Objects.Drawables /// Whether a hit was processed. protected bool UpdateJudgement(bool userTriggered) { + if (Judgement == null) + return false; + var partial = Judgement as IPartialJudgement; // Never re-process non-partial hits From 6a7e868a2e1f55cbf1ff4f7211d71d1f04289c40 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 21 Aug 2017 15:36:01 +0900 Subject: [PATCH 085/483] Make taiko major bar line triangles show up again. Fixes #1081 --- .../Objects/Drawables/DrawableBarLineMajor.cs | 14 ++++++++-- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 28 ++++++++++++++----- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLineMajor.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLineMajor.cs index c07be915d5..7a4cf1f1f7 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLineMajor.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLineMajor.cs @@ -20,10 +20,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// private const float triangle_size = 20f; + private readonly Container triangleContainer; + public DrawableBarLineMajor(BarLine barLine) : base(barLine) { - Add(new Container + Add(triangleContainer = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -53,5 +55,13 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Tracker.Alpha = 1f; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + using (triangleContainer.BeginAbsoluteSequence(HitObject.StartTime)) + triangleContainer.FadeOut(150); + } } -} \ No newline at end of file +} diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index eb9e41f771..678de7f713 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -45,6 +45,8 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Container topLevelHitContainer; + private readonly Container barlineContainer; + private readonly Container overlayBackgroundContainer; private readonly Container backgroundContainer; @@ -85,7 +87,7 @@ namespace osu.Game.Rulesets.Taiko.UI { new Container { - Name = "Masked elements", + Name = "Masked elements before hit objects", RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Left = HIT_TARGET_OFFSET }, Masking = true, @@ -103,13 +105,21 @@ namespace osu.Game.Rulesets.Taiko.UI Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit - }, - content = new Container - { - RelativeSizeAxes = Axes.Both, - }, + } } }, + barlineContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = HIT_TARGET_OFFSET } + }, + content = new Container + { + Name = "Hit objects", + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = HIT_TARGET_OFFSET }, + Masking = true + }, kiaiExplosionContainer = new Container { Name = "Kiai hit explosions", @@ -198,6 +208,10 @@ namespace osu.Game.Rulesets.Taiko.UI base.Add(h); + var barline = h as DrawableBarLine; + if (barline != null) + barlineContainer.Add(barline.CreateProxy()); + // Swells should be moved at the very top of the playfield when they reach the hit target var swell = h as DrawableSwell; if (swell != null) @@ -239,4 +253,4 @@ namespace osu.Game.Rulesets.Taiko.UI hitExplosionContainer.Children.FirstOrDefault(e => e.Judgement == judgedObject.Judgement)?.VisualiseSecondHit(); } } -} \ No newline at end of file +} From 5d13efa76d6f4bb566b6c6c4d01d077059ae10bf Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 21 Aug 2017 16:14:44 +0900 Subject: [PATCH 086/483] Remove the concept of "queued hit objects", add a default speed adjustment. --- osu-framework | 2 +- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 52 +++++++++++----------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/osu-framework b/osu-framework index aba135ff83..92e1dc21c0 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit aba135ff83feabd9ca2e8e8075b811b64a9006ad +Subproject commit 92e1dc21c069a6b65ee71060f2f37f3f4180fd20 diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index f8e090d613..b89f5e15c6 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -151,10 +151,6 @@ namespace osu.Game.Rulesets.UI /// public readonly BindableBool Reversed = new BindableBool(); - /// - /// Hit objects that are to be re-processed on the next update. - /// - private readonly List queuedHitObjects = new List(); private readonly Container speedAdjustments; private readonly Axes scrollingAxes; @@ -168,6 +164,9 @@ namespace osu.Game.Rulesets.UI this.scrollingAxes = scrollingAxes; AddInternal(speedAdjustments = new Container { RelativeSizeAxes = Axes.Both }); + + // Default speed adjustment + AddSpeedAdjustment(new SpeedAdjustmentContainer(new MultiplierControlPoint(0))); } /// @@ -180,6 +179,21 @@ namespace osu.Game.Rulesets.UI speedAdjustment.VisibleTimeRange.BindTo(VisibleTimeRange); speedAdjustment.Reversed.BindTo(Reversed); speedAdjustments.Add(speedAdjustment); + + // We now need to re-sort the hit objects in the last speed adjustment prior to this one, to see if they need a new parent + var previousSpeedAdjustment = speedAdjustments.LastOrDefault(s => s.ControlPoint.StartTime < speedAdjustment.ControlPoint.StartTime); + if (previousSpeedAdjustment == null) + return; + + foreach (DrawableHitObject h in previousSpeedAdjustment.Children) + { + var newSpeedAdjustment = adjustmentContainerFor(h); + if (newSpeedAdjustment == previousSpeedAdjustment) + continue; + + previousSpeedAdjustment.Remove(h); + newSpeedAdjustment.Add(h); + } } public override IEnumerable Objects => speedAdjustments.SelectMany(s => s.Children); @@ -194,30 +208,14 @@ namespace osu.Game.Rulesets.UI if (!(hitObject is IScrollingHitObject)) throw new InvalidOperationException($"Hit objects added to a {nameof(ScrollingHitObjectContainer)} must implement {nameof(IScrollingHitObject)}."); - queuedHitObjects.Add(hitObject); + var target = adjustmentContainerFor(hitObject); + if (target == null) + throw new InvalidOperationException($"A {nameof(SpeedAdjustmentContainer)} to container {hitObject.ToString()} could not be found."); + + target.Add(hitObject); } - public override bool Remove(DrawableHitObject hitObject) => speedAdjustments.Any(s => s.Remove(hitObject)) || queuedHitObjects.Remove(hitObject); - - protected override void Update() - { - base.Update(); - - // Todo: At the moment this is going to re-process every single Update, however this will only be a null-op - // when there are no SpeedAdjustmentContainers available. This should probably error or something, but it's okay for now. - - for (int i = queuedHitObjects.Count - 1; i >= 0; i--) - { - var hitObject = queuedHitObjects[i]; - - var target = adjustmentContainerFor(hitObject); - if (target == null) - continue; - - target.Add(hitObject); - queuedHitObjects.RemoveAt(i); - } - } + public override bool Remove(DrawableHitObject hitObject) => speedAdjustments.Any(s => s.Remove(hitObject)); /// /// Finds the which provides the speed adjustment active at the start time @@ -237,4 +235,4 @@ namespace osu.Game.Rulesets.UI private SpeedAdjustmentContainer adjustmentContainerAt(double time) => speedAdjustments.FirstOrDefault(c => c.CanContain(time)) ?? speedAdjustments.LastOrDefault(); } } -} \ No newline at end of file +} From 9369c18d7772a0820fc0721d83444d105dd58860 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 21 Aug 2017 16:18:04 +0900 Subject: [PATCH 087/483] Update framework. --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 92e1dc21c0..bce1e26732 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 92e1dc21c069a6b65ee71060f2f37f3f4180fd20 +Subproject commit bce1e26732360caf4acb716fde439de48805014e From 6e0d2182cbd2e196fc2fafe917eaf29252f62e38 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 21 Aug 2017 16:24:16 +0900 Subject: [PATCH 088/483] CI. --- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index b89f5e15c6..0a8469c928 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -210,7 +210,7 @@ namespace osu.Game.Rulesets.UI var target = adjustmentContainerFor(hitObject); if (target == null) - throw new InvalidOperationException($"A {nameof(SpeedAdjustmentContainer)} to container {hitObject.ToString()} could not be found."); + throw new InvalidOperationException($"A {nameof(SpeedAdjustmentContainer)} to container {hitObject} could not be found."); target.Add(hitObject); } From 877c69d5fea29641a81093972c74a873b92d568f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Aug 2017 17:43:26 +0900 Subject: [PATCH 089/483] Add local chat echo support --- osu.Game/Online/Chat/Channel.cs | 49 +++++++++- osu.Game/Online/Chat/LocalEchoMessage.cs | 12 +++ osu.Game/Online/Chat/Message.cs | 17 +++- osu.Game/Overlays/Chat/ChatLine.cs | 114 ++++++++++++++-------- osu.Game/Overlays/Chat/DrawableChannel.cs | 60 +++++++++--- osu.Game/Overlays/ChatOverlay.cs | 69 ++++++------- osu.Game/osu.Game.csproj | 1 + 7 files changed, 223 insertions(+), 99 deletions(-) create mode 100644 osu.Game/Online/Chat/LocalEchoMessage.cs diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 01685cc7dc..0c10ddde97 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using Newtonsoft.Json; using osu.Framework.Configuration; @@ -26,6 +27,8 @@ namespace osu.Game.Online.Chat public readonly SortedList Messages = new SortedList(Comparer.Default); + private readonly List pendingMessages = new List(); + public Bindable Joined = new Bindable(); public bool ReadOnly => Name != "#lazer"; @@ -38,12 +41,23 @@ namespace osu.Game.Online.Chat } public event Action> NewMessagesArrived; + public event Action PendingMessageResolved; + public event Action MessageRemoved; + + public void AddLocalEcho(LocalEchoMessage message) + { + pendingMessages.Add(message); + Messages.Add(message); + + NewMessagesArrived?.Invoke(new[] { message }); + } public void AddNewMessages(params Message[] messages) { messages = messages.Except(Messages).ToArray(); - Messages.AddRange(messages); + foreach (Message message in messages) + Messages.Add(message); purgeOldMessages(); @@ -52,11 +66,42 @@ namespace osu.Game.Online.Chat private void purgeOldMessages() { - int messageCount = Messages.Count; + // never purge local echos + int messageCount = Messages.Count - pendingMessages.Count; if (messageCount > MAX_HISTORY) Messages.RemoveRange(0, messageCount - MAX_HISTORY); } + /// + /// Replace or remove a message from the channel. + /// + /// The local echo message (client-side). + /// The response message, or null if the message became invalid. + public void ReplaceMessage(LocalEchoMessage echo, Message final) + { + if (!pendingMessages.Remove(echo)) + Trace.Fail("Attempted to remove echo that wasn't present"); + + Messages.Remove(echo); + + if (final == null) + { + MessageRemoved?.Invoke(echo); + return; + } + + if (Messages.Contains(final)) + { + // message already inserted, so let's throw away this update. + // we may want to handle this better in the future, but for the time being api requests are single-threaded so order is assumed. + MessageRemoved?.Invoke(echo); + return; + } + + Messages.Add(final); + PendingMessageResolved?.Invoke(echo, final); + } + public override string ToString() => Name; } } diff --git a/osu.Game/Online/Chat/LocalEchoMessage.cs b/osu.Game/Online/Chat/LocalEchoMessage.cs new file mode 100644 index 0000000000..079ec58686 --- /dev/null +++ b/osu.Game/Online/Chat/LocalEchoMessage.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Online.Chat +{ + public class LocalEchoMessage : Message + { + public LocalEchoMessage() : base(null) + { + } + } +} diff --git a/osu.Game/Online/Chat/Message.cs b/osu.Game/Online/Chat/Message.cs index 4c7e099647..fc61b9f37a 100644 --- a/osu.Game/Online/Chat/Message.cs +++ b/osu.Game/Online/Chat/Message.cs @@ -11,7 +11,7 @@ namespace osu.Game.Online.Chat public class Message : IComparable, IEquatable { [JsonProperty(@"message_id")] - public readonly long Id; + public readonly long? Id; //todo: this should be inside sender. [JsonProperty(@"sender_id")] @@ -37,14 +37,23 @@ namespace osu.Game.Online.Chat { } - public Message(long id) + public Message(long? id) { Id = id; } - public int CompareTo(Message other) => Id.CompareTo(other.Id); + public int CompareTo(Message other) + { - public bool Equals(Message other) => Id == other?.Id; + if (!Id.HasValue) + return other.Id.HasValue ? 1 : Timestamp.CompareTo(other.Timestamp); + if (!other.Id.HasValue) + return -1; + + return Id.Value.CompareTo(other.Id.Value); + } + + public virtual bool Equals(Message other) => Id == other?.Id; public override int GetHashCode() => Id.GetHashCode(); } diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index fcebca6fe3..afc6589f57 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -2,26 +2,24 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Online.Chat; -using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Graphics.Effects; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Allocation; using osu.Game.Users; -using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Chat { public class ChatLine : Container { - public readonly Message Message; - - private static readonly Color4[] username_colours = { + private static readonly Color4[] username_colours = + { OsuColour.FromHex("588c7e"), OsuColour.FromHex("b2a367"), OsuColour.FromHex("c98f65"), @@ -69,6 +67,8 @@ namespace osu.Game.Overlays.Chat private Color4 customUsernameColour; + private OsuSpriteText timestamp; + public ChatLine(Message message) { Message = message; @@ -79,6 +79,26 @@ namespace osu.Game.Overlays.Chat Padding = new MarginPadding { Left = padding, Right = padding }; } + private Message message; + private OsuSpriteText username; + private OsuTextFlowContainer contentFlow; + + public Message Message + { + get { return message; } + set + { + if (message == value) return; + + message = value; + + if (!IsLoaded) + return; + + updateMessageContent(); + } + } + [BackgroundDependencyLoader(true)] private void load(OsuColour colours, UserProfileOverlay profile) { @@ -86,49 +106,54 @@ namespace osu.Game.Overlays.Chat loadProfile = u => profile?.ShowUser(u); } + private bool senderHasBackground => !string.IsNullOrEmpty(message.Sender.Colour); + protected override void LoadComplete() { base.LoadComplete(); - bool hasBackground = !string.IsNullOrEmpty(Message.Sender.Colour); - Drawable username = new OsuSpriteText + bool hasBackground = senderHasBackground; + + Drawable effectedUsername = username = new OsuSpriteText { Font = @"Exo2.0-BoldItalic", - Text = $@"{Message.Sender.Username}" + (hasBackground ? "" : ":"), - Colour = hasBackground ? customUsernameColour : username_colours[Message.UserId % username_colours.Length], + Colour = hasBackground ? customUsernameColour : username_colours[message.Sender.Id % username_colours.Length], TextSize = text_size, }; if (hasBackground) { // Background effect - username = username.WithEffect(new EdgeEffect + effectedUsername = new Container { + AutoSizeAxes = Axes.Both, + Masking = true, CornerRadius = 4, - Parameters = new EdgeEffectParameters - { - Radius = 1, - Colour = OsuColour.FromHex(Message.Sender.Colour), - Type = EdgeEffectType.Shadow, - } - }, d => - { - d.Padding = new MarginPadding { Left = 3, Right = 3, Bottom = 1, Top = -3 }; - d.Y = 3; - }) - // Drop shadow effect - .WithEffect(new EdgeEffect - { - CornerRadius = 4, - Parameters = new EdgeEffectParameters + EdgeEffect = new EdgeEffectParameters { Roundness = 1, Offset = new Vector2(0, 3), Radius = 3, Colour = Color4.Black.Opacity(0.3f), Type = EdgeEffectType.Shadow, + }, + // Drop shadow effect + Child = new Container + { + AutoSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 4, + EdgeEffect = new EdgeEffectParameters + { + Radius = 1, + Colour = OsuColour.FromHex(message.Sender.Colour), + Type = EdgeEffectType.Shadow, + }, + Padding = new MarginPadding { Left = 3, Right = 3, Bottom = 1, Top = -3 }, + Y = 3, + Child = username, } - }); + }; } Children = new Drawable[] @@ -138,23 +163,21 @@ namespace osu.Game.Overlays.Chat Size = new Vector2(message_padding, text_size), Children = new Drawable[] { - new OsuSpriteText + timestamp = new OsuSpriteText { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Font = @"Exo2.0-SemiBold", - Text = $@"{Message.Timestamp.LocalDateTime:HH:mm:ss}", FixedWidth = true, TextSize = text_size * 0.75f, - Alpha = 0.4f, }, new ClickableContainer { AutoSizeAxes = Axes.Both, Origin = Anchor.TopRight, Anchor = Anchor.TopRight, - Child = username, - Action = () => loadProfile(Message.Sender), + Child = effectedUsername, + Action = () => loadProfile(message.Sender), }, } }, @@ -165,18 +188,27 @@ namespace osu.Game.Overlays.Chat Padding = new MarginPadding { Left = message_padding + padding }, Children = new Drawable[] { - new OsuTextFlowContainer(t => + contentFlow = new OsuTextFlowContainer(t => { t.TextSize = text_size; }) { - t.TextSize = text_size; - }) - { - Text = Message.Content, AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, } } } }; + + updateMessageContent(); + FinishTransforms(true); + } + + private void updateMessageContent() + { + this.FadeTo(message is LocalEchoMessage ? 0.4f : 1.0f, 500, Easing.OutQuint); + timestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint); + + timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}"; + username.Text = $@"{message.Sender.Username}" + (senderHasBackground ? "" : ":"); + contentFlow.Text = message.Content; } } } diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 8a2fa95ed1..38a736993e 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -3,7 +3,9 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; +using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -14,8 +16,19 @@ namespace osu.Game.Overlays.Chat { public class DrawableChannel : Container { + private class ChatLineContainer : FillFlowContainer + { + protected override int Compare(Drawable x, Drawable y) + { + var xC = (ChatLine)x; + var yC = (ChatLine)y; + + return xC.Message.CompareTo(yC.Message); + } + } + public readonly Channel Channel; - private readonly FillFlowContainer flow; + private readonly ChatLineContainer flow; private readonly ScrollContainer scroll; public DrawableChannel(Channel channel) @@ -32,20 +45,19 @@ namespace osu.Game.Overlays.Chat // Some chat lines have effects that slightly protrude to the bottom, // which we do not want to mask away, hence the padding. Padding = new MarginPadding { Bottom = 5 }, - Children = new Drawable[] + Child = flow = new ChatLineContainer { - flow = new FillFlowContainer - { - Direction = FillDirection.Vertical, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = 20, Right = 20 } - } - } + Padding = new MarginPadding { Left = 20, Right = 20 }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + }, } }; - channel.NewMessagesArrived += newMessagesArrived; + Channel.NewMessagesArrived += newMessagesArrived; + Channel.MessageRemoved += messageRemoved; + Channel.PendingMessageResolved += pendingMessageResolved; } [BackgroundDependencyLoader] @@ -63,15 +75,19 @@ namespace osu.Game.Overlays.Chat protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); + Channel.NewMessagesArrived -= newMessagesArrived; + Channel.MessageRemoved -= messageRemoved; + Channel.PendingMessageResolved -= pendingMessageResolved; } private void newMessagesArrived(IEnumerable newMessages) { + // Add up to last Channel.MAX_HISTORY messages var displayMessages = newMessages.Skip(Math.Max(0, newMessages.Count() - Channel.MAX_HISTORY)); - //up to last Channel.MAX_HISTORY messages - flow.AddRange(displayMessages.Select(m => new ChatLine(m))); + foreach (Message m in displayMessages) + flow.Add(new ChatLine(m)); if (!IsLoaded) return; @@ -90,6 +106,24 @@ namespace osu.Game.Overlays.Chat } } + private void pendingMessageResolved(Message existing, Message updated) + { + var found = flow.Children.LastOrDefault(c => c.Message == existing); + if (found != null) + { + Trace.Assert(updated.Id.HasValue, "An updated message was returned with no ID."); + + flow.Remove(found); + found.Message = updated; + flow.Add(found); + } + } + + private void messageRemoved(Message removed) + { + flow.Children.FirstOrDefault(c => c.Message == removed)?.FadeColour(Color4.Red, 400).FadeOut(600).Expire(); + } + private void scrollToEnd() => ScheduleAfterChildren(() => scroll.ScrollToEnd()); } } diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index e7a4c1c0ab..705772aec3 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -6,23 +6,23 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using OpenTK; +using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Configuration; 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.Configuration; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.Chat; -using osu.Game.Graphics.UserInterface; -using osu.Framework.Graphics.UserInterface; -using OpenTK.Graphics; -using osu.Framework.Input; -using osu.Game.Configuration; -using osu.Game.Graphics; using osu.Game.Overlays.Chat; -using osu.Game.Graphics.Containers; namespace osu.Game.Overlays { @@ -37,7 +37,7 @@ namespace osu.Game.Overlays private readonly LoadingAnimation loading; - private readonly FocusedTextBox inputTextBox; + private readonly FocusedTextBox textbox; private APIAccess api; @@ -130,7 +130,7 @@ namespace osu.Game.Overlays }, Children = new Drawable[] { - inputTextBox = new FocusedTextBox + textbox = new FocusedTextBox { RelativeSizeAxes = Axes.Both, Height = 1, @@ -175,7 +175,7 @@ namespace osu.Game.Overlays if (state == Visibility.Visible) { - inputTextBox.HoldFocus = false; + textbox.HoldFocus = false; if (1f - chatHeight.Value < channel_selection_min_height) { chatContainer.ResizeHeightTo(1f - channel_selection_min_height, 800, Easing.OutQuint); @@ -186,7 +186,7 @@ namespace osu.Game.Overlays } else { - inputTextBox.HoldFocus = true; + textbox.HoldFocus = true; } }; } @@ -242,8 +242,8 @@ namespace osu.Game.Overlays protected override void OnFocus(InputState state) { - //this is necessary as inputTextBox is masked away and therefore can't get focus :( - GetContainingInputManager().ChangeFocus(inputTextBox); + //this is necessary as textbox is masked away and therefore can't get focus :( + GetContainingInputManager().ChangeFocus(textbox); base.OnFocus(state); } @@ -252,7 +252,7 @@ namespace osu.Game.Overlays this.MoveToY(0, transition_length, Easing.OutQuint); this.FadeIn(transition_length, Easing.OutQuint); - inputTextBox.HoldFocus = true; + textbox.HoldFocus = true; base.PopIn(); } @@ -261,7 +261,7 @@ namespace osu.Game.Overlays this.MoveToY(Height, transition_length, Easing.InSine); this.FadeOut(transition_length, Easing.InSine); - inputTextBox.HoldFocus = false; + textbox.HoldFocus = false; base.PopOut(); } @@ -336,7 +336,7 @@ namespace osu.Game.Overlays currentChannel = value; - inputTextBox.Current.Disabled = currentChannel.ReadOnly; + textbox.Current.Disabled = currentChannel.ReadOnly; channelTabs.Current.Value = value; var loaded = loadedChannels.Find(d => d.Channel == value); @@ -437,51 +437,42 @@ namespace osu.Game.Overlays { var postText = textbox.Text; + textbox.Text = string.Empty; + if (string.IsNullOrEmpty(postText)) return; + var target = currentChannel; + + if (target == null) return; + if (!api.IsLoggedIn) { - currentChannel?.AddNewMessages(new ErrorMessage("Please login to participate in chat!")); - textbox.Text = string.Empty; + target.AddNewMessages(new ErrorMessage("Please login to participate in chat!")); return; } - if (currentChannel == null) return; - if (postText[0] == '/') { // TODO: handle commands - currentChannel.AddNewMessages(new ErrorMessage("Chat commands are not supported yet!")); - textbox.Text = string.Empty; + target.AddNewMessages(new ErrorMessage("Chat commands are not supported yet!")); return; } - var message = new Message + var message = new LocalEchoMessage { Sender = api.LocalUser.Value, Timestamp = DateTimeOffset.Now, - TargetType = TargetType.Channel, //TODO: read this from currentChannel - TargetId = currentChannel.Id, + TargetType = TargetType.Channel, //TODO: read this from channel + TargetId = target.Id, Content = postText }; - textbox.ReadOnly = true; var req = new PostMessageRequest(message); - req.Failure += e => - { - textbox.FlashColour(Color4.Red, 1000); - textbox.ReadOnly = false; - }; - - req.Success += m => - { - currentChannel.AddNewMessages(m); - - textbox.ReadOnly = false; - textbox.Text = string.Empty; - }; + target.AddLocalEcho(message); + req.Failure += e => target.ReplaceMessage(message, null); + req.Success += m => target.ReplaceMessage(message, m); api.Queue(req); } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 07ab58bffc..655bc08248 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -101,6 +101,7 @@ + From 9ba2258f80236152ffcad17f29531cc8e7c3c93b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Aug 2017 17:44:39 +0900 Subject: [PATCH 090/483] Add spaces for smoogipoo --- osu.Game/Overlays/ChatOverlay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 705772aec3..6dd5425fd1 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -414,6 +414,7 @@ namespace osu.Game.Overlays if (fetchReq != null) return; fetchReq = new GetMessagesRequest(careChannels, lastMessageId); + fetchReq.Success += delegate (List messages) { foreach (var group in messages.Where(m => m.TargetType == TargetType.Channel).GroupBy(m => m.TargetId)) @@ -424,6 +425,7 @@ namespace osu.Game.Overlays Debug.Write("success!"); fetchReq = null; }; + fetchReq.Failure += delegate { Debug.Write("failure!"); From 1d0b89d592bf5e5141047fd8313175d35888228a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Aug 2017 18:51:14 +0900 Subject: [PATCH 091/483] Restore usage of AddRange --- osu.Game/Online/Chat/Channel.cs | 3 +-- osu.Game/Overlays/Chat/DrawableChannel.cs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 0c10ddde97..2878856159 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -56,8 +56,7 @@ namespace osu.Game.Online.Chat { messages = messages.Except(Messages).ToArray(); - foreach (Message message in messages) - Messages.Add(message); + Messages.AddRange(messages); purgeOldMessages(); diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 38a736993e..840edaece2 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -86,8 +86,7 @@ namespace osu.Game.Overlays.Chat // Add up to last Channel.MAX_HISTORY messages var displayMessages = newMessages.Skip(Math.Max(0, newMessages.Count() - Channel.MAX_HISTORY)); - foreach (Message m in displayMessages) - flow.Add(new ChatLine(m)); + flow.AddRange(displayMessages.Select(m => new ChatLine(m))); if (!IsLoaded) return; From 7d1c270126a60b075504ca4ae4769e03fc94cee3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Aug 2017 23:34:08 +0900 Subject: [PATCH 092/483] Review fixes --- osu.Game/Online/Chat/Channel.cs | 2 +- osu.Game/Online/Chat/Message.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 2878856159..81d488353a 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -79,7 +79,7 @@ namespace osu.Game.Online.Chat public void ReplaceMessage(LocalEchoMessage echo, Message final) { if (!pendingMessages.Remove(echo)) - Trace.Fail("Attempted to remove echo that wasn't present"); + throw new InvalidOperationException("Attempted to remove echo that wasn't present"); Messages.Remove(echo); diff --git a/osu.Game/Online/Chat/Message.cs b/osu.Game/Online/Chat/Message.cs index fc61b9f37a..509861868a 100644 --- a/osu.Game/Online/Chat/Message.cs +++ b/osu.Game/Online/Chat/Message.cs @@ -44,7 +44,6 @@ namespace osu.Game.Online.Chat public int CompareTo(Message other) { - if (!Id.HasValue) return other.Id.HasValue ? 1 : Timestamp.CompareTo(other.Timestamp); if (!other.Id.HasValue) From a9fe1d94f7646a95dec42f680f54199b7de3665a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Aug 2017 23:41:51 +0900 Subject: [PATCH 093/483] Remove unnecessary using --- osu.Game/Online/Chat/Channel.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 81d488353a..bec4aadb18 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using Newtonsoft.Json; using osu.Framework.Configuration; From 5c489eb3f059d08f808e88323877a19bc50909ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Aug 2017 23:46:37 +0900 Subject: [PATCH 094/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index bce1e26732..f1527e5456 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit bce1e26732360caf4acb716fde439de48805014e +Subproject commit f1527e5456cd228ddfb68cf6d56eb5d28dc360bf From 31bb1ebe0e3058fe1f174fc4bea3aeaa2d1f7400 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 12:42:35 +0900 Subject: [PATCH 095/483] Add comment and index on column --- osu.Game/Beatmaps/BeatmapInfo.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 432da57a5c..ebf77bf9df 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -52,6 +52,10 @@ namespace osu.Game.Beatmaps [JsonProperty("file_sha2")] public string Hash { get; set; } + /// + /// MD5 is kept for legacy support (matching against replays, osu-web-10 etc.). + /// + [Indexed] [JsonProperty("file_md5")] public string MD5Hash { get; set; } From 964982e2e61885db1ab701e9b6eb242e4d2a25d5 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 13:00:35 +0900 Subject: [PATCH 096/483] Remove now unneeded ApplyBeatmap. --- osu.Game/Rulesets/UI/RulesetContainer.cs | 7 ------- .../Rulesets/UI/ScrollingRulesetContainer.cs | 19 ++++++++----------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 50fcaa128c..5b19200f2d 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -173,8 +173,6 @@ namespace osu.Game.Rulesets.UI // Post-process the beatmap processor.PostProcess(Beatmap); - ApplyBeatmap(); - // Add mods, should always be the last thing applied to give full control to mods applyMods(Mods); } @@ -192,11 +190,6 @@ namespace osu.Game.Rulesets.UI mod.ApplyToRulesetContainer(this); } - /// - /// Called when the beatmap of this hit renderer has been set. Used to apply any default values from the beatmap. - /// - protected virtual void ApplyBeatmap() { } - /// /// Creates a processor to perform post-processing operations /// on HitObjects in converted Beatmaps. diff --git a/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs b/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs index 64e865473d..ff156f788c 100644 --- a/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs +++ b/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs @@ -39,17 +39,6 @@ namespace osu.Game.Rulesets.UI [BackgroundDependencyLoader] private void load() - { - DefaultControlPoints.ForEach(c => applySpeedAdjustment(c, Playfield)); - } - - private void applySpeedAdjustment(MultiplierControlPoint controlPoint, ScrollingPlayfield playfield) - { - playfield.HitObjects.AddSpeedAdjustment(CreateSpeedAdjustmentContainer(controlPoint)); - playfield.NestedPlayfields.ForEach(p => applySpeedAdjustment(controlPoint, p)); - } - - protected override void ApplyBeatmap() { // Calculate default multiplier control points var lastTimingPoint = new TimingControlPoint(); @@ -95,6 +84,14 @@ namespace osu.Game.Rulesets.UI // If we have no control points, add a default one if (DefaultControlPoints.Count == 0) DefaultControlPoints.Add(new MultiplierControlPoint()); + + DefaultControlPoints.ForEach(c => applySpeedAdjustment(c, Playfield)); + } + + private void applySpeedAdjustment(MultiplierControlPoint controlPoint, ScrollingPlayfield playfield) + { + playfield.HitObjects.AddSpeedAdjustment(CreateSpeedAdjustmentContainer(controlPoint)); + playfield.NestedPlayfields.ForEach(p => applySpeedAdjustment(controlPoint, p)); } /// From 4eec59f669684fcb32758e95b3fc5a6521a58fca Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 13:01:51 +0900 Subject: [PATCH 097/483] Only set the number of availableColumns once, at ManiaRulesetContainer level. # Conflicts: # osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs # osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs # osu.Game/Rulesets/UI/RulesetContainer.cs --- .../Beatmaps/ManiaBeatmapConverter.cs | 14 ++++++++++--- .../Beatmaps/Patterns/PatternGenerator.cs | 4 +--- .../UI/ManiaRulesetContainer.cs | 20 +++++++++---------- osu.Game/Rulesets/UI/RulesetContainer.cs | 19 +++++++++++++----- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index b55b9fdb37..e5a3c7849e 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -28,12 +28,18 @@ namespace osu.Game.Rulesets.Mania.Beatmaps private Pattern lastPattern = new Pattern(); private FastRandom random; private Beatmap beatmap; - private bool isForCurrentRuleset; - protected override Beatmap ConvertBeatmap(Beatmap original, bool isForCurrentRuleset) + private readonly int availableColumns; + private readonly bool isForCurrentRuleset; + + public ManiaBeatmapConverter(bool isForCurrentRuleset, int availableColumns) { this.isForCurrentRuleset = isForCurrentRuleset; + this.availableColumns = availableColumns; + } + protected override Beatmap ConvertBeatmap(Beatmap original) + { beatmap = original; BeatmapDifficulty difficulty = original.BeatmapInfo.Difficulty; @@ -89,7 +95,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// The hit objects generated. private IEnumerable generateSpecific(HitObject original) { - var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern); + var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern) { AvailableColumns = availableColumns }; Pattern newPattern = generator.Generate(); lastPattern = newPattern; @@ -128,6 +134,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps if (conversion == null) return null; + conversion.AvailableColumns = availableColumns; + Pattern newPattern = conversion.Generate(); lastPattern = newPattern; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs index dda4d07182..6b85a51402 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns /// /// The number of columns available to create the pattern. /// - protected readonly int AvailableColumns; + public int AvailableColumns; /// /// The last pattern. @@ -37,8 +37,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns PreviousPattern = previousPattern; HitObject = hitObject; Beatmap = beatmap; - - AvailableColumns = (int)Math.Round(beatmap.BeatmapInfo.Difficulty.CircleSize); } /// diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 9584dc34b8..58ce05b165 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -33,9 +33,10 @@ namespace osu.Game.Rulesets.Mania.UI public class ManiaRulesetContainer : ScrollingRulesetContainer { /// - /// Preferred column count. This will only have an effect during the initialization of the play field. + /// The number of columns which the should display, and which + /// the beatmap converter will attempt to convert beatmaps to use. /// - public int PreferredColumns; + private int availableColumns; public IEnumerable BarLines; @@ -76,14 +77,7 @@ namespace osu.Game.Rulesets.Mania.UI BarLines.ForEach(Playfield.Add); } - protected override void ApplyBeatmap() - { - base.ApplyBeatmap(); - - PreferredColumns = (int)Math.Max(1, Math.Round(Beatmap.BeatmapInfo.Difficulty.CircleSize)); - } - - protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(PreferredColumns) + protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(availableColumns) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -95,7 +89,11 @@ namespace osu.Game.Rulesets.Mania.UI public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo); - protected override BeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter(); + protected override BeatmapConverter CreateBeatmapConverter() + { + availableColumns = (int)Math.Max(1, Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.CircleSize)); + return new ManiaBeatmapConverter(IsForCurrentRuleset, availableColumns); + } protected override DrawableHitObject GetVisualRepresentation(ManiaHitObject h) { diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 5b19200f2d..c7240448b9 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -139,16 +139,25 @@ namespace osu.Game.Rulesets.UI protected IEnumerable Mods; /// + /// The this was created with. + /// + protected readonly WorkingBeatmap WorkingBeatmap; + + /// + /// Whether to assume the beatmap passed into this is for the current ruleset. /// Creates a hit renderer for a beatmap. /// /// The ruleset being repesented. - /// The beatmap to create the hit renderer for. + /// The beatmap to create the hit renderer for. /// Whether to assume the beatmap is for the current ruleset. internal RulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) : base(ruleset) + internal RulesetContainer(Ruleset ruleset, WorkingBeatmap workingBeatmap, bool isForCurrentRuleset) + : base(ruleset) { - Debug.Assert(beatmap != null, "RulesetContainer initialized with a null beatmap."); + Debug.Assert(workingBeatmap != null, "RulesetContainer initialized with a null beatmap."); - Mods = beatmap.Mods.Value; + WorkingBeatmap = workingBeatmap; + Mods = workingBeatmap.Mods.Value; RelativeSizeAxes = Axes.Both; @@ -156,11 +165,11 @@ namespace osu.Game.Rulesets.UI BeatmapProcessor processor = CreateBeatmapProcessor(); // Check if the beatmap can be converted - if (!converter.CanConvert(beatmap.Beatmap)) + if (!converter.CanConvert(workingBeatmap.Beatmap)) throw new BeatmapInvalidForRulesetException($"{nameof(Beatmap)} can not be converted for the current ruleset (converter: {converter})."); // Convert the beatmap - Beatmap = converter.Convert(beatmap.Beatmap, isForCurrentRuleset); + Beatmap = converter.Convert(workingBeatmap.Beatmap, isForCurrentRuleset); // Apply difficulty adjustments from mods before using Difficulty. foreach (var mod in Mods.OfType()) From 88151eff3f2a49b0882b833392935656357c4131 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 13:34:58 +0900 Subject: [PATCH 098/483] Fix dofficulty calculators not working and make mania set the correct key count for non-mania specific maps. --- .../ManiaDifficultyCalculator.cs | 5 +++-- .../UI/ManiaRulesetContainer.cs | 16 +++++++++++++++- .../TaikoDifficultyCalculator.cs | 4 ++-- osu.Game/Beatmaps/DifficultyCalculator.cs | 6 +++++- osu.Game/Rulesets/UI/RulesetContainer.cs | 2 +- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs index aaba4d94f0..1f01750f44 100644 --- a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs @@ -6,6 +6,7 @@ using osu.Game.Rulesets.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Objects; using System.Collections.Generic; +using System; namespace osu.Game.Rulesets.Mania { @@ -21,6 +22,6 @@ namespace osu.Game.Rulesets.Mania return 0; } - protected override BeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter(); + protected override BeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter(true, (int)Math.Max(1, Math.Round(Beatmap.BeatmapInfo.Difficulty.CircleSize))); } -} \ No newline at end of file +} diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 58ce05b165..6502b77cac 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -91,7 +91,21 @@ namespace osu.Game.Rulesets.Mania.UI protected override BeatmapConverter CreateBeatmapConverter() { - availableColumns = (int)Math.Max(1, Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.CircleSize)); + if (IsForCurrentRuleset) + availableColumns = (int)Math.Max(1, Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.CircleSize)); + else + { + float percentSliderOrSpinner = WorkingBeatmap.Beatmap.HitObjects.Count(h => h is IHasEndTime) / WorkingBeatmap.Beatmap.HitObjects.Count; + if (percentSliderOrSpinner < 0.2) + availableColumns = 7; + else if (percentSliderOrSpinner < 0.3 || Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.CircleSize) >= 5) + availableColumns = Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty) > 5 ? 7 : 6; + else if (percentSliderOrSpinner > 0.6) + availableColumns = Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty) > 4 ? 5 : 4; + else + availableColumns = Math.Max(4, Math.Min((int)Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty) + 1, 7)); + } + return new ManiaBeatmapConverter(IsForCurrentRuleset, availableColumns); } diff --git a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs index 33e9510f1c..35f849c704 100644 --- a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs @@ -135,6 +135,6 @@ namespace osu.Game.Rulesets.Taiko return difficulty; } - protected override BeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter(); + protected override BeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter(true); } -} \ No newline at end of file +} diff --git a/osu.Game/Beatmaps/DifficultyCalculator.cs b/osu.Game/Beatmaps/DifficultyCalculator.cs index 474d38aa1b..5071e2c1b6 100644 --- a/osu.Game/Beatmaps/DifficultyCalculator.cs +++ b/osu.Game/Beatmaps/DifficultyCalculator.cs @@ -30,11 +30,15 @@ namespace osu.Game.Beatmaps public abstract class DifficultyCalculator : DifficultyCalculator where T : HitObject { + protected readonly Beatmap Beatmap; + protected List Objects; protected DifficultyCalculator(Beatmap beatmap) { - Objects = CreateBeatmapConverter().Convert(beatmap, true).HitObjects; + Beatmap = beatmap; + + Objects = CreateBeatmapConverter().Convert(beatmap).HitObjects; foreach (var h in Objects) h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.Difficulty); diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index c7240448b9..1d5b27a7fb 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -169,7 +169,7 @@ namespace osu.Game.Rulesets.UI throw new BeatmapInvalidForRulesetException($"{nameof(Beatmap)} can not be converted for the current ruleset (converter: {converter})."); // Convert the beatmap - Beatmap = converter.Convert(workingBeatmap.Beatmap, isForCurrentRuleset); + Beatmap = converter.Convert(workingBeatmap.Beatmap); // Apply difficulty adjustments from mods before using Difficulty. foreach (var mod in Mods.OfType()) From cd3c825bd22231ac520ac900d5fc14c05bb318b2 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 14:04:14 +0900 Subject: [PATCH 099/483] Fix mania playfield not working. --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 1 + osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index b836b54fa8..0c9351cad2 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -125,6 +125,7 @@ namespace osu.Game.Rulesets.Mania.UI for (int i = 0; i < columnCount; i++) { var c = new Column(); + c.Reversed.BindTo(Reversed); c.VisibleTimeRange.BindTo(VisibleTimeRange); columns.Add(c); diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 6502b77cac..aea2d26791 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -74,6 +74,8 @@ namespace osu.Game.Rulesets.Mania.UI [BackgroundDependencyLoader] private void load() { + Playfield.Reversed.Value = true; + BarLines.ForEach(Playfield.Add); } @@ -81,8 +83,6 @@ namespace osu.Game.Rulesets.Mania.UI { Anchor = Anchor.Centre, Origin = Anchor.Centre, - // Invert by default for now (should be moved to config/skin later) - Scale = new Vector2(1, -1) }; public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this); From 9a7c9e9af0107e3af439e422c7fcdd59f9b67819 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 14:17:57 +0900 Subject: [PATCH 100/483] Disable reversing for now - this needs to be re-implemented in a later PR. --- osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index aea2d26791..9b4d3adb86 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -74,8 +74,6 @@ namespace osu.Game.Rulesets.Mania.UI [BackgroundDependencyLoader] private void load() { - Playfield.Reversed.Value = true; - BarLines.ForEach(Playfield.Add); } From 68c7226d124bb9292dd9fd3364f502460031b5a8 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 14:18:17 +0900 Subject: [PATCH 101/483] Fix cherry pick issues. --- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 2 +- osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs | 7 +++++-- osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs | 2 +- osu.Game/Rulesets/Beatmaps/BeatmapConverter.cs | 8 +++----- osu.Game/Rulesets/UI/RulesetContainer.cs | 7 ++++++- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index e5a3c7849e..9b88a8c96c 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate); random = new FastRandom(seed); - return base.ConvertBeatmap(original, isForCurrentRuleset); + return base.ConvertBeatmap(original); } protected override IEnumerable ConvertHitObject(HitObject original, Beatmap beatmap) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 869d54dded..40147f7c24 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -43,15 +43,18 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(HitObject) }; - protected override Beatmap ConvertBeatmap(Beatmap original, bool isForCurrentRuleset) + public TaikoBeatmapConverter(bool isForCurrentRuleset) { this.isForCurrentRuleset = isForCurrentRuleset; + } + protected override Beatmap ConvertBeatmap(Beatmap original) + { // Rewrite the beatmap info to add the slider velocity multiplier BeatmapInfo info = original.BeatmapInfo.DeepClone(); info.Difficulty.SliderMultiplier *= legacy_velocity_multiplier; - Beatmap converted = base.ConvertBeatmap(original, isForCurrentRuleset); + Beatmap converted = base.ConvertBeatmap(original); // Post processing step to transform hit objects with the same start time into strong hits converted.HitObjects = converted.HitObjects.GroupBy(t => t.StartTime).Select(x => diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index 1ecd699a8e..96e5df12cd 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -91,7 +91,7 @@ namespace osu.Game.Rulesets.Taiko.UI public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this); - protected override BeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter(); + protected override BeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter(IsForCurrentRuleset); public override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo); diff --git a/osu.Game/Rulesets/Beatmaps/BeatmapConverter.cs b/osu.Game/Rulesets/Beatmaps/BeatmapConverter.cs index aafa576d4b..e79d9eee4b 100644 --- a/osu.Game/Rulesets/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Rulesets/Beatmaps/BeatmapConverter.cs @@ -26,21 +26,19 @@ namespace osu.Game.Rulesets.Beatmaps /// Converts a Beatmap using this Beatmap Converter. /// /// The un-converted Beatmap. - /// Whether to assume the beatmap is for the current ruleset. /// The converted Beatmap. - public Beatmap Convert(Beatmap original, bool isForCurrentRuleset) + 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), isForCurrentRuleset); + return ConvertBeatmap(new Beatmap(original)); } /// /// Performs the conversion of a Beatmap using this Beatmap Converter. /// /// The un-converted Beatmap. - /// Whether to assume the beatmap is for the current ruleset. /// The converted Beatmap. - protected virtual Beatmap ConvertBeatmap(Beatmap original, bool isForCurrentRuleset) + protected virtual Beatmap ConvertBeatmap(Beatmap original) { return new Beatmap { diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 1d5b27a7fb..2f1cb915f3 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -143,6 +143,11 @@ namespace osu.Game.Rulesets.UI /// protected readonly WorkingBeatmap WorkingBeatmap; + /// + /// Whether the specified beatmap is assumed to be specific to the current ruleset. + /// + protected readonly bool IsForCurrentRuleset; + /// /// Whether to assume the beatmap passed into this is for the current ruleset. /// Creates a hit renderer for a beatmap. @@ -150,13 +155,13 @@ 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. - internal RulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) : base(ruleset) internal RulesetContainer(Ruleset ruleset, WorkingBeatmap workingBeatmap, bool isForCurrentRuleset) : base(ruleset) { Debug.Assert(workingBeatmap != null, "RulesetContainer initialized with a null beatmap."); WorkingBeatmap = workingBeatmap; + IsForCurrentRuleset = isForCurrentRuleset; Mods = workingBeatmap.Mods.Value; RelativeSizeAxes = Axes.Both; From 909cae5861da45943ec55b5d70d1bd81a8ab6915 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 14:21:28 +0900 Subject: [PATCH 102/483] CI fixes. --- osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs | 1 - osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs | 2 +- osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs index 6b85a51402..6ab9c86b9f 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 9b4d3adb86..0e750a348e 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Mania.UI availableColumns = (int)Math.Max(1, Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.CircleSize)); else { - float percentSliderOrSpinner = WorkingBeatmap.Beatmap.HitObjects.Count(h => h is IHasEndTime) / WorkingBeatmap.Beatmap.HitObjects.Count; + float percentSliderOrSpinner = (float)WorkingBeatmap.Beatmap.HitObjects.Count(h => h is IHasEndTime) / WorkingBeatmap.Beatmap.HitObjects.Count; if (percentSliderOrSpinner < 0.2) availableColumns = 7; else if (percentSliderOrSpinner < 0.3 || Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.CircleSize) >= 5) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 40147f7c24..2bf058fc2b 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps /// private const float taiko_base_distance = 100; - private bool isForCurrentRuleset; + private readonly bool isForCurrentRuleset; protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(HitObject) }; From ff8ad30127b78091a63dab2cfc1c2597e6af9394 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 14:42:49 +0900 Subject: [PATCH 103/483] Add support for binding mousewheel actions --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index a3361743a1..eb7d528897 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -172,6 +172,21 @@ namespace osu.Game.Overlays.KeyBinding return base.OnMouseUp(state, args); } + protected override bool OnWheel(InputState state) + { + if (HasFocus) + { + if (bindTarget.IsHovered) + { + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(state)); + finalise(); + return true; + } + } + + return base.OnWheel(state); + } + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { if (!HasFocus) From 18645fcf297325daa0391619775a4becbb538f4c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 14:44:13 +0900 Subject: [PATCH 104/483] Update volume control logic to use key bindings Fixes them not working at all, too. --- .../UserInterface/Volume/VolumeControl.cs | 22 ++++++++---- .../Volume/VolumeControlReceptor.cs | 28 ++++----------- .../UserInterface/Volume/VolumeMeter.cs | 34 ++++++++++++++++--- .../Bindings/GlobalKeyBindingInputManager.cs | 9 ++++- osu.Game/OsuGame.cs | 3 +- 5 files changed, 60 insertions(+), 36 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index cd77fb9f5b..4c108e793a 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -3,11 +3,11 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Input; using osu.Framework.Threading; using OpenTK; using osu.Framework.Audio; using osu.Framework.Allocation; +using osu.Game.Input.Bindings; namespace osu.Game.Graphics.UserInterface.Volume { @@ -64,15 +64,25 @@ namespace osu.Game.Graphics.UserInterface.Volume volumeMeterMusic.Bindable.ValueChanged -= volumeChanged; } - public void Adjust(InputState state) + public bool Adjust(GlobalAction action) { - if (State == Visibility.Hidden) + switch (action) { - Show(); - return; + case GlobalAction.DecreaseVolume: + if (State == Visibility.Hidden) + Show(); + else + volumeMeterMaster.Decrease(); + return true; + case GlobalAction.IncreaseVolume: + if (State == Visibility.Hidden) + Show(); + else + volumeMeterMaster.Increase(); + return true; } - volumeMeterMaster.TriggerOnWheel(state); + return false; } [BackgroundDependencyLoader] diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs index c155871f33..c222fecb5d 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs @@ -3,32 +3,16 @@ using System; using osu.Framework.Graphics.Containers; -using osu.Framework.Input; -using OpenTK.Input; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; namespace osu.Game.Graphics.UserInterface.Volume { - internal class VolumeControlReceptor : Container + internal class VolumeControlReceptor : Container, IKeyBindingHandler { - public Action ActionRequested; + public Func ActionRequested; - protected override bool OnWheel(InputState state) - { - ActionRequested?.Invoke(state); - return true; - } - - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - switch (args.Key) - { - case Key.Up: - case Key.Down: - ActionRequested?.Invoke(state); - return true; - } - - return base.OnKeyDown(state, args); - } + public bool OnPressed(GlobalAction action) => ActionRequested?.Invoke(action) ?? false; + public bool OnReleased(GlobalAction action) => false; } } diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs index 41fa60bec2..81c4fa9bae 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs @@ -4,15 +4,16 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Input; using osu.Game.Graphics.Sprites; using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; namespace osu.Game.Graphics.UserInterface.Volume { - internal class VolumeMeter : Container + internal class VolumeMeter : Container, IKeyBindingHandler { private readonly Box meterFill; public BindableDouble Bindable { get; } = new BindableDouble(); @@ -76,12 +77,35 @@ namespace osu.Game.Graphics.UserInterface.Volume } } - protected override bool OnWheel(InputState state) + public void Increase() { - Volume += 0.05f * state.Mouse.WheelDelta; - return true; + Volume += 0.05f; + } + + public void Decrease() + { + Volume -= 0.05f; } private void updateFill() => meterFill.ScaleTo(new Vector2(1, (float)Volume), 300, Easing.OutQuint); + + public bool OnPressed(GlobalAction action) + { + if (!IsHovered) return false; + + switch (action) + { + case GlobalAction.DecreaseVolume: + Decrease(); + return true; + case GlobalAction.IncreaseVolume: + Increase(); + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => false; } } \ No newline at end of file diff --git a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs index 5ea66fa600..759396e195 100644 --- a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs @@ -26,7 +26,10 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings), new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar), new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings), - new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.ToggleDirect), + new KeyBinding(new[] { InputKey.Up }, GlobalAction.IncreaseVolume), + new KeyBinding(new[] { InputKey.MouseWheelUp }, GlobalAction.IncreaseVolume), + new KeyBinding(new[] { InputKey.Down }, GlobalAction.DecreaseVolume), + new KeyBinding(new[] { InputKey.MouseWheelDown }, GlobalAction.DecreaseVolume), }; protected override IEnumerable KeyBindingInputQueue => @@ -47,5 +50,9 @@ namespace osu.Game.Input.Bindings ToggleSettings, [Description("Toggle osu!direct")] ToggleDirect, + [Description("Increase Volume")] + IncreaseVolume, + [Description("Decrease Volume")] + DecreaseVolume, } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e3525e423c..6e340a7f1d 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -8,7 +8,6 @@ using osu.Game.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; -using osu.Framework.Input; using osu.Framework.Logging; using osu.Game.Graphics.UserInterface.Volume; using osu.Framework.Allocation; @@ -160,7 +159,7 @@ namespace osu.Game new VolumeControlReceptor { RelativeSizeAxes = Axes.Both, - ActionRequested = delegate(InputState state) { volume.Adjust(state); } + ActionRequested = action => volume.Adjust(action) }, mainContent = new Container { From 09dd0cabd64b6084aa0d40e64e119993c6844289 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 15:58:47 +0900 Subject: [PATCH 105/483] Move beatmap/ruleset change restrictions to OsuGame Allows test cases to more freely exist --- osu.Game/OsuGame.cs | 7 +++++++ osu.Game/Screens/OsuScreen.cs | 13 ------------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e3525e423c..68b5aa1cc9 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -359,6 +359,13 @@ namespace osu.Game { base.UpdateAfterChildren(); + // we only want to apply these restrictions when we are inside a screen stack. + // the use case for not applying is in visual/unit tests. + bool applyRestrictions = currentScreen?.AllowBeatmapRulesetChange ?? false; + + Ruleset.Disabled = applyRestrictions; + Beatmap.Disabled = applyRestrictions; + mainContent.Padding = new MarginPadding { Top = ToolbarOffset }; Cursor.State = currentScreen?.HasLocalCursorDisplayed == false ? Visibility.Visible : Visibility.Hidden; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 6e79d2b427..ae10d8828b 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -69,19 +69,6 @@ namespace osu.Game.Screens sampleExit = audio.Sample.Get(@"UI/melodic-1"); } - protected override void Update() - { - if (!IsCurrentScreen) return; - - if (ParentScreen != null) - { - // we only want to apply these restrictions when we are inside a screen stack. - // the use case for not applying is in visual/unit tests. - Ruleset.Disabled = !AllowBeatmapRulesetChange; - Beatmap.Disabled = !AllowBeatmapRulesetChange; - } - } - protected override void OnResuming(Screen last) { base.OnResuming(last); From 5fcd94880d19f36fba5566f03d3bd0aed6359a36 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 15:58:21 +0900 Subject: [PATCH 106/483] Fix incorrect inequality with multiple speed adjustments at the same start time. --- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 0a8469c928..9745e5d098 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -181,7 +181,7 @@ namespace osu.Game.Rulesets.UI speedAdjustments.Add(speedAdjustment); // We now need to re-sort the hit objects in the last speed adjustment prior to this one, to see if they need a new parent - var previousSpeedAdjustment = speedAdjustments.LastOrDefault(s => s.ControlPoint.StartTime < speedAdjustment.ControlPoint.StartTime); + var previousSpeedAdjustment = speedAdjustments.LastOrDefault(s => s.ControlPoint.StartTime <= speedAdjustment.ControlPoint.StartTime); if (previousSpeedAdjustment == null) return; From b7b8d8b76461b29c9cab011c94460fdbb1e5c29e Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 15:59:38 +0900 Subject: [PATCH 107/483] Let's not construct scrolling containers in load() for now This isn't utilized at the moment, and we should be avoiding this here in the first place. --- osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs index 5d6c03b9de..0ca6fc84c2 100644 --- a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs +++ b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs @@ -51,11 +51,7 @@ namespace osu.Game.Rulesets.Timing { ControlPoint = controlPoint; RelativeSizeAxes = Axes.Both; - } - [BackgroundDependencyLoader] - private void load() - { scrollingContainer = CreateScrollingContainer(); scrollingContainer.ScrollingAxes = ScrollingAxes; From 6f662d721cb47e33dafcd3c9a8b44e9914b9da1f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 16:00:26 +0900 Subject: [PATCH 108/483] Fix possible CollectionModifiedException while adding new SpeedAdjustmentContainers --- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 9745e5d098..2678df7d44 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -185,14 +185,18 @@ namespace osu.Game.Rulesets.UI if (previousSpeedAdjustment == null) return; - foreach (DrawableHitObject h in previousSpeedAdjustment.Children) + for (int i = 0; i < previousSpeedAdjustment.Children.Count; i++) { - var newSpeedAdjustment = adjustmentContainerFor(h); + DrawableHitObject hitObject = previousSpeedAdjustment[i]; + + var newSpeedAdjustment = adjustmentContainerFor(hitObject); if (newSpeedAdjustment == previousSpeedAdjustment) continue; - previousSpeedAdjustment.Remove(h); - newSpeedAdjustment.Add(h); + previousSpeedAdjustment.Remove(hitObject); + newSpeedAdjustment.Add(hitObject); + + i--; } } From 4fc77be62498ae4ae2d998cf38cc8b991a4d11b0 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 16:00:59 +0900 Subject: [PATCH 109/483] Fix incorrect sorting of hit objects into SpeedAdjustmentContainers --- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 2678df7d44..09a8e50809 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -228,7 +228,7 @@ namespace osu.Game.Rulesets.UI /// /// The hit object to find the active for. /// The active at 's start time. Null if there are no speed adjustments. - private SpeedAdjustmentContainer adjustmentContainerFor(DrawableHitObject hitObject) => speedAdjustments.FirstOrDefault(c => c.CanContain(hitObject)) ?? speedAdjustments.LastOrDefault(); + private SpeedAdjustmentContainer adjustmentContainerFor(DrawableHitObject hitObject) => speedAdjustments.LastOrDefault(c => c.CanContain(hitObject)) ?? speedAdjustments.FirstOrDefault(); /// /// Finds the which provides the speed adjustment active at a time. @@ -236,7 +236,7 @@ namespace osu.Game.Rulesets.UI /// /// The time to find the active at. /// The active at . Null if there are no speed adjustments. - private SpeedAdjustmentContainer adjustmentContainerAt(double time) => speedAdjustments.FirstOrDefault(c => c.CanContain(time)) ?? speedAdjustments.LastOrDefault(); + private SpeedAdjustmentContainer adjustmentContainerAt(double time) => speedAdjustments.LastOrDefault(c => c.CanContain(time)) ?? speedAdjustments.FirstOrDefault(); } } } From c3cfad4eb5a009d650a3603093a3afc0b3799ff6 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 16:01:19 +0900 Subject: [PATCH 110/483] Add RemoveSpeedAdjustment --- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 09a8e50809..aea224ab9e 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -200,6 +200,25 @@ namespace osu.Game.Rulesets.UI } } + /// + /// Removes a from this container, re-sorting all hit objects + /// which it contained into new s. + /// + /// The to remove. + public void RemoveSpeedAdjustment(SpeedAdjustmentContainer speedAdjustment) + { + if (!speedAdjustments.Remove(speedAdjustment)) + return; + + while (speedAdjustment.Count > 0) + { + DrawableHitObject hitObject = speedAdjustment[0]; + + speedAdjustment.Remove(hitObject); + Add(hitObject); + } + } + public override IEnumerable Objects => speedAdjustments.SelectMany(s => s.Children); /// From d20ea97e7f8222296b99a21528d66316132cf191 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 16:05:12 +0900 Subject: [PATCH 111/483] Add NUnit test for ScrollingHitObjectContainer Tests ordering of SpeedAdjustmentContainers and DrawableHitObjects added to the ScrollingHitObjectContainer. --- .../Visual/TestCaseScrollingPlayfield.cs | 67 ++++++++++++++++++- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 5 +- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs index e9c29d36c2..2d49b2d0f9 100644 --- a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs @@ -3,19 +3,23 @@ using System; using System.Collections.Generic; +using NUnit.Framework; using OpenTK; using osu.Desktop.Tests.Beatmaps; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Framework.Timing; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Beatmaps; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.Timing; using osu.Game.Rulesets.UI; namespace osu.Desktop.Tests.Visual @@ -23,6 +27,7 @@ namespace osu.Desktop.Tests.Visual /// /// The most minimal implementation of a playfield with scrolling hit objects. /// + [TestFixture] public class TestCaseScrollingPlayfield : OsuTestCase { public TestCaseScrollingPlayfield() @@ -64,6 +69,66 @@ namespace osu.Desktop.Tests.Visual }); } + [Test] + public void TestSpeedAdjustmentOrdering() + { + var hitObjectContainer = new ScrollingPlayfield.ScrollingHitObjectContainer(Axes.X); + + var speedAdjustments = new[] + { + new SpeedAdjustmentContainer(new MultiplierControlPoint()), + new SpeedAdjustmentContainer(new MultiplierControlPoint(1000) + { + TimingPoint = new TimingControlPoint { BeatLength = 500 } + }), + new SpeedAdjustmentContainer(new MultiplierControlPoint(2000) + { + TimingPoint = new TimingControlPoint { BeatLength = 1000 }, + DifficultyPoint = new DifficultyControlPoint { SpeedMultiplier = 2} + }), + new SpeedAdjustmentContainer(new MultiplierControlPoint(3000) + { + TimingPoint = new TimingControlPoint { BeatLength = 1000 }, + DifficultyPoint = new DifficultyControlPoint { SpeedMultiplier = 1} + }), + }; + + var hitObjects = new[] + { + new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = -1000 }), + new DrawableTestHitObject(Axes.X, new TestHitObject()), + new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = 1000 }), + new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = 2000 }), + new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = 3000 }), + new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = 4000 }), + }; + + hitObjects.ForEach(h => hitObjectContainer.Add(h)); + speedAdjustments.ForEach(hitObjectContainer.AddSpeedAdjustment); + + // The 0th index in hitObjectContainer.SpeedAdjustments is the "default" control point + // Check multiplier of the default speed adjustment + Assert.AreEqual(1, hitObjectContainer.SpeedAdjustments[0].ControlPoint.Multiplier); + Assert.AreEqual(1, speedAdjustments[0].ControlPoint.Multiplier); + Assert.AreEqual(2, speedAdjustments[1].ControlPoint.Multiplier); + Assert.AreEqual(2, speedAdjustments[2].ControlPoint.Multiplier); + Assert.AreEqual(1, speedAdjustments[3].ControlPoint.Multiplier); + + // Check insertion of hit objects + Assert.IsTrue(hitObjectContainer.SpeedAdjustments[0].Contains(hitObjects[0])); + Assert.IsTrue(speedAdjustments[0].Contains(hitObjects[1])); + Assert.IsTrue(speedAdjustments[1].Contains(hitObjects[2])); + Assert.IsTrue(speedAdjustments[2].Contains(hitObjects[3])); + Assert.IsTrue(speedAdjustments[3].Contains(hitObjects[4])); + Assert.IsTrue(speedAdjustments[3].Contains(hitObjects[5])); + + hitObjectContainer.RemoveSpeedAdjustment(speedAdjustments[1]); + + // The hit object contained in this speed adjustment should be resorted into the previous one + + Assert.IsTrue(speedAdjustments[0].Contains(hitObjects[2])); + } + private class TestRulesetContainer : ScrollingRulesetContainer { private readonly Axes scrollingAxes; @@ -158,4 +223,4 @@ namespace osu.Desktop.Tests.Visual public override string MaxResultString { get { throw new NotImplementedException(); } } } } -} \ No newline at end of file +} diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index aea224ab9e..bfaacdd08e 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.UI /// /// The container that contains the s and s. /// - internal new readonly ScrollingHitObjectContainer HitObjects; + public new readonly ScrollingHitObjectContainer HitObjects; /// /// Creates a new . @@ -138,7 +138,7 @@ namespace osu.Game.Rulesets.UI /// /// A container that provides the foundation for sorting s into s. /// - internal class ScrollingHitObjectContainer : HitObjectContainer + public class ScrollingHitObjectContainer : HitObjectContainer { /// /// Gets or sets the range of time that is visible by the length of the scrolling axes. @@ -152,6 +152,7 @@ namespace osu.Game.Rulesets.UI public readonly BindableBool Reversed = new BindableBool(); private readonly Container speedAdjustments; + public IReadOnlyList SpeedAdjustments => speedAdjustments; private readonly Axes scrollingAxes; From a737f5fe0da77583cdbd35f41dac09b7a133faf7 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 16:05:19 +0900 Subject: [PATCH 112/483] CI fixes. --- osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs index 0ca6fc84c2..3b13fdf00a 100644 --- a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs +++ b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -27,7 +26,7 @@ namespace osu.Game.Rulesets.Timing public readonly BindableBool Reversed = new BindableBool(); protected override Container Content => content; - private Container content; + private readonly Container content; /// /// The axes which the content of this container will scroll through. @@ -41,7 +40,7 @@ namespace osu.Game.Rulesets.Timing /// public readonly MultiplierControlPoint ControlPoint; - private ScrollingContainer scrollingContainer; + private readonly ScrollingContainer scrollingContainer; /// /// Creates a new . From 5a3c0de7ada1a3a9726e695e02f88a4015442e44 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 16:10:58 +0900 Subject: [PATCH 113/483] Fix further incorrect comparison. --- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index bfaacdd08e..e9f6b4f2ed 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -182,7 +182,7 @@ namespace osu.Game.Rulesets.UI speedAdjustments.Add(speedAdjustment); // We now need to re-sort the hit objects in the last speed adjustment prior to this one, to see if they need a new parent - var previousSpeedAdjustment = speedAdjustments.LastOrDefault(s => s.ControlPoint.StartTime <= speedAdjustment.ControlPoint.StartTime); + var previousSpeedAdjustment = speedAdjustments.LastOrDefault(s => s != speedAdjustment && s.ControlPoint.StartTime <= speedAdjustment.ControlPoint.StartTime); if (previousSpeedAdjustment == null) return; From 0189f014028b9bdcad1d1b43a3a4650294bfed96 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 16:15:40 +0900 Subject: [PATCH 114/483] Explicitly store defaultSpeedAdjustment, and make it un-removable --- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index e9f6b4f2ed..524665487d 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -154,6 +154,8 @@ namespace osu.Game.Rulesets.UI private readonly Container speedAdjustments; public IReadOnlyList SpeedAdjustments => speedAdjustments; + private readonly SpeedAdjustmentContainer defaultSpeedAdjustment; + private readonly Axes scrollingAxes; /// @@ -167,7 +169,7 @@ namespace osu.Game.Rulesets.UI AddInternal(speedAdjustments = new Container { RelativeSizeAxes = Axes.Both }); // Default speed adjustment - AddSpeedAdjustment(new SpeedAdjustmentContainer(new MultiplierControlPoint(0))); + AddSpeedAdjustment(defaultSpeedAdjustment = new SpeedAdjustmentContainer(new MultiplierControlPoint(0))); } /// @@ -208,6 +210,9 @@ namespace osu.Game.Rulesets.UI /// The to remove. public void RemoveSpeedAdjustment(SpeedAdjustmentContainer speedAdjustment) { + if (speedAdjustment == defaultSpeedAdjustment) + throw new InvalidOperationException($"The default {nameof(SpeedAdjustmentContainer)} must not be removed."); + if (!speedAdjustments.Remove(speedAdjustment)) return; @@ -232,11 +237,7 @@ namespace osu.Game.Rulesets.UI if (!(hitObject is IScrollingHitObject)) throw new InvalidOperationException($"Hit objects added to a {nameof(ScrollingHitObjectContainer)} must implement {nameof(IScrollingHitObject)}."); - var target = adjustmentContainerFor(hitObject); - if (target == null) - throw new InvalidOperationException($"A {nameof(SpeedAdjustmentContainer)} to container {hitObject} could not be found."); - - target.Add(hitObject); + adjustmentContainerFor(hitObject).Add(hitObject); } public override bool Remove(DrawableHitObject hitObject) => speedAdjustments.Any(s => s.Remove(hitObject)); @@ -248,7 +249,7 @@ namespace osu.Game.Rulesets.UI /// /// The hit object to find the active for. /// The active at 's start time. Null if there are no speed adjustments. - private SpeedAdjustmentContainer adjustmentContainerFor(DrawableHitObject hitObject) => speedAdjustments.LastOrDefault(c => c.CanContain(hitObject)) ?? speedAdjustments.FirstOrDefault(); + private SpeedAdjustmentContainer adjustmentContainerFor(DrawableHitObject hitObject) => speedAdjustments.LastOrDefault(c => c.CanContain(hitObject)) ?? defaultSpeedAdjustment; /// /// Finds the which provides the speed adjustment active at a time. @@ -256,7 +257,7 @@ namespace osu.Game.Rulesets.UI /// /// The time to find the active at. /// The active at . Null if there are no speed adjustments. - private SpeedAdjustmentContainer adjustmentContainerAt(double time) => speedAdjustments.LastOrDefault(c => c.CanContain(time)) ?? speedAdjustments.FirstOrDefault(); + private SpeedAdjustmentContainer adjustmentContainerAt(double time) => speedAdjustments.LastOrDefault(c => c.CanContain(time)) ?? defaultSpeedAdjustment; } } } From e337fbcf4fe9dedc008a1ff33be26919ca2a6de9 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 16:22:40 +0900 Subject: [PATCH 115/483] Make availableColumns into a ctor argument. --- .../Beatmaps/ManiaBeatmapConverter.cs | 14 ++++++-------- .../Legacy/DistanceObjectPatternGenerator.cs | 4 ++-- .../Legacy/EndTimeObjectPatternGenerator.cs | 4 ++-- .../Patterns/Legacy/HitObjectPatternGenerator.cs | 4 ++-- .../Beatmaps/Patterns/Legacy/PatternGenerator.cs | 4 ++-- .../Beatmaps/Patterns/PatternGenerator.cs | 7 ++++--- 6 files changed, 18 insertions(+), 19 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 9b88a8c96c..262f1c67ed 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// The hit objects generated. private IEnumerable generateSpecific(HitObject original) { - var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern) { AvailableColumns = availableColumns }; + var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, availableColumns, lastPattern); Pattern newPattern = generator.Generate(); lastPattern = newPattern; @@ -119,14 +119,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps Patterns.PatternGenerator conversion = null; if (distanceData != null) - conversion = new DistanceObjectPatternGenerator(random, original, beatmap, lastPattern); + conversion = new DistanceObjectPatternGenerator(random, original, beatmap, availableColumns, lastPattern); else if (endTimeData != null) - conversion = new EndTimeObjectPatternGenerator(random, original, beatmap); + conversion = new EndTimeObjectPatternGenerator(random, original, beatmap, availableColumns); else if (positionData != null) { computeDensity(original.StartTime); - conversion = new HitObjectPatternGenerator(random, original, beatmap, lastPattern, lastTime, lastPosition, density, lastStair); + conversion = new HitObjectPatternGenerator(random, original, beatmap, availableColumns, lastPattern, lastTime, lastPosition, density, lastStair); recordNote(original.StartTime, positionData.Position); } @@ -134,8 +134,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps if (conversion == null) return null; - conversion.AvailableColumns = availableColumns; - Pattern newPattern = conversion.Generate(); lastPattern = newPattern; @@ -150,8 +148,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator { - public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, Pattern previousPattern) - : base(random, hitObject, beatmap, previousPattern) + public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern) + : base(random, hitObject, beatmap, availableColumns, previousPattern) { } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index c03a8438ae..20966a75f7 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -29,8 +29,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy private PatternType convertType; - public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, Pattern previousPattern) - : base(random, hitObject, beatmap, previousPattern) + public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern) + : base(random, hitObject, beatmap, availableColumns, previousPattern) { convertType = PatternType.None; if (Beatmap.ControlPointInfo.EffectPointAt(hitObject.StartTime).KiaiMode) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs index 6ad7489e0f..c353496410 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs @@ -15,8 +15,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { private readonly double endTime; - public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap) - : base(random, hitObject, beatmap, new Pattern()) + public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns) + : base(random, hitObject, beatmap, availableColumns, new Pattern()) { 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 99f55cb98b..0716671da3 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -20,8 +20,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy private readonly PatternType convertType; - public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair) - : base(random, hitObject, beatmap, previousPattern) + public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair) + : base(random, hitObject, beatmap, availableColumns, previousPattern) { StairType = lastStair; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs index b72618c36c..d1b962bdd4 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs @@ -25,8 +25,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// protected readonly FastRandom Random; - protected PatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, Pattern previousPattern) - : base(hitObject, beatmap, previousPattern) + protected PatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern) + : base(hitObject, beatmap, availableColumns, previousPattern) { Random = random; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs index 6ab9c86b9f..4fe100df23 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns /// /// The number of columns available to create the pattern. /// - public int AvailableColumns; + protected readonly int AvailableColumns; /// /// The last pattern. @@ -31,11 +31,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns /// protected readonly Beatmap Beatmap; - protected PatternGenerator(HitObject hitObject, Beatmap beatmap, Pattern previousPattern) + protected PatternGenerator(HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern) { - PreviousPattern = previousPattern; HitObject = hitObject; Beatmap = beatmap; + AvailableColumns = availableColumns; + PreviousPattern = previousPattern; } /// From 2f2abf122b38a4d53c0c1b02449781010f0f0dcd Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 16:46:12 +0900 Subject: [PATCH 116/483] Add exceptions galore. --- .../Beatmaps/ManiaBeatmapConverter.cs | 2 ++ .../Patterns/Legacy/HitObjectPatternGenerator.cs | 3 +++ .../Beatmaps/Patterns/Legacy/PatternGenerator.cs | 12 +++++++++++- .../Beatmaps/Patterns/PatternGenerator.cs | 6 ++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 262f1c67ed..be670936fd 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -34,6 +34,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps public ManiaBeatmapConverter(bool isForCurrentRuleset, int availableColumns) { + if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns)); + this.isForCurrentRuleset = isForCurrentRuleset; this.availableColumns = availableColumns; } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index 0716671da3..077b926635 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -23,6 +23,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair) : base(random, hitObject, beatmap, availableColumns, previousPattern) { + if (previousTime > hitObject.StartTime) throw new ArgumentOutOfRangeException(nameof(previousTime)); + if (density < 0) throw new ArgumentOutOfRangeException(nameof(density)); + StairType = lastStair; TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime); diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs index d1b962bdd4..a3173f9784 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs @@ -28,8 +28,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy protected PatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern) : base(hitObject, beatmap, availableColumns, previousPattern) { - Random = random; + if (random == null) throw new ArgumentNullException(nameof(random)); + if (beatmap == null) throw new ArgumentNullException(nameof(beatmap)); + if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns)); + if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern)); + Random = random; RandomStart = AvailableColumns == 8 ? 1 : 0; } @@ -62,6 +66,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// The amount of notes to be generated. protected int GetRandomNoteCount(double p2, double p3, double p4 = 0, double p5 = 0, double p6 = 0) { + if (p2 < 0 || p2 > 1) throw new ArgumentOutOfRangeException(nameof(p2)); + if (p3 < 0 || p3 > 1) throw new ArgumentOutOfRangeException(nameof(p3)); + if (p4 < 0 || p4 > 1) throw new ArgumentOutOfRangeException(nameof(p4)); + if (p5 < 0 || p5 > 1) throw new ArgumentOutOfRangeException(nameof(p5)); + if (p6 < 0 || p6 > 1) throw new ArgumentOutOfRangeException(nameof(p6)); + double val = Random.NextDouble(); if (val >= 1 - p6) return 6; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs index 4fe100df23..ef321232c8 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; @@ -33,6 +34,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns protected PatternGenerator(HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern) { + if (hitObject == null) throw new ArgumentNullException(nameof(hitObject)); + if (beatmap == null) throw new ArgumentNullException(nameof(beatmap)); + if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns)); + if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern)); + HitObject = hitObject; Beatmap = beatmap; AvailableColumns = availableColumns; From 803cbddfe224e756a52696e965a2168736943ccc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 16:58:47 +0900 Subject: [PATCH 117/483] Ensure score's user is set directly from API Previously would fail in visualtests due to `OsuGame` case. --- osu.Game/Screens/Play/Player.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 3f399d69e6..992c5c5f6f 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -23,6 +23,7 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Ranking; using osu.Framework.Audio.Sample; using osu.Game.Beatmaps; +using osu.Game.Online.API; namespace osu.Game.Screens.Play { @@ -50,6 +51,8 @@ namespace osu.Game.Screens.Play private RulesetInfo ruleset; + private APIAccess api; + private ScoreProcessor scoreProcessor; protected RulesetContainer RulesetContainer; @@ -69,9 +72,12 @@ namespace osu.Game.Screens.Play private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true; [BackgroundDependencyLoader(permitNulls: true)] - private void load(AudioManager audio, OsuConfigManager config, OsuGame osu) + private void load(AudioManager audio, OsuConfigManager config, OsuGame osu, APIAccess api) { + this.api = api; + dimLevel = config.GetBindable(OsuSetting.DimLevel); + mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); sampleRestart = audio.Sample.Get(@"Gameplay/restart"); @@ -235,7 +241,7 @@ namespace osu.Game.Screens.Play Ruleset = ruleset }; scoreProcessor.PopulateScore(score); - score.User = RulesetContainer.Replay?.User ?? (Game as OsuGame)?.API?.LocalUser?.Value; + score.User = RulesetContainer.Replay?.User ?? api.LocalUser.Value; Push(new Results(score)); }); } From 8f32fd28c927b3a90a35e6dbf9d5f33dfbbee0e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 17:21:19 +0900 Subject: [PATCH 118/483] Fix backwards conditional --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 68b5aa1cc9..8cb45c39a5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -361,7 +361,7 @@ namespace osu.Game // we only want to apply these restrictions when we are inside a screen stack. // the use case for not applying is in visual/unit tests. - bool applyRestrictions = currentScreen?.AllowBeatmapRulesetChange ?? false; + bool applyRestrictions = !currentScreen?.AllowBeatmapRulesetChange ?? false; Ruleset.Disabled = applyRestrictions; Beatmap.Disabled = applyRestrictions; From a26885c1ab46c72b6df4647fcd1db7bfdfb0d144 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 17:25:45 +0900 Subject: [PATCH 119/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index f1527e5456..ba70b8eaa9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit f1527e5456cd228ddfb68cf6d56eb5d28dc360bf +Subproject commit ba70b8eaa9b79d4248873d4399f3b9e918fc3c8f From d8de6e289c18f495239c8db4539cb7622733e022 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 17:38:51 +0900 Subject: [PATCH 120/483] Don't start rotating the cursor until it has travelled a minimum disatnce Some people, myself included, were annoyed by the rotation starting too soon (especially when dragging up and left one pixel). --- osu.Game/Graphics/Cursor/MenuCursor.cs | 29 +++++++++++++++++++------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 9658cfdb09..ea02feef0e 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Input; using osu.Game.Configuration; using System; +using System.Diagnostics; using osu.Framework.Graphics.Textures; namespace osu.Game.Graphics.Cursor @@ -21,20 +22,31 @@ namespace osu.Game.Graphics.Cursor private bool dragging; + private bool startRotation; + protected override bool OnMouseMove(InputState state) { if (dragging) { - Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown ?? state.Mouse.Delta; - float degrees = (float)MathHelper.RadiansToDegrees(Math.Atan2(-offset.X, offset.Y)) + 24.3f; + Debug.Assert(state.Mouse.PositionMouseDown != null); - // Always rotate in the direction of least distance - float diff = (degrees - ActiveCursor.Rotation) % 360; - if (diff < -180) diff += 360; - if (diff > 180) diff -= 360; - degrees = ActiveCursor.Rotation + diff; + // don't start rotating until we're moved a minimum distance away from the mouse down location, + // else it can have an annoying effect. + startRotation |= Vector2.Distance(state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30; - ActiveCursor.RotateTo(degrees, 600, Easing.OutQuint); + if (startRotation) + { + Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown.Value; + float degrees = (float)MathHelper.RadiansToDegrees(Math.Atan2(-offset.X, offset.Y)) + 24.3f; + + // Always rotate in the direction of least distance + float diff = (degrees - ActiveCursor.Rotation) % 360; + if (diff < -180) diff += 360; + if (diff > 180) diff -= 360; + degrees = ActiveCursor.Rotation + diff; + + ActiveCursor.RotateTo(degrees, 600, Easing.OutQuint); + } } return base.OnMouseMove(state); @@ -61,6 +73,7 @@ namespace osu.Game.Graphics.Cursor if (!state.Mouse.HasMainButtonPressed) { dragging = false; + startRotation = false; ((Cursor)ActiveCursor).AdditiveLayer.FadeOut(500, Easing.OutQuint); ActiveCursor.RotateTo(0, 600 * (1 + Math.Abs(ActiveCursor.Rotation / 720)), Easing.OutElasticHalf); From 97acff535d97d6fbe760b86dff2dd57221ba8255 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 18:21:00 +0900 Subject: [PATCH 121/483] Tidy up conditionals --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 53 ++++++++----------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index eb7d528897..6c697c8660 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -136,40 +136,34 @@ namespace osu.Game.Overlays.KeyBinding protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) { - if (HasFocus) - { - if (bindTarget.IsHovered) - { - if (!AllowMainMouseButtons) - { - switch (args.Button) - { - case MouseButton.Left: - case MouseButton.Right: - return true; - } - } + if (!HasFocus || !bindTarget.IsHovered) + return base.OnMouseDown(state, args); - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(state)); - return true; + if (!AllowMainMouseButtons) + { + switch (args.Button) + { + case MouseButton.Left: + case MouseButton.Right: + return true; } } - return base.OnMouseDown(state, args); + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(state)); + return true; } protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { - if (HasFocus && !state.Mouse.Buttons.Any()) - { - if (bindTarget.IsHovered) - finalise(); - else - updateBindTarget(); - return true; - } + // don't do anything until the last button is released. + if (!HasFocus || state.Mouse.Buttons.Any()) + return base.OnMouseUp(state, args); - return base.OnMouseUp(state, args); + if (bindTarget.IsHovered) + finalise(); + else + updateBindTarget(); + return true; } protected override bool OnWheel(InputState state) @@ -211,13 +205,10 @@ namespace osu.Game.Overlays.KeyBinding protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) { - if (HasFocus) - { - finalise(); - return true; - } + if (!HasFocus) return base.OnKeyUp(state, args); - return base.OnKeyUp(state, args); + finalise(); + return true; } private void finalise() From c5a20e337274356283092a6f67b7184019dfb824 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 18:02:38 +0900 Subject: [PATCH 122/483] Remove permitNulls --- osu.Game/Screens/Play/Player.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 992c5c5f6f..615e04d6c2 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -71,8 +71,8 @@ namespace osu.Game.Screens.Play private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true; - [BackgroundDependencyLoader(permitNulls: true)] - private void load(AudioManager audio, OsuConfigManager config, OsuGame osu, APIAccess api) + [BackgroundDependencyLoader] + private void load(AudioManager audio, OsuConfigManager config, APIAccess api) { this.api = api; @@ -92,7 +92,7 @@ namespace osu.Game.Screens.Play if (beatmap == null) throw new InvalidOperationException("Beatmap was not loaded"); - ruleset = osu?.Ruleset.Value ?? beatmap.BeatmapInfo.Ruleset; + ruleset = Ruleset.Value ?? beatmap.BeatmapInfo.Ruleset; var rulesetInstance = ruleset.CreateInstance(); try From b46a51fd8b7ccdbdd6019cff246a82c2efa72444 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 18:36:32 +0900 Subject: [PATCH 123/483] Make the speed adjustment containers ordered decreasingly by their control point start time. --- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 524665487d..6f0b7ac4ac 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -151,7 +151,7 @@ namespace osu.Game.Rulesets.UI /// public readonly BindableBool Reversed = new BindableBool(); - private readonly Container speedAdjustments; + private readonly SortedContainer speedAdjustments; public IReadOnlyList SpeedAdjustments => speedAdjustments; private readonly SpeedAdjustmentContainer defaultSpeedAdjustment; @@ -166,7 +166,7 @@ namespace osu.Game.Rulesets.UI { this.scrollingAxes = scrollingAxes; - AddInternal(speedAdjustments = new Container { RelativeSizeAxes = Axes.Both }); + AddInternal(speedAdjustments = new SortedContainer { RelativeSizeAxes = Axes.Both }); // Default speed adjustment AddSpeedAdjustment(defaultSpeedAdjustment = new SpeedAdjustmentContainer(new MultiplierControlPoint(0))); @@ -257,7 +257,21 @@ namespace osu.Game.Rulesets.UI /// /// The time to find the active at. /// The active at . Null if there are no speed adjustments. - private SpeedAdjustmentContainer adjustmentContainerAt(double time) => speedAdjustments.LastOrDefault(c => c.CanContain(time)) ?? defaultSpeedAdjustment; + private SpeedAdjustmentContainer adjustmentContainerAt(double time) => speedAdjustments.First(c => c.CanContain(time)) ?? defaultSpeedAdjustment; + + private class SortedContainer : Container + { + protected override int Compare(Drawable x, Drawable y) + { + var sX = (SpeedAdjustmentContainer)x; + var sY = (SpeedAdjustmentContainer)y; + + int result = sY.ControlPoint.StartTime.CompareTo(sX.ControlPoint.StartTime); + if (result != 0) + return result; + return base.Compare(x, y); + } + } } } } From 137964b79297e27b9eb36a61e176f2b929068094 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 18:36:56 +0900 Subject: [PATCH 124/483] Fix hit objects not getting added to the correct speed adjustment container. --- .../Timing/SpeedAdjustmentContainer.cs | 5 --- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 38 +++++++------------ 2 files changed, 14 insertions(+), 29 deletions(-) diff --git a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs index 3b13fdf00a..df0abd28df 100644 --- a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs +++ b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs @@ -98,11 +98,6 @@ namespace osu.Game.Rulesets.Timing base.Add(drawable); } - /// - /// Whether a falls within this s affecting timespan. - /// - public bool CanContain(DrawableHitObject hitObject) => CanContain(hitObject.HitObject.StartTime); - /// /// Whether a point in time falls within this s affecting timespan. /// diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 6f0b7ac4ac..550740c5ec 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -181,26 +181,25 @@ namespace osu.Game.Rulesets.UI speedAdjustment.ScrollingAxes = scrollingAxes; speedAdjustment.VisibleTimeRange.BindTo(VisibleTimeRange); speedAdjustment.Reversed.BindTo(Reversed); - speedAdjustments.Add(speedAdjustment); - // We now need to re-sort the hit objects in the last speed adjustment prior to this one, to see if they need a new parent - var previousSpeedAdjustment = speedAdjustments.LastOrDefault(s => s != speedAdjustment && s.ControlPoint.StartTime <= speedAdjustment.ControlPoint.StartTime); - if (previousSpeedAdjustment == null) - return; - - for (int i = 0; i < previousSpeedAdjustment.Children.Count; i++) + if (speedAdjustments.Count > 0) { - DrawableHitObject hitObject = previousSpeedAdjustment[i]; + var existingAdjustment = adjustmentContainerAt(speedAdjustment.ControlPoint.StartTime); + for (int i = 0; i < existingAdjustment.Count; i++) + { + DrawableHitObject hitObject = existingAdjustment[i]; - var newSpeedAdjustment = adjustmentContainerFor(hitObject); - if (newSpeedAdjustment == previousSpeedAdjustment) - continue; + if (!speedAdjustment.CanContain(hitObject.HitObject.StartTime)) + continue; - previousSpeedAdjustment.Remove(hitObject); - newSpeedAdjustment.Add(hitObject); + existingAdjustment.Remove(hitObject); + speedAdjustment.Add(hitObject); - i--; + i--; + } } + + speedAdjustments.Add(speedAdjustment); } /// @@ -237,20 +236,11 @@ namespace osu.Game.Rulesets.UI if (!(hitObject is IScrollingHitObject)) throw new InvalidOperationException($"Hit objects added to a {nameof(ScrollingHitObjectContainer)} must implement {nameof(IScrollingHitObject)}."); - adjustmentContainerFor(hitObject).Add(hitObject); + adjustmentContainerAt(hitObject.HitObject.StartTime).Add(hitObject); } public override bool Remove(DrawableHitObject hitObject) => speedAdjustments.Any(s => s.Remove(hitObject)); - /// - /// Finds the which provides the speed adjustment active at the start time - /// of a hit object. If there is no active at the start time of the hit object, - /// then the first (time-wise) speed adjustment is returned. - /// - /// The hit object to find the active for. - /// The active at 's start time. Null if there are no speed adjustments. - private SpeedAdjustmentContainer adjustmentContainerFor(DrawableHitObject hitObject) => speedAdjustments.LastOrDefault(c => c.CanContain(hitObject)) ?? defaultSpeedAdjustment; - /// /// Finds the which provides the speed adjustment active at a time. /// If there is no active at the time, then the first (time-wise) speed adjustment is returned. From e5d985838f55d95742003d829b6759904786a18d Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 18:37:49 +0900 Subject: [PATCH 125/483] Set ScrollingAxes and RelativeChildOffset a bit more safely. --- .../Rulesets/Timing/LinearScrollingContainer.cs | 8 +++----- osu.Game/Rulesets/Timing/ScrollingContainer.cs | 2 ++ .../Rulesets/Timing/SpeedAdjustmentContainer.cs | 13 +++++++------ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/osu.Game/Rulesets/Timing/LinearScrollingContainer.cs b/osu.Game/Rulesets/Timing/LinearScrollingContainer.cs index db497b7664..f8e87bc022 100644 --- a/osu.Game/Rulesets/Timing/LinearScrollingContainer.cs +++ b/osu.Game/Rulesets/Timing/LinearScrollingContainer.cs @@ -10,12 +10,10 @@ namespace osu.Game.Rulesets.Timing /// internal class LinearScrollingContainer : ScrollingContainer { - private readonly Axes scrollingAxes; private readonly MultiplierControlPoint controlPoint; - public LinearScrollingContainer(Axes scrollingAxes, MultiplierControlPoint controlPoint) + public LinearScrollingContainer(MultiplierControlPoint controlPoint) { - this.scrollingAxes = scrollingAxes; this.controlPoint = controlPoint; } @@ -23,8 +21,8 @@ namespace osu.Game.Rulesets.Timing { base.Update(); - if ((scrollingAxes & Axes.X) > 0) X = (float)(controlPoint.StartTime - Time.Current); - if ((scrollingAxes & Axes.Y) > 0) Y = (float)(controlPoint.StartTime - Time.Current); + if ((ScrollingAxes & Axes.X) > 0) X = (float)(controlPoint.StartTime - Time.Current); + if ((ScrollingAxes & Axes.Y) > 0) Y = (float)(controlPoint.StartTime - Time.Current); } } } diff --git a/osu.Game/Rulesets/Timing/ScrollingContainer.cs b/osu.Game/Rulesets/Timing/ScrollingContainer.cs index 9bb32ead77..ad5fc7c2f0 100644 --- a/osu.Game/Rulesets/Timing/ScrollingContainer.cs +++ b/osu.Game/Rulesets/Timing/ScrollingContainer.cs @@ -96,6 +96,8 @@ namespace osu.Game.Rulesets.Timing { base.Update(); + RelativeChildOffset = new Vector2((ScrollingAxes & Axes.X) > 0 ? (float)ControlPoint.StartTime : 0, (ScrollingAxes & Axes.Y) > 0 ? (float)ControlPoint.StartTime : 0); + // We want our size and position-space along the scrolling axes to span our duration to completely enclose all the hit objects Size = new Vector2((ScrollingAxes & Axes.X) > 0 ? (float)Duration : Size.X, (ScrollingAxes & Axes.Y) > 0 ? (float)Duration : Size.Y); // And we need to make sure the hit object's position-space doesn't change due to our resizing diff --git a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs index df0abd28df..d3bd7685da 100644 --- a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs +++ b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs @@ -31,7 +31,11 @@ namespace osu.Game.Rulesets.Timing /// /// The axes which the content of this container will scroll through. /// - public Axes ScrollingAxes { get; internal set; } + public Axes ScrollingAxes + { + get { return scrollingContainer.ScrollingAxes; } + set { scrollingContainer.ScrollingAxes = value; } + } public override bool RemoveWhenNotAlive => false; @@ -52,11 +56,8 @@ namespace osu.Game.Rulesets.Timing RelativeSizeAxes = Axes.Both; scrollingContainer = CreateScrollingContainer(); - - scrollingContainer.ScrollingAxes = ScrollingAxes; scrollingContainer.ControlPoint = ControlPoint; scrollingContainer.VisibleTimeRange.BindTo(VisibleTimeRange); - scrollingContainer.RelativeChildOffset = new Vector2((ScrollingAxes & Axes.X) > 0 ? (float)ControlPoint.StartTime : 0, (ScrollingAxes & Axes.Y) > 0 ? (float)ControlPoint.StartTime : 0); AddInternal(content = scrollingContainer); } @@ -107,6 +108,6 @@ namespace osu.Game.Rulesets.Timing /// Creates the which contains the scrolling s of this container. /// /// The . - protected virtual ScrollingContainer CreateScrollingContainer() => new LinearScrollingContainer(ScrollingAxes, ControlPoint); + protected virtual ScrollingContainer CreateScrollingContainer() => new LinearScrollingContainer(ControlPoint); } -} \ No newline at end of file +} From 1964bc72e5c933c051b84b483bf62d0c223e0277 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 18:39:09 +0900 Subject: [PATCH 126/483] Should be FirstOrDefault for hit objects occuriung before the first control point. --- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 550740c5ec..007f2af803 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -247,7 +247,7 @@ namespace osu.Game.Rulesets.UI /// /// The time to find the active at. /// The active at . Null if there are no speed adjustments. - private SpeedAdjustmentContainer adjustmentContainerAt(double time) => speedAdjustments.First(c => c.CanContain(time)) ?? defaultSpeedAdjustment; + private SpeedAdjustmentContainer adjustmentContainerAt(double time) => speedAdjustments.FirstOrDefault(c => c.CanContain(time)) ?? defaultSpeedAdjustment; private class SortedContainer : Container { From ad63cbf45505c8fe2ba027cf3d9fe78e551e5a56 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 18:54:41 +0900 Subject: [PATCH 127/483] Fix default comparator being inverted. --- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 007f2af803..7143401824 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -259,7 +259,7 @@ namespace osu.Game.Rulesets.UI int result = sY.ControlPoint.StartTime.CompareTo(sX.ControlPoint.StartTime); if (result != 0) return result; - return base.Compare(x, y); + return base.Compare(y, x); } } } From d64071f3de78291766b494d1078099f051badd3e Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 18:55:27 +0900 Subject: [PATCH 128/483] Fix up + make test case more sane. --- .../Visual/TestCaseScrollingPlayfield.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs index 2d49b2d0f9..c8c95da618 100644 --- a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs @@ -115,18 +115,18 @@ namespace osu.Desktop.Tests.Visual Assert.AreEqual(1, speedAdjustments[3].ControlPoint.Multiplier); // Check insertion of hit objects - Assert.IsTrue(hitObjectContainer.SpeedAdjustments[0].Contains(hitObjects[0])); - Assert.IsTrue(speedAdjustments[0].Contains(hitObjects[1])); - Assert.IsTrue(speedAdjustments[1].Contains(hitObjects[2])); - Assert.IsTrue(speedAdjustments[2].Contains(hitObjects[3])); - Assert.IsTrue(speedAdjustments[3].Contains(hitObjects[4])); - Assert.IsTrue(speedAdjustments[3].Contains(hitObjects[5])); + Assert.IsTrue(hitObjectContainer.SpeedAdjustments[4].Contains(hitObjects[0])); + Assert.IsTrue(hitObjectContainer.SpeedAdjustments[3].Contains(hitObjects[1])); + Assert.IsTrue(hitObjectContainer.SpeedAdjustments[2].Contains(hitObjects[2])); + Assert.IsTrue(hitObjectContainer.SpeedAdjustments[1].Contains(hitObjects[3])); + Assert.IsTrue(hitObjectContainer.SpeedAdjustments[0].Contains(hitObjects[4])); + Assert.IsTrue(hitObjectContainer.SpeedAdjustments[0].Contains(hitObjects[5])); - hitObjectContainer.RemoveSpeedAdjustment(speedAdjustments[1]); + hitObjectContainer.RemoveSpeedAdjustment(hitObjectContainer.SpeedAdjustments[3]); - // The hit object contained in this speed adjustment should be resorted into the previous one + // The hit object contained in this speed adjustment should be resorted into the one occuring before it - Assert.IsTrue(speedAdjustments[0].Contains(hitObjects[2])); + Assert.IsTrue(hitObjectContainer.SpeedAdjustments[3].Contains(hitObjects[1])); } private class TestRulesetContainer : ScrollingRulesetContainer From 322dfe0250eef71d0321e53bd70d4238d1ad48a4 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 19:17:12 +0900 Subject: [PATCH 129/483] Fix ScrollingContainer possibly not getting the correct size to cover hit objects. --- osu.Game/Rulesets/Timing/ScrollingContainer.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Timing/ScrollingContainer.cs b/osu.Game/Rulesets/Timing/ScrollingContainer.cs index ad5fc7c2f0..e4b098d2bd 100644 --- a/osu.Game/Rulesets/Timing/ScrollingContainer.cs +++ b/osu.Game/Rulesets/Timing/ScrollingContainer.cs @@ -74,8 +74,7 @@ namespace osu.Game.Rulesets.Timing // absolutely-sized element along the scrolling axes and adding a corresponding duration value. This introduces a bit of error, but will never under-estimate.ion. // Find the largest element that is absolutely-sized along ScrollingAxes - float maxAbsoluteSize = Children.Where(c => (c.RelativeSizeAxes & ScrollingAxes) == 0) - .Select(c => (ScrollingAxes & Axes.X) > 0 ? c.Width : c.Height) + float maxAbsoluteSize = Children.Select(c => (ScrollingAxes & Axes.X) > 0 ? c.DrawWidth : c.DrawHeight) .DefaultIfEmpty().Max(); float ourAbsoluteSize = (ScrollingAxes & Axes.X) > 0 ? DrawWidth : DrawHeight; From ab0e3ccc5502074cb493cfbb44cf160443467745 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 19:33:18 +0900 Subject: [PATCH 130/483] Make SimpleNotifications support word wrap --- osu.Game/Overlays/Notifications/SimpleNotification.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Notifications/SimpleNotification.cs b/osu.Game/Overlays/Notifications/SimpleNotification.cs index e10cc26546..daf1ac838d 100644 --- a/osu.Game/Overlays/Notifications/SimpleNotification.cs +++ b/osu.Game/Overlays/Notifications/SimpleNotification.cs @@ -4,17 +4,16 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using OpenTK; namespace osu.Game.Overlays.Notifications { public class SimpleNotification : Notification { - private string text; + private string text = string.Empty; public string Text { get { return text; } @@ -36,7 +35,7 @@ namespace osu.Game.Overlays.Notifications } } - private readonly SpriteText textDrawable; + private readonly TextFlowContainer textDrawable; private readonly SpriteIcon iconDrawable; protected Box IconBackgound; @@ -59,9 +58,8 @@ namespace osu.Game.Overlays.Notifications } }); - Content.Add(textDrawable = new OsuSpriteText + Content.Add(textDrawable = new TextFlowContainer(t => t.TextSize = 16) { - TextSize = 16, Colour = OsuColour.Gray(128), AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, From 0ea6c65be6525c295902f3cd884c97d82bedb1d9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 19:34:06 +0900 Subject: [PATCH 131/483] Fix potentially racey behaviour of versionManager initialisation Changing the state while the container wasn't necessarily completed loading caused inconsistent behaviour. --- osu.Desktop/OsuGameDesktop.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index 88c8a206c8..a623347540 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -20,16 +20,11 @@ namespace osu.Desktop { internal class OsuGameDesktop : OsuGame { - private readonly VersionManager versionManager; + private VersionManager versionManager; public OsuGameDesktop(string[] args = null) : base(args) { - versionManager = new VersionManager - { - Depth = int.MinValue, - State = Visibility.Hidden - }; } public override Storage GetStorageForStableInstall() @@ -88,11 +83,15 @@ namespace osu.Desktop { base.LoadComplete(); - LoadComponentAsync(versionManager, Add); + LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }); + ScreenChanged += s => { - if (!versionManager.IsPresent && s is Intro) + if (s is Intro && s.ChildScreen == null) + { + Add(versionManager); versionManager.State = Visibility.Visible; + } }; } From 9f69aa908225ea55dbdc9ee172c1688183d721bf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 19:41:39 +0900 Subject: [PATCH 132/483] Show a notification after a successful update Allows access to the github changelog --- osu.Desktop/Overlays/VersionManager.cs | 48 +++++++++++++++++++++- osu.Game/Configuration/OsuConfigManager.cs | 5 ++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index b445340f50..dab2d160c5 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; @@ -19,6 +20,7 @@ using OpenTK.Graphics; using System.Net.Http; using osu.Framework.Logging; using osu.Game; +using osu.Game.Configuration; namespace osu.Desktop.Overlays { @@ -26,18 +28,24 @@ namespace osu.Desktop.Overlays { private UpdateManager updateManager; private NotificationOverlay notificationOverlay; + private OsuConfigManager config; + private OsuGameBase game; public override bool HandleInput => false; [BackgroundDependencyLoader] - private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game) + private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config) { notificationOverlay = notification; + this.config = config; + this.game = game; AutoSizeAxes = Axes.Both; Anchor = Anchor.BottomCentre; Origin = Anchor.BottomCentre; + Alpha = 0; + State = Visibility.Hidden; Children = new Drawable[] { @@ -91,6 +99,44 @@ namespace osu.Desktop.Overlays checkForUpdateAsync(); } + protected override void LoadComplete() + { + base.LoadComplete(); + + State = Visibility.Visible; + + var version = game.Version; + var lastVersion = config.Get(OsuSetting.Version); + if (char.IsNumber(version[0]) && version != lastVersion) + { + config.Set(OsuSetting.Version, version); + + // only show a notification if we've previously saved a version to the config file (ie. not the first run). + if (!string.IsNullOrEmpty(lastVersion)) + Scheduler.AddDelayed(() => notificationOverlay.Post(new UpdateCompleteNotification(version)), 5000); + } + } + + private class UpdateCompleteNotification : SimpleNotification + { + public UpdateCompleteNotification(string version) + { + Text = $"You are now running osu!lazer {version}.\nClick to see what's new!"; + Icon = FontAwesome.fa_check_square; + Activated = delegate + { + Process.Start($"https://github.com/ppy/osu/releases/tag/v{version}"); + return true; + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + IconBackgound.Colour = colours.BlueDark; + } + } + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 6b07d5c967..44a6af841c 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -70,6 +70,8 @@ namespace osu.Game.Configuration // Update Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); + + Set(OsuSetting.Version, string.Empty); } public OsuConfigManager(Storage storage) : base(storage) @@ -106,6 +108,7 @@ namespace osu.Game.Configuration SnakingInSliders, SnakingOutSliders, ShowFpsDisplay, - ChatDisplayHeight + ChatDisplayHeight, + Version } } From 480d839d678e4eb1a537a559984c8718f3a09c49 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 19:51:42 +0900 Subject: [PATCH 133/483] Allow the notification overlay to close when all notifications are dismissed --- osu.Game/Overlays/NotificationOverlay.cs | 11 ++++++++++- osu.Game/Overlays/Notifications/Notification.cs | 4 ++-- .../Overlays/Notifications/NotificationSection.cs | 2 ++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 7eabb592c6..5b9c3d20a0 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays private ScrollContainer scrollContainer; private FlowContainer sections; - [BackgroundDependencyLoader(permitNulls: true)] + [BackgroundDependencyLoader] private void load() { Width = width; @@ -72,6 +72,13 @@ namespace osu.Game.Overlays private int runningDepth; + private void notificationClosed() + { + // hide ourselves if all notifications have been dismissed. + if (sections.Select(c => c.DisplayedCount).Sum() > 0) + State = Visibility.Hidden; + } + public void Post(Notification notification) { Schedule(() => @@ -81,6 +88,8 @@ namespace osu.Game.Overlays ++runningDepth; notification.Depth = notification.DisplayOnTop ? runningDepth : -runningDepth; + notification.Closed += notificationClosed; + var hasCompletionTarget = notification as IHasCompletionTarget; if (hasCompletionTarget != null) hasCompletionTarget.CompletionTarget = Post; diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 14446a468c..b63efd3226 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -19,9 +19,9 @@ namespace osu.Game.Overlays.Notifications public abstract class Notification : Container { /// - /// Use requested close. + /// User requested close. /// - public Action Closed; + public event Action Closed; /// /// Run on user activating the notification. Return true to close. diff --git a/osu.Game/Overlays/Notifications/NotificationSection.cs b/osu.Game/Overlays/Notifications/NotificationSection.cs index efd3b39ee2..705800d4aa 100644 --- a/osu.Game/Overlays/Notifications/NotificationSection.cs +++ b/osu.Game/Overlays/Notifications/NotificationSection.cs @@ -24,6 +24,8 @@ namespace osu.Game.Overlays.Notifications private FlowContainer notifications; + public int DisplayedCount => notifications.Count; + public void Add(Notification notification) { notifications.Add(notification); From c29d3437ba7e4f14f7e218a4effb5232be419c41 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Tue, 22 Aug 2017 13:35:30 +0200 Subject: [PATCH 134/483] fix merge changes --- osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index 70879006e9..3b0a1bda99 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -22,7 +22,7 @@ namespace osu.Game.Graphics.UserInterface { Add(new CapsWarning { - TextSize = 20, + Size = new Vector2(20), }); } @@ -63,7 +63,7 @@ namespace osu.Game.Graphics.UserInterface } } - private class CapsWarning : TextAwesome, IHasTooltip + private class CapsWarning : SpriteIcon, IHasTooltip { public string TooltipText => Console.CapsLock ? @"Caps lock is active" : string.Empty; @@ -91,7 +91,7 @@ namespace osu.Game.Graphics.UserInterface updateVisibility(); } - private void updateVisibility() => FadeTo(Console.CapsLock ? 1 : 0, 250, EasingTypes.OutQuint); + private void updateVisibility() => this.FadeTo(Console.CapsLock ? 1 : 0, 250, Easing.OutQuint); } } } From db275517096197d86e721172d274d6b2d2356157 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 20:51:20 +0900 Subject: [PATCH 135/483] Make hit objects put in ScrollingContainers strictly ordered by start time This won't change anything as is since all hit objects are given a depth at the moment. --- osu.Game/Rulesets/Timing/ScrollingContainer.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/osu.Game/Rulesets/Timing/ScrollingContainer.cs b/osu.Game/Rulesets/Timing/ScrollingContainer.cs index e4b098d2bd..d2a6939dd3 100644 --- a/osu.Game/Rulesets/Timing/ScrollingContainer.cs +++ b/osu.Game/Rulesets/Timing/ScrollingContainer.cs @@ -45,18 +45,15 @@ namespace osu.Game.Rulesets.Timing RelativePositionAxes = Axes.Both; } - public override void InvalidateFromChild(Invalidation invalidation) + protected override int Compare(Drawable x, Drawable y) { - // We only want to re-compute our size when a child's size or position has changed - if ((invalidation & Invalidation.RequiredParentSizeToFit) == 0) - { - base.InvalidateFromChild(invalidation); - return; - } + var hX = (DrawableHitObject)x; + var hY = (DrawableHitObject)y; - durationBacking.Invalidate(); - - base.InvalidateFromChild(invalidation); + int result = hY.HitObject.StartTime.CompareTo(hX.HitObject.StartTime); + if (result != 0) + return result; + return base.Compare(y, x); } private double computeDuration() From d080a7e970252059cef1df35f5f3080d77cbecfc Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 20:51:53 +0900 Subject: [PATCH 136/483] Determine size of ScrollingContainer a bit better to avoid taiko weirdness --- .../Objects/Drawables/DrawableHit.cs | 15 ++++--- .../Objects/Drawables/DrawableSwell.cs | 2 + .../Drawables/DrawableTaikoHitObject.cs | 4 +- .../Rulesets/Timing/ScrollingContainer.cs | 41 +++++++------------ 4 files changed, 27 insertions(+), 35 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 5fcae7d0f4..6b041dfe25 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -28,14 +28,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables FillMode = FillMode.Fit; } - protected override void LoadComplete() - { - base.LoadComplete(); - - // We need to set this here because RelativeSizeAxes won't/can't set our size by default with a different RelativeChildSize - Width *= Parent.RelativeChildSize.X; - } - protected override void CheckJudgement(bool userTriggered) { if (!userTriggered) @@ -71,6 +63,13 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return UpdateJudgement(true); } + protected override void Update() + { + base.Update(); + + Size = BaseSize * Parent.RelativeChildSize; + } + protected override void UpdateState(ArmedState state) { var circlePiece = MainPiece as CirclePiece; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index fc3bc82520..4eb5c46838 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -199,6 +199,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { base.Update(); + Size = BaseSize * Parent.RelativeChildSize; + // Make the swell stop at the hit target X = (float)Math.Max(Time.Current, HitObject.StartTime); diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 765002fb34..46cdfcc365 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -16,6 +16,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { public override Vector2 OriginPosition => new Vector2(DrawHeight / 2); + protected readonly Vector2 BaseSize; + protected readonly TaikoPiece MainPiece; public new TaikoHitType HitObject; @@ -29,7 +31,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Origin = Anchor.Custom; RelativeSizeAxes = Axes.Both; - Size = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE); + Size = BaseSize = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE); Add(MainPiece = CreateMainPiece()); MainPiece.KiaiMode = HitObject.Kiai; diff --git a/osu.Game/Rulesets/Timing/ScrollingContainer.cs b/osu.Game/Rulesets/Timing/ScrollingContainer.cs index d2a6939dd3..c8da8d7ac9 100644 --- a/osu.Game/Rulesets/Timing/ScrollingContainer.cs +++ b/osu.Game/Rulesets/Timing/ScrollingContainer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; using osu.Framework.Caching; using osu.Framework.Configuration; @@ -34,7 +35,7 @@ namespace osu.Game.Rulesets.Timing /// internal MultiplierControlPoint ControlPoint; - private Cached durationBacking; + private Cached durationBacking = new Cached(); /// /// Creates a new . @@ -56,35 +57,23 @@ namespace osu.Game.Rulesets.Timing return base.Compare(y, x); } - private double computeDuration() + public override void Add(DrawableHitObject drawable) { - if (!Children.Any()) - return 0; - - double baseDuration = Children.Max(c => (c.HitObject as IHasEndTime)?.EndTime ?? c.HitObject.StartTime) - ControlPoint.StartTime; - - // If we have a singular hit object at the timing section's start time, let's set a sane default duration - if (baseDuration == 0) - baseDuration = 1; - - // This container needs to resize such that it completely encloses the hit objects to avoid masking optimisations. This is done by converting the largest - // absolutely-sized element along the scrolling axes and adding a corresponding duration value. This introduces a bit of error, but will never under-estimate.ion. - - // Find the largest element that is absolutely-sized along ScrollingAxes - float maxAbsoluteSize = Children.Select(c => (ScrollingAxes & Axes.X) > 0 ? c.DrawWidth : c.DrawHeight) - .DefaultIfEmpty().Max(); - - float ourAbsoluteSize = (ScrollingAxes & Axes.X) > 0 ? DrawWidth : DrawHeight; - - // Add the extra duration to account for the absolute size - baseDuration *= 1 + maxAbsoluteSize / ourAbsoluteSize; - - return baseDuration; + durationBacking.Invalidate(); + base.Add(drawable); } + public override bool Remove(DrawableHitObject drawable) + { + durationBacking.Invalidate(); + return base.Remove(drawable); + } + + // Todo: This may underestimate the size of the hit object in some cases, but won't be too much of a problem for now + private double computeDuration() => Math.Max(0, Children.Select(c => (c.HitObject as IHasEndTime)?.EndTime ?? c.HitObject.StartTime).DefaultIfEmpty().Max() - ControlPoint.StartTime) + 1000; + /// - /// The maximum duration of any one hit object inside this . This is calculated as the maximum - /// duration of all hit objects relative to this 's . + /// An approximate total duration of this scrolling container. /// public double Duration => durationBacking.IsValid ? durationBacking : (durationBacking.Value = computeDuration()); From f8576d44b12feb101f6983a18784828b9f16364f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 22 Aug 2017 21:08:27 +0900 Subject: [PATCH 137/483] Add some more xmldoc. --- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 7143401824..92845c3f3a 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -173,7 +173,8 @@ namespace osu.Game.Rulesets.UI } /// - /// Adds a to this container. + /// Adds a to this container, re-sorting all hit objects + /// in the last that occurred (time-wise) before it. /// /// The . public void AddSpeedAdjustment(SpeedAdjustmentContainer speedAdjustment) @@ -184,6 +185,8 @@ namespace osu.Game.Rulesets.UI if (speedAdjustments.Count > 0) { + // We need to re-sort all hit objects in the speed adjustment container prior to figure out if they + // should now lie within this one var existingAdjustment = adjustmentContainerAt(speedAdjustment.ControlPoint.StartTime); for (int i = 0; i < existingAdjustment.Count; i++) { From d81956e9741b7dbfdfae35d514e1a1eba002fe5e Mon Sep 17 00:00:00 2001 From: Jorolf Date: Tue, 22 Aug 2017 15:43:45 +0200 Subject: [PATCH 138/483] use GameHost to check if caps lock is enabled --- osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index 3b0a1bda99..2b175b9eed 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using System; using osu.Framework.Graphics.Shapes; +using osu.Framework.Platform; namespace osu.Game.Graphics.UserInterface { @@ -65,10 +66,12 @@ namespace osu.Game.Graphics.UserInterface private class CapsWarning : SpriteIcon, IHasTooltip { - public string TooltipText => Console.CapsLock ? @"Caps lock is active" : string.Empty; + public string TooltipText => host.CapsLockEnabled ? @"Caps lock is active" : string.Empty; public override bool HandleInput => true; + private GameHost host; + public CapsWarning() { Icon = FontAwesome.fa_warning; @@ -80,9 +83,10 @@ namespace osu.Game.Graphics.UserInterface } [BackgroundDependencyLoader] - private void load(OsuColour colour) + private void load(OsuColour colour, GameHost host) { Colour = colour.YellowLight; + this.host = host; } protected override void Update() @@ -91,7 +95,7 @@ namespace osu.Game.Graphics.UserInterface updateVisibility(); } - private void updateVisibility() => this.FadeTo(Console.CapsLock ? 1 : 0, 250, Easing.OutQuint); + private void updateVisibility() => this.FadeTo(host.CapsLockEnabled ? 1 : 0, 250, Easing.OutQuint); } } } From 71af30d2225e4c74bd2210ef37694e7ec8a15bd0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 22:48:50 +0900 Subject: [PATCH 139/483] Remove redundant visibility changes --- osu.Desktop/Overlays/VersionManager.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index dab2d160c5..1c0c1475b1 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -45,7 +45,6 @@ namespace osu.Desktop.Overlays Origin = Anchor.BottomCentre; Alpha = 0; - State = Visibility.Hidden; Children = new Drawable[] { @@ -103,11 +102,9 @@ namespace osu.Desktop.Overlays { base.LoadComplete(); - State = Visibility.Visible; - var version = game.Version; var lastVersion = config.Get(OsuSetting.Version); - if (char.IsNumber(version[0]) && version != lastVersion) + if (game.IsDeployedBuild && version != lastVersion) { config.Set(OsuSetting.Version, version); From ef2d9ffede813a5c2ddff6d01af1f269ea3a9496 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 23:43:10 +0900 Subject: [PATCH 140/483] Fix redundant initialiser --- osu.Game/Rulesets/Timing/ScrollingContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Timing/ScrollingContainer.cs b/osu.Game/Rulesets/Timing/ScrollingContainer.cs index c8da8d7ac9..6e77c49e3d 100644 --- a/osu.Game/Rulesets/Timing/ScrollingContainer.cs +++ b/osu.Game/Rulesets/Timing/ScrollingContainer.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Timing /// internal MultiplierControlPoint ControlPoint; - private Cached durationBacking = new Cached(); + private Cached durationBacking; /// /// Creates a new . From dbde27ceefdeae85ad2927ba59baae21b5f62c81 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Aug 2017 23:43:40 +0900 Subject: [PATCH 141/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index ba70b8eaa9..74f644bad0 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit ba70b8eaa9b79d4248873d4399f3b9e918fc3c8f +Subproject commit 74f644bad039606e242d8782014d8c249a38b6a3 From fd3239ad15fa0833a3b6f2c4b7010840e60f6300 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 12:36:53 +0900 Subject: [PATCH 142/483] Fix KeyBindingStore not getting correct defaults for variants. --- osu.Game/Input/KeyBindingStore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Input/KeyBindingStore.cs b/osu.Game/Input/KeyBindingStore.cs index 56302acafe..c5ba1683dd 100644 --- a/osu.Game/Input/KeyBindingStore.cs +++ b/osu.Game/Input/KeyBindingStore.cs @@ -22,7 +22,7 @@ namespace osu.Game.Input { var ruleset = info.CreateInstance(); foreach (var variant in ruleset.AvailableVariants) - insertDefaults(ruleset.GetDefaultKeyBindings(), info.ID, variant); + insertDefaults(ruleset.GetDefaultKeyBindings(variant), info.ID, variant); } } From a6266850d60c6366666a4e0223f6e01d0183fa8a Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 12:46:28 +0900 Subject: [PATCH 143/483] Make KeyBindingRow take a non-action enum. --- osu-framework | 2 +- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/osu-framework b/osu-framework index 74f644bad0..1fd9259e86 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 74f644bad039606e242d8782014d8c249a38b6a3 +Subproject commit 1fd9259e86379838dbbc43c12a2238df83800fc0 diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 6c697c8660..c182382d70 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 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.Framework.Allocation; @@ -22,7 +21,7 @@ namespace osu.Game.Overlays.KeyBinding { internal class KeyBindingRow : Container, IFilterable { - private readonly Enum action; + private readonly object action; private readonly IEnumerable bindings; private const float transition_time = 150; @@ -50,7 +49,7 @@ namespace osu.Game.Overlays.KeyBinding public string[] FilterTerms => new[] { text.Text }.Concat(bindings.Select(b => b.KeyCombination.ReadableString())).ToArray(); - public KeyBindingRow(Enum action, IEnumerable bindings) + public KeyBindingRow(object action, IEnumerable bindings) { this.action = action; this.bindings = bindings; From b2db550cb457abf41bcf12658731d6f9768655d2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Aug 2017 12:47:20 +0900 Subject: [PATCH 144/483] Fix notification count including fading (already closed) notifications --- osu.Game/Overlays/NotificationOverlay.cs | 2 +- osu.Game/Overlays/Notifications/Notification.cs | 6 +++--- osu.Game/Overlays/Notifications/NotificationSection.cs | 7 ++----- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 5b9c3d20a0..260214a14f 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -75,7 +75,7 @@ namespace osu.Game.Overlays private void notificationClosed() { // hide ourselves if all notifications have been dismissed. - if (sections.Select(c => c.DisplayedCount).Sum() > 0) + if (sections.Select(c => c.DisplayedCount).Sum() == 0) State = Visibility.Hidden; } diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index b63efd3226..422051364e 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -142,12 +142,12 @@ namespace osu.Game.Overlays.Notifications NotificationContent.MoveToX(0, 500, Easing.OutQuint); } - private bool wasClosed; + public bool WasClosed; public virtual void Close() { - if (wasClosed) return; - wasClosed = true; + if (WasClosed) return; + WasClosed = true; Closed?.Invoke(); this.FadeOut(100); diff --git a/osu.Game/Overlays/Notifications/NotificationSection.cs b/osu.Game/Overlays/Notifications/NotificationSection.cs index 705800d4aa..09768ba0ea 100644 --- a/osu.Game/Overlays/Notifications/NotificationSection.cs +++ b/osu.Game/Overlays/Notifications/NotificationSection.cs @@ -24,12 +24,9 @@ namespace osu.Game.Overlays.Notifications private FlowContainer notifications; - public int DisplayedCount => notifications.Count; + public int DisplayedCount => notifications.Count(n => !n.WasClosed); - public void Add(Notification notification) - { - notifications.Add(notification); - } + public void Add(Notification notification) => notifications.Add(notification); public IEnumerable AcceptTypes; From be96fb32b30aeb4c2b461c0974a34c8c03545967 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 12:47:47 +0900 Subject: [PATCH 145/483] Make RulesetContainer load KeyBindingInputManager in load() --- osu.Game/Rulesets/UI/RulesetContainer.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 2f1cb915f3..ebf570fecc 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.UI /// /// The key conversion input manager for this RulesetContainer. /// - public readonly PassThroughInputManager KeyBindingInputManager; + public PassThroughInputManager KeyBindingInputManager; /// /// Whether we are currently providing the local user a gameplay cursor. @@ -76,6 +76,11 @@ namespace osu.Game.Rulesets.UI internal RulesetContainer(Ruleset ruleset) { Ruleset = ruleset; + } + + [BackgroundDependencyLoader] + private void load() + { KeyBindingInputManager = CreateInputManager(); KeyBindingInputManager.RelativeSizeAxes = Axes.Both; } From 38a4c841636144d2d46405166d0cf7ee0e62a44f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 12:48:53 +0900 Subject: [PATCH 146/483] Load SettingsSubsection in load() Fixes header not being displayed with variant bindings. This follows what SettingsSection does. --- .../Overlays/Settings/SettingsSubsection.cs | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Settings/SettingsSubsection.cs b/osu.Game/Overlays/Settings/SettingsSubsection.cs index ac6d2fa239..0fbb5b92f7 100644 --- a/osu.Game/Overlays/Settings/SettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/SettingsSubsection.cs @@ -7,14 +7,15 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; namespace osu.Game.Overlays.Settings { public abstract class SettingsSubsection : FillFlowContainer, IHasFilterableChildren { - protected override Container Content => content; + protected override Container Content => FlowContent; - private readonly Container content; + protected readonly FillFlowContainer FlowContent; protected abstract string Header { get; } @@ -33,6 +34,19 @@ namespace osu.Game.Overlays.Settings RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Direction = FillDirection.Vertical; + + FlowContent = new FillFlowContainer + { + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }; + } + + [BackgroundDependencyLoader] + private void load() + { AddRangeInternal(new Drawable[] { new OsuSpriteText @@ -41,13 +55,7 @@ namespace osu.Game.Overlays.Settings Margin = new MarginPadding { Bottom = 10 }, Font = @"Exo2.0-Black", }, - content = new FillFlowContainer - { - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 5), - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - }, + FlowContent }); } } From c1860f2ce21450801151fea1bc408890d2fcf566 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 12:49:30 +0900 Subject: [PATCH 147/483] Make KeyBindingOverlay support variants as settings sub sections. --- .../KeyBinding/GlobalKeyBindingsSection.cs | 24 ++++++++++++------ ...ngsSection.cs => KeyBindingsSubsection.cs} | 25 ++++++++----------- .../KeyBinding/RulesetBindingsSection.cs | 16 ++++++++---- .../KeyBinding/VariantBindingsSubsection.cs | 23 +++++++++++++++++ osu.Game/Overlays/KeyBindingOverlay.cs | 2 +- osu.Game/osu.Game.csproj | 3 ++- 6 files changed, 63 insertions(+), 30 deletions(-) rename osu.Game/Overlays/KeyBinding/{KeyBindingsSection.cs => KeyBindingsSubsection.cs} (57%) create mode 100644 osu.Game/Overlays/KeyBinding/VariantBindingsSubsection.cs diff --git a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs index 7dd9919e5d..77de9fc865 100644 --- a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs @@ -3,21 +3,29 @@ using osu.Framework.Input.Bindings; using osu.Game.Graphics; +using osu.Game.Overlays.Settings; namespace osu.Game.Overlays.KeyBinding { - public class GlobalKeyBindingsSection : KeyBindingsSection + public class GlobalKeyBindingsSection : SettingsSection { - private readonly string name; + public override FontAwesome Icon => FontAwesome.fa_osu_hot; + public override string Header => "Global"; - public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail; - public override string Header => name; - - public GlobalKeyBindingsSection(KeyBindingInputManager manager, string name) + public GlobalKeyBindingsSection(KeyBindingInputManager manager) { - this.name = name; + Add(new DefaultBindingsSubsection(manager)); + } - Defaults = manager.DefaultKeyBindings; + private class DefaultBindingsSubsection : KeyBindingsSubsection + { + protected override string Header => string.Empty; + + public DefaultBindingsSubsection(KeyBindingInputManager manager) + : base(0) + { + Defaults = manager.DefaultKeyBindings; + } } } } \ No newline at end of file diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs similarity index 57% rename from osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs rename to osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index 44c28ee9c8..9bbbf539c5 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 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.Framework.Allocation; @@ -12,38 +11,34 @@ using OpenTK; namespace osu.Game.Overlays.KeyBinding { - public abstract class KeyBindingsSection : SettingsSection + public abstract class KeyBindingsSubsection : SettingsSubsection { protected IEnumerable Defaults; protected RulesetInfo Ruleset; - protected KeyBindingsSection() + private readonly int variant; + + protected KeyBindingsSubsection(int variant) { + this.variant = variant; + FlowContent.Spacing = new Vector2(0, 1); } [BackgroundDependencyLoader] private void load(KeyBindingStore store) { - var enumType = Defaults?.FirstOrDefault()?.Action?.GetType(); - - if (enumType == null) return; - - // for now let's just assume a variant of zero. - // this will need to be implemented in a better way in the future. - int? variant = null; - if (Ruleset != null) - variant = 0; - var bindings = store.Query(Ruleset?.ID, variant); - foreach (Enum v in Enum.GetValues(enumType)) + foreach (var defaultBinding in Defaults) + { // one row per valid action. - Add(new KeyBindingRow(v, bindings.Where(b => b.Action.Equals((int)(object)v))) + Add(new KeyBindingRow(defaultBinding.Action, bindings.Where(b => b.Action.Equals((int)defaultBinding.Action))) { AllowMainMouseButtons = Ruleset != null }); + } } } } \ No newline at end of file diff --git a/osu.Game/Overlays/KeyBinding/RulesetBindingsSection.cs b/osu.Game/Overlays/KeyBinding/RulesetBindingsSection.cs index 20941115e3..885e149cb2 100644 --- a/osu.Game/Overlays/KeyBinding/RulesetBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/RulesetBindingsSection.cs @@ -2,20 +2,26 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Graphics; +using osu.Game.Overlays.Settings; using osu.Game.Rulesets; namespace osu.Game.Overlays.KeyBinding { - public class RulesetBindingsSection : KeyBindingsSection + public class RulesetBindingsSection : SettingsSection { - public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail; - public override string Header => Ruleset.Name; + public override FontAwesome Icon => FontAwesome.fa_osu_hot; + public override string Header => ruleset.Name; + + private readonly RulesetInfo ruleset; public RulesetBindingsSection(RulesetInfo ruleset) { - Ruleset = ruleset; + this.ruleset = ruleset; - Defaults = ruleset.CreateInstance().GetDefaultKeyBindings(); + var r = ruleset.CreateInstance(); + + foreach (var variant in r.AvailableVariants) + Add(new VariantBindingsSubsection(ruleset, variant)); } } } \ No newline at end of file diff --git a/osu.Game/Overlays/KeyBinding/VariantBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/VariantBindingsSubsection.cs new file mode 100644 index 0000000000..f58cb632de --- /dev/null +++ b/osu.Game/Overlays/KeyBinding/VariantBindingsSubsection.cs @@ -0,0 +1,23 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets; + +namespace osu.Game.Overlays.KeyBinding +{ + public class VariantBindingsSubsection : KeyBindingsSubsection + { + protected override string Header => variant > 0 ? $"Variant: {variant}" : string.Empty; + + private readonly int variant; + + public VariantBindingsSubsection(RulesetInfo ruleset, int variant) + : base(variant) + { + this.variant = variant; + + Ruleset = ruleset; + Defaults = ruleset.CreateInstance().GetDefaultKeyBindings(variant); + } + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/KeyBindingOverlay.cs b/osu.Game/Overlays/KeyBindingOverlay.cs index 827d361099..72c653030c 100644 --- a/osu.Game/Overlays/KeyBindingOverlay.cs +++ b/osu.Game/Overlays/KeyBindingOverlay.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader(permitNulls: true)] private void load(RulesetStore rulesets, GlobalKeyBindingInputManager global) { - AddSection(new GlobalKeyBindingsSection(global, "Global")); + AddSection(new GlobalKeyBindingsSection(global)); foreach (var ruleset in rulesets.AllRulesets) AddSection(new RulesetBindingsSection(ruleset)); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 11b99c1796..32a8df6357 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -105,9 +105,10 @@ - + + From 0e41fc8842d3c870c47acd046868d3bd948417c0 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 12:49:50 +0900 Subject: [PATCH 148/483] Add mania bindings. --- osu.Game.Rulesets.Mania/ManiaInputManager.cs | 26 +++++++++++-- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 37 +++++++++++++++++++ .../UI/ManiaRulesetContainer.cs | 2 +- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaInputManager.cs b/osu.Game.Rulesets.Mania/ManiaInputManager.cs index b608e4d8d6..0fac1bef10 100644 --- a/osu.Game.Rulesets.Mania/ManiaInputManager.cs +++ b/osu.Game.Rulesets.Mania/ManiaInputManager.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.ComponentModel; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.UI; @@ -8,14 +9,33 @@ namespace osu.Game.Rulesets.Mania { public class ManiaInputManager : RulesetInputManager { - public ManiaInputManager(RulesetInfo ruleset) - : base(ruleset, 0, SimultaneousBindingMode.Unique) + public ManiaInputManager(RulesetInfo ruleset, int variant) + : base(ruleset, variant, SimultaneousBindingMode.Unique) { } } public enum ManiaAction { - // placeholder + [Description("Key 1")] + Key1, + [Description("Key 2")] + Key2, + [Description("Key 3")] + Key3, + [Description("Key 4")] + Key4, + [Description("Key 5")] + Key5, + [Description("Key 6")] + Key6, + [Description("Key 7")] + Key7, + [Description("Key 8")] + Key8, + [Description("Key 9")] + Key9, + [Description("Special")] + Special } } diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index c7809f83ed..f073d5a04c 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -8,6 +8,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; using System.Collections.Generic; using osu.Framework.Graphics; +using osu.Framework.Input.Bindings; using osu.Game.Graphics; using osu.Game.Rulesets.Mania.Scoring; using osu.Game.Rulesets.Scoring; @@ -120,5 +121,41 @@ namespace osu.Game.Rulesets.Mania : base(rulesetInfo) { } + + public override IEnumerable AvailableVariants => new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + + public override IEnumerable GetDefaultKeyBindings(int variant = 0) + { + var leftKeys = new[] + { + InputKey.A, + InputKey.S, + InputKey.D, + InputKey.F + }; + + var rightKeys = new[] + { + InputKey.J, + InputKey.K, + InputKey.L, + InputKey.Semicolon + }; + + ManiaAction currentKey = ManiaAction.Key1; + + var bindings = new List(); + + for (int i = 0; i < variant / 2; i++) + bindings.Add(new KeyBinding(leftKeys[leftKeys.Length - 1 - i], currentKey++)); + + for (int i = 0; i < variant / 2; i++) + bindings.Add(new KeyBinding(rightKeys[i], currentKey++)); + + if (variant % 2 == 1) + bindings.Add(new KeyBinding(InputKey.Space, ManiaAction.Special)); + + return bindings; + } } } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 0e750a348e..782fa5f69e 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.Mania.UI public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this); - public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo); + public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, availableColumns); protected override BeatmapConverter CreateBeatmapConverter() { From 84dd1283dec2e73b1c96d6deabd9ed1906156532 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 13:39:51 +0900 Subject: [PATCH 149/483] Fix nullref. --- osu.Game/Rulesets/UI/RulesetContainer.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index ebf570fecc..7fed5c2225 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -249,7 +249,7 @@ namespace osu.Game.Rulesets.UI public Playfield Playfield { get; private set; } protected override Container Content => content; - private readonly Container content; + private Container content; private readonly List> drawableObjects = new List>(); @@ -261,6 +261,11 @@ namespace osu.Game.Rulesets.UI /// Whether to assume the beatmap is for the current ruleset. protected RulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) : base(ruleset, beatmap, isForCurrentRuleset) + { + } + + [BackgroundDependencyLoader] + private void load() { InputManager.Add(content = new Container { @@ -269,11 +274,6 @@ namespace osu.Game.Rulesets.UI }); AddInternal(InputManager); - } - - [BackgroundDependencyLoader] - private void load() - { KeyBindingInputManager.Add(Playfield = CreatePlayfield()); loadObjects(); From d8dfcc614a4a182da84be71f6ca579cc79804abc Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 13:42:11 +0900 Subject: [PATCH 150/483] Make mania work with key bindings --- .../Visual/TestCaseManiaHitObjects.cs | 7 +- .../Visual/TestCaseManiaPlayfield.cs | 178 +++++++++--------- .../Objects/Drawables/DrawableHoldNote.cs | 51 +++-- .../Drawables/DrawableManiaHitObject.cs | 10 +- .../Objects/Drawables/DrawableNote.cs | 22 +-- osu.Game.Rulesets.Mania/UI/Column.cs | 34 ++-- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 25 +-- .../UI/ManiaRulesetContainer.cs | 8 +- 8 files changed, 146 insertions(+), 189 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs b/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs index 7dcc48c778..76235bbf19 100644 --- a/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs +++ b/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs @@ -3,6 +3,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; using OpenTK; @@ -40,8 +41,8 @@ namespace osu.Desktop.Tests.Visual RelativeChildSize = new Vector2(1, 10000), Children = new[] { - new DrawableNote(new Note { StartTime = 5000 }) { AccentColour = Color4.Red }, - new DrawableNote(new Note { StartTime = 6000 }) { AccentColour = Color4.Red } + new DrawableNote(new Note { StartTime = 5000 }, ManiaAction.Key1) { AccentColour = Color4.Red }, + new DrawableNote(new Note { StartTime = 6000 }, ManiaAction.Key1) { AccentColour = Color4.Red } } } } @@ -66,7 +67,7 @@ namespace osu.Desktop.Tests.Visual { StartTime = 5000, Duration = 1000 - }) { AccentColour = Color4.Red } + }, ManiaAction.Key1) { AccentColour = Color4.Red } } } } diff --git a/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs index ed0e5d81e9..c52594930e 100644 --- a/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs @@ -3,109 +3,34 @@ using System; using System.Linq; -using osu.Framework.Configuration; +using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; -using osu.Framework.Input; using osu.Framework.Timing; +using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Timing; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Timing; using OpenTK; -using OpenTK.Input; +using osu.Game.Rulesets; namespace osu.Desktop.Tests.Visual { internal class TestCaseManiaPlayfield : OsuTestCase { + private const double start_time = 500; + private const double duration = 500; + public override string Description => @"Mania playfield"; protected override double TimePerAction => 200; + private RulesetInfo maniaRuleset; + public TestCaseManiaPlayfield() { - Action createPlayfield = (cols, pos) => - { - Clear(); - Add(new ManiaPlayfield(cols) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - SpecialColumnPosition = pos, - Scale = new Vector2(1, -1) - }); - }; - - const double start_time = 500; - const double duration = 500; - - Func createTimingChange = (time, gravity) => new ManiaSpeedAdjustmentContainer(new MultiplierControlPoint(time) - { - TimingPoint = { BeatLength = 1000 } - }, gravity ? ScrollingAlgorithm.Gravity : ScrollingAlgorithm.Basic); - - Action createPlayfieldWithNotes = gravity => - { - Clear(); - - var rateAdjustClock = new StopwatchClock(true) { Rate = 1 }; - - ManiaPlayfield playField; - Add(playField = new ManiaPlayfield(4) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Scale = new Vector2(1, -1), - Clock = new FramedClock(rateAdjustClock) - }); - - if (!gravity) - playField.Columns.ForEach(c => c.Add(createTimingChange(0, false))); - - for (double t = start_time; t <= start_time + duration; t += 100) - { - if (gravity) - playField.Columns.ElementAt(0).Add(createTimingChange(t, true)); - - playField.Add(new DrawableNote(new Note - { - StartTime = t, - Column = 0 - }, new Bindable(Key.D))); - - if (gravity) - playField.Columns.ElementAt(3).Add(createTimingChange(t, true)); - - playField.Add(new DrawableNote(new Note - { - StartTime = t, - Column = 3 - }, new Bindable(Key.K))); - } - - if (gravity) - playField.Columns.ElementAt(1).Add(createTimingChange(start_time, true)); - - playField.Add(new DrawableHoldNote(new HoldNote - { - StartTime = start_time, - Duration = duration, - Column = 1 - }, new Bindable(Key.F))); - - if (gravity) - playField.Columns.ElementAt(2).Add(createTimingChange(start_time, true)); - - playField.Add(new DrawableHoldNote(new HoldNote - { - StartTime = start_time, - Duration = duration, - Column = 2 - }, new Bindable(Key.J))); - }; - AddStep("1 column", () => createPlayfield(1, SpecialColumnPosition.Normal)); AddStep("4 columns", () => createPlayfield(4, SpecialColumnPosition.Normal)); AddStep("Left special style", () => createPlayfield(4, SpecialColumnPosition.Left)); @@ -122,21 +47,94 @@ namespace osu.Desktop.Tests.Visual AddWaitStep((int)Math.Ceiling((start_time + duration) / TimePerAction)); } - private void triggerKeyDown(Column column) + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets) { - column.TriggerOnKeyDown(new InputState(), new KeyDownEventArgs + maniaRuleset = rulesets.GetRuleset(3); + } + + private SpeedAdjustmentContainer createTimingChange(double time, bool gravity) => new ManiaSpeedAdjustmentContainer(new MultiplierControlPoint(time) + { + TimingPoint = { BeatLength = 1000 } + }, gravity ? ScrollingAlgorithm.Gravity : ScrollingAlgorithm.Basic); + + private void createPlayfield(int cols, SpecialColumnPosition specialPos) + { + Clear(); + + var inputManager = new ManiaInputManager(maniaRuleset, cols) { RelativeSizeAxes = Axes.Both }; + Add(inputManager); + + inputManager.Add(new ManiaPlayfield(cols) { - Key = column.Key, - Repeat = false + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + SpecialColumnPosition = specialPos, + Scale = new Vector2(1, -1) }); } - private void triggerKeyUp(Column column) + private void createPlayfieldWithNotes(bool gravity) { - column.TriggerOnKeyUp(new InputState(), new KeyUpEventArgs + Clear(); + + var rateAdjustClock = new StopwatchClock(true) { Rate = 1 }; + + var inputManager = new ManiaInputManager(maniaRuleset, 4) { RelativeSizeAxes = Axes.Both }; + Add(inputManager); + + ManiaPlayfield playField; + inputManager.Add(playField = new ManiaPlayfield(4) { - Key = column.Key + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(1, -1), + Clock = new FramedClock(rateAdjustClock) }); + + if (!gravity) + playField.Columns.ForEach(c => c.Add(createTimingChange(0, false))); + + for (double t = start_time; t <= start_time + duration; t += 100) + { + if (gravity) + playField.Columns.ElementAt(0).Add(createTimingChange(t, true)); + + playField.Add(new DrawableNote(new Note + { + StartTime = t, + Column = 0 + }, ManiaAction.Key1)); + + if (gravity) + playField.Columns.ElementAt(3).Add(createTimingChange(t, true)); + + playField.Add(new DrawableNote(new Note + { + StartTime = t, + Column = 3 + }, ManiaAction.Key4)); + } + + if (gravity) + playField.Columns.ElementAt(1).Add(createTimingChange(start_time, true)); + + playField.Add(new DrawableHoldNote(new HoldNote + { + StartTime = start_time, + Duration = duration, + Column = 1 + }, ManiaAction.Key2)); + + if (gravity) + playField.Columns.ElementAt(2).Add(createTimingChange(start_time, true)); + + playField.Add(new DrawableHoldNote(new HoldNote + { + StartTime = start_time, + Duration = duration, + Column = 2 + }, ManiaAction.Key3)); } } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 17b0b0a607..e06f71cb64 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -5,20 +5,18 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; using OpenTK.Graphics; -using osu.Framework.Configuration; -using OpenTK.Input; -using osu.Framework.Input; using OpenTK; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Mania.Judgements; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Input.Bindings; namespace osu.Game.Rulesets.Mania.Objects.Drawables { /// /// Visualises a hit object. /// - public class DrawableHoldNote : DrawableManiaHitObject + public class DrawableHoldNote : DrawableManiaHitObject, IKeyBindingHandler { private readonly DrawableNote head; private readonly DrawableNote tail; @@ -36,8 +34,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// private bool hasBroken; - public DrawableHoldNote(HoldNote hitObject, Bindable key = null) - : base(hitObject, key) + public DrawableHoldNote(HoldNote hitObject, ManiaAction action) + : base(hitObject, action) { RelativeSizeAxes = Axes.Both; Height = (float)HitObject.Duration; @@ -58,12 +56,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime), RelativeChildSize = new Vector2(1, (float)HitObject.Duration) }, - head = new DrawableHeadNote(this, key) + head = new DrawableHeadNote(this, action) { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre }, - tail = new DrawableTailNote(this, key) + tail = new DrawableTailNote(this, action) { Anchor = Anchor.BottomCentre, Origin = Anchor.TopCentre @@ -106,16 +104,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + public bool OnPressed(ManiaAction action) { - // Make sure the keypress happened within the body of the hold note + // Make sure the action happened within the body of the hold note if (Time.Current < HitObject.StartTime || Time.Current > HitObject.EndTime) return false; - if (args.Key != Key) - return false; - - if (args.Repeat) + if (action != Action) return false; // The user has pressed during the body of the hold note, after the head note and its hit windows have passed @@ -126,13 +121,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables return true; } - protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) + public bool OnReleased(ManiaAction action) { // Make sure that the user started holding the key during the hold note if (!holdStartTime.HasValue) return false; - if (args.Key != Key) + if (action != Action) return false; holdStartTime = null; @@ -151,8 +146,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { private readonly DrawableHoldNote holdNote; - public DrawableHeadNote(DrawableHoldNote holdNote, Bindable key = null) - : base(holdNote.HitObject.Head, key) + public DrawableHeadNote(DrawableHoldNote holdNote, ManiaAction action) + : base(holdNote.HitObject.Head, action) { this.holdNote = holdNote; @@ -160,9 +155,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Y = 0; } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + public override bool OnPressed(ManiaAction action) { - if (!base.OnKeyDown(state, args)) + if (!base.OnPressed(action)) return false; // We only want to trigger a holding state from the head if the head has received a judgement @@ -188,8 +183,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { private readonly DrawableHoldNote holdNote; - public DrawableTailNote(DrawableHoldNote holdNote, Bindable key = null) - : base(holdNote.HitObject.Tail, key) + public DrawableTailNote(DrawableHoldNote holdNote, ManiaAction action) + : base(holdNote.HitObject.Tail, action) { this.holdNote = holdNote; @@ -210,7 +205,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables tailJudgement.HasBroken = holdNote.hasBroken; } - protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) + public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down + + public override bool OnReleased(ManiaAction action) { // Make sure that the user started holding the key during the hold note if (!holdNote.holdStartTime.HasValue) @@ -219,7 +216,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (Judgement.Result != HitResult.None) return false; - if (args.Key != Key) + if (action != Action) return false; UpdateJudgement(true); @@ -227,12 +224,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables // Handled by the hold note, which will set holding = false return false; } - - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) - { - // Tail doesn't handle key down - return false; - } } } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index 10dc607ec3..bfef05ea07 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -2,8 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK.Graphics; -using OpenTK.Input; -using osu.Framework.Configuration; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Objects.Drawables; @@ -15,17 +13,17 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// The key that will trigger input for this hit object. /// - protected Bindable Key { get; private set; } = new Bindable(); + protected ManiaAction Action { get; } public new TObject HitObject; - protected DrawableManiaHitObject(TObject hitObject, Bindable key = null) + protected DrawableManiaHitObject(TObject hitObject, ManiaAction? action = null) : base(hitObject) { HitObject = hitObject; - if (key != null) - Key.BindTo(key); + if (action != null) + Action = action.Value; } public override Color4 AccentColour diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 9322fed3eb..c201ab7bd0 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -3,10 +3,8 @@ using System; using OpenTK.Graphics; -using OpenTK.Input; -using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Input; +using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; using osu.Game.Rulesets.Objects.Drawables; @@ -16,12 +14,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// Visualises a hit object. /// - public class DrawableNote : DrawableManiaHitObject + public class DrawableNote : DrawableManiaHitObject, IKeyBindingHandler { private readonly NotePiece headPiece; - public DrawableNote(Note hitObject, Bindable key = null) - : base(hitObject, key) + public DrawableNote(Note hitObject, ManiaAction action) + : base(hitObject, action) { RelativeSizeAxes = Axes.X; Height = 100; @@ -81,18 +79,14 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + public virtual bool OnPressed(ManiaAction action) { - if (Judgement.Result != HitResult.None) - return false; - - if (args.Key != Key) - return false; - - if (args.Repeat) + if (action != Action) return false; return UpdateJudgement(true); } + + public virtual bool OnReleased(ManiaAction action) => false; } } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 9fbc9ba5e7..a8f5b4919d 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -3,17 +3,15 @@ using OpenTK; using OpenTK.Graphics; -using OpenTK.Input; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Colour; -using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using System; -using osu.Framework.Configuration; +using osu.Framework.Input.Bindings; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Judgements; @@ -32,10 +30,7 @@ namespace osu.Game.Rulesets.Mania.UI private const float column_width = 45; private const float special_column_width = 70; - /// - /// The key that will trigger input actions for this column and hit objects contained inside it. - /// - public Bindable Key = new Bindable(); + public ManiaAction Action; private readonly Box background; private readonly Container hitTargetBar; @@ -101,8 +96,8 @@ namespace osu.Game.Rulesets.Mania.UI // For column lighting, we need to capture input events before the notes new InputTarget { - KeyDown = onKeyDown, - KeyUp = onKeyUp + Pressed = onPressed, + Released = onReleased } } }, @@ -199,12 +194,9 @@ namespace osu.Game.Rulesets.Mania.UI HitObjects.Add(hitObject); } - private bool onKeyDown(InputState state, KeyDownEventArgs args) + private bool onPressed(ManiaAction action) { - if (args.Repeat) - return false; - - if (args.Key == Key) + if (action == Action) { background.FadeTo(background.Alpha + 0.2f, 50, Easing.OutQuint); keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint); @@ -213,9 +205,9 @@ namespace osu.Game.Rulesets.Mania.UI return false; } - private bool onKeyUp(InputState state, KeyUpEventArgs args) + private bool onReleased(ManiaAction action) { - if (args.Key == Key) + if (action == Action) { background.FadeTo(0.2f, 800, Easing.OutQuart); keyIcon.ScaleTo(1f, 400, Easing.OutQuart); @@ -227,10 +219,10 @@ namespace osu.Game.Rulesets.Mania.UI /// /// This is a simple container which delegates various input events that have to be captured before the notes. /// - private class InputTarget : Container + private class InputTarget : Container, IKeyBindingHandler { - public Func KeyDown; - public Func KeyUp; + public Func Pressed; + public Func Released; public InputTarget() { @@ -239,8 +231,8 @@ namespace osu.Game.Rulesets.Mania.UI Alpha = 0; } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) => KeyDown?.Invoke(state, args) ?? false; - protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) => KeyUp?.Invoke(state, args) ?? false; + public bool OnPressed(ManiaAction action) => Pressed?.Invoke(action) ?? false; + public bool OnReleased(ManiaAction action) => Released?.Invoke(action) ?? false; } } } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 0c9351cad2..be14585354 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -122,12 +122,16 @@ namespace osu.Game.Rulesets.Mania.UI } }; + var currentAction = ManiaAction.Key1; for (int i = 0; i < columnCount; i++) { var c = new Column(); c.Reversed.BindTo(Reversed); c.VisibleTimeRange.BindTo(VisibleTimeRange); + c.IsSpecial = isSpecialColumn(i); + c.Action = c.IsSpecial ? ManiaAction.Special : currentAction++; + columns.Add(c); AddNested(c); } @@ -145,15 +149,11 @@ namespace osu.Game.Rulesets.Mania.UI specialColumnColour = colours.BlueDark; // Set the special column + colour + key - for (int i = 0; i < columnCount; i++) + foreach (var column in Columns) { - Column column = Columns.ElementAt(i); - column.IsSpecial = isSpecialColumn(i); - if (!column.IsSpecial) continue; - column.Key.Value = Key.Space; column.AccentColour = specialColumnColour; } @@ -167,21 +167,6 @@ namespace osu.Game.Rulesets.Mania.UI nonSpecialColumns[i].AccentColour = colour; nonSpecialColumns[nonSpecialColumns.Count - 1 - i].AccentColour = colour; } - - // We'll set the keys for non-special columns in another separate loop because it's not mirrored like the above colours - // Todo: This needs to go when we get to bindings and use Button1, ..., ButtonN instead - for (int i = 0; i < nonSpecialColumns.Count; i++) - { - Column column = nonSpecialColumns[i]; - - int keyOffset = default_keys.Length / 2 - nonSpecialColumns.Count / 2 + i; - if (keyOffset >= 0 && keyOffset < default_keys.Length) - column.Key.Value = default_keys[keyOffset]; - else - // There is no default key defined for this column. Let's set this to Unknown for now - // however note that this will be gone after bindings are in place - column.Key.Value = Key.Unknown; - } } /// diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 782fa5f69e..5a3da6d074 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -5,9 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using OpenTK; -using OpenTK.Input; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Input; @@ -109,15 +107,15 @@ namespace osu.Game.Rulesets.Mania.UI protected override DrawableHitObject GetVisualRepresentation(ManiaHitObject h) { - Bindable key = Playfield.Columns.ElementAt(h.Column).Key; + ManiaAction action = Playfield.Columns.ElementAt(h.Column).Action; var holdNote = h as HoldNote; if (holdNote != null) - return new DrawableHoldNote(holdNote, key); + return new DrawableHoldNote(holdNote, action); var note = h as Note; if (note != null) - return new DrawableNote(note, key); + return new DrawableNote(note, action); return null; } From 68e7cf854f8798568379d1d78a434588cafa4dd5 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 14:19:14 +0900 Subject: [PATCH 151/483] Add variant names. --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 ++ .../KeyBinding/VariantBindingsSubsection.cs | 13 +++++++------ osu.Game/Rulesets/Ruleset.cs | 7 +++++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index f073d5a04c..6c356195b2 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -157,5 +157,7 @@ namespace osu.Game.Rulesets.Mania return bindings; } + + public override string GetVariantName(int variant) => $"{variant}K"; } } diff --git a/osu.Game/Overlays/KeyBinding/VariantBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/VariantBindingsSubsection.cs index f58cb632de..dca5f53b4a 100644 --- a/osu.Game/Overlays/KeyBinding/VariantBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/VariantBindingsSubsection.cs @@ -7,17 +7,18 @@ namespace osu.Game.Overlays.KeyBinding { public class VariantBindingsSubsection : KeyBindingsSubsection { - protected override string Header => variant > 0 ? $"Variant: {variant}" : string.Empty; - - private readonly int variant; + protected override string Header => variantName; + private readonly string variantName; public VariantBindingsSubsection(RulesetInfo ruleset, int variant) : base(variant) { - this.variant = variant; - Ruleset = ruleset; - Defaults = ruleset.CreateInstance().GetDefaultKeyBindings(variant); + + var rulesetInstance = ruleset.CreateInstance(); + + variantName = rulesetInstance.GetVariantName(variant); + Defaults = rulesetInstance.GetDefaultKeyBindings(variant); } } } \ No newline at end of file diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 32d958b462..c54aeb7852 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -63,5 +63,12 @@ namespace osu.Game.Rulesets /// A variant. /// A list of valid s. public virtual IEnumerable GetDefaultKeyBindings(int variant = 0) => new KeyBinding[] { }; + + /// + /// Gets the name for a key binding variant. This is used for display in the settings overlay. + /// + /// The variant. + /// A descriptive name of the variant. + public virtual string GetVariantName(int variant) => string.Empty; } } From e777ccc3398a155b33423bf3f056d8d075142368 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Aug 2017 14:38:26 +0900 Subject: [PATCH 152/483] Avoid threading conflicts when resetting the database in unit tests --- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index ecaf0db096..eb456d7a63 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -13,7 +13,6 @@ using osu.Framework.Platform; using osu.Game.IPC; using osu.Framework.Allocation; using osu.Game.Beatmaps; -using osu.Game.Rulesets; namespace osu.Game.Tests.Beatmaps.IO { @@ -98,16 +97,14 @@ namespace osu.Game.Tests.Beatmaps.IO private OsuGameBase loadOsu(GameHost host) { + host.Storage.DeleteDatabase(@"client"); + var osu = new OsuGameBase(); Task.Run(() => host.Run(osu)); while (!osu.IsLoaded) Thread.Sleep(1); - //reset beatmap database (sqlite and storage backing) - osu.Dependencies.Get().Reset(); - osu.Dependencies.Get().Reset(); - return osu; } From 751bd3432e3dc4dee25bbb097a7dc019619d53dc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Aug 2017 14:48:58 +0900 Subject: [PATCH 153/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 74f644bad0..e2d41820b3 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 74f644bad039606e242d8782014d8c249a38b6a3 +Subproject commit e2d41820b3795d97f8510a18fad5e42caeb23f0a From 0c60563fda957d7efc27fd0b62a6b8a592d9ef62 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 15:24:08 +0900 Subject: [PATCH 154/483] Update framework. --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 1fd9259e86..e2d41820b3 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 1fd9259e86379838dbbc43c12a2238df83800fc0 +Subproject commit e2d41820b3795d97f8510a18fad5e42caeb23f0a From 7639e096d865cb044186df0fc4ca4d085b4e9d5c Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 15:30:17 +0900 Subject: [PATCH 155/483] No longer flip legacy replay mouse positions. --- osu.Game/Rulesets/Scoring/ScoreStore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreStore.cs b/osu.Game/Rulesets/Scoring/ScoreStore.cs index c6421522b4..c06d31e38f 100644 --- a/osu.Game/Rulesets/Scoring/ScoreStore.cs +++ b/osu.Game/Rulesets/Scoring/ScoreStore.cs @@ -137,7 +137,7 @@ namespace osu.Game.Rulesets.Scoring frames.Add(new ReplayFrame( lastTime, float.Parse(split[1]), - 384 - float.Parse(split[2]), + float.Parse(split[2]), (ReplayButtonState)int.Parse(split[3]) )); } From 4395ea3850baaf67047cc910c4e60a028e76af5c Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 15:37:22 +0900 Subject: [PATCH 156/483] Add applied suggestions. --- osu.Game.Rulesets.Mania/ManiaInputManager.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaInputManager.cs b/osu.Game.Rulesets.Mania/ManiaInputManager.cs index 0fac1bef10..a574bc75ec 100644 --- a/osu.Game.Rulesets.Mania/ManiaInputManager.cs +++ b/osu.Game.Rulesets.Mania/ManiaInputManager.cs @@ -17,8 +17,10 @@ namespace osu.Game.Rulesets.Mania public enum ManiaAction { + [Description("Special")] + Special, [Description("Key 1")] - Key1, + Key1 = 10, [Description("Key 2")] Key2, [Description("Key 3")] @@ -34,8 +36,6 @@ namespace osu.Game.Rulesets.Mania [Description("Key 8")] Key8, [Description("Key 9")] - Key9, - [Description("Special")] - Special + Key9 } } From bdd0a51c6e178ca0ccac027087f8f576037513f8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Aug 2017 16:10:10 +0900 Subject: [PATCH 157/483] Fix left keys setting defaults in incorrect order --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 6c356195b2..ed46da4f85 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -146,8 +146,8 @@ namespace osu.Game.Rulesets.Mania var bindings = new List(); - for (int i = 0; i < variant / 2; i++) - bindings.Add(new KeyBinding(leftKeys[leftKeys.Length - 1 - i], currentKey++)); + for (int i = leftKeys.Length - variant / 2; i < leftKeys.Length; i++) + bindings.Add(new KeyBinding(leftKeys[i], currentKey++)); for (int i = 0; i < variant / 2; i++) bindings.Add(new KeyBinding(rightKeys[i], currentKey++)); From efdd5eb152d532adeed652e8d63f8b930b5331f2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Aug 2017 16:10:31 +0900 Subject: [PATCH 158/483] Fix global key bindings being fetched with a non-null variant --- osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs | 2 +- osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs index 77de9fc865..8ebd4ac545 100644 --- a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.KeyBinding protected override string Header => string.Empty; public DefaultBindingsSubsection(KeyBindingInputManager manager) - : base(0) + : base(null) { Defaults = manager.DefaultKeyBindings; } diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index 9bbbf539c5..38a5b1a171 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -17,9 +17,9 @@ namespace osu.Game.Overlays.KeyBinding protected RulesetInfo Ruleset; - private readonly int variant; + private readonly int? variant; - protected KeyBindingsSubsection(int variant) + protected KeyBindingsSubsection(int? variant) { this.variant = variant; From 42e6865493f3e87f9b1be8659d8f074b42e92b0c Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 15:35:31 +0900 Subject: [PATCH 159/483] Flip hit objects. --- osu.Game.Rulesets.Osu/Mods/OsuMod.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs index 3b0cfc1ef1..6bc9f868ac 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs @@ -7,8 +7,12 @@ using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; using System; +using System.Collections.Generic; using System.Linq; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; +using OpenTK; namespace osu.Game.Rulesets.Osu.Mods { @@ -28,10 +32,23 @@ namespace osu.Game.Rulesets.Osu.Mods public override double ScoreMultiplier => 1.06; } - public class OsuModHardRock : ModHardRock + public class OsuModHardRock : ModHardRock, IApplicableMod { public override double ScoreMultiplier => 1.06; public override bool Ranked => true; + + public void ApplyToRulesetContainer(RulesetContainer rulesetContainer) + { + rulesetContainer.Objects.OfType().ForEach(h => h.Position = new Vector2(h.Position.X, 384 - h.Y)); + rulesetContainer.Objects.OfType().ForEach(s => + { + var newControlPoints = new List(); + s.ControlPoints.ForEach(c => newControlPoints.Add(new Vector2(c.X, 384 - c.Y))); + + s.ControlPoints = newControlPoints; + s.Curve?.Calculate(); // Recalculate the slider curve + }); + } } public class OsuModSuddenDeath : ModSuddenDeath From 8ddc13e394fdaa355152f9067c0790d3f09fba8a Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 16:48:13 +0900 Subject: [PATCH 160/483] Fix replays not loading. --- osu.Game/Rulesets/UI/RulesetContainer.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 2f1cb915f3..8a12286bc6 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.UI /// Sets a replay to be used, overriding local input. /// /// The replay, null for local input. - public void SetReplay(Replay replay) + public virtual void SetReplay(Replay replay) { Replay = replay; InputManager.ReplayInputHandler = replay != null ? CreateReplayInputHandler(replay) : null; @@ -272,6 +272,11 @@ namespace osu.Game.Rulesets.UI KeyBindingInputManager.Add(Playfield = CreatePlayfield()); loadObjects(); + } + + public override void SetReplay(Replay replay) + { + base.SetReplay(replay); if (InputManager?.ReplayInputHandler != null) InputManager.ReplayInputHandler.ToScreenSpace = Playfield.ScaledContent.ToScreenSpace; From 1972b78cb13d8bea10d7392bd4a63be6efef1a92 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Aug 2017 15:28:33 +0900 Subject: [PATCH 161/483] Make OsuTestCases use new non-realtime option --- osu.Desktop.Tests/Visual/OsuTestCase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop.Tests/Visual/OsuTestCase.cs b/osu.Desktop.Tests/Visual/OsuTestCase.cs index e54f7dbeb5..e366aecb21 100644 --- a/osu.Desktop.Tests/Visual/OsuTestCase.cs +++ b/osu.Desktop.Tests/Visual/OsuTestCase.cs @@ -14,7 +14,7 @@ namespace osu.Desktop.Tests.Visual [Test] public override void RunTest() { - using (var host = new HeadlessGameHost()) + using (var host = new HeadlessGameHost(realtime: false)) host.Run(new OsuTestCaseTestRunner(this)); } From 022063f15766d147690f32180254cae5e806d33b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Aug 2017 16:51:09 +0900 Subject: [PATCH 162/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index e2d41820b3..1ba1e8ef1e 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit e2d41820b3795d97f8510a18fad5e42caeb23f0a +Subproject commit 1ba1e8ef1e5ec0466632be02492023a081cb85ab From 56292bd7f0b1ee64a5fe7d24af2f36f47d1c98c1 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 16:54:06 +0900 Subject: [PATCH 163/483] Use constant definition. --- osu.Game.Rulesets.Osu/Mods/OsuMod.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs index 6bc9f868ac..432c6d391c 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using OpenTK; @@ -39,11 +40,11 @@ namespace osu.Game.Rulesets.Osu.Mods public void ApplyToRulesetContainer(RulesetContainer rulesetContainer) { - rulesetContainer.Objects.OfType().ForEach(h => h.Position = new Vector2(h.Position.X, 384 - h.Y)); + rulesetContainer.Objects.OfType().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Y)); rulesetContainer.Objects.OfType().ForEach(s => { var newControlPoints = new List(); - s.ControlPoints.ForEach(c => newControlPoints.Add(new Vector2(c.X, 384 - c.Y))); + s.ControlPoints.ForEach(c => newControlPoints.Add(new Vector2(c.X, OsuPlayfield.BASE_SIZE.Y - c.Y))); s.ControlPoints = newControlPoints; s.Curve?.Calculate(); // Recalculate the slider curve From e9dde822a1c29b5cb160965116b895c4ac3baa93 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Aug 2017 19:25:40 +0900 Subject: [PATCH 164/483] Expose triangles in OsuButton for further customisation --- osu.Game/Graphics/UserInterface/OsuButton.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 5650fc6f48..abc1b036bc 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -24,6 +24,8 @@ namespace osu.Game.Graphics.UserInterface private SampleChannel sampleClick; private SampleChannel sampleHover; + protected Triangles Triangles; + public OsuButton() { Height = 40; @@ -52,7 +54,7 @@ namespace osu.Game.Graphics.UserInterface AddRange(new Drawable[] { - new Triangles + Triangles = new Triangles { RelativeSizeAxes = Axes.Both, ColourDark = colours.BlueDarker, @@ -120,4 +122,4 @@ namespace osu.Game.Graphics.UserInterface } } } -} \ No newline at end of file +} From c99ed6fd440fa88906c13757fa9b08f381041083 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Aug 2017 19:26:49 +0900 Subject: [PATCH 165/483] Add reset button Also fixes a regression causing multiple rows to be displayed for a single action --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 13 +++++++ .../KeyBinding/KeyBindingsSubsection.cs | 36 ++++++++++++++++--- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index c182382d70..ee997a2185 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -109,6 +109,17 @@ namespace osu.Game.Overlays.KeyBinding buttons.Add(new KeyButton(b)); } + public void RestoreDefaults() + { + int i = 0; + foreach (var d in Defaults) + { + var button = buttons[i++]; + button.UpdateKeyCombination(d); + store.Update(button.KeyBinding); + } + } + protected override bool OnHover(InputState state) { this.FadeEdgeEffectTo(1, transition_time, Easing.OutQuint); @@ -129,6 +140,8 @@ namespace osu.Game.Overlays.KeyBinding public bool AllowMainMouseButtons; + public IEnumerable Defaults; + private bool isModifier(Key k) => k < Key.F1; protected override bool OnClick(InputState state) => true; diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs index 38a5b1a171..bd69403831 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingsSubsection.cs @@ -4,10 +4,14 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Graphics; +using osu.Game.Graphics.UserInterface; using osu.Game.Input; using osu.Game.Overlays.Settings; using osu.Game.Rulesets; using OpenTK; +using osu.Game.Graphics; namespace osu.Game.Overlays.KeyBinding { @@ -31,14 +35,38 @@ namespace osu.Game.Overlays.KeyBinding { var bindings = store.Query(Ruleset?.ID, variant); - foreach (var defaultBinding in Defaults) + foreach (var defaultGroup in Defaults.GroupBy(d => d.Action)) { // one row per valid action. - Add(new KeyBindingRow(defaultBinding.Action, bindings.Where(b => b.Action.Equals((int)defaultBinding.Action))) + Add(new KeyBindingRow(defaultGroup.Key, bindings.Where(b => b.Action.Equals((int)defaultGroup.Key))) { - AllowMainMouseButtons = Ruleset != null + AllowMainMouseButtons = Ruleset != null, + Defaults = defaultGroup.Select(d => d.KeyCombination) }); } + + Add(new ResetButton + { + Action = () => Children.OfType().ForEach(k => k.RestoreDefaults()) + }); } } -} \ No newline at end of file + + internal class ResetButton : OsuButton + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Text = "Reset"; + RelativeSizeAxes = Axes.X; + Margin = new MarginPadding { Top = 5 }; + Height = 20; + + Content.CornerRadius = 5; + + BackgroundColour = colours.PinkDark; + Triangles.ColourDark = colours.PinkDarker; + Triangles.ColourLight = colours.Pink; + } + } +} From 115e5c95aff64557c8c900a76feaa0dac8061e09 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 23 Aug 2017 20:50:03 +0900 Subject: [PATCH 166/483] Make ScrollingPlayfield.Reversed protected; make ManiaPlayfield 'invertible'. --- .../Visual/TestCaseManiaPlayfield.cs | 45 ++++++++++--------- .../Visual/TestCaseScrollingPlayfield.cs | 6 ++- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 17 ++++++- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 4 +- 4 files changed, 45 insertions(+), 27 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs index c52594930e..fb14bdb3bf 100644 --- a/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; @@ -13,7 +12,6 @@ using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Timing; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Timing; -using OpenTK; using osu.Game.Rulesets; namespace osu.Desktop.Tests.Visual @@ -39,12 +37,12 @@ namespace osu.Desktop.Tests.Visual AddStep("8 columns", () => createPlayfield(8, SpecialColumnPosition.Normal)); AddStep("Left special style", () => createPlayfield(8, SpecialColumnPosition.Left)); AddStep("Right special style", () => createPlayfield(8, SpecialColumnPosition.Right)); + AddStep("Reversed", () => createPlayfield(4, SpecialColumnPosition.Normal, true)); AddStep("Notes with input", () => createPlayfieldWithNotes(false)); - AddWaitStep((int)Math.Ceiling((start_time + duration) / TimePerAction)); - + AddStep("Notes with input (reversed)", () => createPlayfieldWithNotes(false, true)); AddStep("Notes with gravity", () => createPlayfieldWithNotes(true)); - AddWaitStep((int)Math.Ceiling((start_time + duration) / TimePerAction)); + AddStep("Notes with gravity (reversed)", () => createPlayfieldWithNotes(true, true)); } [BackgroundDependencyLoader] @@ -58,23 +56,25 @@ namespace osu.Desktop.Tests.Visual TimingPoint = { BeatLength = 1000 } }, gravity ? ScrollingAlgorithm.Gravity : ScrollingAlgorithm.Basic); - private void createPlayfield(int cols, SpecialColumnPosition specialPos) + private void createPlayfield(int cols, SpecialColumnPosition specialPos, bool inverted = false) { Clear(); var inputManager = new ManiaInputManager(maniaRuleset, cols) { RelativeSizeAxes = Axes.Both }; Add(inputManager); - inputManager.Add(new ManiaPlayfield(cols) + ManiaPlayfield playfield; + inputManager.Add(playfield = new ManiaPlayfield(cols) { Anchor = Anchor.Centre, Origin = Anchor.Centre, - SpecialColumnPosition = specialPos, - Scale = new Vector2(1, -1) + SpecialColumnPosition = specialPos }); + + playfield.Inverted.Value = inverted; } - private void createPlayfieldWithNotes(bool gravity) + private void createPlayfieldWithNotes(bool gravity, bool inverted = false) { Clear(); @@ -83,33 +83,34 @@ namespace osu.Desktop.Tests.Visual var inputManager = new ManiaInputManager(maniaRuleset, 4) { RelativeSizeAxes = Axes.Both }; Add(inputManager); - ManiaPlayfield playField; - inputManager.Add(playField = new ManiaPlayfield(4) + ManiaPlayfield playfield; + inputManager.Add(playfield = new ManiaPlayfield(4) { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Scale = new Vector2(1, -1), Clock = new FramedClock(rateAdjustClock) }); + playfield.Inverted.Value = inverted; + if (!gravity) - playField.Columns.ForEach(c => c.Add(createTimingChange(0, false))); + playfield.Columns.ForEach(c => c.Add(createTimingChange(0, false))); for (double t = start_time; t <= start_time + duration; t += 100) { if (gravity) - playField.Columns.ElementAt(0).Add(createTimingChange(t, true)); + playfield.Columns.ElementAt(0).Add(createTimingChange(t, true)); - playField.Add(new DrawableNote(new Note + playfield.Add(new DrawableNote(new Note { StartTime = t, Column = 0 }, ManiaAction.Key1)); if (gravity) - playField.Columns.ElementAt(3).Add(createTimingChange(t, true)); + playfield.Columns.ElementAt(3).Add(createTimingChange(t, true)); - playField.Add(new DrawableNote(new Note + playfield.Add(new DrawableNote(new Note { StartTime = t, Column = 3 @@ -117,9 +118,9 @@ namespace osu.Desktop.Tests.Visual } if (gravity) - playField.Columns.ElementAt(1).Add(createTimingChange(start_time, true)); + playfield.Columns.ElementAt(1).Add(createTimingChange(start_time, true)); - playField.Add(new DrawableHoldNote(new HoldNote + playfield.Add(new DrawableHoldNote(new HoldNote { StartTime = start_time, Duration = duration, @@ -127,9 +128,9 @@ namespace osu.Desktop.Tests.Visual }, ManiaAction.Key2)); if (gravity) - playField.Columns.ElementAt(2).Add(createTimingChange(start_time, true)); + playfield.Columns.ElementAt(2).Add(createTimingChange(start_time, true)); - playField.Add(new DrawableHoldNote(new HoldNote + playfield.Add(new DrawableHoldNote(new HoldNote { StartTime = start_time, Duration = duration, diff --git a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs index c8c95da618..444adf6c24 100644 --- a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs @@ -64,8 +64,8 @@ namespace osu.Desktop.Tests.Visual AddStep("Reverse direction", () => { - horizontalRulesetContainer.Playfield.Reversed.Toggle(); - verticalRulesetContainer.Playfield.Reversed.Toggle(); + horizontalRulesetContainer.Playfield.Reverse(); + verticalRulesetContainer.Playfield.Reverse(); }); } @@ -210,6 +210,8 @@ namespace osu.Desktop.Tests.Visual content = new Container { RelativeSizeAxes = Axes.Both } }; } + + public void Reverse() => Reversed.Toggle(); } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index be14585354..d3dc920fc6 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -14,6 +14,7 @@ using osu.Framework.Allocation; using OpenTK.Input; using System.Linq; using System.Collections.Generic; +using osu.Framework.Configuration; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Framework.Graphics.Shapes; @@ -45,6 +46,11 @@ namespace osu.Game.Rulesets.Mania.UI } } + /// + /// Whether this playfield should be inverted. This flips everything inside the playfield. + /// + public readonly Bindable Inverted = new Bindable(true); + private readonly FlowContainer columns; public IEnumerable Columns => columns.Children; @@ -64,6 +70,8 @@ namespace osu.Game.Rulesets.Mania.UI if (columnCount <= 0) throw new ArgumentException("Can't have zero or fewer columns."); + Inverted.Value = true; + InternalChildren = new Drawable[] { new Container @@ -126,7 +134,6 @@ namespace osu.Game.Rulesets.Mania.UI for (int i = 0; i < columnCount; i++) { var c = new Column(); - c.Reversed.BindTo(Reversed); c.VisibleTimeRange.BindTo(VisibleTimeRange); c.IsSpecial = isSpecialColumn(i); @@ -135,6 +142,14 @@ namespace osu.Game.Rulesets.Mania.UI columns.Add(c); AddNested(c); } + + Inverted.ValueChanged += invertedChanged; + Inverted.TriggerChange(); + } + + private void invertedChanged(bool newValue) + { + Scale = new Vector2(1, newValue ? -1 : 1); } [BackgroundDependencyLoader] diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 92845c3f3a..1d13e2abb1 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -55,9 +55,9 @@ namespace osu.Game.Rulesets.UI }; /// - /// Whether to reverse the scrolling direction is reversed. + /// Whether to reverse the scrolling direction is reversed. Note that this does _not_ invert the hit objects. /// - public readonly BindableBool Reversed = new BindableBool(); + protected readonly BindableBool Reversed = new BindableBool(); /// /// The container that contains the s and s. From 2cace0e1ab045c172b9571dcd0154b56751decfe Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 24 Aug 2017 09:48:53 +0530 Subject: [PATCH 167/483] Don't use virtual methods in ctor, always create closeButton. --- osu.Game/Overlays/Chat/ChatTabControl.cs | 41 ++++++++++++------------ 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index c11e474b76..5b65f7c036 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Chat Margin = new MarginPadding(10), }); - AddTabItem(selectorTab = new ChannelTabItem.ChannelSelectorTabItem(new Channel { Name = "+" })); + base.AddTabItem(selectorTab = new ChannelTabItem.ChannelSelectorTabItem(new Channel { Name = "+" })); ChannelSelectorActive.BindTo(selectorTab.Active); } @@ -129,7 +129,7 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1.1f), transition_length, Easing.OutQuint); - closeButton?.MoveToX(-5f, 0.5f, Easing.OutElastic); + closeButton.MoveToX(-5f, 0.5f, Easing.OutElastic); box.FadeColour(backgroundActive, transition_length, Easing.OutQuint); highlightBox.FadeIn(transition_length, Easing.OutQuint); @@ -141,7 +141,7 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1), transition_length, Easing.OutQuint); - closeButton?.MoveToX(5f, 0.5f, Easing.InElastic); + closeButton.MoveToX(5f, 0.5f, Easing.InElastic); box.FadeColour(backgroundInactive, transition_length, Easing.OutQuint); highlightBox.FadeOut(transition_length, Easing.OutQuint); @@ -151,7 +151,8 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(InputState state) { - closeButton?.FadeIn(1f, Easing.InBounce); + if (IsRemovable) + closeButton.FadeIn(1f, Easing.InBounce); if (!Active) box.FadeColour(backgroundHover, transition_length, Easing.OutQuint); @@ -160,7 +161,9 @@ namespace osu.Game.Overlays.Chat protected override void OnHoverLost(InputState state) { - closeButton?.FadeOut(1f, Easing.OutBounce); + if (closeButton.IsPresent) + closeButton.FadeOut(1f, Easing.OutBounce); + updateState(); } @@ -250,25 +253,21 @@ namespace osu.Game.Overlays.Chat Font = @"Exo2.0-Bold", TextSize = 18, }, + closeButton = new Button + { + Alpha = 0, + Width = 20, + Height = 20, + Margin = new MarginPadding { Right = 10 }, + Origin = Anchor.CentreRight, + Anchor = Anchor.CentreRight, + Text = @"x", + BackgroundColour = Color4.Transparent, + Action = delegate { if (IsRemovable) OnRequestClose?.Invoke(); }, + }, }, }, }; - - if (IsRemovable) - { - Add(closeButton = new Button - { - Alpha = 0, - Width = 20, - Height = 20, - Margin = new MarginPadding { Right = 10 }, - Origin = Anchor.CentreRight, - Anchor = Anchor.CentreRight, - Text = @"x", - BackgroundColour = Color4.Transparent, - Action = () => OnRequestClose?.Invoke(), - }); - } } public class ChannelSelectorTabItem : ChannelTabItem From 6291bd5ced4d8834afbb7b8e9ec5d90e575106a9 Mon Sep 17 00:00:00 2001 From: naoey Date: Thu, 24 Aug 2017 10:40:42 +0530 Subject: [PATCH 168/483] Handle null current channel in setter, update framework. --- osu-framework | 2 +- osu.Game/Overlays/ChatOverlay.cs | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/osu-framework b/osu-framework index 1ba1e8ef1e..d492c2ffe6 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 1ba1e8ef1e5ec0466632be02492023a081cb85ab +Subproject commit d492c2ffe6ce5dac2a8e05118d86e6907186329b diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 38432860c3..b20019ed1a 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -334,7 +334,15 @@ namespace osu.Game.Overlays set { - if (currentChannel == value || value == null) return; + if (currentChannel == value) return; + + if (value == null) + { + currentChannel = null; + textbox.Current.Disabled = true; + currentChannelContainer.Clear(false); + return; + } currentChannel = value; @@ -397,11 +405,7 @@ namespace osu.Game.Overlays { if (channel == null) return; - if (channel == CurrentChannel) - { - currentChannel = null; - currentChannelContainer.Clear(false); - } + if (channel == CurrentChannel) CurrentChannel = null; careChannels.Remove(channel); loadedChannels.Remove(loadedChannels.Find(c => c.Channel == channel)); From 189988236b91f63b5e374f9289025ac938cebf4d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 15:23:17 +0900 Subject: [PATCH 169/483] Move PlayerInputManager logic inside RulesetInputManager --- osu.Game/Rulesets/UI/RulesetContainer.cs | 20 +-- osu.Game/Rulesets/UI/RulesetInputManager.cs | 163 +++++++++++++++++++- osu.Game/Screens/Play/PlayerInputManager.cs | 140 ----------------- osu.Game/osu.Game.csproj | 1 - 4 files changed, 169 insertions(+), 155 deletions(-) delete mode 100644 osu.Game/Screens/Play/PlayerInputManager.cs diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 84cadeb2a1..0a16335c77 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -9,7 +9,6 @@ using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Screens.Play; using System; using System.Collections.Generic; using System.Diagnostics; @@ -43,7 +42,7 @@ namespace osu.Game.Rulesets.UI /// /// The input manager for this RulesetContainer. /// - internal readonly PlayerInputManager InputManager = new PlayerInputManager(); + internal IHasReplayHandler ReplayInputManager => (IHasReplayHandler)KeyBindingInputManager; /// /// The key conversion input manager for this RulesetContainer. @@ -58,7 +57,7 @@ namespace osu.Game.Rulesets.UI /// /// Whether we have a replay loaded currently. /// - public bool HasReplayLoaded => InputManager.ReplayInputHandler != null; + public bool HasReplayLoaded => ReplayInputManager.ReplayInputHandler != null; public abstract IEnumerable Objects { get; } @@ -76,11 +75,7 @@ namespace osu.Game.Rulesets.UI internal RulesetContainer(Ruleset ruleset) { Ruleset = ruleset; - } - [BackgroundDependencyLoader] - private void load() - { KeyBindingInputManager = CreateInputManager(); KeyBindingInputManager.RelativeSizeAxes = Axes.Both; } @@ -113,7 +108,7 @@ namespace osu.Game.Rulesets.UI public virtual void SetReplay(Replay replay) { Replay = replay; - InputManager.ReplayInputHandler = replay != null ? CreateReplayInputHandler(replay) : null; + ReplayInputManager.ReplayInputHandler = replay != null ? CreateReplayInputHandler(replay) : null; } } @@ -267,13 +262,12 @@ namespace osu.Game.Rulesets.UI [BackgroundDependencyLoader] private void load() { - InputManager.Add(content = new Container + KeyBindingInputManager.Add(content = new Container { RelativeSizeAxes = Axes.Both, - Children = new[] { KeyBindingInputManager } }); - AddInternal(InputManager); + AddInternal(KeyBindingInputManager); KeyBindingInputManager.Add(Playfield = CreatePlayfield()); loadObjects(); @@ -283,8 +277,8 @@ namespace osu.Game.Rulesets.UI { base.SetReplay(replay); - if (InputManager?.ReplayInputHandler != null) - InputManager.ReplayInputHandler.ToScreenSpace = Playfield.ScaledContent.ToScreenSpace; + if (ReplayInputManager?.ReplayInputHandler != null) + ReplayInputManager.ReplayInputHandler.ToScreenSpace = input => Playfield.ScaledContent.ToScreenSpace(input); } /// diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 6d22b2e91e..bd7e51e937 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -1,20 +1,176 @@ // Copyright (c) 2007-2017 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.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Input; using osu.Framework.Input.Bindings; +using osu.Framework.Timing; +using osu.Game.Configuration; using osu.Game.Input.Bindings; +using osu.Game.Input.Handlers; using osu.Game.Screens.Play; +using OpenTK.Input; namespace osu.Game.Rulesets.UI { - public abstract class RulesetInputManager : DatabasedKeyBindingInputManager, ICanAttachKeyCounter + public abstract class RulesetInputManager : DatabasedKeyBindingInputManager, ICanAttachKeyCounter, IHasReplayHandler where T : struct { protected RulesetInputManager(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) : base(ruleset, variant, unique) { } + private List lastPressedActions = new List(); + + protected override void HandleNewState(InputState state) + { + base.HandleNewState(state); + + var replayState = state as ReplayInputHandler.ReplayState; + + if (replayState == null) return; + + // Here we handle states specifically coming from a replay source. + // These have extra action information rather than keyboard keys or mouse buttons. + + List newActions = replayState.PressedActions; + + foreach (var released in lastPressedActions.Except(newActions)) + PropagateReleased(KeyBindingInputQueue, released); + + foreach (var pressed in newActions.Except(lastPressedActions)) + PropagatePressed(KeyBindingInputQueue, pressed); + + lastPressedActions = newActions; + } + + private ManualClock clock; + private IFrameBasedClock parentClock; + + private ReplayInputHandler replayInputHandler; + public ReplayInputHandler ReplayInputHandler + { + get + { + return replayInputHandler; + } + set + { + if (replayInputHandler != null) RemoveHandler(replayInputHandler); + + replayInputHandler = value; + UseParentState = replayInputHandler == null; + + if (replayInputHandler != null) + AddHandler(replayInputHandler); + } + } + + private Bindable mouseDisabled; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + mouseDisabled = config.GetBindable(OsuSetting.MouseDisableButtons); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + //our clock will now be our parent's clock, but we want to replace this to allow manual control. + parentClock = Clock; + + Clock = new FramedClock(clock = new ManualClock + { + CurrentTime = parentClock.CurrentTime, + Rate = parentClock.Rate, + }); + } + + /// + /// Whether we running up-to-date with our parent clock. + /// If not, we will need to keep processing children until we catch up. + /// + private bool requireMoreUpdateLoops; + + /// + /// Whether we in a valid state (ie. should we keep processing children frames). + /// This should be set to false when the replay is, for instance, waiting for future frames to arrive. + /// + private bool validState; + + protected override bool RequiresChildrenUpdate => base.RequiresChildrenUpdate && validState; + + private bool isAttached => replayInputHandler != null && !UseParentState; + + private const int max_catch_up_updates_per_frame = 50; + + public override bool UpdateSubTree() + { + requireMoreUpdateLoops = true; + validState = true; + + int loops = 0; + + while (validState && requireMoreUpdateLoops && loops++ < max_catch_up_updates_per_frame) + if (!base.UpdateSubTree()) + return false; + + return true; + } + + protected override void Update() + { + if (parentClock == null) return; + + clock.Rate = parentClock.Rate; + clock.IsRunning = parentClock.IsRunning; + + if (!isAttached) + { + clock.CurrentTime = parentClock.CurrentTime; + } + else + { + double? newTime = replayInputHandler.SetFrameFromTime(parentClock.CurrentTime); + + if (newTime == null) + { + // we shouldn't execute for this time value. probably waiting on more replay data. + validState = false; + return; + } + + clock.CurrentTime = newTime.Value; + } + + requireMoreUpdateLoops = clock.CurrentTime != parentClock.CurrentTime; + base.Update(); + } + + protected override void TransformState(InputState state) + { + base.TransformState(state); + + // we don't want to transform the state if a replay is present (for now, at least). + if (replayInputHandler != null) return; + + var mouse = state.Mouse as Framework.Input.MouseState; + + if (mouse != null) + { + if (mouseDisabled.Value) + { + mouse.SetPressed(MouseButton.Left, false); + mouse.SetPressed(MouseButton.Right, false); + } + } + } + public void Attach(KeyCounterCollection keyCounter) { var receptor = new ActionReceptor(keyCounter); @@ -37,6 +193,11 @@ namespace osu.Game.Rulesets.UI } } + public interface IHasReplayHandler + { + ReplayInputHandler ReplayInputHandler { get; set; } + } + public interface ICanAttachKeyCounter { void Attach(KeyCounterCollection keyCounter); diff --git a/osu.Game/Screens/Play/PlayerInputManager.cs b/osu.Game/Screens/Play/PlayerInputManager.cs deleted file mode 100644 index f5e57f9e9d..0000000000 --- a/osu.Game/Screens/Play/PlayerInputManager.cs +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using OpenTK.Input; -using osu.Framework.Allocation; -using osu.Framework.Configuration; -using osu.Framework.Input; -using osu.Framework.Timing; -using osu.Game.Configuration; -using osu.Game.Input.Handlers; - -namespace osu.Game.Screens.Play -{ - public class PlayerInputManager : PassThroughInputManager - { - private ManualClock clock; - private IFrameBasedClock parentClock; - - private ReplayInputHandler replayInputHandler; - public ReplayInputHandler ReplayInputHandler - { - get - { - return replayInputHandler; - } - set - { - if (replayInputHandler != null) RemoveHandler(replayInputHandler); - - replayInputHandler = value; - UseParentState = replayInputHandler == null; - - if (replayInputHandler != null) - AddHandler(replayInputHandler); - } - } - - private Bindable mouseDisabled; - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - mouseDisabled = config.GetBindable(OsuSetting.MouseDisableButtons); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - //our clock will now be our parent's clock, but we want to replace this to allow manual control. - parentClock = Clock; - - Clock = new FramedClock(clock = new ManualClock - { - CurrentTime = parentClock.CurrentTime, - Rate = parentClock.Rate, - }); - } - - /// - /// Whether we running up-to-date with our parent clock. - /// If not, we will need to keep processing children until we catch up. - /// - private bool requireMoreUpdateLoops; - - /// - /// Whether we in a valid state (ie. should we keep processing children frames). - /// This should be set to false when the replay is, for instance, waiting for future frames to arrive. - /// - private bool validState; - - protected override bool RequiresChildrenUpdate => base.RequiresChildrenUpdate && validState; - - private bool isAttached => replayInputHandler != null && !UseParentState; - - private const int max_catch_up_updates_per_frame = 50; - - public override bool UpdateSubTree() - { - requireMoreUpdateLoops = true; - validState = true; - - int loops = 0; - - while (validState && requireMoreUpdateLoops && loops++ < max_catch_up_updates_per_frame) - if (!base.UpdateSubTree()) - return false; - - return true; - } - - protected override void Update() - { - if (parentClock == null) return; - - clock.Rate = parentClock.Rate; - clock.IsRunning = parentClock.IsRunning; - - if (!isAttached) - { - clock.CurrentTime = parentClock.CurrentTime; - } - else - { - double? newTime = replayInputHandler.SetFrameFromTime(parentClock.CurrentTime); - - if (newTime == null) - { - // we shouldn't execute for this time value. probably waiting on more replay data. - validState = false; - return; - } - - clock.CurrentTime = newTime.Value; - } - - requireMoreUpdateLoops = clock.CurrentTime != parentClock.CurrentTime; - base.Update(); - } - - protected override void TransformState(InputState state) - { - base.TransformState(state); - - // we don't want to transform the state if a replay is present (for now, at least). - if (replayInputHandler != null) return; - - var mouse = state.Mouse as Framework.Input.MouseState; - - if (mouse != null) - { - if (mouseDisabled.Value) - { - mouse.SetPressed(MouseButton.Left, false); - mouse.SetPressed(MouseButton.Right, false); - } - } - } - } -} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 32a8df6357..4e9e769cb7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -321,7 +321,6 @@ - From a7a7e0323f8ff199d10b3ccb11d6c3c9539348b8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 15:36:42 +0900 Subject: [PATCH 170/483] Update autoplay and replay handling to result in actions, not keys --- .../Replays/OsuReplayInputHandler.cs | 32 +++++++++++++++++++ .../UI/OsuRulesetContainer.cs | 4 +++ .../osu.Game.Rulesets.Osu.csproj | 1 + .../Replays/TaikoFramedReplayInputHandler.cs | 16 ++++------ osu.Game/Input/Handlers/ReplayInputHandler.cs | 15 +++++++++ .../Replays/FramedReplayInputHandler.cs | 28 +++------------- osu.Game/Rulesets/UI/RulesetContainer.cs | 2 +- 7 files changed, 64 insertions(+), 34 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs diff --git a/osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs b/osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs new file mode 100644 index 0000000000..a54679b8cc --- /dev/null +++ b/osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using osu.Framework.Input; +using osu.Game.Rulesets.Replays; +using OpenTK; + +namespace osu.Game.Rulesets.Osu.Replays +{ + public class OsuReplayInputHandler : FramedReplayInputHandler + { + public OsuReplayInputHandler(Replay replay) + : base(replay) + { + } + + public override List GetPendingStates() + { + List actions = new List(); + + if (CurrentFrame?.MouseLeft ?? false) actions.Add(OsuAction.LeftButton); + if (CurrentFrame?.MouseRight ?? false) actions.Add(OsuAction.RightButton); + + return new List + { + new ReplayState + { + Mouse = new ReplayMouseState(ToScreenSpace(Position ?? Vector2.Zero)), + PressedActions = actions + } + }; + } + } +} diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs index 083f11945c..0b87bf7346 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs @@ -10,9 +10,11 @@ using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; +using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Osu.UI { @@ -49,6 +51,8 @@ namespace osu.Game.Rulesets.Osu.UI return null; } + protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new OsuReplayInputHandler(replay); + protected override Vector2 GetPlayfieldAspectAdjust() => new Vector2(0.75f); } } diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index 1422ded407..0c9e53cf69 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -78,6 +78,7 @@ + diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs index f6425dd66f..89093ae05e 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs @@ -4,7 +4,6 @@ using osu.Game.Rulesets.Replays; using System.Collections.Generic; using osu.Framework.Input; -using OpenTK.Input; namespace osu.Game.Rulesets.Taiko.Replays { @@ -17,21 +16,18 @@ namespace osu.Game.Rulesets.Taiko.Replays public override List GetPendingStates() { - var keys = new List(); + var keys = new List(); if (CurrentFrame?.MouseRight1 == true) - keys.Add(Key.F); + keys.Add(TaikoAction.LeftCentre); if (CurrentFrame?.MouseRight2 == true) - keys.Add(Key.J); + keys.Add(TaikoAction.RightCentre); if (CurrentFrame?.MouseLeft1 == true) - keys.Add(Key.D); + keys.Add(TaikoAction.LeftRim); if (CurrentFrame?.MouseLeft2 == true) - keys.Add(Key.K); + keys.Add(TaikoAction.RightRim); - return new List - { - new InputState { Keyboard = new ReplayKeyboardState(keys) } - }; + return new List { new ReplayState { PressedActions = keys } }; } } } diff --git a/osu.Game/Input/Handlers/ReplayInputHandler.cs b/osu.Game/Input/Handlers/ReplayInputHandler.cs index 76e038048c..5f86495580 100644 --- a/osu.Game/Input/Handlers/ReplayInputHandler.cs +++ b/osu.Game/Input/Handlers/ReplayInputHandler.cs @@ -2,6 +2,8 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; +using osu.Framework.Input; using osu.Framework.Input.Handlers; using osu.Framework.Platform; using OpenTK; @@ -29,5 +31,18 @@ namespace osu.Game.Input.Handlers public override bool IsActive => true; public override int Priority => 0; + + public class ReplayState : InputState + where T : struct + { + public List PressedActions; + + public override InputState Clone() + { + var clone = (ReplayState)base.Clone(); + clone.PressedActions = new List(PressedActions); + return clone; + } + } } } \ No newline at end of file diff --git a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs index 60da35fd91..f0d68c0467 100644 --- a/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs +++ b/osu.Game/Rulesets/Replays/FramedReplayInputHandler.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Input; using osu.Framework.MathUtils; using osu.Game.Input.Handlers; @@ -18,7 +17,7 @@ namespace osu.Game.Rulesets.Replays /// The ReplayHandler will take a replay and handle the propagation of updates to the input stack. /// It handles logic of any frames which *must* be executed. /// - public class FramedReplayInputHandler : ReplayInputHandler + public abstract class FramedReplayInputHandler : ReplayInputHandler { private readonly Replay replay; @@ -31,7 +30,7 @@ namespace osu.Game.Rulesets.Replays private int nextFrameIndex => MathHelper.Clamp(currentFrameIndex + (currentDirection > 0 ? 1 : -1), 0, Frames.Count - 1); - public FramedReplayInputHandler(Replay replay) + protected FramedReplayInputHandler(Replay replay) { this.replay = replay; } @@ -51,7 +50,7 @@ namespace osu.Game.Rulesets.Replays { } - private Vector2? position + protected Vector2? Position { get { @@ -62,23 +61,7 @@ namespace osu.Game.Rulesets.Replays } } - public override List GetPendingStates() - { - var buttons = new HashSet(); - if (CurrentFrame?.MouseLeft ?? false) - buttons.Add(MouseButton.Left); - if (CurrentFrame?.MouseRight ?? false) - buttons.Add(MouseButton.Right); - - return new List - { - new InputState - { - Mouse = new ReplayMouseState(ToScreenSpace(position ?? Vector2.Zero), buttons), - Keyboard = new ReplayKeyboardState(new List()) - } - }; - } + public override List GetPendingStates() => new List(); public bool AtLastFrame => currentFrameIndex == Frames.Count - 1; public bool AtFirstFrame => currentFrameIndex == 0; @@ -133,10 +116,9 @@ namespace osu.Game.Rulesets.Replays protected class ReplayMouseState : MouseState { - public ReplayMouseState(Vector2 position, IEnumerable list) + public ReplayMouseState(Vector2 position) { Position = position; - list.ForEach(b => SetPressed(b, true)); } } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 0a16335c77..17417856a1 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -97,7 +97,7 @@ namespace osu.Game.Rulesets.UI /// The input manager. public abstract PassThroughInputManager CreateInputManager(); - protected virtual FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new FramedReplayInputHandler(replay); + protected virtual FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => null; public Replay Replay { get; private set; } From f0635af40deeae8f3c44bcd328a9a39a6c9c7583 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 15:48:40 +0900 Subject: [PATCH 171/483] Add documentation and regions to RulesetInputManager --- osu.Game/Rulesets/UI/RulesetInputManager.cs | 43 +++++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index bd7e51e937..75e273adea 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -23,6 +23,8 @@ namespace osu.Game.Rulesets.UI { } + #region Action mapping (for replays) + private List lastPressedActions = new List(); protected override void HandleNewState(InputState state) @@ -47,8 +49,9 @@ namespace osu.Game.Rulesets.UI lastPressedActions = newActions; } - private ManualClock clock; - private IFrameBasedClock parentClock; + #endregion + + #region IHasReplayHandler private ReplayInputHandler replayInputHandler; public ReplayInputHandler ReplayInputHandler @@ -69,13 +72,12 @@ namespace osu.Game.Rulesets.UI } } - private Bindable mouseDisabled; + #endregion - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - mouseDisabled = config.GetBindable(OsuSetting.MouseDisableButtons); - } + #region Clock control + + private ManualClock clock; + private IFrameBasedClock parentClock; protected override void LoadComplete() { @@ -152,6 +154,18 @@ namespace osu.Game.Rulesets.UI base.Update(); } + #endregion + + #region Setting application (disables etc.) + + private Bindable mouseDisabled; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + mouseDisabled = config.GetBindable(OsuSetting.MouseDisableButtons); + } + protected override void TransformState(InputState state) { base.TransformState(state); @@ -171,6 +185,10 @@ namespace osu.Game.Rulesets.UI } } + #endregion + + #region Key Counter Attachment + public void Attach(KeyCounterCollection keyCounter) { var receptor = new ActionReceptor(keyCounter); @@ -191,13 +209,22 @@ namespace osu.Game.Rulesets.UI public bool OnReleased(T action) => Target.Children.OfType>().Any(c => c.OnReleased(action)); } + + #endregion } + /// + /// Expose the in a capable . + /// public interface IHasReplayHandler { ReplayInputHandler ReplayInputHandler { get; set; } } + /// + /// Supports attaching a . + /// Keys will be populated automatically and a receptor will be injected inside. + /// public interface ICanAttachKeyCounter { void Attach(KeyCounterCollection keyCounter); From 511fccdba733a8f70112024fd9a182ac636342c8 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 24 Aug 2017 17:28:47 +0900 Subject: [PATCH 172/483] Add editor menu bar test case. --- osu-framework | 2 +- .../Visual/TestCaseEditorMenuBar.cs | 184 ++++++++++++++++++ osu.Desktop.Tests/osu.Desktop.Tests.csproj | 1 + 3 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs diff --git a/osu-framework b/osu-framework index 1ba1e8ef1e..fbbcd942e2 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 1ba1e8ef1e5ec0466632be02492023a081cb85ab +Subproject commit fbbcd942e262778b166acde2cc89a10782734f2d diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs new file mode 100644 index 0000000000..455c25f385 --- /dev/null +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -0,0 +1,184 @@ +// Copyright (c) 2007-2017 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Testing; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; + +namespace osu.Desktop.Tests.Visual +{ + public class TestCaseEditorMenuBar : TestCase + { + public TestCaseEditorMenuBar() + { + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 500, + Child = new EditorMenuBar + { + Items = new[] + { + new EditorMenuBarItem("File") + { + Items = new OsuContextMenuItem[] + { + new EditorContextMenuItem("Clear All Notes"), + new EditorContextMenuItem("Open Difficulty..."), + new EditorContextMenuItem("Save"), + new EditorContextMenuItem("Create a new Difficulty..."), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Revert to Saved"), + new EditorContextMenuItem("Revert to Saved (Full)"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Test Beatmap"), + new EditorContextMenuItem("Open AiMod"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Upload Beatmap..."), + new EditorContextMenuItem("Export Package"), + new EditorContextMenuItem("Export Map Package"), + new EditorContextMenuItem("Import from..."), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Open Song Folder"), + new EditorContextMenuItem("Open .osu in Notepad"), + new EditorContextMenuItem("Open .osb in Notepad"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Exit"), + } + }, + new EditorMenuBarItem("Timing") + { + Items = new[] + { + new EditorContextMenuItem("Time Signature"), + new EditorContextMenuItem("Metronome Clicks"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Add Timing Section"), + new EditorContextMenuItem("Add Inheriting Section"), + new EditorContextMenuItem("Reset Current Section"), + new EditorContextMenuItem("Delete Timing Section"), + new EditorContextMenuItem("Resnap Current Section"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Timing Setup"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Resnap All Notes", MenuItemType.Destructive), + new EditorContextMenuItem("Move all notes in time...", MenuItemType.Destructive), + new EditorContextMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), + new EditorContextMenuItem("Delete All Timing Sections", MenuItemType.Destructive), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Set Current Position as Preview Point"), + } + }, + new EditorMenuBarItem("Testing") + { + Items = new[] + { + new EditorContextMenuItem("Item 1"), + new EditorContextMenuItem("Item 2"), + new EditorContextMenuItem("Item 3"), + } + }, + } + } + }); + } + } + + public class EditorMenuBar : MenuBar + { + } + + public class EditorMenuBarItem : MenuBarItem + { + private const int fade_duration = 250; + private const float text_size = 17; + + private readonly Container background; + + private Color4 normalColour; + + public EditorMenuBarItem(string title) + : base(title) + { + Content.Padding = new MarginPadding(8); + + AddInternal(background = new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Depth = float.MaxValue, + Alpha = 0, + Child = new Container + { + // The following is done so we can have top rounded corners but not bottom corners + RelativeSizeAxes = Axes.Both, + Height = 2, + Masking = true, + CornerRadius = 5, + Child = new Box { RelativeSizeAxes = Axes.Both } + } + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray3; + ContextMenu.Menu.Background.Colour = colours.Gray3; + TitleText.Colour = normalColour = colours.BlueLight; + } + + public override void Open() + { + base.Open(); + + background.FadeIn(fade_duration, Easing.OutQuint); + TitleText.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + } + + public override void Close() + { + base.Close(); + + background.FadeOut(fade_duration, Easing.OutQuint); + TitleText.FadeColour(normalColour, fade_duration, Easing.OutQuint); + } + + protected override SpriteText CreateTitleText() => new OsuSpriteText { TextSize = text_size }; + + protected override ContextMenu CreateContextMenu() => new OsuContextMenu + { + OriginPosition = new Vector2(8, 0) + }; + } + + public class EditorContextMenuSpacer : EditorContextMenuItem + { + public override bool HandleInput => false; + + public EditorContextMenuSpacer() + : base(" ") + { + } + } + + public class EditorContextMenuItem : OsuContextMenuItem + { + private const int min_text_length = 40; + + public EditorContextMenuItem(string title, MenuItemType type = MenuItemType.Standard) + : base(title.PadRight(min_text_length), type) + { + } + } +} diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj index 24d112a45c..86268e6110 100644 --- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj +++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj @@ -87,6 +87,7 @@ + From 76a95495d36e8069159775cc82a008317c47abc0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 17:30:10 +0900 Subject: [PATCH 173/483] Move shared code to base class --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 11 ----------- osu.Game/Overlays/Direct/DirectListPanel.cs | 15 --------------- osu.Game/Overlays/Direct/DirectPanel.cs | 17 +++++++++++++++++ 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 98ab5e88f8..822edd02df 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -26,22 +26,11 @@ namespace osu.Game.Overlays.Direct { Height = 140 + vertical_padding; //full height of all the elements plus vertical padding (autosize uses the image) CornerRadius = 4; - Masking = true; - - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Offset = new Vector2(0f, 1f), - Radius = 3f, - Colour = Color4.Black.Opacity(0.25f), - }; } protected override void LoadComplete() { base.LoadComplete(); - - this.FadeInFromZero(200, Easing.Out); bottomPanel.LayoutDuration = 200; bottomPanel.LayoutEasing = Easing.Out; bottomPanel.Origin = Anchor.BottomLeft; diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 5b45fc7725..0821fbea3a 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -29,21 +29,6 @@ namespace osu.Game.Overlays.Direct RelativeSizeAxes = Axes.X; Height = height; CornerRadius = 5; - Masking = true; - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Offset = new Vector2(0f, 1f), - Radius = 3f, - Colour = Color4.Black.Opacity(0.25f), - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - this.FadeInFromZero(200, Easing.Out); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 2f048b0e3d..9395e6817d 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Framework.Extensions.Color4Extensions; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -10,6 +11,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using OpenTK.Graphics; namespace osu.Game.Overlays.Direct { @@ -20,6 +22,21 @@ namespace osu.Game.Overlays.Direct protected DirectPanel(BeatmapSetInfo setInfo) { SetInfo = setInfo; + + Masking = true; + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Offset = new Vector2(0f, 1f), + Radius = 3f, + Colour = Color4.Black.Opacity(0.25f), + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + this.FadeInFromZero(200, Easing.Out); } protected List GetDifficultyIcons() From 26a4238a383a034feca20a3c586476d41832b57b Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 24 Aug 2017 17:31:23 +0900 Subject: [PATCH 174/483] Make classes private for now. --- .../Visual/TestCaseEditorMenuBar.cs | 146 +++++++++--------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 455c25f385..7c46107365 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -92,93 +92,93 @@ namespace osu.Desktop.Tests.Visual } }); } - } - public class EditorMenuBar : MenuBar - { - } - - public class EditorMenuBarItem : MenuBarItem - { - private const int fade_duration = 250; - private const float text_size = 17; - - private readonly Container background; - - private Color4 normalColour; - - public EditorMenuBarItem(string title) - : base(title) + private class EditorMenuBar : MenuBar { - Content.Padding = new MarginPadding(8); + } - AddInternal(background = new Container + private class EditorMenuBarItem : MenuBarItem + { + private const int fade_duration = 250; + private const float text_size = 17; + + private readonly Container background; + + private Color4 normalColour; + + public EditorMenuBarItem(string title) + : base(title) { - RelativeSizeAxes = Axes.Both, - Masking = true, - Depth = float.MaxValue, - Alpha = 0, - Child = new Container + Content.Padding = new MarginPadding(8); + + AddInternal(background = new Container { - // The following is done so we can have top rounded corners but not bottom corners RelativeSizeAxes = Axes.Both, - Height = 2, Masking = true, - CornerRadius = 5, - Child = new Box { RelativeSizeAxes = Axes.Both } - } - }); + Depth = float.MaxValue, + Alpha = 0, + Child = new Container + { + // The following is done so we can have top rounded corners but not bottom corners + RelativeSizeAxes = Axes.Both, + Height = 2, + Masking = true, + CornerRadius = 5, + Child = new Box { RelativeSizeAxes = Axes.Both } + } + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray3; + ContextMenu.Menu.Background.Colour = colours.Gray3; + TitleText.Colour = normalColour = colours.BlueLight; + } + + public override void Open() + { + base.Open(); + + background.FadeIn(fade_duration, Easing.OutQuint); + TitleText.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + } + + public override void Close() + { + base.Close(); + + background.FadeOut(fade_duration, Easing.OutQuint); + TitleText.FadeColour(normalColour, fade_duration, Easing.OutQuint); + } + + protected override SpriteText CreateTitleText() => new OsuSpriteText { TextSize = text_size }; + + protected override ContextMenu CreateContextMenu() => new OsuContextMenu + { + OriginPosition = new Vector2(8, 0) + }; } - [BackgroundDependencyLoader] - private void load(OsuColour colours) + private class EditorContextMenuSpacer : EditorContextMenuItem { - background.Colour = colours.Gray3; - ContextMenu.Menu.Background.Colour = colours.Gray3; - TitleText.Colour = normalColour = colours.BlueLight; + public override bool HandleInput => false; + + public EditorContextMenuSpacer() + : base(" ") + { + } } - public override void Open() + private class EditorContextMenuItem : OsuContextMenuItem { - base.Open(); + private const int min_text_length = 40; - background.FadeIn(fade_duration, Easing.OutQuint); - TitleText.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - } - - public override void Close() - { - base.Close(); - - background.FadeOut(fade_duration, Easing.OutQuint); - TitleText.FadeColour(normalColour, fade_duration, Easing.OutQuint); - } - - protected override SpriteText CreateTitleText() => new OsuSpriteText { TextSize = text_size }; - - protected override ContextMenu CreateContextMenu() => new OsuContextMenu - { - OriginPosition = new Vector2(8, 0) - }; - } - - public class EditorContextMenuSpacer : EditorContextMenuItem - { - public override bool HandleInput => false; - - public EditorContextMenuSpacer() - : base(" ") - { - } - } - - public class EditorContextMenuItem : OsuContextMenuItem - { - private const int min_text_length = 40; - - public EditorContextMenuItem(string title, MenuItemType type = MenuItemType.Standard) - : base(title.PadRight(min_text_length), type) - { + public EditorContextMenuItem(string title, MenuItemType type = MenuItemType.Standard) + : base(title.PadRight(min_text_length), type) + { + } } } } From 4e1cf329c88628cfaa537dd81c420c3350534e6d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 17:39:39 +0900 Subject: [PATCH 175/483] Move background logic to base class; reduce overdraw after set fades in --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 10 ++------- osu.Game/Overlays/Direct/DirectPanel.cs | 25 ++++++++++++++++++++- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 822edd02df..5b648633c1 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -39,14 +39,8 @@ namespace osu.Game.Overlays.Direct [BackgroundDependencyLoader] private void load(OsuColour colours, LocalisationEngine localisation) { - Children = new[] + AddRange(new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }, - CreateBackground(), new Box { RelativeSizeAxes = Axes.Both, @@ -174,7 +168,7 @@ namespace osu.Game.Overlays.Direct new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), }, }, - }; + }); } } } diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 9395e6817d..a56c15b532 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -2,10 +2,12 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; @@ -19,6 +21,8 @@ namespace osu.Game.Overlays.Direct { protected readonly BeatmapSetInfo SetInfo; + protected Box BlackBackground; + protected DirectPanel(BeatmapSetInfo setInfo) { SetInfo = setInfo; @@ -33,6 +37,21 @@ namespace osu.Game.Overlays.Direct }; } + [BackgroundDependencyLoader] + private void load() + { + AddRange(new[] + { + // temporary blackness until the actual background loads. + BlackBackground = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + CreateBackground(), + }); + } + protected override void LoadComplete() { base.LoadComplete(); @@ -55,7 +74,11 @@ namespace osu.Game.Overlays.Direct Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fill, - OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out), + OnLoadComplete = d => + { + d.FadeInFromZero(400, Easing.Out); + BlackBackground.Delay(400).FadeOut(); + }, }) { RelativeSizeAxes = Axes.Both, From a863eb2a2ffef640a85be6e287de46980af71a1f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 24 Aug 2017 17:43:56 +0900 Subject: [PATCH 176/483] Add EditorMenuBarItem colours. --- osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 7c46107365..8d14f5f2df 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -31,7 +31,7 @@ namespace osu.Desktop.Tests.Visual { new EditorMenuBarItem("File") { - Items = new OsuContextMenuItem[] + Items = new[] { new EditorContextMenuItem("Clear All Notes"), new EditorContextMenuItem("Open Difficulty..."), @@ -179,6 +179,13 @@ namespace osu.Desktop.Tests.Visual : base(title.PadRight(min_text_length), type) { } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + BackgroundColourHover = colours.Gray2; + } } } } From c39bb6e64777933287fabcf1f7a6b25945638ba2 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 24 Aug 2017 17:50:22 +0900 Subject: [PATCH 177/483] Pretty-ifying test case. --- .../Visual/TestCaseEditorMenuBar.cs | 127 +++++++++--------- 1 file changed, 60 insertions(+), 67 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 8d14f5f2df..49a382c9f9 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -20,83 +20,76 @@ namespace osu.Desktop.Tests.Visual { public TestCaseEditorMenuBar() { - Add(new Container + Add(new MenuBar { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Width = 500, - Child = new EditorMenuBar + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Y = 50, + Items = new[] { - Items = new[] + new EditorMenuBarItem("File") { - new EditorMenuBarItem("File") + Items = new[] { - Items = new[] - { - new EditorContextMenuItem("Clear All Notes"), - new EditorContextMenuItem("Open Difficulty..."), - new EditorContextMenuItem("Save"), - new EditorContextMenuItem("Create a new Difficulty..."), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Revert to Saved"), - new EditorContextMenuItem("Revert to Saved (Full)"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Test Beatmap"), - new EditorContextMenuItem("Open AiMod"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Upload Beatmap..."), - new EditorContextMenuItem("Export Package"), - new EditorContextMenuItem("Export Map Package"), - new EditorContextMenuItem("Import from..."), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Open Song Folder"), - new EditorContextMenuItem("Open .osu in Notepad"), - new EditorContextMenuItem("Open .osb in Notepad"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Exit"), - } - }, - new EditorMenuBarItem("Timing") + new EditorContextMenuItem("Clear All Notes"), + new EditorContextMenuItem("Open Difficulty..."), + new EditorContextMenuItem("Save"), + new EditorContextMenuItem("Create a new Difficulty..."), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Revert to Saved"), + new EditorContextMenuItem("Revert to Saved (Full)"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Test Beatmap"), + new EditorContextMenuItem("Open AiMod"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Upload Beatmap..."), + new EditorContextMenuItem("Export Package"), + new EditorContextMenuItem("Export Map Package"), + new EditorContextMenuItem("Import from..."), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Open Song Folder"), + new EditorContextMenuItem("Open .osu in Notepad"), + new EditorContextMenuItem("Open .osb in Notepad"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Exit"), + } + }, + new EditorMenuBarItem("Timing") + { + Items = new[] { - Items = new[] - { - new EditorContextMenuItem("Time Signature"), - new EditorContextMenuItem("Metronome Clicks"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Add Timing Section"), - new EditorContextMenuItem("Add Inheriting Section"), - new EditorContextMenuItem("Reset Current Section"), - new EditorContextMenuItem("Delete Timing Section"), - new EditorContextMenuItem("Resnap Current Section"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Timing Setup"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Resnap All Notes", MenuItemType.Destructive), - new EditorContextMenuItem("Move all notes in time...", MenuItemType.Destructive), - new EditorContextMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), - new EditorContextMenuItem("Delete All Timing Sections", MenuItemType.Destructive), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Set Current Position as Preview Point"), - } - }, - new EditorMenuBarItem("Testing") + new EditorContextMenuItem("Time Signature"), + new EditorContextMenuItem("Metronome Clicks"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Add Timing Section"), + new EditorContextMenuItem("Add Inheriting Section"), + new EditorContextMenuItem("Reset Current Section"), + new EditorContextMenuItem("Delete Timing Section"), + new EditorContextMenuItem("Resnap Current Section"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Timing Setup"), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Resnap All Notes", MenuItemType.Destructive), + new EditorContextMenuItem("Move all notes in time...", MenuItemType.Destructive), + new EditorContextMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), + new EditorContextMenuItem("Delete All Timing Sections", MenuItemType.Destructive), + new EditorContextMenuSpacer(), + new EditorContextMenuItem("Set Current Position as Preview Point"), + } + }, + new EditorMenuBarItem("Testing") + { + Items = new[] { - Items = new[] - { - new EditorContextMenuItem("Item 1"), - new EditorContextMenuItem("Item 2"), - new EditorContextMenuItem("Item 3"), - } - }, - } + new EditorContextMenuItem("Item 1"), + new EditorContextMenuItem("Item 2"), + new EditorContextMenuItem("Item 3"), + } + }, } }); } - private class EditorMenuBar : MenuBar - { - } - private class EditorMenuBarItem : MenuBarItem { private const int fade_duration = 250; From a2549157ca578f548a4342e7f6d7a3ba0ffcbf90 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 18:18:03 +0900 Subject: [PATCH 178/483] Add hover effects --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 3 +- osu.Game/Overlays/Direct/DirectListPanel.cs | 13 +--- osu.Game/Overlays/Direct/DirectPanel.cs | 85 +++++++++++++++++---- 3 files changed, 76 insertions(+), 25 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 5b648633c1..0cc1c18d8d 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -25,7 +25,6 @@ namespace osu.Game.Overlays.Direct public DirectGridPanel(BeatmapSetInfo beatmap) : base(beatmap) { Height = 140 + vertical_padding; //full height of all the elements plus vertical padding (autosize uses the image) - CornerRadius = 4; } protected override void LoadComplete() @@ -39,6 +38,8 @@ namespace osu.Game.Overlays.Direct [BackgroundDependencyLoader] private void load(OsuColour colours, LocalisationEngine localisation) { + Content.CornerRadius = 4; + AddRange(new Drawable[] { new Box diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 0821fbea3a..d284c50bc4 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -28,20 +28,15 @@ namespace osu.Game.Overlays.Direct { RelativeSizeAxes = Axes.X; Height = height; - CornerRadius = 5; } [BackgroundDependencyLoader] private void load(LocalisationEngine localisation) { - Children = new[] + Content.CornerRadius = 5; + + AddRange(new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }, - CreateBackground(), new Box { RelativeSizeAxes = Axes.Both, @@ -132,7 +127,7 @@ namespace osu.Game.Overlays.Direct }, }, }, - }; + }); } private class DownloadButton : OsuClickableContainer diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index a56c15b532..7e95c1674b 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -9,11 +9,14 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Transforms; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using OpenTK.Graphics; +using osu.Framework.Input; +using osu.Framework.MathUtils; namespace osu.Game.Overlays.Direct { @@ -23,35 +26,62 @@ namespace osu.Game.Overlays.Direct protected Box BlackBackground; + private const double hover_transition_time = 400; + + private Container content; + + protected override Container Content => content; + protected DirectPanel(BeatmapSetInfo setInfo) { SetInfo = setInfo; - - Masking = true; - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Offset = new Vector2(0f, 1f), - Radius = 3f, - Colour = Color4.Black.Opacity(0.25f), - }; } [BackgroundDependencyLoader] private void load() { - AddRange(new[] + AddInternal(content = new Container { - // temporary blackness until the actual background loads. - BlackBackground = new Box + RelativeSizeAxes = Axes.Both, + Masking = true, + EdgeEffect = new EdgeEffectParameters { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, + Type = EdgeEffectType.Shadow, + Offset = new Vector2(0f, 1f), + Radius = 2f, + Colour = Color4.Black.Opacity(0.25f), }, - CreateBackground(), + Children = new[] + { + // temporary blackness until the actual background loads. + BlackBackground = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + CreateBackground(), + } }); } + protected override bool OnHover(InputState state) + { + content.FadeEdgeEffectTo(1f, hover_transition_time, Easing.OutQuint); + content.TransformTo(content.PopulateTransform(new TransformEdgeEffectRadius(), 14, hover_transition_time, Easing.OutQuint)); + content.MoveToY(-4, hover_transition_time, Easing.OutQuint); + + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + content.FadeEdgeEffectTo(0.25f, hover_transition_time, Easing.OutQuint); + content.TransformTo(content.PopulateTransform(new TransformEdgeEffectRadius(), 2, hover_transition_time, Easing.OutQuint)); + content.MoveToY(0, hover_transition_time, Easing.OutQuint); + + base.OnHoverLost(state); + } + protected override void LoadComplete() { base.LoadComplete(); @@ -127,5 +157,30 @@ namespace osu.Game.Overlays.Direct Value = value; } } + + private class TransformEdgeEffectRadius : Transform + { + /// + /// Current value of the transformed colour in linear colour space. + /// + private float 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 => "EdgeEffect.Colour"; + + protected override void Apply(Container c, double time) + { + EdgeEffectParameters e = c.EdgeEffect; + e.Radius = valueAt(time); + c.EdgeEffect = e; + } + + protected override void ReadIntoStartValue(Container d) => StartValue = d.EdgeEffect.Radius; + } } } From 36629f52074162d881c245d2293f139e889b39da Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 18:51:34 +0900 Subject: [PATCH 179/483] Make ProgressBar usable in more places than just MusicController --- .../Graphics/UserInterface/ProgressBar.cs | 67 +++++++++++++++++++ osu.Game/Overlays/MusicController.cs | 45 ------------- osu.Game/osu.Game.csproj | 1 + 3 files changed, 68 insertions(+), 45 deletions(-) create mode 100644 osu.Game/Graphics/UserInterface/ProgressBar.cs diff --git a/osu.Game/Graphics/UserInterface/ProgressBar.cs b/osu.Game/Graphics/UserInterface/ProgressBar.cs new file mode 100644 index 0000000000..f22983a6e6 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/ProgressBar.cs @@ -0,0 +1,67 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using OpenTK.Graphics; + +namespace osu.Game.Graphics.UserInterface +{ + public class ProgressBar : SliderBar + { + public Action OnSeek; + + private readonly Box fill; + private readonly Box background; + + public Color4 FillColour + { + set { fill.Colour = value; } + } + + public Color4 BackgroundColour + { + set + { + background.Alpha = 1; + background.Colour = value; + } + } + + public double EndTime + { + set { CurrentNumber.MaxValue = value; } + } + + public double CurrentTime + { + set { CurrentNumber.Value = value; } + } + + public ProgressBar() + { + CurrentNumber.MinValue = 0; + CurrentNumber.MaxValue = 1; + RelativeSizeAxes = Axes.X; + + Children = new Drawable[] + { + background = new Box + { + Alpha = 0, + RelativeSizeAxes = Axes.Both + }, + fill = new Box { RelativeSizeAxes = Axes.Y } + }; + } + + protected override void UpdateValue(float value) + { + fill.Width = value * UsableWidth; + } + + protected override void OnUserChange() => OnSeek?.Invoke(Current); + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index d970089942..f2c90f009a 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -15,7 +15,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; using osu.Framework.Localisation; using osu.Framework.Threading; @@ -434,49 +433,5 @@ namespace osu.Game.Overlays sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4"); } } - - private class ProgressBar : SliderBar - { - public Action OnSeek; - - private readonly Box fill; - - public Color4 FillColour - { - set { fill.Colour = value; } - } - - public double EndTime - { - set { CurrentNumber.MaxValue = value; } - } - - public double CurrentTime - { - set { CurrentNumber.Value = value; } - } - - public ProgressBar() - { - CurrentNumber.MinValue = 0; - CurrentNumber.MaxValue = 1; - RelativeSizeAxes = Axes.X; - - Children = new Drawable[] - { - fill = new Box - { - RelativeSizeAxes = Axes.Y - } - }; - } - - protected override void UpdateValue(float value) - { - fill.Width = value * UsableWidth; - } - - protected override void OnUserChange() => OnSeek?.Invoke(Current); - } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 32a8df6357..f361c141f1 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -116,6 +116,7 @@ + From cacf256aade865ecc9748219827b56a06510125e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 18:51:50 +0900 Subject: [PATCH 180/483] Add placeholder download method with progress bar --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 7 +++++ osu.Game/Overlays/Direct/DirectListPanel.cs | 1 + osu.Game/Overlays/Direct/DirectPanel.cs | 29 ++++++++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 0cc1c18d8d..3a9e75bd38 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -12,6 +12,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; +using osu.Framework.Input; namespace osu.Game.Overlays.Direct { @@ -171,5 +172,11 @@ namespace osu.Game.Overlays.Direct }, }); } + + protected override bool OnClick(InputState state) + { + StartDownload(); + return true; + } } } diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index d284c50bc4..b3502b0827 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -124,6 +124,7 @@ namespace osu.Game.Overlays.Direct Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Size = new Vector2(height - vertical_padding * 2), + Action = StartDownload }, }, }, diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 7e95c1674b..8738d8ea90 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -17,6 +17,8 @@ using osu.Game.Graphics.Sprites; using OpenTK.Graphics; using osu.Framework.Input; using osu.Framework.MathUtils; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; namespace osu.Game.Overlays.Direct { @@ -30,6 +32,9 @@ namespace osu.Game.Overlays.Direct private Container content; + private APIAccess api; + private ProgressBar progressBar; + protected override Container Content => content; protected DirectPanel(BeatmapSetInfo setInfo) @@ -38,8 +43,10 @@ namespace osu.Game.Overlays.Direct } [BackgroundDependencyLoader] - private void load() + private void load(APIAccess api, OsuColour colours) { + this.api = api; + AddInternal(content = new Container { RelativeSizeAxes = Axes.Both, @@ -60,6 +67,16 @@ namespace osu.Game.Overlays.Direct Colour = Color4.Black, }, CreateBackground(), + progressBar = new ProgressBar + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Height = 0, + Alpha = 0, + BackgroundColour = Color4.Black.Opacity(0.7f), + FillColour = colours.Blue, + Depth = -1, + }, } }); } @@ -82,6 +99,16 @@ namespace osu.Game.Overlays.Direct base.OnHoverLost(state); } + protected void StartDownload() + { + progressBar.FadeIn(400, Easing.OutQuint); + progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); + + progressBar.Current.Value = 0.5f; + + api.Queue(new APIRequest()); + } + protected override void LoadComplete() { base.LoadComplete(); From dac54c362a4050107ac11135ecf1445aff8af809 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 15:39:35 +0900 Subject: [PATCH 181/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 1ba1e8ef1e..da5fbf8c58 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 1ba1e8ef1e5ec0466632be02492023a081cb85ab +Subproject commit da5fbf8c580b079671298f6da54be10a00bf434c From 4ab209bdce8a5fbc234c6bf899e62a9c8290db5b Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 24 Aug 2017 19:05:51 +0900 Subject: [PATCH 182/483] Add EditorContextMenu in line with framework changes To avoid public Menu. --- osu-framework | 2 +- osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/osu-framework b/osu-framework index fbbcd942e2..a5fd0c82c8 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit fbbcd942e262778b166acde2cc89a10782734f2d +Subproject commit a5fd0c82c8f86d41c80ac1b0b07727cb312330f1 diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 49a382c9f9..7a9c97f5d5 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -126,7 +126,6 @@ namespace osu.Desktop.Tests.Visual private void load(OsuColour colours) { background.Colour = colours.Gray3; - ContextMenu.Menu.Background.Colour = colours.Gray3; TitleText.Colour = normalColour = colours.BlueLight; } @@ -148,12 +147,21 @@ namespace osu.Desktop.Tests.Visual protected override SpriteText CreateTitleText() => new OsuSpriteText { TextSize = text_size }; - protected override ContextMenu CreateContextMenu() => new OsuContextMenu + protected override ContextMenu CreateContextMenu() => new EditorContextMenu { OriginPosition = new Vector2(8, 0) }; } + private class EditorContextMenu : OsuContextMenu + { + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Menu.Background.Colour = colours.Gray3; + } + } + private class EditorContextMenuSpacer : EditorContextMenuItem { public override bool HandleInput => false; From 314108146a9ae75bcdb82b7413bd998794febc94 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:14:17 +0900 Subject: [PATCH 183/483] Add a download API request --- osu.Game/Online/API/APIRequest.cs | 43 +++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index 23268a9ca9..307afb2d2b 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -11,11 +11,11 @@ namespace osu.Game.Online.API /// An API request with a well-defined response type. /// /// Type of the response (used for deserialisation). - public class APIRequest : APIRequest + public abstract class APIRequest : APIRequest { protected override WebRequest CreateWebRequest() => new JsonWebRequest(Uri); - public APIRequest() + protected APIRequest() { base.Success += onSuccess; } @@ -28,10 +28,36 @@ namespace osu.Game.Online.API public new event APISuccessHandler Success; } + public abstract class APIDownloadRequest : APIRequest + { + protected override WebRequest CreateWebRequest() + { + var request = new WebRequest(Uri); + request.DownloadProgress += request_Progress; + return request; + } + + private void request_Progress(WebRequest request, long current, long total) => API.Scheduler.Add(delegate { Progress?.Invoke(current, total); }); + + protected APIDownloadRequest() + { + base.Success += onSuccess; + } + + private void onSuccess() + { + Success?.Invoke(WebRequest.ResponseData); + } + + public event APIProgressHandler Progress; + + public new event APISuccessHandler Success; + } + /// /// AN API request with no specified response type. /// - public class APIRequest + public abstract class APIRequest { /// /// The maximum amount of time before this request will fail. @@ -42,7 +68,7 @@ namespace osu.Game.Online.API protected virtual WebRequest CreateWebRequest() => new WebRequest(Uri); - protected virtual string Uri => $@"{api.Endpoint}/api/v2/{Target}"; + protected virtual string Uri => $@"{API.Endpoint}/api/v2/{Target}"; private double remainingTime => Math.Max(0, Timeout - (DateTime.Now.TotalMilliseconds() - (startTime ?? 0))); @@ -52,7 +78,7 @@ namespace osu.Game.Online.API public double StartTime => startTime ?? -1; - private APIAccess api; + protected APIAccess API; protected WebRequest WebRequest; public event APISuccessHandler Success; @@ -64,7 +90,7 @@ namespace osu.Game.Online.API public void Perform(APIAccess api) { - this.api = api; + API = api; if (checkAndProcessFailure()) return; @@ -109,9 +135,9 @@ namespace osu.Game.Online.API /// Whether we are in a failed or cancelled state. private bool checkAndProcessFailure() { - if (api == null || pendingFailure == null) return cancelled; + if (API == null || pendingFailure == null) return cancelled; - api.Scheduler.Add(pendingFailure); + API.Scheduler.Add(pendingFailure); pendingFailure = null; return true; } @@ -119,5 +145,6 @@ namespace osu.Game.Online.API public delegate void APIFailureHandler(Exception e); public delegate void APISuccessHandler(); + public delegate void APIProgressHandler(long current, long total); public delegate void APISuccessHandler(T content); } From 3c10b2d3d9b44e06bf95f88a8c26371d976634b5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:14:35 +0900 Subject: [PATCH 184/483] Populate set IDs in GetBeatmapSetsResponse --- osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs index ca984d3511..e4763f73ee 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapSetsRequest.cs @@ -46,6 +46,9 @@ namespace osu.Game.Online.API.Requests [JsonProperty(@"favourite_count")] private int favouriteCount { get; set; } + [JsonProperty(@"id")] + private int onlineId { get; set; } + [JsonProperty(@"beatmaps")] private IEnumerable beatmaps { get; set; } @@ -53,6 +56,7 @@ namespace osu.Game.Online.API.Requests { return new BeatmapSetInfo { + OnlineBeatmapSetID = onlineId, Metadata = this, OnlineInfo = new BeatmapSetOnlineInfo { From 9c82593c9e82a23ebc9f435674f1b6172a1351e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:15:45 +0900 Subject: [PATCH 185/483] Add cancel event to ProgressNotification --- osu.Game/Overlays/Notifications/ProgressNotification.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index f42b4b6cb3..a31291e1b8 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -152,11 +152,14 @@ namespace osu.Game.Overlays.Notifications break; case ProgressNotificationState.Active: case ProgressNotificationState.Queued: - State = ProgressNotificationState.Cancelled; + if (CancelRequested?.Invoke() != false) + State = ProgressNotificationState.Cancelled; break; } } + public Func CancelRequested { get; set; } + /// /// The function to post completion notifications back to. /// From 32a23c7fe41fd2c4f978385fdb6f32f576d9e0dc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:16:03 +0900 Subject: [PATCH 186/483] Add initial osu!direct beatmap download and import process --- osu.Game/Overlays/Direct/DirectPanel.cs | 82 ++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 8738d8ea90..b44a100d3c 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; +using System.IO; +using System.Threading.Tasks; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -19,6 +21,9 @@ using osu.Framework.Input; using osu.Framework.MathUtils; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; +using osu.Framework.Logging; +using osu.Game.Beatmaps.IO; +using osu.Game.Overlays.Notifications; namespace osu.Game.Overlays.Direct { @@ -34,6 +39,8 @@ namespace osu.Game.Overlays.Direct private APIAccess api; private ProgressBar progressBar; + private BeatmapManager beatmaps; + private NotificationOverlay notifications; protected override Container Content => content; @@ -43,9 +50,11 @@ namespace osu.Game.Overlays.Direct } [BackgroundDependencyLoader] - private void load(APIAccess api, OsuColour colours) + private void load(APIAccess api, BeatmapManager beatmaps, OsuColour colours, NotificationOverlay notifications) { this.api = api; + this.beatmaps = beatmaps; + this.notifications = notifications; AddInternal(content = new Container { @@ -101,12 +110,79 @@ namespace osu.Game.Overlays.Direct protected void StartDownload() { + if (!api.LocalUser.Value.IsSupporter) + { + notifications.Post(new SimpleNotification + { + Icon = FontAwesome.fa_superpowers, + Text = "You gotta be a supporter to download for now 'yo" + }); + return; + } + progressBar.FadeIn(400, Easing.OutQuint); progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); - progressBar.Current.Value = 0.5f; + progressBar.Current.Value = 0; - api.Queue(new APIRequest()); + ProgressNotification downloadNotification = new ProgressNotification + { + Text = $"Downloading {SetInfo.Metadata.Artist} - {SetInfo.Metadata.Title}", + }; + + var request = new DownloadBeatmapSetRequest(SetInfo); + request.Failure += e => + { + progressBar.Current.Value = 0; + progressBar.FadeOut(500); + downloadNotification.State = ProgressNotificationState.Completed; + Logger.Error(e, "Failed to get beatmap download information"); + }; + + request.Progress += (current, total) => + { + float progress = (float)current / total; + + progressBar.Current.Value = progress; + + downloadNotification.State = ProgressNotificationState.Active; + downloadNotification.Progress = progress; + }; + + request.Success += data => + { + progressBar.Current.Value = 1; + progressBar.FadeOut(500); + + downloadNotification.State = ProgressNotificationState.Completed; + + using (var stream = new MemoryStream(data)) + using (var archive = new OszArchiveReader(stream)) + beatmaps.Import(archive); + }; + + downloadNotification.CancelRequested += () => + { + request.Cancel(); + return true; + }; + + notifications.Post(downloadNotification); + + // don't run in the main api queue as this is a long-running task. + Task.Run(() => request.Perform(api)); + } + + public class DownloadBeatmapSetRequest : APIDownloadRequest + { + private readonly BeatmapSetInfo beatmapSet; + + public DownloadBeatmapSetRequest(BeatmapSetInfo beatmapSet) + { + this.beatmapSet = beatmapSet; + } + + protected override string Target => $@"beatmapsets/{beatmapSet.OnlineBeatmapSetID}/download"; } protected override void LoadComplete() From 9adff5f697221b0d7f8ab9460315c681345a6a3f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:18:47 +0900 Subject: [PATCH 187/483] Add osu!direct toggle to toolbar --- osu.Game/OsuGame.cs | 1 + osu.Game/Overlays/Toolbar/Toolbar.cs | 1 + .../Overlays/Toolbar/ToolbarDirectButton.cs | 19 +++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 4 files changed, 22 insertions(+) create mode 100644 osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 8c82071c23..43e3731166 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -219,6 +219,7 @@ namespace osu.Game dependencies.Cache(settings); dependencies.Cache(social); + dependencies.Cache(direct); dependencies.Cache(chat); dependencies.Cache(userProfile); dependencies.Cache(musicController); diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 32344ca7eb..e36db1f9da 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -58,6 +58,7 @@ namespace osu.Game.Overlays.Toolbar AutoSizeAxes = Axes.X, Children = new Drawable[] { + new ToolbarDirectButton(), new ToolbarChatButton(), new ToolbarSocialButton(), new ToolbarMusicButton(), diff --git a/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs b/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs new file mode 100644 index 0000000000..484b079d23 --- /dev/null +++ b/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs @@ -0,0 +1,19 @@ +using osu.Framework.Allocation; +using osu.Game.Graphics; + +namespace osu.Game.Overlays.Toolbar +{ + internal class ToolbarDirectButton : ToolbarOverlayToggleButton + { + public ToolbarDirectButton() + { + SetIcon(FontAwesome.fa_download); + } + + [BackgroundDependencyLoader] + private void load(DirectOverlay direct) + { + StateContainer = direct; + } + } +} \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f361c141f1..15c400b21e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -130,6 +130,7 @@ + From 0082640548d3e6cab5cdfbfe0ed2cb442511ccda Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:25:18 +0900 Subject: [PATCH 188/483] Add missing licence header --- osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs b/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs index 484b079d23..32e149b31a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs @@ -1,3 +1,6 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + using osu.Framework.Allocation; using osu.Game.Graphics; From a7e6efd34fc83ceb33cf7c8a31200d3d709e1dad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:30:18 +0900 Subject: [PATCH 189/483] Rename keys -> actions --- .../Replays/TaikoFramedReplayInputHandler.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs index 89093ae05e..fce0179721 100644 --- a/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs +++ b/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs @@ -16,18 +16,18 @@ namespace osu.Game.Rulesets.Taiko.Replays public override List GetPendingStates() { - var keys = new List(); + var actions = new List(); if (CurrentFrame?.MouseRight1 == true) - keys.Add(TaikoAction.LeftCentre); + actions.Add(TaikoAction.LeftCentre); if (CurrentFrame?.MouseRight2 == true) - keys.Add(TaikoAction.RightCentre); + actions.Add(TaikoAction.RightCentre); if (CurrentFrame?.MouseLeft1 == true) - keys.Add(TaikoAction.LeftRim); + actions.Add(TaikoAction.LeftRim); if (CurrentFrame?.MouseLeft2 == true) - keys.Add(TaikoAction.RightRim); + actions.Add(TaikoAction.RightRim); - return new List { new ReplayState { PressedActions = keys } }; + return new List { new ReplayState { PressedActions = actions } }; } } } From c9f90efb8ac418d52949628a0018f31bf605b0a1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:31:57 +0900 Subject: [PATCH 190/483] Add more checks and remove direct cast --- osu.Game/Rulesets/UI/RulesetContainer.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 17417856a1..a7472f4dbc 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.UI /// /// The input manager for this RulesetContainer. /// - internal IHasReplayHandler ReplayInputManager => (IHasReplayHandler)KeyBindingInputManager; + internal IHasReplayHandler ReplayInputManager => KeyBindingInputManager as IHasReplayHandler; /// /// The key conversion input manager for this RulesetContainer. @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.UI /// /// Whether we have a replay loaded currently. /// - public bool HasReplayLoaded => ReplayInputManager.ReplayInputHandler != null; + public bool HasReplayLoaded => ReplayInputManager?.ReplayInputHandler != null; public abstract IEnumerable Objects { get; } @@ -107,6 +107,9 @@ namespace osu.Game.Rulesets.UI /// The replay, null for local input. public virtual void SetReplay(Replay replay) { + if (ReplayInputManager == null) + throw new InvalidOperationException($"A {nameof(KeyBindingInputManager)} which supports replay loading is not available"); + Replay = replay; ReplayInputManager.ReplayInputHandler = replay != null ? CreateReplayInputHandler(replay) : null; } From 2b667cf789a57ac5c73a5c274dbceef2ba544086 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:32:55 +0900 Subject: [PATCH 191/483] Fix typos --- osu.Game/Rulesets/UI/RulesetInputManager.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 75e273adea..0419070b42 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -94,13 +94,13 @@ namespace osu.Game.Rulesets.UI } /// - /// Whether we running up-to-date with our parent clock. + /// Whether we are running up-to-date with our parent clock. /// If not, we will need to keep processing children until we catch up. /// private bool requireMoreUpdateLoops; /// - /// Whether we in a valid state (ie. should we keep processing children frames). + /// Whether we are in a valid state (ie. should we keep processing children frames). /// This should be set to false when the replay is, for instance, waiting for future frames to arrive. /// private bool validState; @@ -229,4 +229,4 @@ namespace osu.Game.Rulesets.UI { void Attach(KeyCounterCollection keyCounter); } -} \ No newline at end of file +} From 1b0a1dd4108285dbec840ad8cf9a9ef1b014d066 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 20:37:03 +0900 Subject: [PATCH 192/483] Add missing licence header --- osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs b/osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs index a54679b8cc..0811a68392 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuReplayInputHandler.cs @@ -1,4 +1,7 @@ -using System.Collections.Generic; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; using osu.Framework.Input; using osu.Game.Rulesets.Replays; using OpenTK; From febf0348be646d1af5aeda1ae1ee8dcf5206a298 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Aug 2017 21:26:50 +0900 Subject: [PATCH 193/483] Permit nulls to allow test cases to run successfully --- osu.Game/Overlays/Direct/DirectPanel.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index b44a100d3c..bc30fb83f5 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Direct SetInfo = setInfo; } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(permitNulls: true)] private void load(APIAccess api, BeatmapManager beatmaps, OsuColour colours, NotificationOverlay notifications) { this.api = api; @@ -110,6 +110,8 @@ namespace osu.Game.Overlays.Direct protected void StartDownload() { + if (api == null) return; + if (!api.LocalUser.Value.IsSupporter) { notifications.Post(new SimpleNotification From f8cc4238ffa88e96e42a8744986e1adfe65b3288 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Thu, 24 Aug 2017 22:13:20 +0200 Subject: [PATCH 194/483] cleanup code --- .../UserInterface/OsuPasswordTextBox.cs | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index 2b175b9eed..2fdbf64d08 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -7,8 +7,8 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; -using System; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; using osu.Framework.Platform; namespace osu.Game.Graphics.UserInterface @@ -19,14 +19,35 @@ namespace osu.Game.Graphics.UserInterface public override bool AllowClipboardExport => false; + private readonly CapsWarning warning; + + private GameHost host; + public OsuPasswordTextBox() { - Add(new CapsWarning + Add(warning = new CapsWarning { Size = new Vector2(20), + Origin = Anchor.CentreRight, + Anchor = Anchor.CentreRight, + Margin = new MarginPadding { Right = 10 }, + Alpha = 0, }); } + [BackgroundDependencyLoader] + private void load(GameHost host) + { + this.host = host; + } + + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + { + if (args.Key == OpenTK.Input.Key.CapsLock) + warning.FadeTo(host.CapsLockEnabled ? 1 : 0, 250, Easing.OutQuint); + return base.OnKeyDown(state, args); + } + public class PasswordMaskChar : Container { private readonly CircularContainer circle; @@ -66,36 +87,18 @@ namespace osu.Game.Graphics.UserInterface private class CapsWarning : SpriteIcon, IHasTooltip { - public string TooltipText => host.CapsLockEnabled ? @"Caps lock is active" : string.Empty; - - public override bool HandleInput => true; - - private GameHost host; + public string TooltipText => @"Caps lock is active"; public CapsWarning() { Icon = FontAwesome.fa_warning; - Origin = Anchor.CentreRight; - Anchor = Anchor.CentreRight; - Margin = new MarginPadding { Right = 10 }; - AlwaysPresent = true; - Alpha = 0; } [BackgroundDependencyLoader] - private void load(OsuColour colour, GameHost host) + private void load(OsuColour colour) { Colour = colour.YellowLight; - this.host = host; } - - protected override void Update() - { - base.Update(); - updateVisibility(); - } - - private void updateVisibility() => this.FadeTo(host.CapsLockEnabled ? 1 : 0, 250, Easing.OutQuint); } } } From 2dd3e513732d7c0cde6ecd5e0c8d0b3543d337ae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Aug 2017 10:51:28 +0900 Subject: [PATCH 195/483] Ensure other full-screen overlays are closed when direct is open (and vice-versa) --- osu.Game/OsuGame.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 43e3731166..82177ab05e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -226,6 +226,23 @@ namespace osu.Game dependencies.Cache(notificationOverlay); dependencies.Cache(dialogOverlay); + // ensure only one of these overlays are open at once. + var singleDisplayOverlays = new OverlayContainer[] { chat, social, direct }; + foreach (var overlay in singleDisplayOverlays) + { + overlay.StateChanged += (container, state) => + { + if (state == Visibility.Hidden) return; + + foreach (var c in singleDisplayOverlays) + { + if (c == container) continue; + c.State = Visibility.Hidden; + } + }; + } + + // ensure both overlays aren't presented at the same time chat.StateChanged += (container, state) => social.State = state == Visibility.Visible ? Visibility.Hidden : social.State; social.StateChanged += (container, state) => chat.State = state == Visibility.Visible ? Visibility.Hidden : chat.State; From 7f617e2c3659ab1dad686c6971e056be0e169884 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Aug 2017 11:53:41 +0900 Subject: [PATCH 196/483] Remove downloaded beatmap panels from osu!direct --- osu.Game/Overlays/DirectOverlay.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index b1c7dab778..f270aec43e 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -161,11 +161,19 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuColour colours, APIAccess api, RulesetStore rulesets) + private void load(OsuColour colours, APIAccess api, RulesetStore rulesets, BeatmapManager beatmaps) { this.api = api; this.rulesets = rulesets; resultCountsContainer.Colour = colours.Yellow; + + beatmaps.BeatmapSetAdded += setAdded; + } + + private void setAdded(BeatmapSetInfo set) + { + // if a new map was imported, we should remove it from search results (download completed etc.) + panels?.FirstOrDefault(p => p.SetInfo.OnlineBeatmapSetID == set.OnlineBeatmapSetID)?.FadeOut(400).Expire(); } private void updateResultCounts() From ca0d1b79b2b772e2c789be0b78c2a0dd7d50aa33 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Aug 2017 11:54:18 +0900 Subject: [PATCH 197/483] Disallow multiple download requests for the same panel --- osu.Game/Overlays/Direct/DirectPanel.cs | 30 +++++++++++++++++++------ 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index bc30fb83f5..4f02ce1bf6 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Direct { public abstract class DirectPanel : Container { - protected readonly BeatmapSetInfo SetInfo; + public readonly BeatmapSetInfo SetInfo; protected Box BlackBackground; @@ -108,10 +108,23 @@ namespace osu.Game.Overlays.Direct base.OnHoverLost(state); } + // this should eventually be moved to a more central place, like BeatmapManager. + private DownloadBeatmapSetRequest downloadRequest; + protected void StartDownload() { if (api == null) return; + // we already have an active download running. + if (downloadRequest != null) + { + content.MoveToX(-5, 50, Easing.OutSine).Then() + .MoveToX(5, 100, Easing.InOutSine).Then() + .MoveToX(-5, 100, Easing.InOutSine).Then() + .MoveToX(0, 50, Easing.InSine).Then(); + return; + } + if (!api.LocalUser.Value.IsSupporter) { notifications.Post(new SimpleNotification @@ -132,16 +145,18 @@ namespace osu.Game.Overlays.Direct Text = $"Downloading {SetInfo.Metadata.Artist} - {SetInfo.Metadata.Title}", }; - var request = new DownloadBeatmapSetRequest(SetInfo); - request.Failure += e => + downloadRequest = new DownloadBeatmapSetRequest(SetInfo); + downloadRequest.Failure += e => { progressBar.Current.Value = 0; progressBar.FadeOut(500); downloadNotification.State = ProgressNotificationState.Completed; Logger.Error(e, "Failed to get beatmap download information"); + + downloadRequest = null; }; - request.Progress += (current, total) => + downloadRequest.Progress += (current, total) => { float progress = (float)current / total; @@ -151,7 +166,7 @@ namespace osu.Game.Overlays.Direct downloadNotification.Progress = progress; }; - request.Success += data => + downloadRequest.Success += data => { progressBar.Current.Value = 1; progressBar.FadeOut(500); @@ -165,14 +180,15 @@ namespace osu.Game.Overlays.Direct downloadNotification.CancelRequested += () => { - request.Cancel(); + downloadRequest.Cancel(); + downloadRequest = null; return true; }; notifications.Post(downloadNotification); // don't run in the main api queue as this is a long-running task. - Task.Run(() => request.Perform(api)); + Task.Run(() => downloadRequest.Perform(api)); } public class DownloadBeatmapSetRequest : APIDownloadRequest From 7055cb581d71a9d7fe438f7ec9e6beeba26824e4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Aug 2017 11:54:35 +0900 Subject: [PATCH 198/483] Load direct panels more asynchronously to avoid stutter --- osu.Game/Overlays/DirectOverlay.cs | 60 +++++++++++++++--------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index f270aec43e..f734e43826 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays private readonly FillFlowContainer resultCountsContainer; private readonly OsuSpriteText resultCountsText; - private readonly FillFlowContainer panels; + private FillFlowContainer panels; protected override Color4 BackgroundColour => OsuColour.FromHex(@"485e74"); protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"465b71"); @@ -48,17 +48,6 @@ namespace osu.Game.Overlays if (beatmapSets?.Equals(value) ?? false) return; beatmapSets = value; - if (BeatmapSets == null) - { - foreach (var p in panels.Children) - { - p.FadeOut(200); - p.Expire(); - } - - return; - } - recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); } } @@ -108,13 +97,6 @@ namespace osu.Game.Overlays }, } }, - panels = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Spacing = new Vector2(panel_padding), - Margin = new MarginPadding { Top = 10 }, - }, }; Filter.Search.Current.ValueChanged += text => { if (text != string.Empty) Header.Tabs.Current.Value = DirectTab.Search; }; @@ -193,18 +175,38 @@ namespace osu.Game.Overlays private void recreatePanels(PanelDisplayStyle displayStyle) { + if (panels != null) + { + panels.FadeOut(200); + panels.Expire(); + panels = null; + } + if (BeatmapSets == null) return; - panels.ChildrenEnumerable = BeatmapSets.Select(b => - { - switch (displayStyle) - { - case PanelDisplayStyle.Grid: - return new DirectGridPanel(b) { Width = 400 }; - default: - return new DirectListPanel(b); - } - }); + var newPanels = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(panel_padding), + Margin = new MarginPadding { Top = 10 }, + ChildrenEnumerable = BeatmapSets.Select(b => + { + switch (displayStyle) + { + case PanelDisplayStyle.Grid: + return new DirectGridPanel(b) { Width = 400 }; + default: + return new DirectListPanel(b); + } + }) + }; + + LoadComponentAsync(newPanels, p => + { + if (panels != null) ScrollFlow.Remove(panels); + ScrollFlow.Add(panels = newPanels); + }); } private GetBeatmapSetsRequest getSetsRequest; From 86bde4b6b253e87fd92ae8026878a4a5128f35cf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Aug 2017 13:03:34 +0900 Subject: [PATCH 199/483] Use the correct icon for osu!direct in the toolbar --- osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs b/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs index 32e149b31a..dacb6d67b8 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Toolbar { public ToolbarDirectButton() { - SetIcon(FontAwesome.fa_download); + SetIcon(FontAwesome.fa_osu_chevron_down_o); } [BackgroundDependencyLoader] From 67b3cbce2f9fa436d19f5ffa77982c83521a3442 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Aug 2017 13:04:32 +0900 Subject: [PATCH 200/483] Fix beatmap background being disposed too early Causes weird transitions on the music controller --- osu.Game/OsuGameBase.cs | 8 ++------ osu.Game/Overlays/MusicController.cs | 12 ++++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 952dc900a2..a7136ce803 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -152,14 +152,10 @@ namespace osu.Game Beatmap.ValueChanged += b => { - // compare to last baetmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) + // compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) if (lastBeatmap?.Track != b.Track) { - // this disposal is done to stop the audio track. - // it may not be exactly what we want for cases beatmaps are reused, as it will - // trigger a fresh load of contained resources. - lastBeatmap?.Dispose(); - + lastBeatmap?.Track?.Dispose(); Audio.Track.AddItem(b.Track); } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index f2c90f009a..cb4628825e 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -348,23 +348,23 @@ namespace osu.Game.Overlays playerContainer.Add(new AsyncLoadWrapper(new Background(beatmap) { - OnLoadComplete = d => + OnLoadComplete = newBackground => { switch (direction) { case TransformDirection.Next: - d.Position = new Vector2(400, 0); - d.MoveToX(0, 500, Easing.OutCubic); + newBackground.Position = new Vector2(400, 0); + newBackground.MoveToX(0, 500, Easing.OutCubic); currentBackground.MoveToX(-400, 500, Easing.OutCubic); break; case TransformDirection.Prev: - d.Position = new Vector2(-400, 0); - d.MoveToX(0, 500, Easing.OutCubic); + newBackground.Position = new Vector2(-400, 0); + newBackground.MoveToX(0, 500, Easing.OutCubic); currentBackground.MoveToX(400, 500, Easing.OutCubic); break; } currentBackground.Expire(); - currentBackground = d; + currentBackground = newBackground; } }) { From 72a16e31dd9468912df4c555d72ba10010e49adf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Aug 2017 13:07:10 +0900 Subject: [PATCH 201/483] Remove unnecessary old code --- osu.Game/OsuGame.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 82177ab05e..30bc09d50f 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -242,11 +242,6 @@ namespace osu.Game }; } - - // ensure both overlays aren't presented at the same time - chat.StateChanged += (container, state) => social.State = state == Visibility.Visible ? Visibility.Hidden : social.State; - social.StateChanged += (container, state) => chat.State = state == Visibility.Visible ? Visibility.Hidden : chat.State; - LoadComponentAsync(Toolbar = new Toolbar { Depth = -4, From 70154d10365fbf7929987778c65c15df104f30d0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Aug 2017 14:36:14 +0900 Subject: [PATCH 202/483] Update usage of FadeEdgeEffect Improves the visual appearance of DirectPanels' shadows too. --- osu-framework | 2 +- osu.Game/Overlays/Direct/DirectPanel.cs | 58 +++++++------------ osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 4 +- 3 files changed, 23 insertions(+), 41 deletions(-) diff --git a/osu-framework b/osu-framework index da5fbf8c58..3db7e23165 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit da5fbf8c580b079671298f6da54be10a00bf434c +Subproject commit 3db7e231653ec6ffe28b5dcd1a86230ec754cc1c diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 4f02ce1bf6..a642f72821 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -11,14 +11,12 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Transforms; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using OpenTK.Graphics; using osu.Framework.Input; -using osu.Framework.MathUtils; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Framework.Logging; @@ -49,6 +47,23 @@ namespace osu.Game.Overlays.Direct SetInfo = setInfo; } + private readonly EdgeEffectParameters edgeEffectNormal = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Offset = new Vector2(0f, 1f), + Radius = 2f, + Colour = Color4.Black.Opacity(0.25f), + }; + + private readonly EdgeEffectParameters edgeEffectHovered = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Offset = new Vector2(0f, 5f), + Radius = 10f, + Colour = Color4.Black.Opacity(0.3f), + }; + + [BackgroundDependencyLoader(permitNulls: true)] private void load(APIAccess api, BeatmapManager beatmaps, OsuColour colours, NotificationOverlay notifications) { @@ -60,13 +75,7 @@ namespace osu.Game.Overlays.Direct { RelativeSizeAxes = Axes.Both, Masking = true, - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Offset = new Vector2(0f, 1f), - Radius = 2f, - Colour = Color4.Black.Opacity(0.25f), - }, + EdgeEffect = edgeEffectNormal, Children = new[] { // temporary blackness until the actual background loads. @@ -92,8 +101,7 @@ namespace osu.Game.Overlays.Direct protected override bool OnHover(InputState state) { - content.FadeEdgeEffectTo(1f, hover_transition_time, Easing.OutQuint); - content.TransformTo(content.PopulateTransform(new TransformEdgeEffectRadius(), 14, hover_transition_time, Easing.OutQuint)); + content.TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint); content.MoveToY(-4, hover_transition_time, Easing.OutQuint); return base.OnHover(state); @@ -101,8 +109,7 @@ namespace osu.Game.Overlays.Direct protected override void OnHoverLost(InputState state) { - content.FadeEdgeEffectTo(0.25f, hover_transition_time, Easing.OutQuint); - content.TransformTo(content.PopulateTransform(new TransformEdgeEffectRadius(), 2, hover_transition_time, Easing.OutQuint)); + content.TweenEdgeEffectTo(edgeEffectNormal, hover_transition_time, Easing.OutQuint); content.MoveToY(0, hover_transition_time, Easing.OutQuint); base.OnHoverLost(state); @@ -278,30 +285,5 @@ namespace osu.Game.Overlays.Direct Value = value; } } - - private class TransformEdgeEffectRadius : Transform - { - /// - /// Current value of the transformed colour in linear colour space. - /// - private float 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 => "EdgeEffect.Colour"; - - protected override void Apply(Container c, double time) - { - EdgeEffectParameters e = c.EdgeEffect; - e.Radius = valueAt(time); - c.EdgeEffect = e; - } - - protected override void ReadIntoStartValue(Container d) => StartValue = d.EdgeEffect.Radius; - } } } diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index ee997a2185..046e56573f 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -122,14 +122,14 @@ namespace osu.Game.Overlays.KeyBinding protected override bool OnHover(InputState state) { - this.FadeEdgeEffectTo(1, transition_time, Easing.OutQuint); + FadeEdgeEffectTo(1, transition_time, Easing.OutQuint); return base.OnHover(state); } protected override void OnHoverLost(InputState state) { - this.FadeEdgeEffectTo(0, transition_time, Easing.OutQuint); + FadeEdgeEffectTo(0, transition_time, Easing.OutQuint); base.OnHoverLost(state); } From 06c392d6f2690a4f34d895b775c61f2326dde344 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 25 Aug 2017 15:09:07 +0900 Subject: [PATCH 203/483] Update OsuMenu in line with framework. --- osu-framework | 2 +- osu.Game/Graphics/UserInterface/OsuMenu.cs | 23 ++++++++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/osu-framework b/osu-framework index da5fbf8c58..5a189d1050 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit da5fbf8c580b079671298f6da54be10a00bf434c +Subproject commit 5a189d1050579b217bfe6b6c17c3ee6d6ef9c839 diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index e597bc44b5..79519e26a0 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -5,28 +5,39 @@ using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterface { - public class OsuMenu : Menu + public class OsuMenu : Menu + where TItem : MenuItem { public OsuMenu() { CornerRadius = 4; - Background.Colour = Color4.Black.Opacity(0.5f); - - ItemsContainer.Padding = new MarginPadding(5); + BackgroundColour = Color4.Black.Opacity(0.5f); } protected override void AnimateOpen() => this.FadeIn(300, Easing.OutQuint); - protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint); - protected override void UpdateContentHeight() + protected override void UpdateMenuHeight() { var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight; this.ResizeTo(new Vector2(1, State == MenuState.Opened ? actualHeight : 0), 300, Easing.OutQuint); } + + protected override FlowContainer CreateItemsFlow() + { + var flow = base.CreateItemsFlow(); + flow.Padding = new MarginPadding(5); + + return flow; + } + } + + public class OsuMenu : OsuMenu + { } } From 7467d24d35849fa9dbfe9b69530f5ca7a91d6447 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 25 Aug 2017 15:10:12 +0900 Subject: [PATCH 204/483] Update OsuContextMenu in line with framework. --- .../Graphics/UserInterface/OsuContextMenu.cs | 149 +++++++++++++++--- .../UserInterface/OsuContextMenuItem.cs | 107 ++----------- 2 files changed, 133 insertions(+), 123 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs index d4882cce1e..ddb91d42a1 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -1,52 +1,151 @@ // Copyright (c) 2007-2017 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.Audio; +using osu.Framework.Audio.Sample; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input; +using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { - public class OsuContextMenu : ContextMenu - where TItem : ContextMenuItem + public class OsuContextMenu : OsuMenu + where TItem : OsuContextMenuItem { - protected override Menu CreateMenu() => new CustomMenu(); + private const int fade_duration = 250; - public class CustomMenu : Menu + public OsuContextMenu() { - private const int fade_duration = 250; - - public CustomMenu() + CornerRadius = 5; + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.1f), + Radius = 4, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.ContextMenuGray; + } + + protected override void AnimateOpen() => this.FadeIn(fade_duration, Easing.OutQuint); + protected override void AnimateClose() => this.FadeOut(fade_duration, Easing.OutQuint); + + protected override FlowContainer CreateItemsFlow() + { + var flow = base.CreateItemsFlow(); + flow.Padding = new MarginPadding { Vertical = OsuContextMenuItemRepresentation.MARGIN_VERTICAL }; + + return flow; + } + + protected override MenuItemRepresentation CreateMenuItemRepresentation(TItem model) => new OsuContextMenuItemRepresentation(this, model); + + #region OsuContextMenuItemRepresentation + private class OsuContextMenuItemRepresentation : MenuItemRepresentation + { + private const int margin_horizontal = 17; + private const int text_size = 17; + private const int transition_length = 80; + public const int MARGIN_VERTICAL = 4; + + private SampleChannel sampleClick; + private SampleChannel sampleHover; + + private OsuSpriteText text; + private OsuSpriteText textBold; + + public OsuContextMenuItemRepresentation(Menu menu, TItem model) + : base(menu, model) { - CornerRadius = 5; - ItemsContainer.Padding = new MarginPadding { Vertical = OsuContextMenuItem.MARGIN_VERTICAL }; - Masking = true; - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.1f), - Radius = 4, - }; } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(AudioManager audio) { - Background.Colour = colours.ContextMenuGray; + sampleHover = audio.Sample.Get(@"UI/generic-hover"); + sampleClick = audio.Sample.Get(@"UI/generic-click"); + + BackgroundColour = Color4.Transparent; + BackgroundColourHover = OsuColour.FromHex(@"172023"); + + updateTextColour(); } - protected override void AnimateOpen() => this.FadeIn(fade_duration, Easing.OutQuint); - protected override void AnimateClose() => this.FadeOut(fade_duration, Easing.OutQuint); - - protected override void UpdateContentHeight() + private void updateTextColour() { - var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight; - this.ResizeTo(new Vector2(1, State == MenuState.Opened ? actualHeight : 0), 300, Easing.OutQuint); + switch (Model.Type) + { + case MenuItemType.Standard: + textBold.Colour = text.Colour = Color4.White; + break; + case MenuItemType.Destructive: + textBold.Colour = text.Colour = Color4.Red; + break; + case MenuItemType.Highlighted: + textBold.Colour = text.Colour = OsuColour.FromHex(@"ffcc22"); + break; + } } + + protected override bool OnHover(InputState state) + { + sampleHover.Play(); + textBold.FadeIn(transition_length, Easing.OutQuint); + text.FadeOut(transition_length, Easing.OutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + textBold.FadeOut(transition_length, Easing.OutQuint); + text.FadeIn(transition_length, Easing.OutQuint); + base.OnHoverLost(state); + } + + protected override bool OnClick(InputState state) + { + sampleClick.Play(); + return base.OnClick(state); + } + + protected override Drawable CreateText(string title) => new Container + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Children = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = text_size, + Text = title, + Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, + }, + textBold = new OsuSpriteText + { + AlwaysPresent = true, + Alpha = 0, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = text_size, + Text = title, + Font = @"Exo2.0-Bold", + Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, + } + } + }; } + #endregion } } \ No newline at end of file diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenuItem.cs b/osu.Game/Graphics/UserInterface/OsuContextMenuItem.cs index 196e905bdc..bf00208b88 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenuItem.cs @@ -1,114 +1,25 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK.Graphics; -using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Sample; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; +using System; using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input; -using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { - public class OsuContextMenuItem : ContextMenuItem + public class OsuContextMenuItem : MenuItem { - private const int transition_length = 80; - private const int margin_horizontal = 17; - public const int MARGIN_VERTICAL = 4; - private const int text_size = 17; + public readonly MenuItemType Type; - private OsuSpriteText text; - private OsuSpriteText textBold; - - private SampleChannel sampleClick; - private SampleChannel sampleHover; - - private readonly MenuItemType type; - - protected override Container CreateTextContainer(string title) => new Container + public OsuContextMenuItem(string text, MenuItemType type = MenuItemType.Standard) + : base(text) { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Children = new Drawable[] - { - text = new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = text_size, - Text = title, - Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, - }, - textBold = new OsuSpriteText - { - AlwaysPresent = true, - Alpha = 0, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = text_size, - Text = title, - Font = @"Exo2.0-Bold", - Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, - } - } - }; - - public OsuContextMenuItem(string title, MenuItemType type = MenuItemType.Standard) : base(title) - { - this.type = type; + Type = type; } - [BackgroundDependencyLoader] - private void load(AudioManager audio) + public OsuContextMenuItem(string text, MenuItemType type, Action action) + : base(text, action) { - sampleHover = audio.Sample.Get(@"UI/generic-hover"); - sampleClick = audio.Sample.Get(@"UI/generic-click"); - - BackgroundColour = Color4.Transparent; - BackgroundColourHover = OsuColour.FromHex(@"172023"); - - updateTextColour(); - } - - private void updateTextColour() - { - switch (type) - { - case MenuItemType.Standard: - textBold.Colour = text.Colour = Color4.White; - break; - case MenuItemType.Destructive: - textBold.Colour = text.Colour = Color4.Red; - break; - case MenuItemType.Highlighted: - textBold.Colour = text.Colour = OsuColour.FromHex(@"ffcc22"); - break; - } - } - - protected override bool OnHover(InputState state) - { - sampleHover.Play(); - textBold.FadeIn(transition_length, Easing.OutQuint); - text.FadeOut(transition_length, Easing.OutQuint); - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - textBold.FadeOut(transition_length, Easing.OutQuint); - text.FadeIn(transition_length, Easing.OutQuint); - base.OnHoverLost(state); - } - - protected override bool OnClick(InputState state) - { - sampleClick.Play(); - return base.OnClick(state); + Type = type; } } } \ No newline at end of file From 4fb95706184c4b5310daf96b3c6c76bfeb28dfbc Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 25 Aug 2017 15:10:29 +0900 Subject: [PATCH 205/483] Create IHasOsuContextMenu and update OsuContextMenuContainer in line with framework. --- .../Visual/TestCaseContextMenu.cs | 19 +++++++++---------- .../Graphics/Cursor/IHasOsuContextMenu.cs | 9 +++++++++ .../Cursor/OsuContextMenuContainer.cs | 4 ++-- osu.Game/osu.Game.csproj | 1 + 4 files changed, 21 insertions(+), 12 deletions(-) create mode 100644 osu.Game/Graphics/Cursor/IHasOsuContextMenu.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseContextMenu.cs b/osu.Desktop.Tests/Visual/TestCaseContextMenu.cs index f0894f794a..2ac3a28bd4 100644 --- a/osu.Desktop.Tests/Visual/TestCaseContextMenu.cs +++ b/osu.Desktop.Tests/Visual/TestCaseContextMenu.cs @@ -3,9 +3,8 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; @@ -67,9 +66,9 @@ namespace osu.Desktop.Tests.Visual ); } - private class MyContextMenuContainer : Container, IHasContextMenu + private class MyContextMenuContainer : Container, IHasOsuContextMenu { - public ContextMenuItem[] ContextMenuItems => new ContextMenuItem[] + public OsuContextMenuItem[] ContextMenuItems => new[] { new OsuContextMenuItem(@"Some option"), new OsuContextMenuItem(@"Highlighted option", MenuItemType.Highlighted), @@ -81,16 +80,16 @@ namespace osu.Desktop.Tests.Visual }; } - private class AnotherContextMenuContainer : Container, IHasContextMenu + private class AnotherContextMenuContainer : Container, IHasOsuContextMenu { - public ContextMenuItem[] ContextMenuItems => new ContextMenuItem[] + public OsuContextMenuItem[] ContextMenuItems => new[] { new OsuContextMenuItem(@"Simple option"), new OsuContextMenuItem(@"Simple very very long option"), - new OsuContextMenuItem(@"Change width", MenuItemType.Highlighted) { Action = () => this.ResizeWidthTo(Width * 2, 100, Easing.OutQuint) }, - new OsuContextMenuItem(@"Change height", MenuItemType.Highlighted) { Action = () => this.ResizeHeightTo(Height * 2, 100, Easing.OutQuint) }, - new OsuContextMenuItem(@"Change width back", MenuItemType.Destructive) { Action = () => this.ResizeWidthTo(Width / 2, 100, Easing.OutQuint) }, - new OsuContextMenuItem(@"Change height back", MenuItemType.Destructive) { Action = () => this.ResizeHeightTo(Height / 2, 100, Easing.OutQuint) }, + new OsuContextMenuItem(@"Change width", MenuItemType.Highlighted, () => this.ResizeWidthTo(Width * 2, 100, Easing.OutQuint)), + new OsuContextMenuItem(@"Change height", MenuItemType.Highlighted, () => this.ResizeHeightTo(Height * 2, 100, Easing.OutQuint)), + new OsuContextMenuItem(@"Change width back", MenuItemType.Destructive, () => this.ResizeWidthTo(Width / 2, 100, Easing.OutQuint)), + new OsuContextMenuItem(@"Change height back", MenuItemType.Destructive, () => this.ResizeHeightTo(Height / 2, 100, Easing.OutQuint)), }; } } diff --git a/osu.Game/Graphics/Cursor/IHasOsuContextMenu.cs b/osu.Game/Graphics/Cursor/IHasOsuContextMenu.cs new file mode 100644 index 0000000000..6fb1a3d31f --- /dev/null +++ b/osu.Game/Graphics/Cursor/IHasOsuContextMenu.cs @@ -0,0 +1,9 @@ +using osu.Framework.Graphics.Cursor; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Graphics.Cursor +{ + public interface IHasOsuContextMenu : IHasContextMenu + { + } +} diff --git a/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs b/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs index 9162fd6893..4ee3e31707 100644 --- a/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs @@ -7,8 +7,8 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Graphics.Cursor { - public class OsuContextMenuContainer : ContextMenuContainer + public class OsuContextMenuContainer : ContextMenuContainer { - protected override ContextMenu CreateContextMenu() => new OsuContextMenu(); + protected override Menu CreateMenu() => new OsuContextMenu(); } } \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 97cf1db803..0c710fd242 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -84,6 +84,7 @@ + From b42c9d21fe6922c5733366d43aec415f9a0206ff Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 25 Aug 2017 15:57:43 +0900 Subject: [PATCH 206/483] Update LoginSettings in line with framework. --- osu-framework | 2 +- .../Sections/General/LoginSettings.cs | 90 ++++++++++++------- 2 files changed, 57 insertions(+), 35 deletions(-) diff --git a/osu-framework b/osu-framework index 5a189d1050..2f0674792a 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 5a189d1050579b217bfe6b6c17c3ee6d6ef9c839 +Subproject commit 2f0674792adaf123dcf44ea0099c5707df4a6d60 diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index 7ae45159d9..111dba7151 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -257,9 +257,15 @@ namespace osu.Game.Overlays.Settings.Sections.General private class UserDropdown : OsuEnumDropdown { - protected override DropdownHeader CreateHeader() => new UserDropdownHeader { AccentColour = AccentColour }; - protected override Menu CreateMenu() => new UserDropdownMenu(); - protected override DropdownMenuItem CreateMenuItem(string text, UserAction value) => new UserDropdownMenuItem(text, value) { AccentColour = AccentColour }; + protected override DropdownHeader CreateHeader() + { + var newHeader = new UserDropdownHeader(); + newHeader.AccentColour.BindTo(AccentColour); + + return newHeader; + } + + protected override DropdownMenu CreateMenu() => new UserDropdownMenu(); public Color4 StatusColour { @@ -274,7 +280,52 @@ namespace osu.Game.Overlays.Settings.Sections.General [BackgroundDependencyLoader] private void load(OsuColour colours) { - AccentColour = colours.Gray5; + AccentColour.Value = colours.Gray5; + } + + private class UserDropdownMenu : OsuDropdownMenu + { + public UserDropdownMenu() + { + Masking = true; + CornerRadius = 5; + + Margin = new MarginPadding { Bottom = 5 }; + + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.25f), + Radius = 4, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + } + + protected override FlowContainer CreateItemsFlow() + { + var flow = base.CreateItemsFlow(); + flow.Padding = new MarginPadding(0); + + return flow; + } + + protected override MenuItemRepresentation CreateMenuItemRepresentation(DropdownMenuItem model) => new UserDropdownMenuItem(this, model); + + private class UserDropdownMenuItem : OsuDropdownMenuItemRepresentation + { + public UserDropdownMenuItem(Menu> menu, DropdownMenuItem model) + : base(menu, model) + { + Foreground.Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 5 }; + Label.Margin = new MarginPadding { Left = UserDropdownHeader.LABEL_LEFT_MARGIN - 11 }; + CornerRadius = 5; + } + } } private class UserDropdownHeader : OsuDropdownHeader @@ -324,38 +375,9 @@ namespace osu.Game.Overlays.Settings.Sections.General } } - private class UserDropdownMenu : OsuMenu - { - public UserDropdownMenu() - { - Margin = new MarginPadding { Bottom = 5 }; - CornerRadius = 5; - ItemsContainer.Padding = new MarginPadding(0); - Masking = true; - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.25f), - Radius = 4, - }; - } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Background.Colour = colours.Gray3; - } - } - private class UserDropdownMenuItem : OsuDropdownMenuItem - { - public UserDropdownMenuItem(string text, UserAction current) : base(text, current) - { - Foreground.Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 5 }; - Label.Margin = new MarginPadding { Left = UserDropdownHeader.LABEL_LEFT_MARGIN - 11 }; - CornerRadius = 5; - } - } + } private enum UserAction From 923ffae42c3cbd6403380756474f78cccc2c4e34 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 25 Aug 2017 15:57:55 +0900 Subject: [PATCH 207/483] Update SlimEnumDropdown in line with framework --- .../Overlays/SearchableList/SlimEnumDropdown.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs b/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs index 38e3e44911..e68cddb293 100644 --- a/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs +++ b/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs @@ -12,8 +12,15 @@ namespace osu.Game.Overlays.SearchableList { public class SlimEnumDropdown : OsuEnumDropdown { - protected override DropdownHeader CreateHeader() => new SlimDropdownHeader { AccentColour = AccentColour }; - protected override Menu CreateMenu() => new SlimMenu(); + protected override DropdownHeader CreateHeader() + { + var newHeader = new SlimDropdownHeader(); + newHeader.AccentColour.BindTo(AccentColour); + + return newHeader; + } + + protected override DropdownMenu CreateMenu() => new SlimMenu(); private class SlimDropdownHeader : OsuDropdownHeader { @@ -31,11 +38,11 @@ namespace osu.Game.Overlays.SearchableList } } - private class SlimMenu : OsuMenu + private class SlimMenu : OsuDropdownMenu { public SlimMenu() { - Background.Colour = Color4.Black.Opacity(0.7f); + BackgroundColour = Color4.Black.Opacity(0.7f); } } } From e83a554ffc311f03d73a53551b752395957d47a5 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 25 Aug 2017 15:58:09 +0900 Subject: [PATCH 208/483] Update CollectionsDropdown in line with framework --- .../Overlays/Music/CollectionsDropdown.cs | 57 +++++++++++-------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/osu.Game/Overlays/Music/CollectionsDropdown.cs b/osu.Game/Overlays/Music/CollectionsDropdown.cs index 0c0a636be8..be72d4481a 100644 --- a/osu.Game/Overlays/Music/CollectionsDropdown.cs +++ b/osu.Game/Overlays/Music/CollectionsDropdown.cs @@ -15,13 +15,41 @@ namespace osu.Game.Overlays.Music { public class CollectionsDropdown : OsuDropdown { - protected override DropdownHeader CreateHeader() => new CollectionsHeader { AccentColour = AccentColour }; - protected override Menu CreateMenu() => new CollectionsMenu(); - [BackgroundDependencyLoader] private void load(OsuColour colours) { - AccentColour = colours.Gray6; + AccentColour.Value = colours.Gray6; + } + + protected override DropdownHeader CreateHeader() + { + var newHeader = new CollectionsHeader(); + newHeader.AccentColour.BindTo(AccentColour); + + return newHeader; + } + + protected override DropdownMenu CreateMenu() => new CollectionsMenu(); + + private class CollectionsMenu : OsuDropdownMenu + { + public CollectionsMenu() + { + CornerRadius = 5; + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.3f), + Radius = 3, + Offset = new Vector2(0f, 1f), + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray4; + } } private class CollectionsHeader : OsuDropdownHeader @@ -48,26 +76,5 @@ namespace osu.Game.Overlays.Music }; } } - - private class CollectionsMenu : OsuMenu - { - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Background.Colour = colours.Gray4; - } - - public CollectionsMenu() - { - CornerRadius = 5; - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.3f), - Radius = 3, - Offset = new Vector2(0f, 1f), - }; - } - } } } From a3a5a89636d4cf93b3c8872d62d9cb9d2aa674ca Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 25 Aug 2017 15:58:21 +0900 Subject: [PATCH 209/483] Update OsuDropdown in line with framework --- .../Graphics/UserInterface/OsuDropdown.cs | 165 ++++++++++-------- 1 file changed, 89 insertions(+), 76 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index f5a4219707..d556c58bdd 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -1,9 +1,9 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Linq; using OpenTK.Graphics; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -16,52 +16,96 @@ namespace osu.Game.Graphics.UserInterface { public class OsuDropdown : Dropdown { - protected override DropdownHeader CreateHeader() => new OsuDropdownHeader { AccentColour = AccentColour }; - - protected override Menu CreateMenu() => new OsuMenu(); - - private Color4? accentColour; - public virtual Color4 AccentColour - { - get { return accentColour.GetValueOrDefault(); } - set - { - accentColour = value; - if (Header != null) - ((OsuDropdownHeader)Header).AccentColour = value; - foreach (var item in MenuItems.OfType()) - item.AccentColour = value; - } - } + public readonly Bindable AccentColour = new Bindable(); [BackgroundDependencyLoader] private void load(OsuColour colours) { - if (accentColour == null) - AccentColour = colours.PinkDarker; + if (AccentColour.Value == null) + AccentColour.Value = colours.PinkDarker; } - protected override DropdownMenuItem CreateMenuItem(string text, T value) => new OsuDropdownMenuItem(text, value) { AccentColour = AccentColour }; - - public class OsuDropdownMenuItem : DropdownMenuItem + protected override DropdownHeader CreateHeader() { - public OsuDropdownMenuItem(string text, T current) : base(text, current) + var newHeader = new OsuDropdownHeader(); + newHeader.AccentColour.BindTo(AccentColour); + + return newHeader; + } + + protected override DropdownMenu CreateMenu() + { + var newMenu = new OsuDropdownMenu(); + newMenu.AccentColour.BindTo(AccentColour); + + return newMenu; + } + + #region OsuDropdownMenu + protected class OsuDropdownMenu : DropdownMenu + { + public readonly Bindable AccentColour = new Bindable(); + + protected override MenuItemRepresentation CreateMenuItemRepresentation(DropdownMenuItem model) { - Foreground.Padding = new MarginPadding(2); + var newItem = new OsuDropdownMenuItemRepresentation(this, model); + newItem.AccentColour.BindTo(AccentColour); - Masking = true; - CornerRadius = 6; + return newItem; + } - Children = new[] + #region OsuDropdownMenuItemRepresentation + protected class OsuDropdownMenuItemRepresentation : DropdownMenuItemRepresentation + { + public readonly Bindable AccentColour = new Bindable(); + + private SpriteIcon chevron; + protected OsuSpriteText Label; + + private Color4 nonAccentHoverColour; + private Color4 nonAccentSelectedColour; + + public OsuDropdownMenuItemRepresentation(Menu> menu, DropdownMenuItem model) + : base(menu, model) { - new FillFlowContainer + Foreground.Padding = new MarginPadding(2); + + Masking = true; + CornerRadius = 6; + + AccentColour.ValueChanged += updateAccent; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = Color4.Transparent; + nonAccentHoverColour = colours.PinkDarker; + nonAccentSelectedColour = Color4.Black.Opacity(0.5f); + } + + private void updateAccent(Color4? newValue) + { + BackgroundColourHover = newValue ?? nonAccentHoverColour; + BackgroundColourSelected = newValue ?? nonAccentSelectedColour; + AnimateBackground(IsHovered); + AnimateForeground(IsHovered); + } + + protected override void AnimateForeground(bool hover) + { + base.AnimateForeground(hover); + chevron.Alpha = hover ? 1 : 0; + } + + protected override Drawable CreateText(string title) => new FillFlowContainer { Direction = FillDirection.Horizontal, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Children = new Drawable[] { - Chevron = new SpriteIcon + chevron = new SpriteIcon { AlwaysPresent = true, Icon = FontAwesome.fa_chevron_right, @@ -72,47 +116,18 @@ namespace osu.Game.Graphics.UserInterface Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, }, - Label = new OsuSpriteText { - Text = text, + Label = new OsuSpriteText + { + Text = title, Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, } } - } - }; - } - - private Color4? accentColour; - - protected readonly SpriteIcon Chevron; - protected readonly OsuSpriteText Label; - - protected override void FormatForeground(bool hover = false) - { - base.FormatForeground(hover); - Chevron.Alpha = hover ? 1 : 0; - } - - public Color4 AccentColour - { - get { return accentColour.GetValueOrDefault(); } - set - { - accentColour = value; - BackgroundColourHover = BackgroundColourSelected = value; - FormatBackground(); - FormatForeground(); - } - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BackgroundColour = Color4.Transparent; - BackgroundColourHover = accentColour ?? colours.PinkDarker; - BackgroundColourSelected = Color4.Black.Opacity(0.5f); + }; } + #endregion } + #endregion public class OsuDropdownHeader : DropdownHeader { @@ -125,16 +140,7 @@ namespace osu.Game.Graphics.UserInterface protected readonly SpriteIcon Icon; - private Color4? accentColour; - public virtual Color4 AccentColour - { - get { return accentColour.GetValueOrDefault(); } - set - { - accentColour = value; - BackgroundColourHover = value; - } - } + public readonly Bindable AccentColour = new Bindable(); public OsuDropdownHeader() { @@ -161,13 +167,20 @@ namespace osu.Game.Graphics.UserInterface Size = new Vector2(20), } }; + + AccentColour.ValueChanged += accentColourChanged; } [BackgroundDependencyLoader] private void load(OsuColour colours) { BackgroundColour = Color4.Black.Opacity(0.5f); - BackgroundColourHover = accentColour ?? colours.PinkDarker; + BackgroundColourHover = AccentColour?.Value ?? colours.PinkDarker; + } + + private void accentColourChanged(Color4? newValue) + { + BackgroundColourHover = newValue ?? Color4.White; } } } From ce644138b9f117de9094ffab9cada87a1ebd3df0 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 25 Aug 2017 15:58:30 +0900 Subject: [PATCH 210/483] Update OsuTabControl in line with framework --- .../Graphics/UserInterface/OsuTabControl.cs | 101 ++++++++++-------- 1 file changed, 59 insertions(+), 42 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 5ad412965c..bc673a7af6 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -50,7 +50,7 @@ namespace osu.Game.Graphics.UserInterface accentColour = value; var dropDown = Dropdown as OsuTabDropdown; if (dropDown != null) - dropDown.AccentColour = value; + dropDown.AccentColour.Value = value; foreach (var item in TabContainer.Children.OfType()) item.AccentColour = value; } @@ -142,55 +142,53 @@ namespace osu.Game.Graphics.UserInterface private class OsuTabDropdown : OsuDropdown { - protected override DropdownHeader CreateHeader() => new OsuTabDropdownHeader - { - AccentColour = AccentColour, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - }; - - protected override DropdownMenuItem CreateMenuItem(string text, T value) - { - var item = base.CreateMenuItem(text, value); - item.ForegroundColourHover = Color4.Black; - return item; - } - public OsuTabDropdown() { - DropdownMenu.Anchor = Anchor.TopRight; - DropdownMenu.Origin = Anchor.TopRight; - RelativeSizeAxes = Axes.X; - DropdownMenu.Background.Colour = Color4.Black.Opacity(0.7f); - DropdownMenu.MaxHeight = 400; + + } + + protected override DropdownMenu CreateMenu() => new OsuTabDropdownMenu(); + + protected override DropdownHeader CreateHeader() + { + var newHeader = new OsuTabDropdownHeader + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight + }; + + newHeader.AccentColour.BindTo(AccentColour); + + return newHeader; + } + + private class OsuTabDropdownMenu : OsuDropdownMenu + { + public OsuTabDropdownMenu() + { + Anchor = Anchor.TopRight; + Origin = Anchor.TopRight; + + BackgroundColour = Color4.Black.Opacity(0.7f); + MaxHeight = 400; + } + + protected override MenuItemRepresentation CreateMenuItemRepresentation(DropdownMenuItem model) => new OsuTabDropdownMenuItemRepresentation(this, model); + + private class OsuTabDropdownMenuItemRepresentation : OsuDropdownMenuItemRepresentation + { + public OsuTabDropdownMenuItemRepresentation(Menu> menu, DropdownMenuItem model) + : base(menu, model) + { + ForegroundColourHover = Color4.Black; + } + } } protected class OsuTabDropdownHeader : OsuDropdownHeader { - public override Color4 AccentColour - { - get { return base.AccentColour; } - set - { - base.AccentColour = value; - Foreground.Colour = value; - } - } - - protected override bool OnHover(InputState state) - { - Foreground.Colour = BackgroundColour; - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - Foreground.Colour = BackgroundColourHover; - base.OnHoverLost(state); - } - public OsuTabDropdownHeader() { RelativeSizeAxes = Axes.None; @@ -219,6 +217,25 @@ namespace osu.Game.Graphics.UserInterface }; Padding = new MarginPadding { Left = 5, Right = 5 }; + + AccentColour.ValueChanged += accentColourChanged; + } + + private void accentColourChanged(Color4? newValue) + { + Foreground.Colour = newValue ?? Color4.White; + } + + protected override bool OnHover(InputState state) + { + Foreground.Colour = BackgroundColour; + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + Foreground.Colour = BackgroundColourHover; + base.OnHoverLost(state); } } } From 9f02000174808c0f99f4d97035305e94a1aaa6d2 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 25 Aug 2017 15:58:42 +0900 Subject: [PATCH 211/483] Update FilterControl using new AccentColour definition --- osu.Game/Overlays/Direct/FilterControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 28d26d0641..ca9e8667e6 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -36,7 +36,7 @@ namespace osu.Game.Overlays.Direct [BackgroundDependencyLoader(true)] private void load(OsuGame game, RulesetStore rulesets, OsuColour colours) { - DisplayStyleControl.Dropdown.AccentColour = colours.BlueDark; + DisplayStyleControl.Dropdown.AccentColour.Value = colours.BlueDark; Ruleset.BindTo(game?.Ruleset ?? new Bindable { Value = rulesets.GetRuleset(0) }); foreach (var r in rulesets.AllRulesets) From 3ffc46770472e1d91f2a160350f46e521f0147f7 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 25 Aug 2017 16:27:01 +0900 Subject: [PATCH 212/483] Fix crappy resizing. --- osu-framework | 2 +- osu.Game/Graphics/UserInterface/OsuMenu.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu-framework b/osu-framework index 2f0674792a..56ce220e7f 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 2f0674792adaf123dcf44ea0099c5707df4a6d60 +Subproject commit 56ce220e7f631ce2890597e505d073cdfc0233a1 diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index 79519e26a0..45bee216ad 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -25,7 +25,7 @@ namespace osu.Game.Graphics.UserInterface protected override void UpdateMenuHeight() { var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight; - this.ResizeTo(new Vector2(1, State == MenuState.Opened ? actualHeight : 0), 300, Easing.OutQuint); + this.ResizeHeightTo(State == MenuState.Opened ? actualHeight : 0, 300, Easing.OutQuint); } protected override FlowContainer CreateItemsFlow() From ee85515d951846d1cdd5241c89ec47a77a5efa10 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Aug 2017 18:41:12 +0900 Subject: [PATCH 213/483] Changes in line with framework changes --- osu-framework | 2 +- .../Graphics/UserInterface/OsuContextMenu.cs | 26 ++++------ .../Graphics/UserInterface/OsuDropdown.cs | 48 ++++++++++++++----- osu.Game/Graphics/UserInterface/OsuMenu.cs | 14 +----- .../Graphics/UserInterface/OsuTabControl.cs | 32 ++++++++----- .../Sections/General/LoginSettings.cs | 20 +++----- 6 files changed, 75 insertions(+), 67 deletions(-) diff --git a/osu-framework b/osu-framework index 56ce220e7f..926d7c971d 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 56ce220e7f631ce2890597e505d073cdfc0233a1 +Subproject commit 926d7c971d059c7aeb3ccfb09d06910c46aa3a40 diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs index ddb91d42a1..ad4cd1edbc 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -39,18 +39,12 @@ namespace osu.Game.Graphics.UserInterface protected override void AnimateOpen() => this.FadeIn(fade_duration, Easing.OutQuint); protected override void AnimateClose() => this.FadeOut(fade_duration, Easing.OutQuint); - protected override FlowContainer CreateItemsFlow() - { - var flow = base.CreateItemsFlow(); - flow.Padding = new MarginPadding { Vertical = OsuContextMenuItemRepresentation.MARGIN_VERTICAL }; + protected override MarginPadding ItemFlowContainerPadding => new MarginPadding { Vertical = DrawableOsuContextMenuItem.MARGIN_VERTICAL }; - return flow; - } + protected override DrawableMenuItem CreateDrawableMenuItem(TItem item) => new DrawableOsuContextMenuItem(this, item); - protected override MenuItemRepresentation CreateMenuItemRepresentation(TItem model) => new OsuContextMenuItemRepresentation(this, model); - - #region OsuContextMenuItemRepresentation - private class OsuContextMenuItemRepresentation : MenuItemRepresentation + #region DrawableOsuContextMenuItem + private class DrawableOsuContextMenuItem : DrawableMenuItem { private const int margin_horizontal = 17; private const int text_size = 17; @@ -63,8 +57,8 @@ namespace osu.Game.Graphics.UserInterface private OsuSpriteText text; private OsuSpriteText textBold; - public OsuContextMenuItemRepresentation(Menu menu, TItem model) - : base(menu, model) + public DrawableOsuContextMenuItem(Menu menu, TItem item) + : base(item) { } @@ -82,7 +76,7 @@ namespace osu.Game.Graphics.UserInterface private void updateTextColour() { - switch (Model.Type) + switch (Item.Type) { case MenuItemType.Standard: textBold.Colour = text.Colour = Color4.White; @@ -117,7 +111,7 @@ namespace osu.Game.Graphics.UserInterface return base.OnClick(state); } - protected override Drawable CreateText(string title) => new Container + protected override Drawable CreateContent() => new Container { AutoSizeAxes = Axes.Both, Anchor = Anchor.CentreLeft, @@ -129,7 +123,7 @@ namespace osu.Game.Graphics.UserInterface Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, TextSize = text_size, - Text = title, + Text = Item.Text, Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, }, textBold = new OsuSpriteText @@ -139,7 +133,7 @@ namespace osu.Game.Graphics.UserInterface Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, TextSize = text_size, - Text = title, + Text = Item.Text, Font = @"Exo2.0-Bold", Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, } diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index d556c58bdd..2c691b7763 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -44,18 +44,40 @@ namespace osu.Game.Graphics.UserInterface #region OsuDropdownMenu protected class OsuDropdownMenu : DropdownMenu { + // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring + public OsuDropdownMenu() + { + CornerRadius = 4; + BackgroundColour = Color4.Black.Opacity(0.5f); + } + + // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring + protected override void AnimateOpen() => this.FadeIn(300, Easing.OutQuint); + protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint); + + // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring + protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(5); + + // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring + protected override void UpdateMenuHeight() + { + var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight; + this.ResizeHeightTo(State == MenuState.Opened ? actualHeight : 0, 300, Easing.OutQuint); + } + public readonly Bindable AccentColour = new Bindable(); - protected override MenuItemRepresentation CreateMenuItemRepresentation(DropdownMenuItem model) + + protected override DrawableMenuItem CreateDrawableMenuItem(DropdownMenuItem item) { - var newItem = new OsuDropdownMenuItemRepresentation(this, model); + var newItem = new DrawableOsuDropdownMenuItem(item); newItem.AccentColour.BindTo(AccentColour); return newItem; } - #region OsuDropdownMenuItemRepresentation - protected class OsuDropdownMenuItemRepresentation : DropdownMenuItemRepresentation + #region DrawableOsuDropdownMenuItem + protected class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem { public readonly Bindable AccentColour = new Bindable(); @@ -65,8 +87,8 @@ namespace osu.Game.Graphics.UserInterface private Color4 nonAccentHoverColour; private Color4 nonAccentSelectedColour; - public OsuDropdownMenuItemRepresentation(Menu> menu, DropdownMenuItem model) - : base(menu, model) + public DrawableOsuDropdownMenuItem(DropdownMenuItem item) + : base(item) { Foreground.Padding = new MarginPadding(2); @@ -88,17 +110,17 @@ namespace osu.Game.Graphics.UserInterface { BackgroundColourHover = newValue ?? nonAccentHoverColour; BackgroundColourSelected = newValue ?? nonAccentSelectedColour; - AnimateBackground(IsHovered); - AnimateForeground(IsHovered); + UpdateBackgroundColour(); + UpdateForegroundColour(); } - protected override void AnimateForeground(bool hover) + protected override void UpdateForegroundColour() { - base.AnimateForeground(hover); - chevron.Alpha = hover ? 1 : 0; + base.UpdateForegroundColour(); + chevron.Alpha = IsHovered ? 1 : 0; } - protected override Drawable CreateText(string title) => new FillFlowContainer + protected override Drawable CreateContent() => new FillFlowContainer { Direction = FillDirection.Horizontal, RelativeSizeAxes = Axes.X, @@ -118,7 +140,7 @@ namespace osu.Game.Graphics.UserInterface }, Label = new OsuSpriteText { - Text = title, + Text = Item.Text, Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, } diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index 45bee216ad..0c5bfa2947 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -1,11 +1,9 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterface @@ -28,16 +26,6 @@ namespace osu.Game.Graphics.UserInterface this.ResizeHeightTo(State == MenuState.Opened ? actualHeight : 0, 300, Easing.OutQuint); } - protected override FlowContainer CreateItemsFlow() - { - var flow = base.CreateItemsFlow(); - flow.Padding = new MarginPadding(5); - - return flow; - } - } - - public class OsuMenu : OsuMenu - { + protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(5); } } diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index bc673a7af6..58d853d97e 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -48,9 +48,9 @@ namespace osu.Game.Graphics.UserInterface set { accentColour = value; - var dropDown = Dropdown as OsuTabDropdown; - if (dropDown != null) - dropDown.AccentColour.Value = value; + var dropdown = Dropdown as OsuTabDropdown; + if (dropdown != null) + dropdown.AccentColour.Value = value; foreach (var item in TabContainer.Children.OfType()) item.AccentColour = value; } @@ -140,16 +140,20 @@ namespace osu.Game.Graphics.UserInterface protected override void OnDeactivated() => fadeInactive(); } + // todo: this needs to go private class OsuTabDropdown : OsuDropdown { public OsuTabDropdown() { RelativeSizeAxes = Axes.X; - - } - protected override DropdownMenu CreateMenu() => new OsuTabDropdownMenu(); + protected override DropdownMenu CreateMenu() + { + var menu = new OsuTabDropdownMenu(); + menu.AccentColour.BindTo(AccentColour); + return menu; + } protected override DropdownHeader CreateHeader() { @@ -175,18 +179,24 @@ namespace osu.Game.Graphics.UserInterface MaxHeight = 400; } - protected override MenuItemRepresentation CreateMenuItemRepresentation(DropdownMenuItem model) => new OsuTabDropdownMenuItemRepresentation(this, model); - - private class OsuTabDropdownMenuItemRepresentation : OsuDropdownMenuItemRepresentation + protected override DrawableMenuItem CreateDrawableMenuItem(DropdownMenuItem item) { - public OsuTabDropdownMenuItemRepresentation(Menu> menu, DropdownMenuItem model) - : base(menu, model) + var poop = new DrawableOsuTabDropdownMenuItem(this, item); + poop.AccentColour.BindTo(AccentColour); + return poop; + } + + private class DrawableOsuTabDropdownMenuItem : DrawableOsuDropdownMenuItem + { + public DrawableOsuTabDropdownMenuItem(Menu> menu, DropdownMenuItem item) + : base(item) { ForegroundColourHover = Color4.Black; } } } + protected class OsuTabDropdownHeader : OsuDropdownHeader { public OsuTabDropdownHeader() diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index 111dba7151..ad7c7cf092 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -306,20 +306,14 @@ namespace osu.Game.Overlays.Settings.Sections.General BackgroundColour = colours.Gray3; } - protected override FlowContainer CreateItemsFlow() + protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(); + + protected override DrawableMenuItem CreateDrawableMenuItem(DropdownMenuItem item) => new DrawableUserDropdownMenuItem(this, item); + + private class DrawableUserDropdownMenuItem : DrawableOsuDropdownMenuItem { - var flow = base.CreateItemsFlow(); - flow.Padding = new MarginPadding(0); - - return flow; - } - - protected override MenuItemRepresentation CreateMenuItemRepresentation(DropdownMenuItem model) => new UserDropdownMenuItem(this, model); - - private class UserDropdownMenuItem : OsuDropdownMenuItemRepresentation - { - public UserDropdownMenuItem(Menu> menu, DropdownMenuItem model) - : base(menu, model) + public DrawableUserDropdownMenuItem(Menu> menu, DropdownMenuItem item) + : base(item) { Foreground.Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 5 }; Label.Margin = new MarginPadding { Left = UserDropdownHeader.LABEL_LEFT_MARGIN - 11 }; From 9374bf925ef2771cb74a9f94cec78fe219d57858 Mon Sep 17 00:00:00 2001 From: Jorolf Date: Fri, 25 Aug 2017 16:39:49 +0200 Subject: [PATCH 214/483] only show warning when focused --- .../Graphics/UserInterface/OsuPasswordTextBox.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index 2fdbf64d08..c3cc4fe77b 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -44,10 +44,24 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { if (args.Key == OpenTK.Input.Key.CapsLock) - warning.FadeTo(host.CapsLockEnabled ? 1 : 0, 250, Easing.OutQuint); + updateCapsWarning(host.CapsLockEnabled); return base.OnKeyDown(state, args); } + protected override void OnFocus(InputState state) + { + updateCapsWarning(host.CapsLockEnabled); + base.OnFocus(state); + } + + protected override void OnFocusLost(InputState state) + { + updateCapsWarning(false); + base.OnFocusLost(state); + } + + private void updateCapsWarning(bool visible) => warning.FadeTo(visible ? 1 : 0, 250, Easing.OutQuint); + public class PasswordMaskChar : Container { private readonly CircularContainer circle; From 4385edeb453103fe817e6af7326046d040dd046b Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 28 Aug 2017 11:01:53 +0900 Subject: [PATCH 215/483] Update usages of Menu to reflect ValueChanged events. --- osu-framework | 2 +- .../Graphics/UserInterface/OsuContextMenu.cs | 59 +++++++++++-------- .../Graphics/UserInterface/OsuDropdown.cs | 50 +++++++++------- 3 files changed, 64 insertions(+), 47 deletions(-) diff --git a/osu-framework b/osu-framework index 926d7c971d..743ad1129e 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 926d7c971d059c7aeb3ccfb09d06910c46aa3a40 +Subproject commit 743ad1129edbc1cb8faa14ebc9a6d1846780795c diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs index ad4cd1edbc..9bc2f381c0 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -111,34 +111,45 @@ namespace osu.Game.Graphics.UserInterface return base.OnClick(state); } - protected override Drawable CreateContent() => new Container + protected override Drawable CreateContent() { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Children = new Drawable[] + var container = new Container { - text = new OsuSpriteText + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Children = new Drawable[] { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = text_size, - Text = Item.Text, - Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, - }, - textBold = new OsuSpriteText - { - AlwaysPresent = true, - Alpha = 0, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = text_size, - Text = Item.Text, - Font = @"Exo2.0-Bold", - Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, + text = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = text_size, + Text = Item.Text, + Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, + }, + textBold = new OsuSpriteText + { + AlwaysPresent = true, + Alpha = 0, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = text_size, + Text = Item.Text, + Font = @"Exo2.0-Bold", + Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, + } } - } - }; + }; + + Item.Text.ValueChanged += newText => + { + text.Text = newText; + textBold.Text = newText; + }; + + return container; + } } #endregion } diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index 2c691b7763..8984ba1eba 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -120,32 +120,38 @@ namespace osu.Game.Graphics.UserInterface chevron.Alpha = IsHovered ? 1 : 0; } - protected override Drawable CreateContent() => new FillFlowContainer + protected override Drawable CreateContent() { - Direction = FillDirection.Horizontal, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] + var container = new FillFlowContainer { - chevron = new SpriteIcon + Direction = FillDirection.Horizontal, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] { - AlwaysPresent = true, - Icon = FontAwesome.fa_chevron_right, - Colour = Color4.Black, - Alpha = 0.5f, - Size = new Vector2(8), - Margin = new MarginPadding { Left = 3, Right = 3 }, - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - }, - Label = new OsuSpriteText - { - Text = Item.Text, - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, + chevron = new SpriteIcon + { + AlwaysPresent = true, + Icon = FontAwesome.fa_chevron_right, + Colour = Color4.Black, + Alpha = 0.5f, + Size = new Vector2(8), + Margin = new MarginPadding { Left = 3, Right = 3 }, + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + }, + Label = new OsuSpriteText + { + Text = Item.Text, + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + } } - } - }; + }; + + Item.Text.ValueChanged += newText => Label.Text = newText; + return container; + } } #endregion } From b5c1c05af5443246a1ec19a4cf09d03a7384ed88 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 28 Aug 2017 11:03:51 +0900 Subject: [PATCH 216/483] Remove poop. --- osu.Game/Graphics/UserInterface/OsuTabControl.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 58d853d97e..faa7b269bb 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -181,9 +181,9 @@ namespace osu.Game.Graphics.UserInterface protected override DrawableMenuItem CreateDrawableMenuItem(DropdownMenuItem item) { - var poop = new DrawableOsuTabDropdownMenuItem(this, item); - poop.AccentColour.BindTo(AccentColour); - return poop; + var result = new DrawableOsuTabDropdownMenuItem(this, item); + result.AccentColour.BindTo(AccentColour); + return result; } private class DrawableOsuTabDropdownMenuItem : DrawableOsuDropdownMenuItem From 66db3389f6f8f7ce58e42fb008980fb923739366 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 28 Aug 2017 12:33:31 +0900 Subject: [PATCH 217/483] Update in line with framework changes. --- osu-framework | 2 +- .../Graphics/UserInterface/OsuContextMenu.cs | 63 ++++++++++--------- .../Graphics/UserInterface/OsuDropdown.cs | 38 ++++++----- .../Sections/General/LoginSettings.cs | 6 +- 4 files changed, 64 insertions(+), 45 deletions(-) diff --git a/osu-framework b/osu-framework index 743ad1129e..2958d6fda1 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 743ad1129edbc1cb8faa14ebc9a6d1846780795c +Subproject commit 2958d6fda1be252a0f479609090e72814b177c91 diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs index 9bc2f381c0..4ec349edd7 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -8,6 +8,7 @@ using osu.Framework.Audio.Sample; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; using osu.Game.Graphics.Sprites; @@ -54,8 +55,7 @@ namespace osu.Game.Graphics.UserInterface private SampleChannel sampleClick; private SampleChannel sampleHover; - private OsuSpriteText text; - private OsuSpriteText textBold; + private TextContainer text; public DrawableOsuContextMenuItem(Menu menu, TItem item) : base(item) @@ -79,13 +79,13 @@ namespace osu.Game.Graphics.UserInterface switch (Item.Type) { case MenuItemType.Standard: - textBold.Colour = text.Colour = Color4.White; + text.Colour = Color4.White; break; case MenuItemType.Destructive: - textBold.Colour = text.Colour = Color4.Red; + text.Colour = Color4.Red; break; case MenuItemType.Highlighted: - textBold.Colour = text.Colour = OsuColour.FromHex(@"ffcc22"); + text.Colour = OsuColour.FromHex(@"ffcc22"); break; } } @@ -93,15 +93,15 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnHover(InputState state) { sampleHover.Play(); - textBold.FadeIn(transition_length, Easing.OutQuint); - text.FadeOut(transition_length, Easing.OutQuint); + text.BoldText.FadeIn(transition_length, Easing.OutQuint); + text.NormalText.FadeOut(transition_length, Easing.OutQuint); return base.OnHover(state); } protected override void OnHoverLost(InputState state) { - textBold.FadeOut(transition_length, Easing.OutQuint); - text.FadeIn(transition_length, Easing.OutQuint); + text.BoldText.FadeOut(transition_length, Easing.OutQuint); + text.NormalText.FadeIn(transition_length, Easing.OutQuint); base.OnHoverLost(state); } @@ -111,44 +111,51 @@ namespace osu.Game.Graphics.UserInterface return base.OnClick(state); } - protected override Drawable CreateContent() + protected override Drawable CreateContent() => text = new TextContainer(); + + private class TextContainer : Container, IHasText { - var container = new Container + public string Text { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, + get { return NormalText.Text; } + set + { + NormalText.Text = value; + BoldText.Text = value; + } + } + + public readonly SpriteText NormalText; + public readonly SpriteText BoldText; + + public TextContainer() + { + Anchor = Anchor.CentreLeft; + Origin = Anchor.CentreLeft; + + AutoSizeAxes = Axes.Both; + Children = new Drawable[] { - text = new OsuSpriteText + NormalText = new OsuSpriteText { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, TextSize = text_size, - Text = Item.Text, Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, }, - textBold = new OsuSpriteText + BoldText = new OsuSpriteText { AlwaysPresent = true, Alpha = 0, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, TextSize = text_size, - Text = Item.Text, Font = @"Exo2.0-Bold", Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, } - } - }; - - Item.Text.ValueChanged += newText => - { - text.Text = newText; - textBold.Text = newText; - }; - - return container; + }; + } } } #endregion diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index 8984ba1eba..d67a995e67 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -81,8 +81,7 @@ namespace osu.Game.Graphics.UserInterface { public readonly Bindable AccentColour = new Bindable(); - private SpriteIcon chevron; - protected OsuSpriteText Label; + private TextContainer textContainer; private Color4 nonAccentHoverColour; private Color4 nonAccentSelectedColour; @@ -117,19 +116,32 @@ namespace osu.Game.Graphics.UserInterface protected override void UpdateForegroundColour() { base.UpdateForegroundColour(); - chevron.Alpha = IsHovered ? 1 : 0; + + textContainer.Chevron.Alpha = IsHovered ? 1 : 0; } - protected override Drawable CreateContent() + protected override Drawable CreateContent() => textContainer = new TextContainer(); + + protected class TextContainer : FillFlowContainer, IHasText { - var container = new FillFlowContainer + public string Text { - Direction = FillDirection.Horizontal, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, + get { return Label.Text; } + set { Label.Text = value; } + } + + public readonly OsuSpriteText Label; + public readonly SpriteIcon Chevron; + + public TextContainer() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Direction = FillDirection.Horizontal; + Children = new Drawable[] { - chevron = new SpriteIcon + Chevron = new SpriteIcon { AlwaysPresent = true, Icon = FontAwesome.fa_chevron_right, @@ -142,15 +154,11 @@ namespace osu.Game.Graphics.UserInterface }, Label = new OsuSpriteText { - Text = Item.Text, Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, } - } - }; - - Item.Text.ValueChanged += newText => Label.Text = newText; - return container; + }; + } } } #endregion diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index ad7c7cf092..609b4b1e16 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -316,9 +316,13 @@ namespace osu.Game.Overlays.Settings.Sections.General : base(item) { Foreground.Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 5 }; - Label.Margin = new MarginPadding { Left = UserDropdownHeader.LABEL_LEFT_MARGIN - 11 }; CornerRadius = 5; } + + protected override Drawable CreateContent() => new TextContainer + { + Label = { Margin = new MarginPadding { Left = UserDropdownHeader.LABEL_LEFT_MARGIN - 11 } } + }; } } From fc6c682d886b2d93217c57896e08f764e7d810d5 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 28 Aug 2017 14:42:52 +0900 Subject: [PATCH 218/483] Update in-line with framework changes. --- osu-framework | 2 +- .../Visual/TestCaseContextMenu.cs | 37 ++++++++++--------- .../Graphics/Cursor/IHasOsuContextMenu.cs | 9 ----- .../Cursor/OsuContextMenuContainer.cs | 4 +- .../Graphics/UserInterface/OsuContextMenu.cs | 12 +++--- .../Graphics/UserInterface/OsuDropdown.cs | 4 +- osu.Game/Graphics/UserInterface/OsuMenu.cs | 3 +- .../{OsuContextMenuItem.cs => OsuMenuItem.cs} | 6 +-- .../Graphics/UserInterface/OsuTabControl.cs | 6 +-- .../Sections/General/LoginSettings.cs | 4 +- osu.Game/osu.Game.csproj | 3 +- 11 files changed, 41 insertions(+), 49 deletions(-) delete mode 100644 osu.Game/Graphics/Cursor/IHasOsuContextMenu.cs rename osu.Game/Graphics/UserInterface/{OsuContextMenuItem.cs => OsuMenuItem.cs} (65%) diff --git a/osu-framework b/osu-framework index 2958d6fda1..2cb3e59c8b 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 2958d6fda1be252a0f479609090e72814b177c91 +Subproject commit 2cb3e59c8bc7e67edef4dfe7f9c7dfc01db386a7 diff --git a/osu.Desktop.Tests/Visual/TestCaseContextMenu.cs b/osu.Desktop.Tests/Visual/TestCaseContextMenu.cs index 2ac3a28bd4..0d9c5e7ed1 100644 --- a/osu.Desktop.Tests/Visual/TestCaseContextMenu.cs +++ b/osu.Desktop.Tests/Visual/TestCaseContextMenu.cs @@ -3,8 +3,9 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics.Cursor; +using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; @@ -66,30 +67,30 @@ namespace osu.Desktop.Tests.Visual ); } - private class MyContextMenuContainer : Container, IHasOsuContextMenu + private class MyContextMenuContainer : Container, IHasContextMenu { - public OsuContextMenuItem[] ContextMenuItems => new[] + public MenuItem[] ContextMenuItems => new MenuItem[] { - new OsuContextMenuItem(@"Some option"), - new OsuContextMenuItem(@"Highlighted option", MenuItemType.Highlighted), - new OsuContextMenuItem(@"Another option"), - new OsuContextMenuItem(@"Choose me please"), - new OsuContextMenuItem(@"And me too"), - new OsuContextMenuItem(@"Trying to fill"), - new OsuContextMenuItem(@"Destructive option", MenuItemType.Destructive), + new OsuMenuItem(@"Some option"), + new OsuMenuItem(@"Highlighted option", MenuItemType.Highlighted), + new OsuMenuItem(@"Another option"), + new OsuMenuItem(@"Choose me please"), + new OsuMenuItem(@"And me too"), + new OsuMenuItem(@"Trying to fill"), + new OsuMenuItem(@"Destructive option", MenuItemType.Destructive), }; } - private class AnotherContextMenuContainer : Container, IHasOsuContextMenu + private class AnotherContextMenuContainer : Container, IHasContextMenu { - public OsuContextMenuItem[] ContextMenuItems => new[] + public MenuItem[] ContextMenuItems => new MenuItem[] { - new OsuContextMenuItem(@"Simple option"), - new OsuContextMenuItem(@"Simple very very long option"), - new OsuContextMenuItem(@"Change width", MenuItemType.Highlighted, () => this.ResizeWidthTo(Width * 2, 100, Easing.OutQuint)), - new OsuContextMenuItem(@"Change height", MenuItemType.Highlighted, () => this.ResizeHeightTo(Height * 2, 100, Easing.OutQuint)), - new OsuContextMenuItem(@"Change width back", MenuItemType.Destructive, () => this.ResizeWidthTo(Width / 2, 100, Easing.OutQuint)), - new OsuContextMenuItem(@"Change height back", MenuItemType.Destructive, () => this.ResizeHeightTo(Height / 2, 100, Easing.OutQuint)), + new OsuMenuItem(@"Simple option"), + new OsuMenuItem(@"Simple very very long option"), + new OsuMenuItem(@"Change width", MenuItemType.Highlighted, () => this.ResizeWidthTo(Width * 2, 100, Easing.OutQuint)), + new OsuMenuItem(@"Change height", MenuItemType.Highlighted, () => this.ResizeHeightTo(Height * 2, 100, Easing.OutQuint)), + new OsuMenuItem(@"Change width back", MenuItemType.Destructive, () => this.ResizeWidthTo(Width / 2, 100, Easing.OutQuint)), + new OsuMenuItem(@"Change height back", MenuItemType.Destructive, () => this.ResizeHeightTo(Height / 2, 100, Easing.OutQuint)), }; } } diff --git a/osu.Game/Graphics/Cursor/IHasOsuContextMenu.cs b/osu.Game/Graphics/Cursor/IHasOsuContextMenu.cs deleted file mode 100644 index 6fb1a3d31f..0000000000 --- a/osu.Game/Graphics/Cursor/IHasOsuContextMenu.cs +++ /dev/null @@ -1,9 +0,0 @@ -using osu.Framework.Graphics.Cursor; -using osu.Game.Graphics.UserInterface; - -namespace osu.Game.Graphics.Cursor -{ - public interface IHasOsuContextMenu : IHasContextMenu - { - } -} diff --git a/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs b/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs index 4ee3e31707..1ece10bc60 100644 --- a/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs @@ -7,8 +7,8 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Graphics.Cursor { - public class OsuContextMenuContainer : ContextMenuContainer + public class OsuContextMenuContainer : ContextMenuContainer { - protected override Menu CreateMenu() => new OsuContextMenu(); + protected override Menu CreateMenu() => new OsuContextMenu(); } } \ No newline at end of file diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs index 4ec349edd7..9a2917cd66 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -15,8 +16,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { - public class OsuContextMenu : OsuMenu - where TItem : OsuContextMenuItem + public class OsuContextMenu : OsuMenu { private const int fade_duration = 250; @@ -42,7 +42,7 @@ namespace osu.Game.Graphics.UserInterface protected override MarginPadding ItemFlowContainerPadding => new MarginPadding { Vertical = DrawableOsuContextMenuItem.MARGIN_VERTICAL }; - protected override DrawableMenuItem CreateDrawableMenuItem(TItem item) => new DrawableOsuContextMenuItem(this, item); + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuContextMenuItem(item); #region DrawableOsuContextMenuItem private class DrawableOsuContextMenuItem : DrawableMenuItem @@ -57,9 +57,11 @@ namespace osu.Game.Graphics.UserInterface private TextContainer text; - public DrawableOsuContextMenuItem(Menu menu, TItem item) + public DrawableOsuContextMenuItem(MenuItem item) : base(item) { + if (!(Item is OsuMenuItem)) + throw new ArgumentException($"{nameof(item)} must be a {nameof(OsuMenuItem)}."); } [BackgroundDependencyLoader] @@ -76,7 +78,7 @@ namespace osu.Game.Graphics.UserInterface private void updateTextColour() { - switch (Item.Type) + switch (((OsuMenuItem)Item).Type) { case MenuItemType.Standard: text.Colour = Color4.White; diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index d67a995e67..9c816b8230 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -68,7 +68,7 @@ namespace osu.Game.Graphics.UserInterface public readonly Bindable AccentColour = new Bindable(); - protected override DrawableMenuItem CreateDrawableMenuItem(DropdownMenuItem item) + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) { var newItem = new DrawableOsuDropdownMenuItem(item); newItem.AccentColour.BindTo(AccentColour); @@ -86,7 +86,7 @@ namespace osu.Game.Graphics.UserInterface private Color4 nonAccentHoverColour; private Color4 nonAccentSelectedColour; - public DrawableOsuDropdownMenuItem(DropdownMenuItem item) + public DrawableOsuDropdownMenuItem(MenuItem item) : base(item) { Foreground.Padding = new MarginPadding(2); diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index 0c5bfa2947..6b64e9e367 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -8,8 +8,7 @@ using osu.Framework.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterface { - public class OsuMenu : Menu - where TItem : MenuItem + public class OsuMenu : Menu { public OsuMenu() { diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenuItem.cs b/osu.Game/Graphics/UserInterface/OsuMenuItem.cs similarity index 65% rename from osu.Game/Graphics/UserInterface/OsuContextMenuItem.cs rename to osu.Game/Graphics/UserInterface/OsuMenuItem.cs index bf00208b88..1f78666d20 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenuItem.cs @@ -6,17 +6,17 @@ using osu.Framework.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterface { - public class OsuContextMenuItem : MenuItem + public class OsuMenuItem : MenuItem { public readonly MenuItemType Type; - public OsuContextMenuItem(string text, MenuItemType type = MenuItemType.Standard) + public OsuMenuItem(string text, MenuItemType type = MenuItemType.Standard) : base(text) { Type = type; } - public OsuContextMenuItem(string text, MenuItemType type, Action action) + public OsuMenuItem(string text, MenuItemType type, Action action) : base(text, action) { Type = type; diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index faa7b269bb..32d2bc7c53 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -179,16 +179,16 @@ namespace osu.Game.Graphics.UserInterface MaxHeight = 400; } - protected override DrawableMenuItem CreateDrawableMenuItem(DropdownMenuItem item) + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) { - var result = new DrawableOsuTabDropdownMenuItem(this, item); + var result = new DrawableOsuTabDropdownMenuItem(item); result.AccentColour.BindTo(AccentColour); return result; } private class DrawableOsuTabDropdownMenuItem : DrawableOsuDropdownMenuItem { - public DrawableOsuTabDropdownMenuItem(Menu> menu, DropdownMenuItem item) + public DrawableOsuTabDropdownMenuItem(MenuItem item) : base(item) { ForegroundColourHover = Color4.Black; diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index 609b4b1e16..cf12c8a8e8 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -308,11 +308,11 @@ namespace osu.Game.Overlays.Settings.Sections.General protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(); - protected override DrawableMenuItem CreateDrawableMenuItem(DropdownMenuItem item) => new DrawableUserDropdownMenuItem(this, item); + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableUserDropdownMenuItem(item); private class DrawableUserDropdownMenuItem : DrawableOsuDropdownMenuItem { - public DrawableUserDropdownMenuItem(Menu> menu, DropdownMenuItem item) + public DrawableUserDropdownMenuItem(MenuItem item) : base(item) { Foreground.Padding = new MarginPadding { Top = 5, Bottom = 5, Left = 10, Right = 5 }; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 0c710fd242..325cfba986 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -84,7 +84,6 @@ - @@ -92,7 +91,7 @@ - + From 5dae408ecb1204293a664862b78a9e8567fbfc5a Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 28 Aug 2017 15:32:12 +0900 Subject: [PATCH 219/483] Reimplement TestCaseEditorMenuBar. --- osu-framework | 2 +- .../Visual/TestCaseEditorMenuBar.cs | 272 ++++++++++-------- 2 files changed, 157 insertions(+), 117 deletions(-) diff --git a/osu-framework b/osu-framework index 2cb3e59c8b..f6a1df24ee 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 2cb3e59c8bc7e67edef4dfe7f9c7dfc01db386a7 +Subproject commit f6a1df24eeef78e89f2d6e24fe1b43756eaae51e diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 7a9c97f5d5..b7a4bc355d 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; @@ -20,7 +21,7 @@ namespace osu.Desktop.Tests.Visual { public TestCaseEditorMenuBar() { - Add(new MenuBar + Add(new EditorMenuBar { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -31,162 +32,201 @@ namespace osu.Desktop.Tests.Visual { Items = new[] { - new EditorContextMenuItem("Clear All Notes"), - new EditorContextMenuItem("Open Difficulty..."), - new EditorContextMenuItem("Save"), - new EditorContextMenuItem("Create a new Difficulty..."), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Revert to Saved"), - new EditorContextMenuItem("Revert to Saved (Full)"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Test Beatmap"), - new EditorContextMenuItem("Open AiMod"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Upload Beatmap..."), - new EditorContextMenuItem("Export Package"), - new EditorContextMenuItem("Export Map Package"), - new EditorContextMenuItem("Import from..."), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Open Song Folder"), - new EditorContextMenuItem("Open .osu in Notepad"), - new EditorContextMenuItem("Open .osb in Notepad"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Exit"), + new EditorMenuItem("Clear All Notes"), + new EditorMenuItem("Open Difficulty..."), + new EditorMenuItem("Save"), + new EditorMenuItem("Create a new Difficulty..."), + new EditorMenuSpacer(), + new EditorMenuItem("Revert to Saved"), + new EditorMenuItem("Revert to Saved (Full)"), + new EditorMenuSpacer(), + new EditorMenuItem("Test Beatmap"), + new EditorMenuItem("Open AiMod"), + new EditorMenuSpacer(), + new EditorMenuItem("Upload Beatmap..."), + new EditorMenuItem("Export Package"), + new EditorMenuItem("Export Map Package"), + new EditorMenuItem("Import from..."), + new EditorMenuSpacer(), + new EditorMenuItem("Open Song Folder"), + new EditorMenuItem("Open .osu in Notepad"), + new EditorMenuItem("Open .osb in Notepad"), + new EditorMenuSpacer(), + new EditorMenuItem("Exit"), } }, new EditorMenuBarItem("Timing") { Items = new[] { - new EditorContextMenuItem("Time Signature"), - new EditorContextMenuItem("Metronome Clicks"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Add Timing Section"), - new EditorContextMenuItem("Add Inheriting Section"), - new EditorContextMenuItem("Reset Current Section"), - new EditorContextMenuItem("Delete Timing Section"), - new EditorContextMenuItem("Resnap Current Section"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Timing Setup"), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Resnap All Notes", MenuItemType.Destructive), - new EditorContextMenuItem("Move all notes in time...", MenuItemType.Destructive), - new EditorContextMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), - new EditorContextMenuItem("Delete All Timing Sections", MenuItemType.Destructive), - new EditorContextMenuSpacer(), - new EditorContextMenuItem("Set Current Position as Preview Point"), + new EditorMenuItem("Time Signature"), + new EditorMenuItem("Metronome Clicks"), + new EditorMenuSpacer(), + new EditorMenuItem("Add Timing Section"), + new EditorMenuItem("Add Inheriting Section"), + new EditorMenuItem("Reset Current Section"), + new EditorMenuItem("Delete Timing Section"), + new EditorMenuItem("Resnap Current Section"), + new EditorMenuSpacer(), + new EditorMenuItem("Timing Setup"), + new EditorMenuSpacer(), + new EditorMenuItem("Resnap All Notes", MenuItemType.Destructive), + new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive), + new EditorMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), + new EditorMenuItem("Delete All Timing Sections", MenuItemType.Destructive), + new EditorMenuSpacer(), + new EditorMenuItem("Set Current Position as Preview Point"), } }, new EditorMenuBarItem("Testing") { Items = new[] { - new EditorContextMenuItem("Item 1"), - new EditorContextMenuItem("Item 2"), - new EditorContextMenuItem("Item 3"), + new EditorMenuItem("Item 1"), + new EditorMenuItem("Item 2"), + new EditorMenuItem("Item 3"), } }, } }); } - private class EditorMenuBarItem : MenuBarItem + private class EditorMenuBar : MenuBar { - private const int fade_duration = 250; - private const float text_size = 17; + protected override DrawableMenuBarItem CreateDrawableMenuBarItem(MenuItem item) => new DrawableEditorMenuBarItem(item); - private readonly Container background; - - private Color4 normalColour; - - public EditorMenuBarItem(string title) - : base(title) + private class DrawableEditorMenuBarItem : DrawableMenuBarItem { - Content.Padding = new MarginPadding(8); + private const int fade_duration = 250; + private const float text_size = 17; - AddInternal(background = new Container + private readonly Container background; + + private Color4 normalColour; + + public DrawableEditorMenuBarItem(MenuItem item) + : base(item) { - RelativeSizeAxes = Axes.Both, - Masking = true, - Depth = float.MaxValue, - Alpha = 0, - Child = new Container + if (!(item is EditorMenuBarItem)) + throw new ArgumentException($"{nameof(item)} must be a {nameof(EditorMenuBarItem)}."); + + Text.Padding = new MarginPadding(8); + + AddInternal(background = new Container { - // The following is done so we can have top rounded corners but not bottom corners RelativeSizeAxes = Axes.Both, - Height = 2, Masking = true, - CornerRadius = 5, - Child = new Box { RelativeSizeAxes = Axes.Both } + Depth = float.MaxValue, + Alpha = 0, + Child = new Container + { + // The following is done so we can have top rounded corners but not bottom corners + RelativeSizeAxes = Axes.Both, + Height = 2, + Masking = true, + CornerRadius = 5, + Child = new Box { RelativeSizeAxes = Axes.Both } + } + }); + + Menu.OnOpen += menuOpen; + Menu.OnClose += menuClose; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray3; + Text.Colour = normalColour = colours.BlueLight; + } + + private void menuOpen() + { + background.FadeIn(fade_duration, Easing.OutQuint); + Text.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + } + + private void menuClose() + { + background.FadeOut(fade_duration, Easing.OutQuint); + Text.FadeColour(normalColour, fade_duration, Easing.OutQuint); + } + + protected override SpriteText CreateText() => new OsuSpriteText { TextSize = text_size }; + + protected override Menu CreateMenu() => new EditorMenu(); + + private class EditorMenu : OsuMenu + { + public EditorMenu() + { + Anchor = Anchor.BottomLeft; + BypassAutoSizeAxes = Axes.Both; + OriginPosition = new Vector2(8, 0); } - }); - } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - background.Colour = colours.Gray3; - TitleText.Colour = normalColour = colours.BlueLight; - } + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + } - public override void Open() - { - base.Open(); + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorMenuItem(item); - background.FadeIn(fade_duration, Easing.OutQuint); - TitleText.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - } + private class DrawableEditorMenuItem : DrawableOsuMenuItem + { + public override bool HandleInput => !isSpacer; + private readonly bool isSpacer; - public override void Close() - { - base.Close(); + public DrawableEditorMenuItem(MenuItem item) + : base(item) + { + if (!(item is EditorMenuItem)) + throw new ArgumentException($"{nameof(item)} must be a {nameof(EditorMenuItem)}."); - background.FadeOut(fade_duration, Easing.OutQuint); - TitleText.FadeColour(normalColour, fade_duration, Easing.OutQuint); - } + isSpacer = item is EditorMenuSpacer; + } - protected override SpriteText CreateTitleText() => new OsuSpriteText { TextSize = text_size }; - - protected override ContextMenu CreateContextMenu() => new EditorContextMenu - { - OriginPosition = new Vector2(8, 0) - }; - } - - private class EditorContextMenu : OsuContextMenu - { - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Menu.Background.Colour = colours.Gray3; + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + BackgroundColourHover = colours.Gray2; + } + } + } } } - private class EditorContextMenuSpacer : EditorContextMenuItem + private class EditorMenuBarItem : MenuItem { - public override bool HandleInput => false; + public EditorMenuBarItem(string text) + : base(text) + { + } + } - public EditorContextMenuSpacer() + private class EditorMenuItem : OsuMenuItem + { + private const int min_text_length = 40; + + public EditorMenuItem(string text, MenuItemType type = MenuItemType.Standard) + : base(text.PadRight(min_text_length), type) + { + } + + public EditorMenuItem(string text, MenuItemType type, Action action) + : base(text.PadRight(min_text_length), type, action) + { + } + } + + private class EditorMenuSpacer : EditorMenuItem + { + public EditorMenuSpacer() : base(" ") { } } - - private class EditorContextMenuItem : OsuContextMenuItem - { - private const int min_text_length = 40; - - public EditorContextMenuItem(string title, MenuItemType type = MenuItemType.Standard) - : base(title.PadRight(min_text_length), type) - { - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BackgroundColour = colours.Gray3; - BackgroundColourHover = colours.Gray2; - } - } } } From 7bf6d4aa656a50e0373cec1d099f69037dc284c1 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 28 Aug 2017 15:33:24 +0900 Subject: [PATCH 220/483] Rename DrawableOsuContextMenuItem -> DrawableOsuMenuItem, and move to OsuMenu. --- .../Graphics/UserInterface/OsuContextMenu.cs | 129 +----------------- osu.Game/Graphics/UserInterface/OsuMenu.cs | 126 +++++++++++++++++ 2 files changed, 127 insertions(+), 128 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs index 9a2917cd66..808c72ee5d 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -1,18 +1,11 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using OpenTK.Graphics; using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Sample; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input; -using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { @@ -40,126 +33,6 @@ namespace osu.Game.Graphics.UserInterface protected override void AnimateOpen() => this.FadeIn(fade_duration, Easing.OutQuint); protected override void AnimateClose() => this.FadeOut(fade_duration, Easing.OutQuint); - protected override MarginPadding ItemFlowContainerPadding => new MarginPadding { Vertical = DrawableOsuContextMenuItem.MARGIN_VERTICAL }; - - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuContextMenuItem(item); - - #region DrawableOsuContextMenuItem - private class DrawableOsuContextMenuItem : DrawableMenuItem - { - private const int margin_horizontal = 17; - private const int text_size = 17; - private const int transition_length = 80; - public const int MARGIN_VERTICAL = 4; - - private SampleChannel sampleClick; - private SampleChannel sampleHover; - - private TextContainer text; - - public DrawableOsuContextMenuItem(MenuItem item) - : base(item) - { - if (!(Item is OsuMenuItem)) - throw new ArgumentException($"{nameof(item)} must be a {nameof(OsuMenuItem)}."); - } - - [BackgroundDependencyLoader] - private void load(AudioManager audio) - { - sampleHover = audio.Sample.Get(@"UI/generic-hover"); - sampleClick = audio.Sample.Get(@"UI/generic-click"); - - BackgroundColour = Color4.Transparent; - BackgroundColourHover = OsuColour.FromHex(@"172023"); - - updateTextColour(); - } - - private void updateTextColour() - { - switch (((OsuMenuItem)Item).Type) - { - case MenuItemType.Standard: - text.Colour = Color4.White; - break; - case MenuItemType.Destructive: - text.Colour = Color4.Red; - break; - case MenuItemType.Highlighted: - text.Colour = OsuColour.FromHex(@"ffcc22"); - break; - } - } - - protected override bool OnHover(InputState state) - { - sampleHover.Play(); - text.BoldText.FadeIn(transition_length, Easing.OutQuint); - text.NormalText.FadeOut(transition_length, Easing.OutQuint); - return base.OnHover(state); - } - - protected override void OnHoverLost(InputState state) - { - text.BoldText.FadeOut(transition_length, Easing.OutQuint); - text.NormalText.FadeIn(transition_length, Easing.OutQuint); - base.OnHoverLost(state); - } - - protected override bool OnClick(InputState state) - { - sampleClick.Play(); - return base.OnClick(state); - } - - protected override Drawable CreateContent() => text = new TextContainer(); - - private class TextContainer : Container, IHasText - { - public string Text - { - get { return NormalText.Text; } - set - { - NormalText.Text = value; - BoldText.Text = value; - } - } - - public readonly SpriteText NormalText; - public readonly SpriteText BoldText; - - public TextContainer() - { - Anchor = Anchor.CentreLeft; - Origin = Anchor.CentreLeft; - - AutoSizeAxes = Axes.Both; - - Children = new Drawable[] - { - NormalText = new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = text_size, - Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, - }, - BoldText = new OsuSpriteText - { - AlwaysPresent = true, - Alpha = 0, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = text_size, - Font = @"Exo2.0-Bold", - Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, - } - }; - } - } - } - #endregion + protected override MarginPadding ItemFlowContainerPadding => new MarginPadding { Vertical = DrawableOsuMenuItem.MARGIN_VERTICAL }; } } \ No newline at end of file diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index 6b64e9e367..fa56b183a5 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -1,10 +1,18 @@ // Copyright (c) 2007-2017 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.Audio; +using osu.Framework.Audio.Sample; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input; +using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { @@ -26,5 +34,123 @@ namespace osu.Game.Graphics.UserInterface } protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(5); + + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuMenuItem(item); + + protected class DrawableOsuMenuItem : DrawableMenuItem + { + private const int margin_horizontal = 17; + private const int text_size = 17; + private const int transition_length = 80; + public const int MARGIN_VERTICAL = 4; + + private SampleChannel sampleClick; + private SampleChannel sampleHover; + + private TextContainer text; + + public DrawableOsuMenuItem(MenuItem item) + : base(item) + { + if (!(Item is OsuMenuItem)) + throw new ArgumentException($"{nameof(item)} must be a {nameof(OsuMenuItem)}."); + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + sampleHover = audio.Sample.Get(@"UI/generic-hover"); + sampleClick = audio.Sample.Get(@"UI/generic-click"); + + BackgroundColour = Color4.Transparent; + BackgroundColourHover = OsuColour.FromHex(@"172023"); + + updateTextColour(); + } + + private void updateTextColour() + { + switch (((OsuMenuItem)Item).Type) + { + case MenuItemType.Standard: + text.Colour = Color4.White; + break; + case MenuItemType.Destructive: + text.Colour = Color4.Red; + break; + case MenuItemType.Highlighted: + text.Colour = OsuColour.FromHex(@"ffcc22"); + break; + } + } + + protected override bool OnHover(InputState state) + { + sampleHover.Play(); + text.BoldText.FadeIn(transition_length, Easing.OutQuint); + text.NormalText.FadeOut(transition_length, Easing.OutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + text.BoldText.FadeOut(transition_length, Easing.OutQuint); + text.NormalText.FadeIn(transition_length, Easing.OutQuint); + base.OnHoverLost(state); + } + + protected override bool OnClick(InputState state) + { + sampleClick.Play(); + return base.OnClick(state); + } + + protected override Drawable CreateContent() => text = new TextContainer(); + + private class TextContainer : Container, IHasText + { + public string Text + { + get { return NormalText.Text; } + set + { + NormalText.Text = value; + BoldText.Text = value; + } + } + + public readonly SpriteText NormalText; + public readonly SpriteText BoldText; + + public TextContainer() + { + Anchor = Anchor.CentreLeft; + Origin = Anchor.CentreLeft; + + AutoSizeAxes = Axes.Both; + + Children = new Drawable[] + { + NormalText = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = text_size, + Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, + }, + BoldText = new OsuSpriteText + { + AlwaysPresent = true, + Alpha = 0, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = text_size, + Font = @"Exo2.0-Bold", + Margin = new MarginPadding { Horizontal = margin_horizontal, Vertical = MARGIN_VERTICAL }, + } + }; + } + } + } } } From 7c9c7f93aece86a7e976c9be7032f391832d188d Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 28 Aug 2017 15:42:21 +0900 Subject: [PATCH 221/483] Remove unnecessary exception, replace with default styling. --- osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index b7a4bc355d..95d34543bb 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -107,8 +107,6 @@ namespace osu.Desktop.Tests.Visual public DrawableEditorMenuBarItem(MenuItem item) : base(item) { - if (!(item is EditorMenuBarItem)) - throw new ArgumentException($"{nameof(item)} must be a {nameof(EditorMenuBarItem)}."); Text.Padding = new MarginPadding(8); @@ -181,8 +179,6 @@ namespace osu.Desktop.Tests.Visual public DrawableEditorMenuItem(MenuItem item) : base(item) { - if (!(item is EditorMenuItem)) - throw new ArgumentException($"{nameof(item)} must be a {nameof(EditorMenuItem)}."); isSpacer = item is EditorMenuSpacer; } From 83fe8514a49de4af590d2d076751220d7e2ba709 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 28 Aug 2017 15:44:05 +0900 Subject: [PATCH 222/483] Remove unnecessary exception, replace with default value. --- osu.Game/Graphics/UserInterface/OsuMenu.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index fa56b183a5..efc6998ca7 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -52,8 +52,7 @@ namespace osu.Game.Graphics.UserInterface public DrawableOsuMenuItem(MenuItem item) : base(item) { - if (!(Item is OsuMenuItem)) - throw new ArgumentException($"{nameof(item)} must be a {nameof(OsuMenuItem)}."); + } [BackgroundDependencyLoader] @@ -70,8 +69,9 @@ namespace osu.Game.Graphics.UserInterface private void updateTextColour() { - switch (((OsuMenuItem)Item).Type) + switch ((Item as OsuMenuItem)?.Type) { + default: case MenuItemType.Standard: text.Colour = Color4.White; break; From 5c3b7ac12ca35da401f06f981ff814791be0b97b Mon Sep 17 00:00:00 2001 From: Kelvin <2yangk23@gmail.com> Date: Mon, 28 Aug 2017 00:22:18 -0700 Subject: [PATCH 223/483] Allow rearranging playlist tracks --- osu.Game/Overlays/Music/PlaylistItem.cs | 43 ++++++++++++++++++++++++- osu.Game/Overlays/Music/PlaylistList.cs | 7 ++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 4145a8d1f0..6c38755e72 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Framework.Input; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Graphics; @@ -28,6 +29,7 @@ namespace osu.Game.Overlays.Music private IEnumerable titleSprites; private UnicodeBindableString titleBind; private UnicodeBindableString artistBind; + private FillFlowContainer Playlist; public readonly BeatmapSetInfo BeatmapSetInfo; @@ -48,8 +50,9 @@ namespace osu.Game.Overlays.Music } } - public PlaylistItem(BeatmapSetInfo setInfo) + public PlaylistItem(FillFlowContainer playlist, BeatmapSetInfo setInfo) { + Playlist = playlist; BeatmapSetInfo = setInfo; RelativeSizeAxes = Axes.X; @@ -132,6 +135,44 @@ namespace osu.Game.Overlays.Music return true; } + protected override bool OnDragStart(InputState state) + { + return true; + } + + // Maybe render some ghost text + protected override bool OnDrag(InputState state) + { + return true; + } + + private int clamp(int value, int min, int max) + { + return (value <= min) ? min : (value >= max) ? max : value; + } + + protected override bool OnDragEnd(InputState state) + { + int src = (int) Depth; + int dst = clamp((int) ((state.Mouse.Position.Y - Parent.DrawPosition.Y) / Height), 0, Playlist.Count - 1); + + if (src == dst) + return true; + + if (src < dst) + { + for (int i = src + 1; i <= dst; i++) + Playlist.ChangeChildDepth(Playlist[i], i - 1); + } + else + { + for (int i = dst; i < src; i++) + Playlist.ChangeChildDepth(Playlist[i], i + 1); + } + Playlist.ChangeChildDepth(this, dst); + return true; + } + public string[] FilterTerms { get; private set; } private bool matching = true; diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 3dd514edeb..3cbef8c22e 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Music { set { - items.Children = value.Select(item => new PlaylistItem(item) { OnSelect = itemSelected }).ToList(); + items.Children = value.Select((item, index) => new PlaylistItem(items, item) { OnSelect = itemSelected, Depth = index }).ToList(); } } @@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Music public void AddBeatmapSet(BeatmapSetInfo beatmapSet) { - items.Add(new PlaylistItem(beatmapSet) { OnSelect = itemSelected }); + items.Add(new PlaylistItem(items, beatmapSet) { OnSelect = itemSelected, Depth = items.Count }); } public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) @@ -96,6 +96,9 @@ namespace osu.Game.Overlays.Music } } + // Compare with reversed ChildID and Depth + protected override int Compare(Drawable x, Drawable y) => base.Compare(y, x); + public IEnumerable FilterableChildren => Children; public ItemSearchContainer() From 97ebf382883210c1828a276b9a2685c2f5e071f5 Mon Sep 17 00:00:00 2001 From: Kelvin <2yangk23@gmail.com> Date: Mon, 28 Aug 2017 00:56:03 -0700 Subject: [PATCH 224/483] Use PlaylistList to manage Prev/Next tracks --- osu.Game/Overlays/Music/PlaylistItem.cs | 2 +- osu.Game/Overlays/Music/PlaylistList.cs | 18 ++++++++++++++++++ osu.Game/Overlays/Music/PlaylistOverlay.cs | 16 ++++++++-------- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 6c38755e72..f6ba78c897 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -29,8 +29,8 @@ namespace osu.Game.Overlays.Music private IEnumerable titleSprites; private UnicodeBindableString titleBind; private UnicodeBindableString artistBind; - private FillFlowContainer Playlist; + private readonly FillFlowContainer Playlist; public readonly BeatmapSetInfo BeatmapSetInfo; public Action OnSelect; diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 3cbef8c22e..019049eb96 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -46,6 +46,24 @@ namespace osu.Game.Overlays.Music } } + public BeatmapSetInfo NextItem + { + get + { + var available = items.Children; + return (available.SkipWhile(i => !i.Selected).Skip(1).FirstOrDefault() ?? available.FirstOrDefault())?.BeatmapSetInfo; + } + } + + public BeatmapSetInfo PreviousItem + { + get + { + var available = items.Children.Reverse(); + return (available.SkipWhile(i => !i.Selected).Skip(1).FirstOrDefault() ?? available.FirstOrDefault())?.BeatmapSetInfo; + } + } + public PlaylistList() { Children = new Drawable[] diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 83e92c5554..e987e7a5c1 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -126,24 +126,24 @@ namespace osu.Game.Overlays.Music public void PlayPrevious() { - var currentID = beatmapBacking.Value?.BeatmapSetInfo.ID ?? -1; - var available = BeatmapSets.Reverse(); - - var playable = available.SkipWhile(b => b.ID != currentID).Skip(1).FirstOrDefault() ?? available.FirstOrDefault(); + var playable = list.PreviousItem; if (playable != null) + { playSpecified(playable.Beatmaps[0]); + list.SelectedItem = playable; + } } public void PlayNext() { - var currentID = beatmapBacking.Value?.BeatmapSetInfo.ID ?? -1; - var available = BeatmapSets; - - var playable = available.SkipWhile(b => b.ID != currentID).Skip(1).FirstOrDefault() ?? available.FirstOrDefault(); + var playable = list.NextItem; if (playable != null) + { playSpecified(playable.Beatmaps[0]); + list.SelectedItem = playable; + } } private void playSpecified(BeatmapInfo info) From 2f5d8a7f884a365b0302f8f0d863146d1c1e34a9 Mon Sep 17 00:00:00 2001 From: Kelvin <2yangk23@gmail.com> Date: Mon, 28 Aug 2017 01:08:51 -0700 Subject: [PATCH 225/483] Fixed code style errors --- osu.Game/Overlays/Music/PlaylistItem.cs | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index f6ba78c897..85c8cd0c93 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Music private UnicodeBindableString titleBind; private UnicodeBindableString artistBind; - private readonly FillFlowContainer Playlist; + private readonly FillFlowContainer playlist; public readonly BeatmapSetInfo BeatmapSetInfo; public Action OnSelect; @@ -52,7 +52,7 @@ namespace osu.Game.Overlays.Music public PlaylistItem(FillFlowContainer playlist, BeatmapSetInfo setInfo) { - Playlist = playlist; + this.playlist = playlist; BeatmapSetInfo = setInfo; RelativeSizeAxes = Axes.X; @@ -117,19 +117,19 @@ namespace osu.Game.Overlays.Music }); } - protected override bool OnHover(Framework.Input.InputState state) + protected override bool OnHover(InputState state) { handle.FadeIn(fade_duration); return base.OnHover(state); } - protected override void OnHoverLost(Framework.Input.InputState state) + protected override void OnHoverLost(InputState state) { handle.FadeOut(fade_duration); } - protected override bool OnClick(Framework.Input.InputState state) + protected override bool OnClick(InputState state) { OnSelect?.Invoke(BeatmapSetInfo); return true; @@ -146,15 +146,10 @@ namespace osu.Game.Overlays.Music return true; } - private int clamp(int value, int min, int max) - { - return (value <= min) ? min : (value >= max) ? max : value; - } - protected override bool OnDragEnd(InputState state) { int src = (int) Depth; - int dst = clamp((int) ((state.Mouse.Position.Y - Parent.DrawPosition.Y) / Height), 0, Playlist.Count - 1); + int dst = clamp((int) ((state.Mouse.Position.Y - Parent.DrawPosition.Y) / Height), 0, playlist.Count - 1); if (src == dst) return true; @@ -162,17 +157,22 @@ namespace osu.Game.Overlays.Music if (src < dst) { for (int i = src + 1; i <= dst; i++) - Playlist.ChangeChildDepth(Playlist[i], i - 1); + playlist.ChangeChildDepth(playlist[i], i - 1); } else { for (int i = dst; i < src; i++) - Playlist.ChangeChildDepth(Playlist[i], i + 1); + playlist.ChangeChildDepth(playlist[i], i + 1); } - Playlist.ChangeChildDepth(this, dst); + playlist.ChangeChildDepth(this, dst); return true; } + private int clamp(int value, int min, int max) + { + return value <= min ? min : value >= max ? max : value; + } + public string[] FilterTerms { get; private set; } private bool matching = true; From b17d9ac06ea649b977ead563b7b5e4ecefe70ab9 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 28 Aug 2017 17:55:50 +0900 Subject: [PATCH 226/483] Move EditorMenuBar into the Edit namespace, and fix a minor styling issue. --- osu-framework | 2 +- .../Visual/TestCaseEditorMenuBar.cs | 145 +-------------- osu.Game/Graphics/UserInterface/OsuMenu.cs | 5 +- osu.Game/Screens/Edit/Editor.cs | 174 ++++++++++++++++++ osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 131 +++++++++++++ .../Screens/Edit/Menus/EditorMenuBarItem.cs | 15 ++ osu.Game/Screens/Edit/Menus/EditorMenuItem.cs | 23 +++ .../Edit/Menus/EditorMenuItemSpacer.cs | 13 ++ osu.Game/osu.Game.csproj | 4 + 9 files changed, 365 insertions(+), 147 deletions(-) create mode 100644 osu.Game/Screens/Edit/Menus/EditorMenuBar.cs create mode 100644 osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs create mode 100644 osu.Game/Screens/Edit/Menus/EditorMenuItem.cs create mode 100644 osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs diff --git a/osu-framework b/osu-framework index f6a1df24ee..c7457f0ce9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit f6a1df24eeef78e89f2d6e24fe1b43756eaae51e +Subproject commit c7457f0ce9ef3f663ee800f6b7fc574e9abff1da diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 95d34543bb..9ff4f4c591 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -1,19 +1,10 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.UserInterface; using osu.Framework.Testing; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Screens.Edit.Menus; namespace osu.Desktop.Tests.Visual { @@ -90,139 +81,5 @@ namespace osu.Desktop.Tests.Visual } }); } - - private class EditorMenuBar : MenuBar - { - protected override DrawableMenuBarItem CreateDrawableMenuBarItem(MenuItem item) => new DrawableEditorMenuBarItem(item); - - private class DrawableEditorMenuBarItem : DrawableMenuBarItem - { - private const int fade_duration = 250; - private const float text_size = 17; - - private readonly Container background; - - private Color4 normalColour; - - public DrawableEditorMenuBarItem(MenuItem item) - : base(item) - { - - Text.Padding = new MarginPadding(8); - - AddInternal(background = new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Depth = float.MaxValue, - Alpha = 0, - Child = new Container - { - // The following is done so we can have top rounded corners but not bottom corners - RelativeSizeAxes = Axes.Both, - Height = 2, - Masking = true, - CornerRadius = 5, - Child = new Box { RelativeSizeAxes = Axes.Both } - } - }); - - Menu.OnOpen += menuOpen; - Menu.OnClose += menuClose; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - background.Colour = colours.Gray3; - Text.Colour = normalColour = colours.BlueLight; - } - - private void menuOpen() - { - background.FadeIn(fade_duration, Easing.OutQuint); - Text.FadeColour(Color4.White, fade_duration, Easing.OutQuint); - } - - private void menuClose() - { - background.FadeOut(fade_duration, Easing.OutQuint); - Text.FadeColour(normalColour, fade_duration, Easing.OutQuint); - } - - protected override SpriteText CreateText() => new OsuSpriteText { TextSize = text_size }; - - protected override Menu CreateMenu() => new EditorMenu(); - - private class EditorMenu : OsuMenu - { - public EditorMenu() - { - Anchor = Anchor.BottomLeft; - BypassAutoSizeAxes = Axes.Both; - OriginPosition = new Vector2(8, 0); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BackgroundColour = colours.Gray3; - } - - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorMenuItem(item); - - private class DrawableEditorMenuItem : DrawableOsuMenuItem - { - public override bool HandleInput => !isSpacer; - private readonly bool isSpacer; - - public DrawableEditorMenuItem(MenuItem item) - : base(item) - { - - isSpacer = item is EditorMenuSpacer; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BackgroundColour = colours.Gray3; - BackgroundColourHover = colours.Gray2; - } - } - } - } - } - - private class EditorMenuBarItem : MenuItem - { - public EditorMenuBarItem(string text) - : base(text) - { - } - } - - private class EditorMenuItem : OsuMenuItem - { - private const int min_text_length = 40; - - public EditorMenuItem(string text, MenuItemType type = MenuItemType.Standard) - : base(text.PadRight(min_text_length), type) - { - } - - public EditorMenuItem(string text, MenuItemType type, Action action) - : base(text.PadRight(min_text_length), type, action) - { - } - } - - private class EditorMenuSpacer : EditorMenuItem - { - public EditorMenuSpacer() - : base(" ") - { - } - } } } diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index efc6998ca7..e0bb23df5d 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -105,9 +105,10 @@ namespace osu.Game.Graphics.UserInterface return base.OnClick(state); } - protected override Drawable CreateContent() => text = new TextContainer(); + protected sealed override Drawable CreateContent() => text = CreateTextContainer(); + protected virtual TextContainer CreateTextContainer() => new TextContainer(); - private class TextContainer : Container, IHasText + protected class TextContainer : Container, IHasText { public string Text { diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 9f33d624e2..0454609689 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -8,6 +8,11 @@ using osu.Framework.Screens; using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Select; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using osu.Game.Screens.Edit.Menus; namespace osu.Game.Screens.Edit { @@ -17,6 +22,175 @@ namespace osu.Game.Screens.Edit protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4"); + internal override bool ShowOverlays => false; + + public Editor() + { + Add(new Container + { + RelativeSizeAxes = Axes.X, + Height = 40, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("111") + }, + new EditorMenuBar + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + X = 100, + Items = new[] + { + new EditorMenuBarItem("File") + { + Items = new[] + { + new EditorMenuItem("Clear all notes"), + new EditorMenuItem("Open difficulty..."), + new EditorMenuItem("Save"), + new EditorMenuItem("Create new difficulty..."), + new EditorMenuSpacer(), + new EditorMenuItem("Revert to saved"), + new EditorMenuItem("Revert to saved (full"), + new EditorMenuSpacer(), + new EditorMenuItem("Test beatmap"), + new EditorMenuItem("Open AiMod"), + new EditorMenuSpacer(), + new EditorMenuItem("Upload Beatmap..."), + new EditorMenuItem("Export package"), + new EditorMenuItem("Export map package"), + new EditorMenuItem("Import from..."), + new EditorMenuSpacer(), + new EditorMenuItem("Open song folder"), + new EditorMenuItem("Open .osu in Notepad"), + new EditorMenuItem("Open .osb in Notepad"), + new EditorMenuSpacer(), + new EditorMenuItem("Exit", MenuItemType.Standard, Exit) + } + }, + new EditorMenuBarItem("Edit") + { + Items = new[] + { + new EditorMenuItem("Undo"), + new EditorMenuItem("Redo"), + new EditorMenuSpacer(), + new EditorMenuItem("Cut"), + new EditorMenuItem("Copy"), + new EditorMenuItem("Paste"), + new EditorMenuItem("Delete"), + new EditorMenuSpacer(), + new EditorMenuItem("Select all"), + new EditorMenuItem("Clone"), + new EditorMenuSpacer(), + new EditorMenuItem("Reverse selection"), + new EditorMenuItem("Flip horizontally"), + new EditorMenuItem("Flip vertically"), + new EditorMenuItem("Rotate 90deg clockwise"), + new EditorMenuItem("Rotate 90deg anticlockwise"), + new EditorMenuItem("Rotate by..."), + new EditorMenuItem("Scale by..."), + new EditorMenuSpacer(), + new EditorMenuItem("Reset selected objects' samples"), + new EditorMenuItem("Reset all samples", MenuItemType.Destructive), + new EditorMenuItem("Reset combo colours", MenuItemType.Destructive), + new EditorMenuItem("Reset breaks", MenuItemType.Destructive), + new EditorMenuSpacer(), + new EditorMenuItem("Nudge backward"), + new EditorMenuItem("Nudge forward") + } + }, + new EditorMenuBarItem("View") + { + Items = new[] + { + new EditorMenuItem("Compose"), + new EditorMenuItem("Design"), + new EditorMenuItem("Timing"), + new EditorMenuSpacer(), + new EditorMenuItem("Song setup..."), + new EditorMenuItem("Timing setup..."), + new EditorMenuSpacer(), + new EditorMenuItem("Volume"), + new EditorMenuItem("Grid level"), + new EditorMenuItem("Show video"), + new EditorMenuItem("Show sample name"), + new EditorMenuItem("Snaking sliders"), + new EditorMenuItem("Hit animations"), + new EditorMenuItem("Follow points"), + new EditorMenuItem("Stacking") + } + }, + new EditorMenuBarItem("Compose") + { + Items = new[] + { + new EditorMenuItem("Snap divisor"), + new EditorMenuItem("Audio rate"), + new EditorMenuItem("Grid snapping"), + new EditorMenuSpacer(), + new EditorMenuItem("Create polygon cricles..."), + new EditorMenuItem("Convert slider to stream"), + new EditorMenuItem("Enable live mapping mode"), + new EditorMenuItem("Sample import") + } + }, + new EditorMenuBarItem("Design") + { + Items = new[] + { + new EditorMenuItem("Move all elements in time...") + } + }, + new EditorMenuBarItem("Timing") + { + Items = new[] + { + new EditorMenuItem("Time signature"), + new EditorMenuItem("Metronome clicks"), + new EditorMenuSpacer(), + new EditorMenuItem("Add timing section"), + new EditorMenuItem("Add inheriting section"), + new EditorMenuItem("Reset current section"), + new EditorMenuItem("Delete timing section"), + new EditorMenuItem("Resnap current section"), + new EditorMenuSpacer(), + new EditorMenuItem("Timing setup..."), + new EditorMenuSpacer(), + new EditorMenuItem("Resnap all notes", MenuItemType.Destructive), + new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive), + new EditorMenuItem("Recalculate slider lengths", MenuItemType.Destructive), + new EditorMenuItem("Delete all timing sections", MenuItemType.Destructive), + new EditorMenuSpacer(), + new EditorMenuItem("Set current position as preview point") + } + }, + new EditorMenuBarItem("Web") + { + Items = new[] + { + new EditorMenuItem("This Beatmap's information page"), + new EditorMenuItem("This Beatmap's thread"), + new EditorMenuItem("Quick reply") + } + }, + new EditorMenuBarItem("Help") + { + Items = new[] + { + new EditorMenuItem("Show in-game help"), + new EditorMenuItem("View FAQ") + } + } + } + } + } + }); + } + protected override void OnResuming(Screen last) { Beatmap.Value.Track?.Stop(); diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs new file mode 100644 index 0000000000..9fd8669922 --- /dev/null +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -0,0 +1,131 @@ +// Copyright (c) 2007-2017 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.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Screens.Edit.Menus +{ + public class EditorMenuBar : MenuBar + { + protected override DrawableMenuBarItem CreateDrawableMenuBarItem(MenuItem item) => new DrawableEditorMenuBarItem(item); + + private class DrawableEditorMenuBarItem : DrawableMenuBarItem + { + private const int fade_duration = 250; + private const float text_size = 14; + + private readonly Container background; + + private Color4 normalColour; + + public DrawableEditorMenuBarItem(MenuItem item) + : base(item) + { + Text.Padding = new MarginPadding(8); + + AddInternal(background = new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Depth = float.MaxValue, + Alpha = 0, + Child = new Container + { + // The following is done so we can have top rounded corners but not bottom corners + RelativeSizeAxes = Axes.Both, + Height = 2, + Masking = true, + CornerRadius = 5, + Child = new Box { RelativeSizeAxes = Axes.Both } + } + }); + + Menu.OnOpen += menuOpen; + Menu.OnClose += menuClose; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.Gray3; + Text.Colour = normalColour = colours.BlueLight; + } + + private void menuOpen() + { + background.FadeIn(fade_duration, Easing.OutQuint); + Text.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + } + + private void menuClose() + { + background.FadeOut(fade_duration, Easing.OutQuint); + Text.FadeColour(normalColour, fade_duration, Easing.OutQuint); + } + + protected override SpriteText CreateText() => new OsuSpriteText { TextSize = text_size }; + + protected override Framework.Graphics.UserInterface.Menu CreateMenu() => new EditorMenu(); + + private class EditorMenu : OsuMenu + { + public EditorMenu() + { + Anchor = Anchor.BottomLeft; + BypassAutoSizeAxes = Axes.Both; + OriginPosition = new Vector2(8, 0); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + } + + protected override MarginPadding ItemFlowContainerPadding => new MarginPadding { Top = 5, Bottom = 5 }; + + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorMenuItem(item); + + private class DrawableEditorMenuItem : DrawableOsuMenuItem + { + public override bool HandleInput => !isSpacer; + private readonly bool isSpacer; + + public DrawableEditorMenuItem(MenuItem item) + : base(item) + { + isSpacer = item is EditorMenuSpacer; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + BackgroundColourHover = colours.Gray2; + } + + protected override TextContainer CreateTextContainer() => new EditorTextContainer(); + + private class EditorTextContainer : TextContainer + { + public EditorTextContainer() + { + BoldText.TextSize = text_size; + NormalText.TextSize = text_size; + } + } + } + } + } + } +} diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs new file mode 100644 index 0000000000..201bc6e5c3 --- /dev/null +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBarItem.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Menus +{ + public class EditorMenuBarItem : MenuItem + { + public EditorMenuBarItem(string text) + : base(text) + { + } + } +} diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuItem.cs b/osu.Game/Screens/Edit/Menus/EditorMenuItem.cs new file mode 100644 index 0000000000..c7e36522cf --- /dev/null +++ b/osu.Game/Screens/Edit/Menus/EditorMenuItem.cs @@ -0,0 +1,23 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Menus +{ + public class EditorMenuItem : OsuMenuItem + { + private const int min_text_length = 40; + + public EditorMenuItem(string text, MenuItemType type = MenuItemType.Standard) + : base(text.PadRight(min_text_length), type) + { + } + + public EditorMenuItem(string text, MenuItemType type, Action action) + : base(text.PadRight(min_text_length), type, action) + { + } + } +} diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs b/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs new file mode 100644 index 0000000000..0e01992846 --- /dev/null +++ b/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Screens.Edit.Menus +{ + public class EditorMenuSpacer : EditorMenuItem + { + public EditorMenuSpacer() + : base(" ") + { + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 325cfba986..05ba3e25ab 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -133,6 +133,10 @@ + + + + From 161718947502777d0e7feeedaef99d0e032ea29d Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 28 Aug 2017 17:53:03 +0800 Subject: [PATCH 227/483] Set DummyWorkingBeatmap's DeletePending to true. --- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 479f274efb..bc4b28168a 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -26,7 +26,7 @@ namespace osu.Game.Beatmaps Title = "no beatmaps available!", Author = "no one", }, - BeatmapSet = new BeatmapSetInfo(), + BeatmapSet = new BeatmapSetInfo { DeletePending = true }, Difficulty = new BeatmapDifficulty { DrainRate = 0, From 4aa5ce8b413eb8afa2cdeaa521d2fef1b42c21c4 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 28 Aug 2017 17:53:57 +0800 Subject: [PATCH 228/483] Always load background and info wedge when no beatmap available. --- osu.Game/Screens/Select/SongSelect.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index aa554152f9..6c149c3f30 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -248,8 +248,7 @@ namespace osu.Game.Screens.Select if (beatmap == null) { - if (!Beatmap.IsDefault) - performLoad(); + performLoad(); } else { From 6304a685c3317b143d7d5d6d3e75769bf7d61dca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 29 Aug 2017 14:43:23 +0900 Subject: [PATCH 229/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index c7457f0ce9..167d5cda8f 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit c7457f0ce9ef3f663ee800f6b7fc574e9abff1da +Subproject commit 167d5cda8f3ddae702ffc8d8d22dac67e48b509c From 12be5b417d58b0a02773888472a40eb2e90847f6 Mon Sep 17 00:00:00 2001 From: Kelvin <2yangk23@gmail.com> Date: Mon, 28 Aug 2017 22:51:26 -0700 Subject: [PATCH 230/483] Use MathHelper.Clamp - Fix formatting --- osu.Game/Overlays/Music/PlaylistItem.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 85c8cd0c93..a86cca117a 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -148,8 +148,8 @@ namespace osu.Game.Overlays.Music protected override bool OnDragEnd(InputState state) { - int src = (int) Depth; - int dst = clamp((int) ((state.Mouse.Position.Y - Parent.DrawPosition.Y) / Height), 0, playlist.Count - 1); + int src = (int)Depth; + int dst = MathHelper.Clamp((int)(state.Mouse.Position.Y / Height), 0, playlist.Count - 1); if (src == dst) return true; @@ -164,15 +164,11 @@ namespace osu.Game.Overlays.Music for (int i = dst; i < src; i++) playlist.ChangeChildDepth(playlist[i], i + 1); } + playlist.ChangeChildDepth(this, dst); return true; } - private int clamp(int value, int min, int max) - { - return value <= min ? min : value >= max ? max : value; - } - public string[] FilterTerms { get; private set; } private bool matching = true; From 636492b9cf8297347e416776a89868bbc43d5b0b Mon Sep 17 00:00:00 2001 From: Kelvin <2yangk23@gmail.com> Date: Mon, 28 Aug 2017 22:59:28 -0700 Subject: [PATCH 231/483] Rearrange tracks in OnDrag --- osu.Game/Overlays/Music/PlaylistItem.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index a86cca117a..6c7e590a88 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -140,13 +140,7 @@ namespace osu.Game.Overlays.Music return true; } - // Maybe render some ghost text protected override bool OnDrag(InputState state) - { - return true; - } - - protected override bool OnDragEnd(InputState state) { int src = (int)Depth; int dst = MathHelper.Clamp((int)(state.Mouse.Position.Y / Height), 0, playlist.Count - 1); From b91757793f3e65da3c84d9fb9bd3302e4b9c94b5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 29 Aug 2017 15:20:56 +0900 Subject: [PATCH 232/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 2cb3e59c8b..167d5cda8f 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 2cb3e59c8bc7e67edef4dfe7f9c7dfc01db386a7 +Subproject commit 167d5cda8f3ddae702ffc8d8d22dac67e48b509c From 85f876a934ae831c786568e1631f7588fd006540 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 29 Aug 2017 15:23:32 +0900 Subject: [PATCH 233/483] Remove unused using statement --- osu.Game/Graphics/UserInterface/OsuMenu.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index efc6998ca7..ab37fd2c90 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 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.Audio; using osu.Framework.Audio.Sample; From 458c3a355fd0c6d20d656a68aaac7e73c5c9cd04 Mon Sep 17 00:00:00 2001 From: Kelvin <2yangk23@gmail.com> Date: Mon, 28 Aug 2017 23:28:58 -0700 Subject: [PATCH 234/483] Rearrange dragging using cheeseburger icon only --- osu.Game/Overlays/Music/PlaylistItem.cs | 77 ++++++++++++++----------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 6c7e590a88..876ad4f767 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -71,15 +71,9 @@ namespace osu.Game.Overlays.Music Children = new Drawable[] { - handle = new SpriteIcon + handle = new PlaylistItemHandle(playlist) { - Anchor = Anchor.TopLeft, - Origin = Anchor.TopLeft, - Size = new Vector2(12), Colour = colours.Gray5, - Icon = FontAwesome.fa_bars, - Alpha = 0f, - Margin = new MarginPadding { Left = 5, Top = 2 }, }, text = new OsuTextFlowContainer { @@ -135,34 +129,6 @@ namespace osu.Game.Overlays.Music return true; } - protected override bool OnDragStart(InputState state) - { - return true; - } - - protected override bool OnDrag(InputState state) - { - int src = (int)Depth; - int dst = MathHelper.Clamp((int)(state.Mouse.Position.Y / Height), 0, playlist.Count - 1); - - if (src == dst) - return true; - - if (src < dst) - { - for (int i = src + 1; i <= dst; i++) - playlist.ChangeChildDepth(playlist[i], i - 1); - } - else - { - for (int i = dst; i < src; i++) - playlist.ChangeChildDepth(playlist[i], i + 1); - } - - playlist.ChangeChildDepth(this, dst); - return true; - } - public string[] FilterTerms { get; private set; } private bool matching = true; @@ -179,5 +145,46 @@ namespace osu.Game.Overlays.Music this.FadeTo(matching ? 1 : 0, 200); } } + + private class PlaylistItemHandle : SpriteIcon + { + private readonly FillFlowContainer playlist; + + public PlaylistItemHandle(FillFlowContainer playlist) + { + this.playlist = playlist; + Anchor = Anchor.TopLeft; + Origin = Anchor.TopLeft; + Size = new Vector2(12); + Icon = FontAwesome.fa_bars; + Alpha = 0f; + Margin = new MarginPadding { Left = 5, Top = 2 }; + } + + protected override bool OnDragStart(InputState state) => true; + + protected override bool OnDrag(InputState state) + { + int src = (int)Parent.Depth; + int dst = MathHelper.Clamp((int)((state.Mouse.Position.Y + Parent.Position.Y) / Parent.Height), 0, playlist.Count - 1); + + if (src == dst) + return true; + + if (src < dst) + { + for (int i = src + 1; i <= dst; i++) + playlist.ChangeChildDepth(playlist[i], i - 1); + } + else + { + for (int i = dst; i < src; i++) + playlist.ChangeChildDepth(playlist[i], i + 1); + } + + playlist.ChangeChildDepth(Parent as PlaylistItem, dst); + return true; + } + } } } From 1eb31afd146305e5204d016a95f2ea43599737b9 Mon Sep 17 00:00:00 2001 From: Kelvin <2yangk23@gmail.com> Date: Tue, 29 Aug 2017 00:39:17 -0700 Subject: [PATCH 235/483] Get destination index using binarysearch --- osu.Game/Overlays/Music/PlaylistItem.cs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 876ad4f767..941b858364 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -166,7 +166,7 @@ namespace osu.Game.Overlays.Music protected override bool OnDrag(InputState state) { int src = (int)Parent.Depth; - int dst = MathHelper.Clamp((int)((state.Mouse.Position.Y + Parent.Position.Y) / Parent.Height), 0, playlist.Count - 1); + int dst = getIndex(state.Mouse.Position.Y + Parent.Position.Y); if (src == dst) return true; @@ -185,6 +185,24 @@ namespace osu.Game.Overlays.Music playlist.ChangeChildDepth(Parent as PlaylistItem, dst); return true; } + + private int getIndex(float position) { + IReadOnlyList items = playlist.Children; + + // Binary Search without matching exact + int min = 0; + int max = items.Count - 1; + while (min <= max) + { + int m = (min + max) / 2; + if (items[m].Y < position) + min = m + 1; + else if (items[m].Y > position) + max = m - 1; + } + + return (int)items[min - 1].Depth; + } } } } From e5bf3f6a6af29f753b3b619293a8b9de6ff477c2 Mon Sep 17 00:00:00 2001 From: Kelvin <2yangk23@gmail.com> Date: Tue, 29 Aug 2017 00:46:11 -0700 Subject: [PATCH 236/483] Fix out of bounds --- osu.Game/Overlays/Music/PlaylistItem.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 941b858364..1491d7d0dd 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -201,7 +202,7 @@ namespace osu.Game.Overlays.Music max = m - 1; } - return (int)items[min - 1].Depth; + return (int)items[Math.Max(0, min - 1)].Depth; } } } From fb3ba4fe0cfa01ce725337e5a04b9c8934050495 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Tue, 29 Aug 2017 00:26:16 +0800 Subject: [PATCH 237/483] Add comment for DeletePending. --- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index bc4b28168a..4fc135a7e4 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -26,7 +26,7 @@ namespace osu.Game.Beatmaps Title = "no beatmaps available!", Author = "no one", }, - BeatmapSet = new BeatmapSetInfo { DeletePending = true }, + BeatmapSet = new BeatmapSetInfo { DeletePending = true }, //let song select show no beatmaps available if this is the only one Difficulty = new BeatmapDifficulty { DrainRate = 0, From 5b8349f90ed14ad09b8a165f4122f86f1cb2d892 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 29 Aug 2017 18:05:27 +0900 Subject: [PATCH 238/483] Revert DummyWorkingBeatmap changes. --- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 4fc135a7e4..479f274efb 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -26,7 +26,7 @@ namespace osu.Game.Beatmaps Title = "no beatmaps available!", Author = "no one", }, - BeatmapSet = new BeatmapSetInfo { DeletePending = true }, //let song select show no beatmaps available if this is the only one + BeatmapSet = new BeatmapSetInfo(), Difficulty = new BeatmapDifficulty { DrainRate = 0, From 39b5b047002d54bc1a9e623a912418fca4be887b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 29 Aug 2017 18:17:01 +0900 Subject: [PATCH 239/483] Don't use Bindable for AccentColour Implements IHasAccentColour for conformity to rest of project. Also fixes a nullref when opening the login menu. --- .../Graphics/UserInterface/OsuDropdown.cs | 127 ++++++++++-------- .../Graphics/UserInterface/OsuTabControl.cs | 74 +++++----- osu.Game/Overlays/Direct/FilterControl.cs | 2 +- .../Overlays/Music/CollectionsDropdown.cs | 10 +- .../SearchableList/SlimEnumDropdown.cs | 8 +- .../Sections/General/LoginSettings.cs | 12 +- 6 files changed, 113 insertions(+), 120 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index 9c816b8230..37bd4f2395 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -1,9 +1,9 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Linq; using OpenTK.Graphics; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -14,35 +14,43 @@ using OpenTK; namespace osu.Game.Graphics.UserInterface { - public class OsuDropdown : Dropdown + public class OsuDropdown : Dropdown, IHasAccentColour { - public readonly Bindable AccentColour = new Bindable(); + private Color4 accentColour; + public Color4 AccentColour + { + get { return accentColour; } + set + { + accentColour = value; + updateAccentColour(); + } + } [BackgroundDependencyLoader] private void load(OsuColour colours) { - if (AccentColour.Value == null) - AccentColour.Value = colours.PinkDarker; + if (accentColour == default(Color4)) + accentColour = colours.PinkDarker; + updateAccentColour(); + } - protected override DropdownHeader CreateHeader() + private void updateAccentColour() { - var newHeader = new OsuDropdownHeader(); - newHeader.AccentColour.BindTo(AccentColour); + var header = Header as IHasAccentColour; + if (header != null) header.AccentColour = accentColour; - return newHeader; + var menu = Menu as IHasAccentColour; + if (menu != null) menu.AccentColour = accentColour; } - protected override DropdownMenu CreateMenu() - { - var newMenu = new OsuDropdownMenu(); - newMenu.AccentColour.BindTo(AccentColour); + protected override DropdownHeader CreateHeader() => new OsuDropdownHeader(); - return newMenu; - } + protected override DropdownMenu CreateMenu() => new OsuDropdownMenu(); #region OsuDropdownMenu - protected class OsuDropdownMenu : DropdownMenu + protected class OsuDropdownMenu : DropdownMenu, IHasAccentColour { // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring public OsuDropdownMenu() @@ -65,23 +73,41 @@ namespace osu.Game.Graphics.UserInterface this.ResizeHeightTo(State == MenuState.Opened ? actualHeight : 0, 300, Easing.OutQuint); } - public readonly Bindable AccentColour = new Bindable(); - - - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) + private Color4 accentColour; + public Color4 AccentColour { - var newItem = new DrawableOsuDropdownMenuItem(item); - newItem.AccentColour.BindTo(AccentColour); - - return newItem; + get { return accentColour; } + set + { + accentColour = value; + foreach (var c in Children.OfType()) + c.AccentColour = value; + } } - #region DrawableOsuDropdownMenuItem - protected class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem - { - public readonly Bindable AccentColour = new Bindable(); + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuDropdownMenuItem(item) { AccentColour = accentColour }; - private TextContainer textContainer; + #region DrawableOsuDropdownMenuItem + protected class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem, IHasAccentColour + { + private Color4? accentColour; + public Color4 AccentColour + { + get { return accentColour ?? nonAccentSelectedColour; } + set + { + accentColour = value; + updateColours(); + } + } + + private void updateColours() + { + BackgroundColourHover = accentColour ?? nonAccentHoverColour; + BackgroundColourSelected = accentColour ?? nonAccentSelectedColour; + UpdateBackgroundColour(); + UpdateForegroundColour(); + } private Color4 nonAccentHoverColour; private Color4 nonAccentSelectedColour; @@ -93,36 +119,29 @@ namespace osu.Game.Graphics.UserInterface Masking = true; CornerRadius = 6; - - AccentColour.ValueChanged += updateAccent; } [BackgroundDependencyLoader] private void load(OsuColour colours) { BackgroundColour = Color4.Transparent; + nonAccentHoverColour = colours.PinkDarker; nonAccentSelectedColour = Color4.Black.Opacity(0.5f); - } - - private void updateAccent(Color4? newValue) - { - BackgroundColourHover = newValue ?? nonAccentHoverColour; - BackgroundColourSelected = newValue ?? nonAccentSelectedColour; - UpdateBackgroundColour(); - UpdateForegroundColour(); + updateColours(); } protected override void UpdateForegroundColour() { base.UpdateForegroundColour(); - textContainer.Chevron.Alpha = IsHovered ? 1 : 0; + var content = Foreground.Child as Content; + if (content != null) content.Chevron.Alpha = IsHovered ? 1 : 0; } - protected override Drawable CreateContent() => textContainer = new TextContainer(); + protected override Drawable CreateContent() => new Content(); - protected class TextContainer : FillFlowContainer, IHasText + protected class Content : FillFlowContainer, IHasText { public string Text { @@ -133,7 +152,7 @@ namespace osu.Game.Graphics.UserInterface public readonly OsuSpriteText Label; public readonly SpriteIcon Chevron; - public TextContainer() + public Content() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -165,7 +184,7 @@ namespace osu.Game.Graphics.UserInterface } #endregion - public class OsuDropdownHeader : DropdownHeader + public class OsuDropdownHeader : DropdownHeader, IHasAccentColour { protected readonly SpriteText Text; protected override string Label @@ -176,7 +195,16 @@ namespace osu.Game.Graphics.UserInterface protected readonly SpriteIcon Icon; - public readonly Bindable AccentColour = new Bindable(); + private Color4 accentColour; + public virtual Color4 AccentColour + { + get { return accentColour; } + set + { + accentColour = value; + BackgroundColourHover = accentColour; + } + } public OsuDropdownHeader() { @@ -203,20 +231,13 @@ namespace osu.Game.Graphics.UserInterface Size = new Vector2(20), } }; - - AccentColour.ValueChanged += accentColourChanged; } [BackgroundDependencyLoader] private void load(OsuColour colours) { BackgroundColour = Color4.Black.Opacity(0.5f); - BackgroundColourHover = AccentColour?.Value ?? colours.PinkDarker; - } - - private void accentColourChanged(Color4? newValue) - { - BackgroundColourHover = newValue ?? Color4.White; + BackgroundColourHover = colours.PinkDarker; } } } diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 32d2bc7c53..89b1f4124b 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -37,34 +37,34 @@ namespace osu.Game.Graphics.UserInterface [BackgroundDependencyLoader] private void load(OsuColour colours) { - if (accentColour == null) + if (accentColour == default(Color4)) AccentColour = colours.Blue; } - private Color4? accentColour; + private Color4 accentColour; public Color4 AccentColour { - get { return accentColour.GetValueOrDefault(); } + get { return accentColour; } set { accentColour = value; - var dropdown = Dropdown as OsuTabDropdown; + var dropdown = Dropdown as IHasAccentColour; if (dropdown != null) - dropdown.AccentColour.Value = value; - foreach (var item in TabContainer.Children.OfType()) - item.AccentColour = value; + dropdown.AccentColour = value; + foreach (var i in TabContainer.Children.OfType()) + i.AccentColour = value; } } - public class OsuTabItem : TabItem + public class OsuTabItem : TabItem, IHasAccentColour { protected readonly SpriteText Text; private readonly Box box; - private Color4? accentColour; + private Color4 accentColour; public Color4 AccentColour { - get { return accentColour.GetValueOrDefault(); } + get { return accentColour; } set { accentColour = value; @@ -103,7 +103,7 @@ namespace osu.Game.Graphics.UserInterface [BackgroundDependencyLoader] private void load(OsuColour colours) { - if (accentColour == null) + if (accentColour == default(Color4)) AccentColour = colours.Blue; } @@ -148,25 +148,13 @@ namespace osu.Game.Graphics.UserInterface RelativeSizeAxes = Axes.X; } - protected override DropdownMenu CreateMenu() + protected override DropdownMenu CreateMenu() => new OsuTabDropdownMenu(); + + protected override DropdownHeader CreateHeader() => new OsuTabDropdownHeader { - var menu = new OsuTabDropdownMenu(); - menu.AccentColour.BindTo(AccentColour); - return menu; - } - - protected override DropdownHeader CreateHeader() - { - var newHeader = new OsuTabDropdownHeader - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight - }; - - newHeader.AccentColour.BindTo(AccentColour); - - return newHeader; - } + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight + }; private class OsuTabDropdownMenu : OsuDropdownMenu { @@ -179,12 +167,7 @@ namespace osu.Game.Graphics.UserInterface MaxHeight = 400; } - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) - { - var result = new DrawableOsuTabDropdownMenuItem(item); - result.AccentColour.BindTo(AccentColour); - return result; - } + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuTabDropdownMenuItem(item) { AccentColour = AccentColour }; private class DrawableOsuTabDropdownMenuItem : DrawableOsuDropdownMenuItem { @@ -199,6 +182,20 @@ namespace osu.Game.Graphics.UserInterface protected class OsuTabDropdownHeader : OsuDropdownHeader { + public override Color4 AccentColour + { + get + { + return base.AccentColour; + } + + set + { + base.AccentColour = value; + Foreground.Colour = value; + } + } + public OsuTabDropdownHeader() { RelativeSizeAxes = Axes.None; @@ -227,13 +224,6 @@ namespace osu.Game.Graphics.UserInterface }; Padding = new MarginPadding { Left = 5, Right = 5 }; - - AccentColour.ValueChanged += accentColourChanged; - } - - private void accentColourChanged(Color4? newValue) - { - Foreground.Colour = newValue ?? Color4.White; } protected override bool OnHover(InputState state) diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index ca9e8667e6..28d26d0641 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -36,7 +36,7 @@ namespace osu.Game.Overlays.Direct [BackgroundDependencyLoader(true)] private void load(OsuGame game, RulesetStore rulesets, OsuColour colours) { - DisplayStyleControl.Dropdown.AccentColour.Value = colours.BlueDark; + DisplayStyleControl.Dropdown.AccentColour = colours.BlueDark; Ruleset.BindTo(game?.Ruleset ?? new Bindable { Value = rulesets.GetRuleset(0) }); foreach (var r in rulesets.AllRulesets) diff --git a/osu.Game/Overlays/Music/CollectionsDropdown.cs b/osu.Game/Overlays/Music/CollectionsDropdown.cs index be72d4481a..3b11d9f52a 100644 --- a/osu.Game/Overlays/Music/CollectionsDropdown.cs +++ b/osu.Game/Overlays/Music/CollectionsDropdown.cs @@ -18,16 +18,10 @@ namespace osu.Game.Overlays.Music [BackgroundDependencyLoader] private void load(OsuColour colours) { - AccentColour.Value = colours.Gray6; + AccentColour = colours.Gray6; } - protected override DropdownHeader CreateHeader() - { - var newHeader = new CollectionsHeader(); - newHeader.AccentColour.BindTo(AccentColour); - - return newHeader; - } + protected override DropdownHeader CreateHeader() => new CollectionsHeader(); protected override DropdownMenu CreateMenu() => new CollectionsMenu(); diff --git a/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs b/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs index e68cddb293..2870607519 100644 --- a/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs +++ b/osu.Game/Overlays/SearchableList/SlimEnumDropdown.cs @@ -12,13 +12,7 @@ namespace osu.Game.Overlays.SearchableList { public class SlimEnumDropdown : OsuEnumDropdown { - protected override DropdownHeader CreateHeader() - { - var newHeader = new SlimDropdownHeader(); - newHeader.AccentColour.BindTo(AccentColour); - - return newHeader; - } + protected override DropdownHeader CreateHeader() => new SlimDropdownHeader(); protected override DropdownMenu CreateMenu() => new SlimMenu(); diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index cf12c8a8e8..a816fa56c1 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -257,13 +257,7 @@ namespace osu.Game.Overlays.Settings.Sections.General private class UserDropdown : OsuEnumDropdown { - protected override DropdownHeader CreateHeader() - { - var newHeader = new UserDropdownHeader(); - newHeader.AccentColour.BindTo(AccentColour); - - return newHeader; - } + protected override DropdownHeader CreateHeader() => new UserDropdownHeader(); protected override DropdownMenu CreateMenu() => new UserDropdownMenu(); @@ -280,7 +274,7 @@ namespace osu.Game.Overlays.Settings.Sections.General [BackgroundDependencyLoader] private void load(OsuColour colours) { - AccentColour.Value = colours.Gray5; + AccentColour = colours.Gray5; } private class UserDropdownMenu : OsuDropdownMenu @@ -319,7 +313,7 @@ namespace osu.Game.Overlays.Settings.Sections.General CornerRadius = 5; } - protected override Drawable CreateContent() => new TextContainer + protected override Drawable CreateContent() => new Content { Label = { Margin = new MarginPadding { Left = UserDropdownHeader.LABEL_LEFT_MARGIN - 11 } } }; From 2535313f4f29db31928f5d2a20a95e48c27919f6 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 29 Aug 2017 18:18:36 +0900 Subject: [PATCH 240/483] Use using. --- osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index c3cc4fe77b..7f193a0e1a 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -3,6 +3,7 @@ using OpenTK; using OpenTK.Graphics; +using OpenTK.Input; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -43,7 +44,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { - if (args.Key == OpenTK.Input.Key.CapsLock) + if (args.Key == Key.CapsLock) updateCapsWarning(host.CapsLockEnabled); return base.OnKeyDown(state, args); } From 24a2dc3d1e2d93185beae32d7d7b9919108db2b9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 29 Aug 2017 18:31:51 +0900 Subject: [PATCH 241/483] Don't use child --- osu.Game/Graphics/UserInterface/OsuDropdown.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index 37bd4f2395..dde154bb61 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -135,7 +135,7 @@ namespace osu.Game.Graphics.UserInterface { base.UpdateForegroundColour(); - var content = Foreground.Child as Content; + var content = Foreground.Children.FirstOrDefault() as Content; if (content != null) content.Chevron.Alpha = IsHovered ? 1 : 0; } From 0e363fce1e05118e929e3d598f10fef75f0c1ce3 Mon Sep 17 00:00:00 2001 From: Kelvin <2yangk23@gmail.com> Date: Tue, 29 Aug 2017 22:25:04 -0700 Subject: [PATCH 242/483] Try to fix stuttering behavior --- osu.Game/Overlays/Music/PlaylistItem.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 1491d7d0dd..9df15bfd04 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -151,6 +150,9 @@ namespace osu.Game.Overlays.Music { private readonly FillFlowContainer playlist; + private const int line_height = 22; + private const int rearrange_buffer = 3; + public PlaylistItemHandle(FillFlowContainer playlist) { this.playlist = playlist; @@ -202,7 +204,12 @@ namespace osu.Game.Overlays.Music max = m - 1; } - return (int)items[Math.Max(0, min - 1)].Depth; + int index = Math.Max(0, min - 1); + // Only move if mouse falls within buffer + if (position - items[index].Y > rearrange_buffer && position - items[index].Y < line_height - rearrange_buffer) { + return (int)items[index].Depth; + } + return (int)Parent.Depth; } } } From 07da29ea1ce6e4c4fb6551f16efcbcf002fdfcd0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Aug 2017 20:41:41 +0900 Subject: [PATCH 243/483] Add context menu to beatmap set header --- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 3 +++ .../Beatmaps/Drawables/BeatmapSetHeader.cs | 23 ++++++++++++++++++- osu.Game/Screens/Select/BeatmapCarousel.cs | 3 +++ osu.Game/Screens/Select/SongSelect.cs | 14 +++++++---- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index ad9a0a787b..dc68c9a49e 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -23,6 +23,8 @@ namespace osu.Game.Beatmaps.Drawables /// public Action StartRequested; + public Action DeleteRequested; + public BeatmapSetHeader Header; private BeatmapGroupState state; @@ -66,6 +68,7 @@ namespace osu.Game.Beatmaps.Drawables Header = new BeatmapSetHeader(beatmap) { GainedSelection = headerGainedSelection, + DeleteRequested = b => DeleteRequested(b), RelativeSizeAxes = Axes.X, }; diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs index a2457ba78e..6510f92547 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs @@ -9,16 +9,22 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Graphics.Sprites; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics.UserInterface; namespace osu.Game.Beatmaps.Drawables { - public class BeatmapSetHeader : Panel + public class BeatmapSetHeader : Panel, IHasContextMenu { public Action GainedSelection; + + public Action DeleteRequested; + private readonly SpriteText title; private readonly SpriteText artist; @@ -148,5 +154,20 @@ namespace osu.Game.Beatmaps.Drawables foreach (var p in panels) difficultyIcons.Add(new DifficultyIcon(p.Beatmap)); } + + public MenuItem[] ContextMenuItems + { + get + { + List items = new List(); + + if (State == PanelSelectedState.NotSelected) + items.Add(new OsuMenuItem("Expand", MenuItemType.Highlighted, () => State = PanelSelectedState.Selected)); + + items.Add(new OsuMenuItem("Delete", MenuItemType.Destructive, () => DeleteRequested?.Invoke(beatmap))); + + return items.ToArray(); + } + } } } \ No newline at end of file diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 264636b258..448f5395b6 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -140,6 +140,8 @@ namespace osu.Game.Screens.Select public Action StartRequested; + public Action DeleteRequested; + public void SelectNext(int direction = 1, bool skipDifficulties = true) { if (groups.All(g => g.State == BeatmapGroupState.Hidden)) @@ -305,6 +307,7 @@ namespace osu.Game.Screens.Select { SelectionChanged = (g, p) => selectGroup(g, p), StartRequested = b => StartRequested?.Invoke(), + DeleteRequested = b => DeleteRequested?.Invoke(b), State = BeatmapGroupState.Collapsed }; } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 6c149c3f30..4eb6da4f88 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -106,6 +106,7 @@ namespace osu.Game.Screens.Select Origin = Anchor.CentreRight, SelectionChanged = carouselSelectionChanged, BeatmapsChanged = carouselBeatmapsLoaded, + DeleteRequested = b => promptDelete(b), StartRequested = () => carouselRaisedStart(), }); Add(FilterControl = new FilterControl @@ -163,7 +164,7 @@ namespace osu.Game.Screens.Select Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2); Footer.AddButton(@"options", colours.Blue, BeatmapOptions.ToggleVisibility, Key.F3); - BeatmapOptions.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, colours.Pink, promptDelete, Key.Number4, float.MaxValue); + BeatmapOptions.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, colours.Pink, () => promptDelete(Beatmap), Key.Number4, float.MaxValue); } if (manager == null) @@ -389,10 +390,12 @@ namespace osu.Game.Screens.Select Beatmap.SetDefault(); } - private void promptDelete() + private void promptDelete(WorkingBeatmap beatmap) { - if (Beatmap != null && !Beatmap.IsDefault) - dialogOverlay?.Push(new BeatmapDeleteDialog(Beatmap)); + if (beatmap == null) + return; + + dialogOverlay?.Push(new BeatmapDeleteDialog(beatmap)); } protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) @@ -408,7 +411,8 @@ namespace osu.Game.Screens.Select case Key.Delete: if (state.Keyboard.ShiftPressed) { - promptDelete(); + if (!Beatmap.IsDefault) + promptDelete(Beatmap); return true; } break; From 8619f28ced14952e50aa9a1f96adb60ae5734f05 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Aug 2017 20:41:53 +0900 Subject: [PATCH 244/483] Add context menu to beatmap difficulty (wip) --- osu.Game/Beatmaps/Drawables/BeatmapPanel.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs index 429ecaf416..f963931c7c 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; @@ -14,16 +15,19 @@ using OpenTK.Graphics; using osu.Framework.Input; using osu.Game.Graphics.Sprites; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; namespace osu.Game.Beatmaps.Drawables { - public class BeatmapPanel : Panel + public class BeatmapPanel : Panel, IHasContextMenu { public BeatmapInfo Beatmap; private readonly Sprite background; public Action GainedSelection; public Action StartRequested; + public Action DeleteRequested; + private readonly Triangles triangles; private readonly StarCounter starCounter; @@ -148,5 +152,12 @@ namespace osu.Game.Beatmaps.Drawables } }; } + + public MenuItem[] ContextMenuItems => new MenuItem[] + { + new OsuMenuItem("Play", MenuItemType.Highlighted), + new OsuMenuItem("Edit"), + new OsuMenuItem("Delete", MenuItemType.Destructive), + }; } } From 2fb4126ffc07eb84c9428009f8a8917f25313655 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Aug 2017 20:53:33 +0900 Subject: [PATCH 245/483] Use BeatmapSetInfo instead of WorkingBeatmap --- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 2 +- osu.Game/Beatmaps/Drawables/BeatmapPanel.cs | 2 +- osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs | 4 ++-- osu.Game/Screens/Select/SongSelect.cs | 7 ++++--- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index dc68c9a49e..a4c7da71d8 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -23,7 +23,7 @@ namespace osu.Game.Beatmaps.Drawables /// public Action StartRequested; - public Action DeleteRequested; + public Action DeleteRequested; public BeatmapSetHeader Header; diff --git a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs index f963931c7c..235c98b43c 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs @@ -157,7 +157,7 @@ namespace osu.Game.Beatmaps.Drawables { new OsuMenuItem("Play", MenuItemType.Highlighted), new OsuMenuItem("Edit"), - new OsuMenuItem("Delete", MenuItemType.Destructive), + new OsuMenuItem("Delete", MenuItemType.Destructive, () => DeleteRequested?.Invoke(Beatmap)), }; } } diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs index 6510f92547..b475a23ffd 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs @@ -23,7 +23,7 @@ namespace osu.Game.Beatmaps.Drawables { public Action GainedSelection; - public Action DeleteRequested; + public Action DeleteRequested; private readonly SpriteText title; private readonly SpriteText artist; @@ -164,7 +164,7 @@ namespace osu.Game.Beatmaps.Drawables if (State == PanelSelectedState.NotSelected) items.Add(new OsuMenuItem("Expand", MenuItemType.Highlighted, () => State = PanelSelectedState.Selected)); - items.Add(new OsuMenuItem("Delete", MenuItemType.Destructive, () => DeleteRequested?.Invoke(beatmap))); + items.Add(new OsuMenuItem("Delete", MenuItemType.Destructive, () => DeleteRequested?.Invoke(beatmap.BeatmapSetInfo))); return items.ToArray(); } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 4eb6da4f88..6cd47aa9f6 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -249,7 +249,8 @@ namespace osu.Game.Screens.Select if (beatmap == null) { - performLoad(); + if (!Beatmap.IsDefault) + performLoad(); } else { @@ -390,7 +391,7 @@ namespace osu.Game.Screens.Select Beatmap.SetDefault(); } - private void promptDelete(WorkingBeatmap beatmap) + private void promptDelete(BeatmapSetInfo beatmap) { if (beatmap == null) return; @@ -412,7 +413,7 @@ namespace osu.Game.Screens.Select if (state.Keyboard.ShiftPressed) { if (!Beatmap.IsDefault) - promptDelete(Beatmap); + promptDelete(Beatmap.Value.BeatmapSetInfo); return true; } break; From 3b4b4b669bb88d4f3a35d54542399499a771fec9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Aug 2017 21:12:46 +0900 Subject: [PATCH 246/483] Add framework for deleting difficulties --- osu.Game/Beatmaps/BeatmapManager.cs | 12 +++++++++- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 3 +++ osu.Game/Screens/Select/BeatmapCarousel.cs | 5 +++- .../Screens/Select/BeatmapDeleteDialog.cs | 23 ++++++++++++------- osu.Game/Screens/Select/SongSelect.cs | 11 ++++++++- 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 1dcab6cb5d..c52576fb9f 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -170,7 +170,7 @@ namespace osu.Game.Beatmaps /// Delete a beatmap from the manager. /// Is a no-op for already deleted beatmaps. /// - /// The beatmap to delete. + /// The beatmap set to delete. public void Delete(BeatmapSetInfo beatmapSet) { lock (beatmaps) @@ -180,6 +180,16 @@ namespace osu.Game.Beatmaps files.Dereference(beatmapSet.Files.Select(f => f.FileInfo).ToArray()); } + /// + /// Delete a beatmap from the manager. + /// Is a no-op for already deleted beatmaps. + /// + /// The beatmap difficulty to delete. + public void Delete(BeatmapInfo beatmap) + { + //todo: implement + } + /// /// Returns a to a usable state if it has previously been deleted but not yet purged. /// Is a no-op for already usable beatmaps. diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index a4c7da71d8..b47210620d 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -25,6 +25,8 @@ namespace osu.Game.Beatmaps.Drawables public Action DeleteRequested; + public Action DeleteDifficultyRequested; + public BeatmapSetHeader Header; private BeatmapGroupState state; @@ -77,6 +79,7 @@ namespace osu.Game.Beatmaps.Drawables { Alpha = 0, GainedSelection = panelGainedSelection, + DeleteRequested = p => DeleteDifficultyRequested?.Invoke(p), StartRequested = p => { StartRequested?.Invoke(p.Beatmap); }, RelativeSizeAxes = Axes.X, }).ToList(); diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 448f5395b6..a1c7f64188 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -140,7 +140,9 @@ namespace osu.Game.Screens.Select public Action StartRequested; - public Action DeleteRequested; + public Action DeleteRequested; + + public Action DeleteDifficultyRequested; public void SelectNext(int direction = 1, bool skipDifficulties = true) { @@ -308,6 +310,7 @@ namespace osu.Game.Screens.Select SelectionChanged = (g, p) => selectGroup(g, p), StartRequested = b => StartRequested?.Invoke(), DeleteRequested = b => DeleteRequested?.Invoke(b), + DeleteDifficultyRequested = b => DeleteDifficultyRequested?.Invoke(b), State = BeatmapGroupState.Collapsed }; } diff --git a/osu.Game/Screens/Select/BeatmapDeleteDialog.cs b/osu.Game/Screens/Select/BeatmapDeleteDialog.cs index 96caf2f236..15ec84a7d8 100644 --- a/osu.Game/Screens/Select/BeatmapDeleteDialog.cs +++ b/osu.Game/Screens/Select/BeatmapDeleteDialog.cs @@ -13,29 +13,36 @@ namespace osu.Game.Screens.Select { private BeatmapManager manager; + private readonly Action deleteAction; + [BackgroundDependencyLoader] private void load(BeatmapManager beatmapManager) { manager = beatmapManager; } - public BeatmapDeleteDialog(WorkingBeatmap beatmap) + public BeatmapDeleteDialog(BeatmapSetInfo beatmap) : this() { - if (beatmap == null) throw new ArgumentNullException(nameof(beatmap)); + BodyText = $@"{beatmap.Metadata?.Artist} - {beatmap.Metadata?.Title} (ALL DIFFICULTIES)"; + deleteAction = () => manager.Delete(beatmap); + } + public BeatmapDeleteDialog(BeatmapInfo beatmap) : this() + { + BodyText = $@"{beatmap.Metadata?.Artist} - {beatmap.Metadata?.Title} [{beatmap.Version}]"; + deleteAction = () => manager.Delete(beatmap); + } + + public BeatmapDeleteDialog() + { Icon = FontAwesome.fa_trash_o; HeaderText = @"Confirm deletion of"; - BodyText = $@"{beatmap.Metadata?.Artist} - {beatmap.Metadata?.Title}"; Buttons = new PopupDialogButton[] { new PopupDialogOkButton { Text = @"Yes. Totally. Delete it.", - Action = () => - { - beatmap.Dispose(); - manager.Delete(beatmap.BeatmapSetInfo); - }, + Action = () => deleteAction(), }, new PopupDialogCancelButton { diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 6cd47aa9f6..b3ee33e7c6 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -107,6 +107,7 @@ namespace osu.Game.Screens.Select SelectionChanged = carouselSelectionChanged, BeatmapsChanged = carouselBeatmapsLoaded, DeleteRequested = b => promptDelete(b), + DeleteDifficultyRequested = b => promptDelete(b), StartRequested = () => carouselRaisedStart(), }); Add(FilterControl = new FilterControl @@ -164,7 +165,7 @@ namespace osu.Game.Screens.Select Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2); Footer.AddButton(@"options", colours.Blue, BeatmapOptions.ToggleVisibility, Key.F3); - BeatmapOptions.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, colours.Pink, () => promptDelete(Beatmap), Key.Number4, float.MaxValue); + BeatmapOptions.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, colours.Pink, () => promptDelete(Beatmap.Value.BeatmapSetInfo), Key.Number4, float.MaxValue); } if (manager == null) @@ -399,6 +400,14 @@ namespace osu.Game.Screens.Select dialogOverlay?.Push(new BeatmapDeleteDialog(beatmap)); } + private void promptDelete(BeatmapInfo beatmap) + { + if (beatmap == null) + return; + + dialogOverlay?.Push(new BeatmapDeleteDialog(beatmap)); + } + protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { if (args.Repeat) return false; From 5a58489adf72eacb03c182b419381d24a6c2a954 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Aug 2017 21:12:58 +0900 Subject: [PATCH 247/483] Hook up play and edit (kinda) --- osu.Game/Beatmaps/Drawables/BeatmapPanel.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs index 235c98b43c..1006380a2b 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs @@ -26,6 +26,7 @@ namespace osu.Game.Beatmaps.Drawables public Action GainedSelection; public Action StartRequested; + public Action EditRequested; public Action DeleteRequested; private readonly Triangles triangles; @@ -155,8 +156,8 @@ namespace osu.Game.Beatmaps.Drawables public MenuItem[] ContextMenuItems => new MenuItem[] { - new OsuMenuItem("Play", MenuItemType.Highlighted), - new OsuMenuItem("Edit"), + new OsuMenuItem("Play", MenuItemType.Highlighted, () => StartRequested?.Invoke(this)), + new OsuMenuItem("Edit", MenuItemType.Standard, () => EditRequested?.Invoke(this)), new OsuMenuItem("Delete", MenuItemType.Destructive, () => DeleteRequested?.Invoke(Beatmap)), }; } From d252af8ab45f4048525da834bbc6f2450b3b5454 Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Thu, 31 Aug 2017 02:36:25 -0400 Subject: [PATCH 248/483] basic implementation of hp --- .../Scoring/OsuScoreProcessor.cs | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 856ca0c98d..df97e06118 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Scoring { base.Reset(); - Health.Value = 1; + Health.Value = 0.5; Accuracy.Value = 1; scoreResultCounts.Clear(); @@ -56,13 +56,21 @@ namespace osu.Game.Rulesets.Osu.Scoring scoreResultCounts[judgement.Score] = scoreResultCounts.GetOrDefault(judgement.Score) + 1; comboResultCounts[judgement.Combo] = comboResultCounts.GetOrDefault(judgement.Combo) + 1; } - - switch (judgement.Result) + switch (judgement.Score) { - case HitResult.Hit: - Health.Value += 0.1f; + case OsuScoreResult.Hit300: + Health.Value += 0.01f; break; - case HitResult.Miss: + + case OsuScoreResult.Hit100: + Health.Value -= 0.01f; + break; + + case OsuScoreResult.Hit50: + Health.Value -= 0.05f; + break; + + case OsuScoreResult.Miss: Health.Value -= 0.2f; break; } From cbc35e0cf3040caff865a33b5a64c3e018951b0d Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Thu, 31 Aug 2017 04:31:48 -0400 Subject: [PATCH 249/483] implemented hp --- .../Scoring/OsuScoreProcessor.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index df97e06118..3a06ef2260 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -23,6 +23,14 @@ namespace osu.Game.Rulesets.Osu.Scoring { } + + float beatmapHp = 0; + + protected override void ComputeTargets(Game.Beatmaps.Beatmap beatmap) + { + beatmapHp = beatmap.BeatmapInfo.Difficulty.DrainRate; + } + protected override void Reset() { base.Reset(); @@ -59,19 +67,19 @@ namespace osu.Game.Rulesets.Osu.Scoring switch (judgement.Score) { case OsuScoreResult.Hit300: - Health.Value += 0.01f; + Health.Value += (10.2 - beatmapHp) * 0.02; break; case OsuScoreResult.Hit100: - Health.Value -= 0.01f; + Health.Value += (8 - beatmapHp) * 0.02; break; case OsuScoreResult.Hit50: - Health.Value -= 0.05f; + Health.Value += (4 - beatmapHp) * 0.02; break; case OsuScoreResult.Miss: - Health.Value -= 0.2f; + Health.Value -= beatmapHp * 0.04; break; } } From af2f45a98058f175b52b89703478c10cd0fb8d34 Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Thu, 31 Aug 2017 04:44:00 -0400 Subject: [PATCH 250/483] slight edits --- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 3a06ef2260..a0662ab51d 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Scoring } - float beatmapHp = 0; + float beatmapHp; protected override void ComputeTargets(Game.Beatmaps.Beatmap beatmap) { @@ -78,6 +78,10 @@ namespace osu.Game.Rulesets.Osu.Scoring Health.Value += (4 - beatmapHp) * 0.02; break; + case OsuScoreResult.SliderTick: + Health.Value += System.Math.Max(7 - beatmapHp, 0) * 0.01; + break; + case OsuScoreResult.Miss: Health.Value -= beatmapHp * 0.04; break; From 04596fee6122886b6488b0dc547b0a65bde61350 Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Thu, 31 Aug 2017 08:26:06 -0400 Subject: [PATCH 251/483] Update OsuScoreProcessor.cs --- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index a0662ab51d..7760e773d3 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Scoring { base.Reset(); - Health.Value = 0.5; + Health.Value = 1; Accuracy.Value = 1; scoreResultCounts.Clear(); From 472710e5db861b3065bbcc7554ad92eb4d1371e4 Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Thu, 31 Aug 2017 21:35:30 -0400 Subject: [PATCH 252/483] trim whitespace --- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index a0662ab51d..a079eb4c80 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -23,7 +23,6 @@ namespace osu.Game.Rulesets.Osu.Scoring { } - float beatmapHp; protected override void ComputeTargets(Game.Beatmaps.Beatmap beatmap) From 1f646e6d548a988fba0fbc102a09e02574a35c85 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 31 Aug 2017 15:49:56 +0900 Subject: [PATCH 253/483] Add hiding support for beatmap difficulties --- osu-framework | 2 +- osu.Game/Beatmaps/BeatmapInfo.cs | 2 + osu.Game/Beatmaps/BeatmapManager.cs | 57 ++++++++++++------- osu.Game/Beatmaps/BeatmapStore.cs | 43 +++++++++++++- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 5 +- osu.Game/Beatmaps/Drawables/BeatmapPanel.cs | 2 +- .../Beatmaps/Drawables/BeatmapSetHeader.cs | 6 ++ osu.Game/Screens/Select/BeatmapCarousel.cs | 38 +++++++++++-- .../Screens/Select/BeatmapDeleteDialog.cs | 19 +------ osu.Game/Screens/Select/SongSelect.cs | 21 +++---- 10 files changed, 136 insertions(+), 59 deletions(-) diff --git a/osu-framework b/osu-framework index 167d5cda8f..2804e052ca 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 167d5cda8f3ddae702ffc8d8d22dac67e48b509c +Subproject commit 2804e052ca2ce068f015771d28170d18573687e1 diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index ebf77bf9df..c962201fe3 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -52,6 +52,8 @@ namespace osu.Game.Beatmaps [JsonProperty("file_sha2")] public string Hash { get; set; } + public bool Hidden { get; set; } + /// /// MD5 is kept for legacy support (matching against replays, osu-web-10 etc.). /// diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index c52576fb9f..551612330b 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -33,11 +33,21 @@ namespace osu.Game.Beatmaps /// public event Action BeatmapSetAdded; + /// + /// Fired when a single difficulty has been hidden. + /// + public event Action BeatmapHidden; + /// /// Fired when a is removed from the database. /// public event Action BeatmapSetRemoved; + /// + /// Fired when a single difficulty has been restored. + /// + public event Action BeatmapRestored; + /// /// A default representation of a WorkingBeatmap to use when no beatmap is available. /// @@ -71,6 +81,8 @@ namespace osu.Game.Beatmaps beatmaps = new BeatmapStore(connection); beatmaps.BeatmapSetAdded += s => BeatmapSetAdded?.Invoke(s); beatmaps.BeatmapSetRemoved += s => BeatmapSetRemoved?.Invoke(s); + beatmaps.BeatmapHidden += b => BeatmapHidden?.Invoke(b); + beatmaps.BeatmapRestored += b => BeatmapRestored?.Invoke(b); this.storage = storage; this.files = files; @@ -162,8 +174,7 @@ namespace osu.Game.Beatmaps // If we have an ID then we already exist in the database. if (beatmapSetInfo.ID != 0) return; - lock (beatmaps) - beatmaps.Add(beatmapSetInfo); + beatmaps.Add(beatmapSetInfo); } /// @@ -173,22 +184,23 @@ namespace osu.Game.Beatmaps /// The beatmap set to delete. public void Delete(BeatmapSetInfo beatmapSet) { - lock (beatmaps) - if (!beatmaps.Delete(beatmapSet)) return; + if (!beatmaps.Delete(beatmapSet)) return; if (!beatmapSet.Protected) files.Dereference(beatmapSet.Files.Select(f => f.FileInfo).ToArray()); } /// - /// Delete a beatmap from the manager. - /// Is a no-op for already deleted beatmaps. + /// Delete a beatmap difficulty. /// - /// The beatmap difficulty to delete. - public void Delete(BeatmapInfo beatmap) - { - //todo: implement - } + /// The beatmap difficulty to hide. + public void Hide(BeatmapInfo beatmap) => beatmaps.Hide(beatmap); + + /// + /// Restore a beatmap difficulty. + /// + /// The beatmap difficulty to restore. + public void Restore(BeatmapInfo beatmap) => beatmaps.Restore(beatmap); /// /// Returns a to a usable state if it has previously been deleted but not yet purged. @@ -197,8 +209,7 @@ namespace osu.Game.Beatmaps /// The beatmap to restore. public void Undelete(BeatmapSetInfo beatmapSet) { - lock (beatmaps) - if (!beatmaps.Undelete(beatmapSet)) return; + if (!beatmaps.Undelete(beatmapSet)) return; if (!beatmapSet.Protected) files.Reference(beatmapSet.Files.Select(f => f.FileInfo).ToArray()); @@ -258,6 +269,13 @@ namespace osu.Game.Beatmaps } } + /// + /// Refresh an existing instance of a from the store. + /// + /// A stale instance. + /// A fresh instance. + public BeatmapSetInfo Refresh(BeatmapSetInfo beatmapSet) => QueryBeatmapSet(s => s.ID == beatmapSet.ID); + /// /// Perform a lookup query on available s. /// @@ -265,7 +283,7 @@ namespace osu.Game.Beatmaps /// Results from the provided query. public List QueryBeatmapSets(Expression> query) { - lock (beatmaps) return beatmaps.QueryAndPopulate(query); + return beatmaps.QueryAndPopulate(query); } /// @@ -275,15 +293,12 @@ namespace osu.Game.Beatmaps /// The first result for the provided query, or null if no results were found. public BeatmapInfo QueryBeatmap(Func query) { - lock (beatmaps) - { - BeatmapInfo set = beatmaps.Query().FirstOrDefault(query); + BeatmapInfo set = beatmaps.Query().FirstOrDefault(query); - if (set != null) - beatmaps.Populate(set); + if (set != null) + beatmaps.Populate(set); - return set; - } + return set; } /// diff --git a/osu.Game/Beatmaps/BeatmapStore.cs b/osu.Game/Beatmaps/BeatmapStore.cs index 8212712bf9..0f2d8cffa6 100644 --- a/osu.Game/Beatmaps/BeatmapStore.cs +++ b/osu.Game/Beatmaps/BeatmapStore.cs @@ -16,11 +16,14 @@ namespace osu.Game.Beatmaps public event Action BeatmapSetAdded; public event Action BeatmapSetRemoved; + public event Action BeatmapHidden; + public event Action BeatmapRestored; + /// /// The current version of this store. Used for migrations (see ). /// The initial version is 1. /// - protected override int StoreVersion => 3; + protected override int StoreVersion => 4; public BeatmapStore(SQLiteConnection connection) : base(connection) @@ -81,6 +84,10 @@ namespace osu.Game.Beatmaps // Added MD5Hash column to BeatmapInfo Connection.MigrateTable(); break; + case 4: + // Added Hidden column to BeatmapInfo + Connection.MigrateTable(); + break; } } } @@ -100,7 +107,7 @@ namespace osu.Game.Beatmaps } /// - /// Delete a to the database. + /// Delete a from the database. /// /// The beatmap to delete. /// Whether the beatmap's was changed. @@ -131,6 +138,38 @@ namespace osu.Game.Beatmaps return true; } + /// + /// Hide a in the database. + /// + /// The beatmap to hide. + /// Whether the beatmap's was changed. + public bool Hide(BeatmapInfo beatmap) + { + if (beatmap.Hidden) return false; + + beatmap.Hidden = true; + Connection.Update(beatmap); + + BeatmapHidden?.Invoke(beatmap); + return true; + } + + /// + /// Restore a previously hidden . + /// + /// The beatmap to restore. + /// Whether the beatmap's was changed. + public bool Restore(BeatmapInfo beatmap) + { + if (!beatmap.Hidden) return false; + + beatmap.Hidden = false; + Connection.Update(beatmap); + + BeatmapRestored?.Invoke(beatmap); + return true; + } + private void cleanupPendingDeletions() { Connection.RunInTransaction(() => diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index b47210620d..19dfc22506 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -25,6 +25,8 @@ namespace osu.Game.Beatmaps.Drawables public Action DeleteRequested; + public Action RestoreHiddenRequested; + public Action DeleteDifficultyRequested; public BeatmapSetHeader Header; @@ -71,10 +73,11 @@ namespace osu.Game.Beatmaps.Drawables { GainedSelection = headerGainedSelection, DeleteRequested = b => DeleteRequested(b), + RestoreHiddenRequested = b => RestoreHiddenRequested(b), RelativeSizeAxes = Axes.X, }; - BeatmapSet.Beatmaps = BeatmapSet.Beatmaps.OrderBy(b => b.StarDifficulty).ToList(); + BeatmapSet.Beatmaps = BeatmapSet.Beatmaps.Where(b => !b.Hidden).OrderBy(b => b.StarDifficulty).ToList(); BeatmapPanels = BeatmapSet.Beatmaps.Select(b => new BeatmapPanel(b) { Alpha = 0, diff --git a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs index 1006380a2b..6b17b3bb8b 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs @@ -158,7 +158,7 @@ namespace osu.Game.Beatmaps.Drawables { new OsuMenuItem("Play", MenuItemType.Highlighted, () => StartRequested?.Invoke(this)), new OsuMenuItem("Edit", MenuItemType.Standard, () => EditRequested?.Invoke(this)), - new OsuMenuItem("Delete", MenuItemType.Destructive, () => DeleteRequested?.Invoke(Beatmap)), + new OsuMenuItem("Hide", MenuItemType.Destructive, () => DeleteRequested?.Invoke(Beatmap)), }; } } diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs index b475a23ffd..ee75b77747 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; @@ -25,6 +26,8 @@ namespace osu.Game.Beatmaps.Drawables public Action DeleteRequested; + public Action RestoreHiddenRequested; + private readonly SpriteText title; private readonly SpriteText artist; @@ -164,6 +167,9 @@ namespace osu.Game.Beatmaps.Drawables if (State == PanelSelectedState.NotSelected) items.Add(new OsuMenuItem("Expand", MenuItemType.Highlighted, () => State = PanelSelectedState.Selected)); + if (beatmap.BeatmapSetInfo.Beatmaps.Any(b => b.Hidden)) + items.Add(new OsuMenuItem("Restore all hidden", MenuItemType.Standard, () => RestoreHiddenRequested?.Invoke(beatmap.BeatmapSetInfo))); + items.Add(new OsuMenuItem("Delete", MenuItemType.Destructive, () => DeleteRequested?.Invoke(beatmap.BeatmapSetInfo))); return items.ToArray(); diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index a1c7f64188..5d495a61f0 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -107,12 +107,39 @@ namespace osu.Game.Screens.Select }); } - public void RemoveBeatmap(BeatmapSetInfo beatmapSet) + public void RemoveBeatmap(BeatmapSetInfo beatmapSet) => removeGroup(groups.Find(b => b.BeatmapSet.ID == beatmapSet.ID)); + + internal void UpdateBeatmap(BeatmapInfo beatmap) { - Schedule(delegate + // todo: this method should not run more than once for the same BeatmapSetInfo. + var set = manager.Refresh(beatmap.BeatmapSet); + + // todo: this method should be smarter as to not recreate panels that haven't changed, etc. + var group = groups.Find(b => b.BeatmapSet.ID == set.ID); + + if (group == null) + return; + + var newGroup = createGroup(set); + + int i = groups.IndexOf(group); + groups.RemoveAt(i); + groups.Insert(i, newGroup); + + if (selectedGroup == group && newGroup.BeatmapPanels.Count == 0) + selectedGroup = null; + + Filter(null, false); + + //check if we can/need to maintain our current selection. + if (selectedGroup == group && newGroup.BeatmapPanels.Count > 0) { - removeGroup(groups.Find(b => b.BeatmapSet.ID == beatmapSet.ID)); - }); + var newSelection = + newGroup.BeatmapPanels.Find(p => p.Beatmap.ID == selectedPanel?.Beatmap.ID) ?? + newGroup.BeatmapPanels[Math.Min(newGroup.BeatmapPanels.Count - 1, group.BeatmapPanels.IndexOf(selectedPanel))]; + + selectGroup(newGroup, newSelection); + } } public void SelectBeatmap(BeatmapInfo beatmap, bool animated = true) @@ -142,6 +169,8 @@ namespace osu.Game.Screens.Select public Action DeleteRequested; + public Action RestoreRequested; + public Action DeleteDifficultyRequested; public void SelectNext(int direction = 1, bool skipDifficulties = true) @@ -310,6 +339,7 @@ namespace osu.Game.Screens.Select SelectionChanged = (g, p) => selectGroup(g, p), StartRequested = b => StartRequested?.Invoke(), DeleteRequested = b => DeleteRequested?.Invoke(b), + RestoreHiddenRequested = s => RestoreRequested?.Invoke(s), DeleteDifficultyRequested = b => DeleteDifficultyRequested?.Invoke(b), State = BeatmapGroupState.Collapsed }; diff --git a/osu.Game/Screens/Select/BeatmapDeleteDialog.cs b/osu.Game/Screens/Select/BeatmapDeleteDialog.cs index 15ec84a7d8..aa37705cdf 100644 --- a/osu.Game/Screens/Select/BeatmapDeleteDialog.cs +++ b/osu.Game/Screens/Select/BeatmapDeleteDialog.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Graphics; @@ -13,28 +12,16 @@ namespace osu.Game.Screens.Select { private BeatmapManager manager; - private readonly Action deleteAction; - [BackgroundDependencyLoader] private void load(BeatmapManager beatmapManager) { manager = beatmapManager; } - public BeatmapDeleteDialog(BeatmapSetInfo beatmap) : this() + public BeatmapDeleteDialog(BeatmapSetInfo beatmap) { - BodyText = $@"{beatmap.Metadata?.Artist} - {beatmap.Metadata?.Title} (ALL DIFFICULTIES)"; - deleteAction = () => manager.Delete(beatmap); - } + BodyText = $@"{beatmap.Metadata?.Artist} - {beatmap.Metadata?.Title}"; - public BeatmapDeleteDialog(BeatmapInfo beatmap) : this() - { - BodyText = $@"{beatmap.Metadata?.Artist} - {beatmap.Metadata?.Title} [{beatmap.Version}]"; - deleteAction = () => manager.Delete(beatmap); - } - - public BeatmapDeleteDialog() - { Icon = FontAwesome.fa_trash_o; HeaderText = @"Confirm deletion of"; Buttons = new PopupDialogButton[] @@ -42,7 +29,7 @@ namespace osu.Game.Screens.Select new PopupDialogOkButton { Text = @"Yes. Totally. Delete it.", - Action = () => deleteAction(), + Action = () => manager.Delete(beatmap), }, new PopupDialogCancelButton { diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index b3ee33e7c6..b743af5351 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -107,7 +107,8 @@ namespace osu.Game.Screens.Select SelectionChanged = carouselSelectionChanged, BeatmapsChanged = carouselBeatmapsLoaded, DeleteRequested = b => promptDelete(b), - DeleteDifficultyRequested = b => promptDelete(b), + RestoreRequested = s => { foreach (var b in s.Beatmaps) manager.Restore(b); }, + DeleteDifficultyRequested = b => manager.Hide(b), StartRequested = () => carouselRaisedStart(), }); Add(FilterControl = new FilterControl @@ -176,6 +177,8 @@ namespace osu.Game.Screens.Select manager.BeatmapSetAdded += onBeatmapSetAdded; manager.BeatmapSetRemoved += onBeatmapSetRemoved; + manager.BeatmapHidden += onBeatmapHidden; + manager.BeatmapRestored += onBeatmapRestored; dialogOverlay = dialog; @@ -192,6 +195,9 @@ namespace osu.Game.Screens.Select carousel.AllowSelection = !Beatmap.Disabled; } + private void onBeatmapRestored(BeatmapInfo b) => carousel.UpdateBeatmap(b); + private void onBeatmapHidden(BeatmapInfo b) => carousel.UpdateBeatmap(b); + private void carouselBeatmapsLoaded() { if (Beatmap.Value.BeatmapSetInfo?.DeletePending == false) @@ -380,10 +386,7 @@ namespace osu.Game.Screens.Select } } - private void addBeatmapSet(BeatmapSetInfo beatmapSet) - { - carousel.AddBeatmap(beatmapSet); - } + private void addBeatmapSet(BeatmapSetInfo beatmapSet) => carousel.AddBeatmap(beatmapSet); private void removeBeatmapSet(BeatmapSetInfo beatmapSet) { @@ -400,14 +403,6 @@ namespace osu.Game.Screens.Select dialogOverlay?.Push(new BeatmapDeleteDialog(beatmap)); } - private void promptDelete(BeatmapInfo beatmap) - { - if (beatmap == null) - return; - - dialogOverlay?.Push(new BeatmapDeleteDialog(beatmap)); - } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { if (args.Repeat) return false; From f9d02afb007870f8bf9d778f99fd4de9d047af46 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Sep 2017 18:13:21 +0900 Subject: [PATCH 254/483] Don't allow selection of a hidden beatmap --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 5d495a61f0..8cdfcf1db0 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -144,7 +144,7 @@ namespace osu.Game.Screens.Select public void SelectBeatmap(BeatmapInfo beatmap, bool animated = true) { - if (beatmap == null) + if (beatmap == null || beatmap.Hidden) { SelectNext(); return; From 3d61cde266f3aac7149e9f18893bff6a8ecfd211 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Sep 2017 18:22:38 +0900 Subject: [PATCH 255/483] Correctly delay loading of PlaySongSelect-specific components --- osu.Game/Screens/Select/PlaySongSelect.cs | 6 ++---- osu.Game/Screens/Select/SongSelect.cs | 11 ++++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 662e1d55a2..7e03707d18 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -54,13 +54,11 @@ namespace osu.Game.Screens.Select ValidForResume = false; Push(new Editor()); }, Key.Number3); - - Beatmap.ValueChanged += beatmap_ValueChanged; } - private void beatmap_ValueChanged(WorkingBeatmap beatmap) + protected override void UpdateBeatmap(WorkingBeatmap beatmap) { - if (!IsCurrentScreen) return; + base.UpdateBeatmap(beatmap); beatmap.Mods.BindTo(modSelect.SelectedMods); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index b743af5351..e0e27e069d 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -244,7 +244,7 @@ namespace osu.Game.Screens.Select ensurePlayingSelected(preview); } - changeBackground(Beatmap.Value); + UpdateBeatmap(Beatmap.Value); }; selectionChangedDebounce?.Cancel(); @@ -312,7 +312,7 @@ namespace osu.Game.Screens.Select { if (Beatmap != null && !Beatmap.Value.BeatmapSetInfo.DeletePending) { - changeBackground(Beatmap); + UpdateBeatmap(Beatmap); ensurePlayingSelected(); } @@ -358,7 +358,12 @@ namespace osu.Game.Screens.Select initialAddSetsTask?.Cancel(); } - private void changeBackground(WorkingBeatmap beatmap) + /// + /// Allow components in SongSelect to update their loaded beatmap details. + /// This is a debounced call (unlike directly binding to WorkingBeatmap.ValueChanged). + /// + /// The working beatmap. + protected virtual void UpdateBeatmap(WorkingBeatmap beatmap) { var backgroundModeBeatmap = Background as BackgroundScreenBeatmap; if (backgroundModeBeatmap != null) From 8e0d18d36f73ddca1d66ef44e3707f900e6c0d8d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Sep 2017 18:26:01 +0900 Subject: [PATCH 256/483] Add a button to restore all hidden difficulties --- .../Sections/Maintenance/GeneralSettings.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs index 9d13a2ae2f..233ca7be60 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs @@ -13,6 +13,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { private OsuButton importButton; private OsuButton deleteButton; + private OsuButton restoreButton; protected override string Header => "General"; @@ -41,6 +42,20 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance Task.Run(() => beatmaps.DeleteAll()).ContinueWith(t => Schedule(() => deleteButton.Enabled.Value = true)); } }, + restoreButton = new OsuButton + { + RelativeSizeAxes = Axes.X, + Text = "Restore all hidden difficulties", + Action = () => + { + restoreButton.Enabled.Value = false; + Task.Run(() => + { + foreach (var b in beatmaps.QueryBeatmaps(b => b.Hidden)) + beatmaps.Restore(b); + }).ContinueWith(t => Schedule(() => restoreButton.Enabled.Value = true)); + } + }, }; } } From b19ae7c44ed3c9df5d1fb7200c11a53d59b84651 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Sep 2017 18:37:46 +0900 Subject: [PATCH 257/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 2804e052ca..2bd341b29d 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 2804e052ca2ce068f015771d28170d18573687e1 +Subproject commit 2bd341b29d6a7ed864aa9c1c5fad4668dafe03a4 From 3ede685ee9985065c079e2099dd2cf0a4706bb2a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Sep 2017 18:44:51 +0900 Subject: [PATCH 258/483] Fix crash on random selection from a previously null selection --- osu.Game/Screens/Select/BeatmapCarousel.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 264636b258..556ba68e95 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -191,7 +191,8 @@ namespace osu.Game.Screens.Select if (!visibleGroups.Any()) return; - randomSelectedBeatmaps.Push(new KeyValuePair(selectedGroup, selectedGroup.SelectedPanel)); + if (selectedGroup != null) + randomSelectedBeatmaps.Push(new KeyValuePair(selectedGroup, selectedGroup.SelectedPanel)); BeatmapGroup group; From c6b226b017f7a9212a195164983202ddbcf0bf42 Mon Sep 17 00:00:00 2001 From: Akash Mozumdar Date: Fri, 1 Sep 2017 15:32:03 -0400 Subject: [PATCH 259/483] refactor --- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index db39629d45..a66ac3298f 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Scoring { } - float beatmapHp; + private float beatmapHp; protected override void ComputeTargets(Game.Beatmaps.Beatmap beatmap) { From dd26c80837edb47bb5287c740e1d67b3e5338cb7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 4 Sep 2017 07:59:32 +0900 Subject: [PATCH 260/483] Delete -> Hide --- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 4 ++-- osu.Game/Beatmaps/Drawables/BeatmapPanel.cs | 4 ++-- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 ++-- osu.Game/Screens/Select/SongSelect.cs | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index 19dfc22506..4a389101e2 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -27,7 +27,7 @@ namespace osu.Game.Beatmaps.Drawables public Action RestoreHiddenRequested; - public Action DeleteDifficultyRequested; + public Action HideDifficultyRequested; public BeatmapSetHeader Header; @@ -82,7 +82,7 @@ namespace osu.Game.Beatmaps.Drawables { Alpha = 0, GainedSelection = panelGainedSelection, - DeleteRequested = p => DeleteDifficultyRequested?.Invoke(p), + HideRequested = p => HideDifficultyRequested?.Invoke(p), StartRequested = p => { StartRequested?.Invoke(p.Beatmap); }, RelativeSizeAxes = Axes.X, }).ToList(); diff --git a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs index 6b17b3bb8b..e216f1b83e 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapPanel.cs @@ -27,7 +27,7 @@ namespace osu.Game.Beatmaps.Drawables public Action GainedSelection; public Action StartRequested; public Action EditRequested; - public Action DeleteRequested; + public Action HideRequested; private readonly Triangles triangles; private readonly StarCounter starCounter; @@ -158,7 +158,7 @@ namespace osu.Game.Beatmaps.Drawables { new OsuMenuItem("Play", MenuItemType.Highlighted, () => StartRequested?.Invoke(this)), new OsuMenuItem("Edit", MenuItemType.Standard, () => EditRequested?.Invoke(this)), - new OsuMenuItem("Hide", MenuItemType.Destructive, () => DeleteRequested?.Invoke(Beatmap)), + new OsuMenuItem("Hide", MenuItemType.Destructive, () => HideRequested?.Invoke(Beatmap)), }; } } diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 7044447508..94ae740c74 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -171,7 +171,7 @@ namespace osu.Game.Screens.Select public Action RestoreRequested; - public Action DeleteDifficultyRequested; + public Action HideDifficultyRequested; public void SelectNext(int direction = 1, bool skipDifficulties = true) { @@ -341,7 +341,7 @@ namespace osu.Game.Screens.Select StartRequested = b => StartRequested?.Invoke(), DeleteRequested = b => DeleteRequested?.Invoke(b), RestoreHiddenRequested = s => RestoreRequested?.Invoke(s), - DeleteDifficultyRequested = b => DeleteDifficultyRequested?.Invoke(b), + HideDifficultyRequested = b => HideDifficultyRequested?.Invoke(b), State = BeatmapGroupState.Collapsed }; } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index e0e27e069d..8925732128 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -108,7 +108,7 @@ namespace osu.Game.Screens.Select BeatmapsChanged = carouselBeatmapsLoaded, DeleteRequested = b => promptDelete(b), RestoreRequested = s => { foreach (var b in s.Beatmaps) manager.Restore(b); }, - DeleteDifficultyRequested = b => manager.Hide(b), + HideDifficultyRequested = b => manager.Hide(b), StartRequested = () => carouselRaisedStart(), }); Add(FilterControl = new FilterControl From 543a71efcc7a8dfff9c5c40d5f99bef42509e0b8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 4 Sep 2017 08:21:07 +0900 Subject: [PATCH 261/483] Fix ObjectDisposal exceptions due to lingering event binds --- osu.Game/Screens/Select/SongSelect.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 8925732128..f97c4fe420 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -353,6 +353,8 @@ namespace osu.Game.Screens.Select { manager.BeatmapSetAdded -= onBeatmapSetAdded; manager.BeatmapSetRemoved -= onBeatmapSetRemoved; + manager.BeatmapHidden -= onBeatmapHidden; + manager.BeatmapRestored -= onBeatmapRestored; } initialAddSetsTask?.Cancel(); From 57678a13d9d3faf49fe0f422b8716893a73bf7f8 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 4 Sep 2017 09:10:04 +0900 Subject: [PATCH 262/483] Update in-line with framework changes. --- osu-framework | 2 +- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 9 ++++++++- osu.Game/Beatmaps/Drawables/Panel.cs | 9 ++++++++- .../Containers/OsuFocusedOverlayContainer.cs | 6 +++--- .../Graphics/UserInterface/BreadcrumbControl.cs | 6 ++++++ .../Graphics/UserInterface/OsuContextMenu.cs | 9 +++++---- osu.Game/Graphics/UserInterface/OsuDropdown.cs | 14 +++++--------- osu.Game/Graphics/UserInterface/OsuMenu.cs | 16 +++++++--------- osu.Game/OsuGame.cs | 4 ++-- osu.Game/Overlays/ChatOverlay.cs | 2 +- osu.Game/Overlays/DialogOverlay.cs | 2 +- osu.Game/Overlays/MainSettings.cs | 2 +- osu.Game/Overlays/MedalSplash/DrawableMedal.cs | 5 +++++ osu.Game/Overlays/MusicController.cs | 2 +- .../Settings/Sections/General/LoginSettings.cs | 4 ++-- osu.Game/Overlays/Settings/Sidebar.cs | 6 ++++++ .../Toolbar/ToolbarOverlayToggleButton.cs | 2 +- osu.Game/Overlays/WaveOverlayContainer.cs | 5 +++++ osu.Game/Screens/Menu/Button.cs | 4 ++++ osu.Game/Screens/Menu/ButtonSystem.cs | 4 ++++ osu.Game/Screens/Play/SkipButton.cs | 8 +++++++- osu.Game/Screens/Play/SquareGraph.cs | 6 ++++++ .../Select/Leaderboards/LeaderboardScore.cs | 8 ++++++++ 23 files changed, 97 insertions(+), 38 deletions(-) diff --git a/osu-framework b/osu-framework index 2bd341b29d..5c0e50379e 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 2bd341b29d6a7ed864aa9c1c5fad4668dafe03a4 +Subproject commit 5c0e50379e47a3805097dbc36a713decc64f49ce diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index 4a389101e2..c66bf637e2 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -11,6 +11,8 @@ namespace osu.Game.Beatmaps.Drawables { public class BeatmapGroup : IStateful { + public event Action StateChanged; + public BeatmapPanel SelectedPanel; /// @@ -42,6 +44,10 @@ namespace osu.Game.Beatmaps.Drawables get { return state; } set { + if (state == value) + return; + state = value; + switch (value) { case BeatmapGroupState.Expanded: @@ -60,7 +66,8 @@ namespace osu.Game.Beatmaps.Drawables panel.State = PanelSelectedState.Hidden; break; } - state = value; + + StateChanged?.Invoke(state); } } diff --git a/osu.Game/Beatmaps/Drawables/Panel.cs b/osu.Game/Beatmaps/Drawables/Panel.cs index d07be88392..d6ed306b39 100644 --- a/osu.Game/Beatmaps/Drawables/Panel.cs +++ b/osu.Game/Beatmaps/Drawables/Panel.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -15,6 +16,8 @@ namespace osu.Game.Beatmaps.Drawables { public const float MAX_HEIGHT = 80; + public event Action StateChanged; + public override bool RemoveWhenNotAlive => false; private readonly Container nestedContainer; @@ -77,11 +80,15 @@ namespace osu.Game.Beatmaps.Drawables set { - if (state == value) return; + if (state == value) + return; var last = state; state = value; + ApplyState(last); + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 0713fa1a52..4ea4f4cdc3 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -19,12 +19,12 @@ namespace osu.Game.Graphics.Containers samplePopIn = audio.Sample.Get(@"UI/melodic-5"); samplePopOut = audio.Sample.Get(@"UI/melodic-4"); - StateChanged += OsuFocusedOverlayContainer_StateChanged; + StateChanged += onStateChanged; } - private void OsuFocusedOverlayContainer_StateChanged(VisibilityContainer arg1, Visibility arg2) + private void onStateChanged(Visibility visibility) { - switch (arg2) + switch (visibility) { case Visibility.Visible: samplePopIn?.Play(); diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs index b3e53280fb..65ece51a70 100644 --- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK; using osu.Framework; using osu.Framework.Graphics; @@ -35,6 +36,8 @@ namespace osu.Game.Graphics.UserInterface private class BreadcrumbTabItem : OsuTabItem, IStateful { + public event Action StateChanged; + public readonly SpriteIcon Chevron; //don't allow clicking between transitions and don't make the chevron clickable @@ -42,6 +45,7 @@ namespace osu.Game.Graphics.UserInterface public override bool HandleInput => State == Visibility.Visible; private Visibility state; + public Visibility State { get { return state; } @@ -62,6 +66,8 @@ namespace osu.Game.Graphics.UserInterface this.FadeOut(transition_duration, Easing.OutQuint); this.ScaleTo(new Vector2(0.8f, 1f), transition_duration, Easing.OutQuint); } + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs index 808c72ee5d..4ce6c98744 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -14,14 +14,17 @@ namespace osu.Game.Graphics.UserInterface private const int fade_duration = 250; public OsuContextMenu() + : base(Direction.Vertical) { - CornerRadius = 5; - EdgeEffect = new EdgeEffectParameters + MaskingContainer.CornerRadius = 5; + MaskingContainer.EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = Color4.Black.Opacity(0.1f), Radius = 4, }; + + ItemsContainer.Padding = new MarginPadding { Vertical = DrawableOsuMenuItem.MARGIN_VERTICAL }; } [BackgroundDependencyLoader] @@ -32,7 +35,5 @@ namespace osu.Game.Graphics.UserInterface protected override void AnimateOpen() => this.FadeIn(fade_duration, Easing.OutQuint); protected override void AnimateClose() => this.FadeOut(fade_duration, Easing.OutQuint); - - protected override MarginPadding ItemFlowContainerPadding => new MarginPadding { Vertical = DrawableOsuMenuItem.MARGIN_VERTICAL }; } } \ No newline at end of file diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index dde154bb61..275cc2ab64 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -57,6 +57,9 @@ namespace osu.Game.Graphics.UserInterface { CornerRadius = 4; BackgroundColour = Color4.Black.Opacity(0.5f); + + // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring + ItemsContainer.Padding = new MarginPadding(5); } // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring @@ -64,14 +67,7 @@ namespace osu.Game.Graphics.UserInterface protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint); // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring - protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(5); - - // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring - protected override void UpdateMenuHeight() - { - var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight; - this.ResizeHeightTo(State == MenuState.Opened ? actualHeight : 0, 300, Easing.OutQuint); - } + protected override void UpdateSize(Vector2 newSize) => this.ResizeTo(newSize, 300, Easing.OutQuint); private Color4 accentColour; public Color4 AccentColour @@ -141,7 +137,7 @@ namespace osu.Game.Graphics.UserInterface protected override Drawable CreateContent() => new Content(); - protected class Content : FillFlowContainer, IHasText + protected new class Content : FillFlowContainer, IHasText { public string Text { diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index ab37fd2c90..a8cb8cafbb 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -12,27 +12,25 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; using osu.Game.Graphics.Sprites; +using OpenTK; namespace osu.Game.Graphics.UserInterface { public class OsuMenu : Menu { - public OsuMenu() + public OsuMenu(Direction direction) + : base(direction) { - CornerRadius = 4; BackgroundColour = Color4.Black.Opacity(0.5f); + + MaskingContainer.CornerRadius = 4; + ItemsContainer.Padding = new MarginPadding(5); } protected override void AnimateOpen() => this.FadeIn(300, Easing.OutQuint); protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint); - protected override void UpdateMenuHeight() - { - var actualHeight = (RelativeSizeAxes & Axes.Y) > 0 ? 1 : ContentHeight; - this.ResizeHeightTo(State == MenuState.Opened ? actualHeight : 0, 300, Easing.OutQuint); - } - - protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(5); + protected override void UpdateSize(Vector2 newSize) => this.ResizeTo(newSize, 300, Easing.OutQuint); protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuMenuItem(item); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 30bc09d50f..c020675881 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -230,13 +230,13 @@ namespace osu.Game var singleDisplayOverlays = new OverlayContainer[] { chat, social, direct }; foreach (var overlay in singleDisplayOverlays) { - overlay.StateChanged += (container, state) => + overlay.StateChanged += state => { if (state == Visibility.Hidden) return; foreach (var c in singleDisplayOverlays) { - if (c == container) continue; + if (c == overlay) continue; c.State = Visibility.Hidden; } }; diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 6dd5425fd1..b5bb1a2d9f 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -169,7 +169,7 @@ namespace osu.Game.Overlays channelTabs.Current.ValueChanged += newChannel => CurrentChannel = newChannel; channelTabs.ChannelSelectorActive.ValueChanged += value => channelSelection.State = value ? Visibility.Visible : Visibility.Hidden; - channelSelection.StateChanged += (overlay, state) => + channelSelection.StateChanged += state => { channelTabs.ChannelSelectorActive.Value = state == Visibility.Visible; diff --git a/osu.Game/Overlays/DialogOverlay.cs b/osu.Game/Overlays/DialogOverlay.cs index 012e93f10d..7853eefd2c 100644 --- a/osu.Game/Overlays/DialogOverlay.cs +++ b/osu.Game/Overlays/DialogOverlay.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays dialogContainer.Add(currentDialog); currentDialog.Show(); - currentDialog.StateChanged += onDialogOnStateChanged; + currentDialog.StateChanged += state => onDialogOnStateChanged(dialog, state); State = Visibility.Visible; } diff --git a/osu.Game/Overlays/MainSettings.cs b/osu.Game/Overlays/MainSettings.cs index b4d9cac045..4fe86d62fd 100644 --- a/osu.Game/Overlays/MainSettings.cs +++ b/osu.Game/Overlays/MainSettings.cs @@ -53,7 +53,7 @@ namespace osu.Game.Overlays private const float hidden_width = 120; - private void keyBindingOverlay_StateChanged(VisibilityContainer container, Visibility visibility) + private void keyBindingOverlay_StateChanged(Visibility visibility) { switch (visibility) { diff --git a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs index 56b26e7176..3ac8af7b2b 100644 --- a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs +++ b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Framework; using OpenTK; using osu.Framework.Allocation; @@ -19,6 +20,8 @@ namespace osu.Game.Overlays.MedalSplash private const float scale_when_unlocked = 0.76f; private const float scale_when_full = 0.6f; + public event Action StateChanged; + private readonly Medal medal; private readonly Container medalContainer; private readonly Sprite medalSprite, medalGlow; @@ -132,6 +135,8 @@ namespace osu.Game.Overlays.MedalSplash state = value; updateState(); + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index cb4628825e..0a06439c3e 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -204,7 +204,7 @@ namespace osu.Game.Overlays beatmapBacking.BindTo(game.Beatmap); - playlist.StateChanged += (c, s) => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint); + playlist.StateChanged += s => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint); } protected override void LoadComplete() diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index a816fa56c1..e62050fae1 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -292,6 +292,8 @@ namespace osu.Game.Overlays.Settings.Sections.General Colour = Color4.Black.Opacity(0.25f), Radius = 4, }; + + ItemsContainer.Padding = new MarginPadding(); } [BackgroundDependencyLoader] @@ -300,8 +302,6 @@ namespace osu.Game.Overlays.Settings.Sections.General BackgroundColour = colours.Gray3; } - protected override MarginPadding ItemFlowContainerPadding => new MarginPadding(); - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableUserDropdownMenuItem(item); private class DrawableUserDropdownMenuItem : DrawableOsuDropdownMenuItem diff --git a/osu.Game/Overlays/Settings/Sidebar.cs b/osu.Game/Overlays/Settings/Sidebar.cs index b22a5ab126..55167188a3 100644 --- a/osu.Game/Overlays/Settings/Sidebar.cs +++ b/osu.Game/Overlays/Settings/Sidebar.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; using osu.Framework; using OpenTK; @@ -19,6 +20,9 @@ namespace osu.Game.Overlays.Settings private readonly FillFlowContainer content; internal const float DEFAULT_WIDTH = ToolbarButton.WIDTH; internal const int EXPANDED_WIDTH = 200; + + public event Action StateChanged; + protected override Container Content => content; public Sidebar() @@ -102,6 +106,8 @@ namespace osu.Game.Overlays.Settings this.ResizeTo(new Vector2(EXPANDED_WIDTH, Height), 500, Easing.OutQuint); break; } + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs index 6d61a096b2..c530e8d7ff 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Toolbar stateContainer.StateChanged -= stateChanged; } - private void stateChanged(VisibilityContainer c, Visibility state) + private void stateChanged(Visibility state) { switch (state) { diff --git a/osu.Game/Overlays/WaveOverlayContainer.cs b/osu.Game/Overlays/WaveOverlayContainer.cs index fd89dcfbc4..4f9783a762 100644 --- a/osu.Game/Overlays/WaveOverlayContainer.cs +++ b/osu.Game/Overlays/WaveOverlayContainer.cs @@ -167,6 +167,8 @@ namespace osu.Game.Overlays private class Wave : Container, IStateful { + public event Action StateChanged; + public float FinalPosition; public Wave() @@ -200,6 +202,7 @@ namespace osu.Game.Overlays } private Visibility state; + public Visibility State { get { return state; } @@ -216,6 +219,8 @@ namespace osu.Game.Overlays this.MoveToY(FinalPosition, APPEAR_DURATION, easing_show); break; } + + StateChanged?.Invoke(State); } } } diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index 0898c079ce..aca169c3dc 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -28,6 +28,8 @@ namespace osu.Game.Screens.Menu /// public class Button : BeatSyncedContainer, IStateful { + public event Action StateChanged; + private readonly Container iconText; private readonly Container box; private readonly Box boxHoverLayer; @@ -266,6 +268,8 @@ namespace osu.Game.Screens.Menu this.FadeOut(explode_duration / 4f * 3); break; } + + StateChanged?.Invoke(State); } } } diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 71f2a16c09..e4dbe00a80 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -22,6 +22,8 @@ namespace osu.Game.Screens.Menu { public class ButtonSystem : Container, IStateful { + public event Action StateChanged; + public Action OnEdit; public Action OnExit; public Action OnDirect; @@ -294,6 +296,8 @@ namespace osu.Game.Screens.Menu backButton.State = state == MenuState.Play ? ButtonState.Expanded : ButtonState.Contracted; settingsButton.State = state == MenuState.TopLevel ? ButtonState.Expanded : ButtonState.Contracted; } + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Screens/Play/SkipButton.cs b/osu.Game/Screens/Play/SkipButton.cs index 3cf371f1e1..6519a8db36 100644 --- a/osu.Game/Screens/Play/SkipButton.cs +++ b/osu.Game/Screens/Play/SkipButton.cs @@ -133,6 +133,8 @@ namespace osu.Game.Screens.Play private class FadeContainer : Container, IStateful { + public event Action StateChanged; + private Visibility state; private ScheduledDelegate scheduledHide; @@ -144,8 +146,10 @@ namespace osu.Game.Screens.Play } set { - var lastState = state; + if (state == value) + return; + var lastState = state; state = value; scheduledHide?.Cancel(); @@ -164,6 +168,8 @@ namespace osu.Game.Screens.Play this.FadeOut(1000, Easing.OutExpo); break; } + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index f3bb523611..81dbf3eca4 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 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.Framework; @@ -170,6 +171,8 @@ namespace osu.Game.Screens.Play private const float padding = 2; public const float WIDTH = cube_size + padding; + public event Action StateChanged; + private readonly List drawableRows = new List(); private float filled; @@ -186,6 +189,7 @@ namespace osu.Game.Screens.Play } private ColumnState state; + public ColumnState State { get { return state; } @@ -196,6 +200,8 @@ namespace osu.Game.Screens.Play if (IsLoaded) fillActive(); + + StateChanged?.Invoke(State); } } diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index d7c85fff90..2987f4476c 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics; @@ -21,6 +22,8 @@ namespace osu.Game.Screens.Select.Leaderboards { public static readonly float HEIGHT = 60; + public event Action StateChanged; + public readonly int RankPosition; public readonly Score Score; @@ -41,11 +44,14 @@ namespace osu.Game.Screens.Select.Leaderboards private readonly FillFlowContainer modsContainer; private Visibility state; + public Visibility State { get { return state; } set { + if (state == value) + return; state = value; switch (state) @@ -88,6 +94,8 @@ namespace osu.Game.Screens.Select.Leaderboards break; } + + StateChanged?.Invoke(State); } } From 2a64bcda85aaa686fbefee7e22fb0a0dca9bd928 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 4 Sep 2017 09:32:44 +0900 Subject: [PATCH 263/483] Fix resizing bug(?). --- osu.Game/Graphics/UserInterface/OsuDropdown.cs | 14 +++++++++++++- osu.Game/Graphics/UserInterface/OsuMenu.cs | 14 +++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index 275cc2ab64..b69186e8b0 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -67,7 +67,19 @@ namespace osu.Game.Graphics.UserInterface protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint); // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring - protected override void UpdateSize(Vector2 newSize) => this.ResizeTo(newSize, 300, Easing.OutQuint); + protected override void UpdateSize(Vector2 newSize) + { + if (Direction == Direction.Vertical) + { + Width = newSize.X; + this.ResizeHeightTo(newSize.Y, 300, Easing.OutQuint); + } + else + { + Height = newSize.Y; + this.ResizeWidthTo(newSize.X, 300, Easing.OutQuint); + } + } private Color4 accentColour; public Color4 AccentColour diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index a8cb8cafbb..103155dd1f 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -30,7 +30,19 @@ namespace osu.Game.Graphics.UserInterface protected override void AnimateOpen() => this.FadeIn(300, Easing.OutQuint); protected override void AnimateClose() => this.FadeOut(300, Easing.OutQuint); - protected override void UpdateSize(Vector2 newSize) => this.ResizeTo(newSize, 300, Easing.OutQuint); + protected override void UpdateSize(Vector2 newSize) + { + if (Direction == Direction.Vertical) + { + Width = newSize.X; + this.ResizeHeightTo(newSize.Y, 300, Easing.OutQuint); + } + else + { + Height = newSize.Y; + this.ResizeWidthTo(newSize.X, 300, Easing.OutQuint); + } + } protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuMenuItem(item); From 9078444a6292fce1bd4e8a4ec6019c5c487a2f9f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 4 Sep 2017 11:03:04 +0900 Subject: [PATCH 264/483] Fix items jumping between two indices in the edge case, use a linear search for now. --- osu.Game/Overlays/Music/PlaylistItem.cs | 45 ++++++++++--------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 9df15bfd04..44bb2687f7 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -150,9 +151,6 @@ namespace osu.Game.Overlays.Music { private readonly FillFlowContainer playlist; - private const int line_height = 22; - private const int rearrange_buffer = 3; - public PlaylistItemHandle(FillFlowContainer playlist) { this.playlist = playlist; @@ -169,7 +167,23 @@ namespace osu.Game.Overlays.Music protected override bool OnDrag(InputState state) { int src = (int)Parent.Depth; - int dst = getIndex(state.Mouse.Position.Y + Parent.Position.Y); + + var matchingItem = playlist.Children.LastOrDefault(c => c.Position.Y < state.Mouse.Position.Y + Parent.Position.Y); + if (matchingItem == null) + return true; + + int dst = (int)matchingItem.Depth; + + // Due to the position predicate above, there is an edge case to consider when an item is moved upwards: + // At the point where the two items cross there will be two items sharing the same condition, and the items will jump back + // and forth between the two positions because of this. This is accentuated if the items span differing line heights. + // The easiest way to avoid this is to ensure the movement direction matches the expected mouse delta + + if (state.Mouse.Delta.Y <= 0 && dst > src) + return true; + + if (state.Mouse.Delta.Y >= 0 && dst < src) + return true; if (src == dst) return true; @@ -188,29 +202,6 @@ namespace osu.Game.Overlays.Music playlist.ChangeChildDepth(Parent as PlaylistItem, dst); return true; } - - private int getIndex(float position) { - IReadOnlyList items = playlist.Children; - - // Binary Search without matching exact - int min = 0; - int max = items.Count - 1; - while (min <= max) - { - int m = (min + max) / 2; - if (items[m].Y < position) - min = m + 1; - else if (items[m].Y > position) - max = m - 1; - } - - int index = Math.Max(0, min - 1); - // Only move if mouse falls within buffer - if (position - items[index].Y > rearrange_buffer && position - items[index].Y < line_height - rearrange_buffer) { - return (int)items[index].Depth; - } - return (int)Parent.Depth; - } } } } From 9b0309e6835a61f7d314e2cfbe6cc97bb4d456ec Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 4 Sep 2017 11:28:15 +0900 Subject: [PATCH 265/483] Use TakeWhile instead of reversing the list. --- osu.Game/Overlays/Music/PlaylistList.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 019049eb96..f463d382b0 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -59,8 +59,8 @@ namespace osu.Game.Overlays.Music { get { - var available = items.Children.Reverse(); - return (available.SkipWhile(i => !i.Selected).Skip(1).FirstOrDefault() ?? available.FirstOrDefault())?.BeatmapSetInfo; + var available = items.Children; + return (available.TakeWhile(i => !i.Selected).LastOrDefault() ?? available.LastOrDefault())?.BeatmapSetInfo; } } From 3b575444bedcfe4db9906abcd8ef7bafb4bd4d65 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 4 Sep 2017 13:12:12 +0900 Subject: [PATCH 266/483] Rewrite PlaylistList as CompositeDrawable and remove all backwards PlaylistList references Now handles drag at a PlaylistList.ItemsScrollContainer level (private class), and PlaylistList itself is no longer a Container so it only supports adding BeatmapSets. Sorry for the rewrite x.x. --- osu.Game/Overlays/Music/PlaylistItem.cs | 66 ++---- osu.Game/Overlays/Music/PlaylistList.cs | 256 ++++++++++++++------- osu.Game/Overlays/Music/PlaylistOverlay.cs | 10 +- 3 files changed, 188 insertions(+), 144 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 44bb2687f7..2aaa182685 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -18,7 +17,7 @@ using OpenTK; namespace osu.Game.Overlays.Music { - internal class PlaylistItem : Container, IFilterable + internal class PlaylistItem : Container, IFilterable, IDraggable { private const float fade_duration = 100; @@ -31,11 +30,12 @@ namespace osu.Game.Overlays.Music private UnicodeBindableString titleBind; private UnicodeBindableString artistBind; - private readonly FillFlowContainer playlist; public readonly BeatmapSetInfo BeatmapSetInfo; public Action OnSelect; + public bool IsDraggable => handle.IsHovered; + private bool selected; public bool Selected { @@ -51,9 +51,8 @@ namespace osu.Game.Overlays.Music } } - public PlaylistItem(FillFlowContainer playlist, BeatmapSetInfo setInfo) + public PlaylistItem(BeatmapSetInfo setInfo) { - this.playlist = playlist; BeatmapSetInfo = setInfo; RelativeSizeAxes = Axes.X; @@ -72,9 +71,9 @@ namespace osu.Game.Overlays.Music Children = new Drawable[] { - handle = new PlaylistItemHandle(playlist) + handle = new PlaylistItemHandle { - Colour = colours.Gray5, + Colour = colours.Gray5 }, text = new OsuTextFlowContainer { @@ -149,11 +148,9 @@ namespace osu.Game.Overlays.Music private class PlaylistItemHandle : SpriteIcon { - private readonly FillFlowContainer playlist; - public PlaylistItemHandle(FillFlowContainer playlist) + public PlaylistItemHandle() { - this.playlist = playlist; Anchor = Anchor.TopLeft; Origin = Anchor.TopLeft; Size = new Vector2(12); @@ -161,47 +158,14 @@ namespace osu.Game.Overlays.Music Alpha = 0f; Margin = new MarginPadding { Left = 5, Top = 2 }; } - - protected override bool OnDragStart(InputState state) => true; - - protected override bool OnDrag(InputState state) - { - int src = (int)Parent.Depth; - - var matchingItem = playlist.Children.LastOrDefault(c => c.Position.Y < state.Mouse.Position.Y + Parent.Position.Y); - if (matchingItem == null) - return true; - - int dst = (int)matchingItem.Depth; - - // Due to the position predicate above, there is an edge case to consider when an item is moved upwards: - // At the point where the two items cross there will be two items sharing the same condition, and the items will jump back - // and forth between the two positions because of this. This is accentuated if the items span differing line heights. - // The easiest way to avoid this is to ensure the movement direction matches the expected mouse delta - - if (state.Mouse.Delta.Y <= 0 && dst > src) - return true; - - if (state.Mouse.Delta.Y >= 0 && dst < src) - return true; - - if (src == dst) - return true; - - if (src < dst) - { - for (int i = src + 1; i <= dst; i++) - playlist.ChangeChildDepth(playlist[i], i - 1); - } - else - { - for (int i = dst; i < src; i++) - playlist.ChangeChildDepth(playlist[i], i + 1); - } - - playlist.ChangeChildDepth(Parent as PlaylistItem, dst); - return true; - } } } + + public interface IDraggable : IDrawable + { + /// + /// Whether this can be dragged in its current state. + /// + bool IsDraggable { get; } + } } diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index f463d382b0..a4550f7f52 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -4,125 +4,205 @@ using System; using System.Collections.Generic; using System.Linq; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; +using OpenTK; namespace osu.Game.Overlays.Music { - internal class PlaylistList : Container + internal class PlaylistList : CompositeDrawable { - private readonly FillFlowContainer items; - - public IEnumerable BeatmapSets - { - set - { - items.Children = value.Select((item, index) => new PlaylistItem(items, item) { OnSelect = itemSelected, Depth = index }).ToList(); - } - } - - public BeatmapSetInfo FirstVisibleSet => items.Children.FirstOrDefault(i => i.MatchingFilter)?.BeatmapSetInfo; - - private void itemSelected(BeatmapSetInfo b) - { - OnSelect?.Invoke(b); - } - public Action OnSelect; - private readonly SearchContainer search; - - public void Filter(string searchTerm) => search.SearchTerm = searchTerm; - - public BeatmapSetInfo SelectedItem - { - get { return items.Children.FirstOrDefault(i => i.Selected)?.BeatmapSetInfo; } - set - { - foreach (PlaylistItem s in items.Children) - s.Selected = s.BeatmapSetInfo.ID == value?.ID; - } - } - - public BeatmapSetInfo NextItem - { - get - { - var available = items.Children; - return (available.SkipWhile(i => !i.Selected).Skip(1).FirstOrDefault() ?? available.FirstOrDefault())?.BeatmapSetInfo; - } - } - - public BeatmapSetInfo PreviousItem - { - get - { - var available = items.Children; - return (available.TakeWhile(i => !i.Selected).LastOrDefault() ?? available.LastOrDefault())?.BeatmapSetInfo; - } - } + private readonly ItemsScrollContainer items; public PlaylistList() { - Children = new Drawable[] + InternalChild = items = new ItemsScrollContainer { - new OsuScrollContainer - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - search = new SearchContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - items = new ItemSearchContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - }, - } - } - }, - }, + RelativeSizeAxes = Axes.Both, + OnSelect = set => OnSelect?.Invoke(set) }; } - public void AddBeatmapSet(BeatmapSetInfo beatmapSet) + public new MarginPadding Padding { - items.Add(new PlaylistItem(items, beatmapSet) { OnSelect = itemSelected, Depth = items.Count }); + get { return base.Padding; } + set { base.Padding = value; } } - public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) + public IEnumerable BeatmapSets { set { items.Sets = value; } } + + public BeatmapSetInfo FirstVisibleSet => items.FirstVisibleSet; + public BeatmapSetInfo NextSet => items.NextSet; + public BeatmapSetInfo PreviousSet => items.PreviousSet; + + public BeatmapSetInfo SelectedSet { - PlaylistItem itemToRemove = items.Children.FirstOrDefault(item => item.BeatmapSetInfo.ID == beatmapSet.ID); - if (itemToRemove != null) items.Remove(itemToRemove); + get { return items.SelectedSet; } + set { items.SelectedSet = value; } } - private class ItemSearchContainer : FillFlowContainer, IHasFilterableChildren + public void AddBeatmapSet(BeatmapSetInfo beatmapSet) => items.AddBeatmapSet(beatmapSet); + public bool RemoveBeatmapSet(BeatmapSetInfo beatmapSet) => items.RemoveBeatmapSet(beatmapSet); + + public void Filter(string searchTerm) => items.SearchTerm = searchTerm; + + private class ItemsScrollContainer : OsuScrollContainer { - public string[] FilterTerms => new string[] { }; - public bool MatchingFilter + public Action OnSelect; + + private readonly SearchContainer search; + private readonly FillFlowContainer items; + + private PlaylistItem draggedItem; + + public ItemsScrollContainer() + { + Children = new Drawable[] + { + search = new SearchContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + items = new ItemSearchContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }, + } + } + }; + } + + public IEnumerable Sets { set { - if (value) - InvalidateLayout(); + items.Clear(); + value.ForEach(AddBeatmapSet); } } - // Compare with reversed ChildID and Depth - protected override int Compare(Drawable x, Drawable y) => base.Compare(y, x); - - public IEnumerable FilterableChildren => Children; - - public ItemSearchContainer() + public string SearchTerm { - LayoutDuration = 200; - LayoutEasing = Easing.OutQuint; + get { return search.SearchTerm; } + set { search.SearchTerm = value; } + } + + public void AddBeatmapSet(BeatmapSetInfo beatmapSet) + { + items.Add(new PlaylistItem(beatmapSet) + { + OnSelect = set => OnSelect?.Invoke(set), + Depth = items.Count + }); + } + + public bool RemoveBeatmapSet(BeatmapSetInfo beatmapSet) + { + var itemToRemove = items.FirstOrDefault(i => i.BeatmapSetInfo.ID == beatmapSet.ID); + if (itemToRemove == null) + return false; + return 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; + + protected override bool OnDragStart(InputState state) + { + draggedItem = items.FirstOrDefault(d => d.IsDraggable); + return draggedItem != null || base.OnDragStart(state); + } + + protected override bool OnDrag(InputState state) + { + if (draggedItem == null) + return base.OnDrag(state); + + // Mouse position in the position space of the items container + Vector2 itemsPos = items.ToLocalSpace(state.Mouse.NativeState.Position); + + int src = (int)draggedItem.Depth; + + var matchingItem = items.LastOrDefault(c => c.Position.Y < itemsPos.Y); + if (matchingItem == null) + return true; + + int dst = (int)matchingItem.Depth; + + // Due to the position predicate above, there is an edge case to consider when an item is moved upwards: + // At the point where the two items cross there will be two items sharing the same condition, and the items will jump back + // and forth between the two positions because of this. This is accentuated if the items span differing line heights. + // The easiest way to avoid this is to ensure the movement direction matches the expected mouse delta + + if (state.Mouse.Delta.Y <= 0 && dst > src) + return true; + + if (state.Mouse.Delta.Y >= 0 && dst < src) + return true; + + if (src == dst) + return true; + + if (src < dst) + { + for (int i = src + 1; i <= dst; i++) + items.ChangeChildDepth(items[i], i - 1); + } + else + { + for (int i = dst; i < src; i++) + items.ChangeChildDepth(items[i], i + 1); + } + + items.ChangeChildDepth(draggedItem, dst); + + return true; + } + + protected override bool OnDragEnd(InputState state) => draggedItem != null || base.OnDragEnd(state); + + private class ItemSearchContainer : FillFlowContainer, IHasFilterableChildren + { + public string[] FilterTerms => new string[] { }; + public bool MatchingFilter + { + set + { + if (value) + InvalidateLayout(); + } + } + + // Compare with reversed ChildID and Depth + protected override int Compare(Drawable x, Drawable y) => base.Compare(y, x); + + public IEnumerable FilterableChildren => Children; + + public ItemSearchContainer() + { + LayoutDuration = 200; + LayoutEasing = Easing.OutQuint; + } } } } diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index e987e7a5c1..d05ad85726 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Music protected override void LoadComplete() { base.LoadComplete(); - beatmapBacking.ValueChanged += b => list.SelectedItem = b?.BeatmapSetInfo; + beatmapBacking.ValueChanged += b => list.SelectedSet = b?.BeatmapSetInfo; beatmapBacking.TriggerChange(); } @@ -126,23 +126,23 @@ namespace osu.Game.Overlays.Music public void PlayPrevious() { - var playable = list.PreviousItem; + var playable = list.PreviousSet; if (playable != null) { playSpecified(playable.Beatmaps[0]); - list.SelectedItem = playable; + list.SelectedSet = playable; } } public void PlayNext() { - var playable = list.NextItem; + var playable = list.NextSet; if (playable != null) { playSpecified(playable.Beatmaps[0]); - list.SelectedItem = playable; + list.SelectedSet = playable; } } From 2ed20f5a6f6ba54b498971d15fb1299aa5ab15e2 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 4 Sep 2017 14:20:40 +0900 Subject: [PATCH 267/483] Add better fix for items swapping erratically. --- osu.Game/Overlays/Music/PlaylistList.cs | 27 +++++++++++-------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index a4550f7f52..8af8943ded 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -143,22 +143,19 @@ namespace osu.Game.Overlays.Music int src = (int)draggedItem.Depth; - var matchingItem = items.LastOrDefault(c => c.Position.Y < itemsPos.Y); - if (matchingItem == null) - return true; + // Find the last item with position < mouse position. Note we can't directly use + // the item positions as they are being transformed + float heightAccumulator = 0; + int dst = 0; + for (; dst < items.Count; dst++) + { + // Using BoundingBox here takes care of scale, paddings, etc... + heightAccumulator += items[dst].BoundingBox.Height; + if (heightAccumulator > itemsPos.Y) + break; + } - int dst = (int)matchingItem.Depth; - - // Due to the position predicate above, there is an edge case to consider when an item is moved upwards: - // At the point where the two items cross there will be two items sharing the same condition, and the items will jump back - // and forth between the two positions because of this. This is accentuated if the items span differing line heights. - // The easiest way to avoid this is to ensure the movement direction matches the expected mouse delta - - if (state.Mouse.Delta.Y <= 0 && dst > src) - return true; - - if (state.Mouse.Delta.Y >= 0 && dst < src) - return true; + dst = MathHelper.Clamp(dst, 0, items.Count - 1); if (src == dst) return true; From 04c3801fcc19c0a21064ee82dceff414f635dc20 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 4 Sep 2017 14:58:28 +0900 Subject: [PATCH 268/483] Add scrolling points so items can be dragged beyond the list. --- osu.Game/Overlays/Music/PlaylistList.cs | 73 +++++++++++++++++++------ 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 8af8943ded..ad964f7458 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -137,46 +137,87 @@ namespace osu.Game.Overlays.Music { if (draggedItem == null) return base.OnDrag(state); + return true; + } - // Mouse position in the position space of the items container - Vector2 itemsPos = items.ToLocalSpace(state.Mouse.NativeState.Position); + protected override bool OnDragEnd(InputState state) + { + var handled = draggedItem != null || base.OnDragEnd(state); + draggedItem = null; - int src = (int)draggedItem.Depth; + return handled; + } + + protected override void Update() + { + base.Update(); + + if (draggedItem == null) + return; + + var mouseState = GetContainingInputManager().CurrentState.Mouse; + + updateScrollPosition(mouseState); + updateDragPosition(mouseState); + } + + private void updateScrollPosition(IMouseState mouseState) + { + const float start_offset = 10; + const double max_power = 50; + const double exp_base = 1.05; + + var localPos = ToLocalSpace(mouseState.Position); + + if (localPos.Y < start_offset) + { + var power = Math.Min(max_power, Math.Abs(start_offset - localPos.Y)); + ScrollBy(-(float)Math.Pow(exp_base, power)); + } + else if (localPos.Y > DrawHeight - start_offset) + { + var power = Math.Min(max_power, Math.Abs(DrawHeight - start_offset - localPos.Y)); + ScrollBy((float)Math.Pow(exp_base, power)); + } + } + + private void updateDragPosition(IMouseState mouseState) + { + var itemsPos = items.ToLocalSpace(mouseState.Position); + + int srcIndex = (int)draggedItem.Depth; // Find the last item with position < mouse position. Note we can't directly use // the item positions as they are being transformed float heightAccumulator = 0; - int dst = 0; - for (; dst < items.Count; dst++) + int dstIndex = 0; + for (; dstIndex < items.Count; dstIndex++) { // Using BoundingBox here takes care of scale, paddings, etc... - heightAccumulator += items[dst].BoundingBox.Height; + heightAccumulator += items[dstIndex].BoundingBox.Height; if (heightAccumulator > itemsPos.Y) break; } - dst = MathHelper.Clamp(dst, 0, items.Count - 1); + dstIndex = MathHelper.Clamp(dstIndex, 0, items.Count - 1); - if (src == dst) - return true; + if (srcIndex == dstIndex) + return; - if (src < dst) + if (srcIndex < dstIndex) { - for (int i = src + 1; i <= dst; i++) + for (int i = srcIndex + 1; i <= dstIndex; i++) items.ChangeChildDepth(items[i], i - 1); } else { - for (int i = dst; i < src; i++) + for (int i = dstIndex; i < srcIndex; i++) items.ChangeChildDepth(items[i], i + 1); } - items.ChangeChildDepth(draggedItem, dst); - - return true; + items.ChangeChildDepth(draggedItem, dstIndex); } - protected override bool OnDragEnd(InputState state) => draggedItem != null || base.OnDragEnd(state); private class ItemSearchContainer : FillFlowContainer, IHasFilterableChildren { From 722b7419d634e4627cf5eed409ee6acc45be702f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 4 Sep 2017 15:06:21 +0900 Subject: [PATCH 269/483] Clamp at the end points. --- osu.Game/Overlays/Music/PlaylistList.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index ad964f7458..6c8fb61ef2 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -8,6 +8,7 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; +using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using OpenTK; @@ -171,11 +172,17 @@ namespace osu.Game.Overlays.Music if (localPos.Y < start_offset) { + if (Current <= 0) + return; + var power = Math.Min(max_power, Math.Abs(start_offset - localPos.Y)); ScrollBy(-(float)Math.Pow(exp_base, power)); } else if (localPos.Y > DrawHeight - start_offset) { + if (IsScrolledToEnd()) + return; + var power = Math.Min(max_power, Math.Abs(DrawHeight - start_offset - localPos.Y)); ScrollBy((float)Math.Pow(exp_base, power)); } From ad966f41f5cc559f60681cac7e64a745c99b30f9 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 4 Sep 2017 15:08:41 +0900 Subject: [PATCH 270/483] Fix CI error. --- osu.Game/Overlays/Music/PlaylistList.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 6c8fb61ef2..e98fc45915 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -8,7 +8,6 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; -using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using OpenTK; From ed0f2a654baccd5425c7a4b0ff8629cd32e8dae2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 4 Sep 2017 18:51:50 +0900 Subject: [PATCH 271/483] Rename variable --- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index a66ac3298f..8ba92a8d30 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -23,11 +23,11 @@ namespace osu.Game.Rulesets.Osu.Scoring { } - private float beatmapHp; + private float hpDrainRate; protected override void ComputeTargets(Game.Beatmaps.Beatmap beatmap) { - beatmapHp = beatmap.BeatmapInfo.Difficulty.DrainRate; + hpDrainRate = beatmap.BeatmapInfo.Difficulty.DrainRate; } protected override void Reset() @@ -66,23 +66,23 @@ namespace osu.Game.Rulesets.Osu.Scoring switch (judgement.Score) { case OsuScoreResult.Hit300: - Health.Value += (10.2 - beatmapHp) * 0.02; + Health.Value += (10.2 - hpDrainRate) * 0.02; break; case OsuScoreResult.Hit100: - Health.Value += (8 - beatmapHp) * 0.02; + Health.Value += (8 - hpDrainRate) * 0.02; break; case OsuScoreResult.Hit50: - Health.Value += (4 - beatmapHp) * 0.02; + Health.Value += (4 - hpDrainRate) * 0.02; break; case OsuScoreResult.SliderTick: - Health.Value += System.Math.Max(7 - beatmapHp, 0) * 0.01; + Health.Value += System.Math.Max(7 - hpDrainRate, 0) * 0.01; break; case OsuScoreResult.Miss: - Health.Value -= beatmapHp * 0.04; + Health.Value -= hpDrainRate * 0.04; break; } } From e9f076244065fa732782bac35293bb7c9027cf1c Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 5 Sep 2017 10:29:51 +0900 Subject: [PATCH 272/483] Don't query GetContainingInputManager every Update. --- osu.Game/Overlays/Music/PlaylistList.cs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index e98fc45915..ff1a8dd0dc 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -59,8 +59,6 @@ namespace osu.Game.Overlays.Music private readonly SearchContainer search; private readonly FillFlowContainer items; - private PlaylistItem draggedItem; - public ItemsScrollContainer() { Children = new Drawable[] @@ -127,14 +125,19 @@ namespace osu.Game.Overlays.Music 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 InputState dragInputState; + private PlaylistItem draggedItem; + protected override bool OnDragStart(InputState state) { + dragInputState = state; draggedItem = items.FirstOrDefault(d => d.IsDraggable); return draggedItem != null || base.OnDragStart(state); } protected override bool OnDrag(InputState state) { + dragInputState = state; if (draggedItem == null) return base.OnDrag(state); return true; @@ -142,6 +145,7 @@ namespace osu.Game.Overlays.Music protected override bool OnDragEnd(InputState state) { + dragInputState = state; var handled = draggedItem != null || base.OnDragEnd(state); draggedItem = null; @@ -155,19 +159,17 @@ namespace osu.Game.Overlays.Music if (draggedItem == null) return; - var mouseState = GetContainingInputManager().CurrentState.Mouse; - - updateScrollPosition(mouseState); - updateDragPosition(mouseState); + updateScrollPosition(); + updateDragPosition(); } - private void updateScrollPosition(IMouseState mouseState) + private void updateScrollPosition() { const float start_offset = 10; const double max_power = 50; const double exp_base = 1.05; - var localPos = ToLocalSpace(mouseState.Position); + var localPos = ToLocalSpace(dragInputState.Mouse.NativeState.Position); if (localPos.Y < start_offset) { @@ -187,9 +189,9 @@ namespace osu.Game.Overlays.Music } } - private void updateDragPosition(IMouseState mouseState) + private void updateDragPosition() { - var itemsPos = items.ToLocalSpace(mouseState.Position); + var itemsPos = items.ToLocalSpace(dragInputState.Mouse.NativeState.Position); int srcIndex = (int)draggedItem.Depth; @@ -250,4 +252,4 @@ namespace osu.Game.Overlays.Music } } } -} \ No newline at end of file +} From 1904b5edfe93bbffdd153a20b4803314c9655234 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 5 Sep 2017 10:37:49 +0900 Subject: [PATCH 273/483] Only store native position instead of input state. --- osu.Game/Overlays/Music/PlaylistList.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index ff1a8dd0dc..360e2ad843 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -125,19 +125,19 @@ namespace osu.Game.Overlays.Music 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 InputState dragInputState; + private Vector2 nativeDragPosition; private PlaylistItem draggedItem; protected override bool OnDragStart(InputState state) { - dragInputState = state; + nativeDragPosition = state.Mouse.NativeState.Position; draggedItem = items.FirstOrDefault(d => d.IsDraggable); return draggedItem != null || base.OnDragStart(state); } protected override bool OnDrag(InputState state) { - dragInputState = state; + nativeDragPosition = state.Mouse.NativeState.Position; if (draggedItem == null) return base.OnDrag(state); return true; @@ -145,7 +145,7 @@ namespace osu.Game.Overlays.Music protected override bool OnDragEnd(InputState state) { - dragInputState = state; + nativeDragPosition = state.Mouse.NativeState.Position; var handled = draggedItem != null || base.OnDragEnd(state); draggedItem = null; @@ -169,7 +169,7 @@ namespace osu.Game.Overlays.Music const double max_power = 50; const double exp_base = 1.05; - var localPos = ToLocalSpace(dragInputState.Mouse.NativeState.Position); + var localPos = ToLocalSpace(nativeDragPosition); if (localPos.Y < start_offset) { @@ -191,7 +191,7 @@ namespace osu.Game.Overlays.Music private void updateDragPosition() { - var itemsPos = items.ToLocalSpace(dragInputState.Mouse.NativeState.Position); + var itemsPos = items.ToLocalSpace(nativeDragPosition); int srcIndex = (int)draggedItem.Depth; From d69b8d7784f1eb2d8b63b5c62d52ad750e5af958 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Sep 2017 17:09:58 +0900 Subject: [PATCH 274/483] Add basic combo score factor to osu! ruleset --- .../Scoring/OsuScoreProcessor.cs | 80 ++++++++++++++++--- 1 file changed, 69 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 8ba92a8d30..8432c5b26a 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -1,8 +1,11 @@ // Copyright (c) 2007-2017 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.Configuration; using osu.Framework.Extensions; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; @@ -14,6 +17,8 @@ namespace osu.Game.Rulesets.Osu.Scoring { internal class OsuScoreProcessor : ScoreProcessor { + public readonly Bindable Mode = new Bindable(ScoringMode.Exponential); + public OsuScoreProcessor() { } @@ -25,9 +30,28 @@ namespace osu.Game.Rulesets.Osu.Scoring private float hpDrainRate; - protected override void ComputeTargets(Game.Beatmaps.Beatmap beatmap) + private int totalAccurateJudgements; + + private readonly Dictionary scoreResultCounts = new Dictionary(); + private readonly Dictionary comboResultCounts = new Dictionary(); + + private double comboMaxScore; + + protected override void ComputeTargets(Beatmap beatmap) { hpDrainRate = beatmap.BeatmapInfo.Difficulty.DrainRate; + totalAccurateJudgements = beatmap.HitObjects.Count; + + foreach (var h in beatmap.HitObjects) + { + // TODO: add support for other object types. + AddJudgement(new OsuJudgement + { + MaxScore = OsuScoreResult.Hit300, + Score = OsuScoreResult.Hit300, + Result = HitResult.Hit + }); + } } protected override void Reset() @@ -41,9 +65,6 @@ namespace osu.Game.Rulesets.Osu.Scoring comboResultCounts.Clear(); } - private readonly Dictionary scoreResultCounts = new Dictionary(); - private readonly Dictionary comboResultCounts = new Dictionary(); - public override void PopulateScore(Score score) { base.PopulateScore(score); @@ -63,6 +84,7 @@ namespace osu.Game.Rulesets.Osu.Scoring scoreResultCounts[judgement.Score] = scoreResultCounts.GetOrDefault(judgement.Score) + 1; comboResultCounts[judgement.Combo] = comboResultCounts.GetOrDefault(judgement.Combo) + 1; } + switch (judgement.Score) { case OsuScoreResult.Hit300: @@ -78,7 +100,7 @@ namespace osu.Game.Rulesets.Osu.Scoring break; case OsuScoreResult.SliderTick: - Health.Value += System.Math.Max(7 - hpDrainRate, 0) * 0.01; + Health.Value += Math.Max(7 - hpDrainRate, 0) * 0.01; break; case OsuScoreResult.Miss: @@ -87,17 +109,53 @@ namespace osu.Game.Rulesets.Osu.Scoring } } - int score = 0; - int maxScore = 0; + calculateScore(); + + calculateScore(); + } + + private void calculateScore() + { + int baseScore = 0; + double comboScore = 0; + + int baseMaxScore = 0; foreach (var j in Judgements) { - score += j.ScoreValue; - maxScore += j.MaxScoreValue; + baseScore += j.ScoreValue; + baseMaxScore += j.MaxScoreValue; + + comboScore += j.ScoreValue * (1 + Combo.Value / 10d); } - TotalScore.Value = score; - Accuracy.Value = (double)score / maxScore; + Accuracy.Value = (double)baseScore / baseMaxScore; + + if (comboScore > comboMaxScore) + comboMaxScore = comboScore; + + if (baseScore == 0) + TotalScore.Value = 0; + else + { + // temporary to make scoring feel more like score v1 without being score v1. + float exponentialFactor = Mode.Value == ScoringMode.Exponential ? (float)Judgements.Count / 100 : 1; + + TotalScore.Value = + (int) + ( + exponentialFactor * + 700000 * comboScore / comboMaxScore + + 300000 * Math.Pow(Accuracy.Value, 10) * ((double)Judgements.Count / totalAccurateJudgements) + + 0 /* bonusScore */ + ); + } + } + + public enum ScoringMode + { + Standardised, + Exponential } } } From 24f7fbe1e5d7ad1d0b4637a1b750c25bc787ccf0 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 5 Sep 2017 19:14:37 +0900 Subject: [PATCH 275/483] Update framework. --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 5c0e50379e..3edf658577 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 5c0e50379e47a3805097dbc36a713decc64f49ce +Subproject commit 3edf65857759f32d5a6d07ed523a2892b09c3c6a From b871323ed8091577a151cd3285152408db0e6643 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 5 Sep 2017 19:26:28 +0900 Subject: [PATCH 276/483] Fix BeatmapGroup initialization not correctly setting panels to Hidden. --- osu.Game/Beatmaps/Drawables/BeatmapGroup.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs index c66bf637e2..9c62289bfa 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapGroup.cs @@ -33,19 +33,16 @@ namespace osu.Game.Beatmaps.Drawables public BeatmapSetHeader Header; - private BeatmapGroupState state; - public List BeatmapPanels; public BeatmapSetInfo BeatmapSet; + private BeatmapGroupState state; public BeatmapGroupState State { get { return state; } set { - if (state == value) - return; state = value; switch (value) @@ -97,6 +94,7 @@ namespace osu.Game.Beatmaps.Drawables Header.AddDifficultyIcons(BeatmapPanels); } + private void headerGainedSelection(BeatmapSetHeader panel) { State = BeatmapGroupState.Expanded; From 0fc2e49ce6b12f2003f043135189293653ea2247 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Sep 2017 19:33:20 +0900 Subject: [PATCH 277/483] Remove second calculateScore call --- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 8432c5b26a..41e0dbff41 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -110,8 +110,6 @@ namespace osu.Game.Rulesets.Osu.Scoring } calculateScore(); - - calculateScore(); } private void calculateScore() From 05f5dfba81c5dd0d2cdf52c8cf933d921f3515db Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 5 Sep 2017 13:57:30 +0200 Subject: [PATCH 278/483] Change difficulty colors and add ExpertPlus ExpertPlus is for beatmaps above 6.75* --- .../Drawables/DifficultyColouredContainer.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs b/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs index 2614baa116..41b77f6584 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs @@ -33,7 +33,8 @@ namespace osu.Game.Beatmaps.Drawables Normal, Hard, Insane, - Expert + Expert, + ExpertPlus } private DifficultyRating getDifficultyRating(BeatmapInfo beatmap) @@ -44,7 +45,8 @@ namespace osu.Game.Beatmaps.Drawables if (rating < 2.25) return DifficultyRating.Normal; if (rating < 3.75) return DifficultyRating.Hard; if (rating < 5.25) return DifficultyRating.Insane; - return DifficultyRating.Expert; + if (rating < 6.75) return DifficultyRating.Expert; + return DifficultyRating.ExpertPlus; } private Color4 getColour(BeatmapInfo beatmap) @@ -55,12 +57,14 @@ namespace osu.Game.Beatmaps.Drawables return palette.Green; default: case DifficultyRating.Normal: - return palette.Yellow; + return palette.Blue; case DifficultyRating.Hard: - return palette.Pink; + return palette.Yellow; case DifficultyRating.Insane: - return palette.Purple; + return palette.Pink; case DifficultyRating.Expert: + return palette.Purple; + case DifficultyRating.ExpertPlus: return palette.Gray0; } } From 081b98ef39c3678ce7c5960505e86fe41627a711 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Sep 2017 21:30:14 +0900 Subject: [PATCH 279/483] "Use" the hitobject Obviously temporary. --- .../Scoring/OsuScoreProcessor.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 41e0dbff41..3ee8f56665 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -44,13 +44,16 @@ namespace osu.Game.Rulesets.Osu.Scoring foreach (var h in beatmap.HitObjects) { - // TODO: add support for other object types. - AddJudgement(new OsuJudgement + if (h != null) { - MaxScore = OsuScoreResult.Hit300, - Score = OsuScoreResult.Hit300, - Result = HitResult.Hit - }); + // TODO: add support for other object types. + AddJudgement(new OsuJudgement + { + MaxScore = OsuScoreResult.Hit300, + Score = OsuScoreResult.Hit300, + Result = HitResult.Hit + }); + } } } From 1e10d977f9c3e7e166a1a4cdecdd1c7837c61073 Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 5 Sep 2017 15:39:27 +0200 Subject: [PATCH 280/483] Accuracy starts at 100% instead of 0% --- osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index 647a1381c6..83203f5a7e 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -268,6 +268,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring base.Reset(); Health.Value = 0; + Accuracy.Value = 1; bonusScore = 0; comboPortion = 0; From 84c22df3f5e8c43422fc7126eee8b903ab85c85f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Sep 2017 19:44:59 +0900 Subject: [PATCH 281/483] Combine Judgement.HitResults into one. --- .../Visual/TestCaseHitObjects.cs | 4 - .../Visual/TestCaseScrollingPlayfield.cs | 4 +- .../Visual/TestCaseTaikoPlayfield.cs | 9 +- .../Judgements/CatchJudgement.cs | 4 +- .../Objects/Drawable/DrawableFruit.cs | 4 +- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 2 +- .../Judgements/HitWindows.cs | 13 ++- .../Judgements/HoldNoteTailJudgement.cs | 20 ++-- .../Judgements/HoldNoteTickJudgement.cs | 6 +- .../Judgements/ManiaHitResult.cs | 21 ---- .../Judgements/ManiaJudgement.cs | 60 +++------- .../Objects/Drawables/DrawableHoldNote.cs | 2 +- .../Objects/Drawables/DrawableHoldNoteTick.cs | 5 +- .../Drawables/DrawableManiaHitObject.cs | 2 - .../Objects/Drawables/DrawableNote.cs | 11 +- .../Scoring/ManiaScoreProcessor.cs | 104 ++++++++---------- .../osu.Game.Rulesets.Mania.csproj | 1 - .../Judgements/OsuJudgement.cs | 34 ++---- .../Objects/Drawables/DrawableHitCircle.cs | 12 +- .../Objects/Drawables/DrawableOsuHitObject.cs | 16 --- .../Objects/Drawables/DrawableSlider.cs | 20 ++-- .../Objects/Drawables/DrawableSliderTick.cs | 8 +- .../Objects/Drawables/DrawableSpinner.cs | 23 +--- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 26 ++--- .../Replays/OsuAutoGenerator.cs | 19 ++-- .../Scoring/OsuScoreProcessor.cs | 39 +++---- .../Judgements/TaikoDrumRollTickJudgement.cs | 18 +-- .../Judgements/TaikoHitResult.cs | 15 --- .../Judgements/TaikoJudgement.cs | 45 ++------ .../Objects/Drawables/DrawableBarLine.cs | 2 - .../Objects/Drawables/DrawableDrumRoll.cs | 9 +- .../Objects/Drawables/DrawableDrumRollTick.cs | 7 +- .../Objects/Drawables/DrawableHit.cs | 6 +- .../Objects/Drawables/DrawableHitStrong.cs | 2 +- .../Objects/Drawables/DrawableSwell.cs | 11 +- .../Drawables/DrawableTaikoHitObject.cs | 2 - .../Scoring/TaikoScoreProcessor.cs | 46 +++----- .../UI/DrawableTaikoJudgement.cs | 23 ++-- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 2 +- .../osu.Game.Rulesets.Taiko.csproj | 1 - .../Rulesets/Judgements/DrawableJudgement.cs | 8 +- osu.Game/Rulesets/Judgements/Judgement.cs | 24 +++- .../Objects/Drawables/DrawableHitObject.cs | 5 - .../Rulesets/Objects/Drawables/HitResult.cs | 27 ++++- osu.Game/Rulesets/Objects/HitObject.cs | 6 + osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 4 +- 46 files changed, 265 insertions(+), 467 deletions(-) delete mode 100644 osu.Game.Rulesets.Mania/Judgements/ManiaHitResult.cs delete mode 100644 osu.Game.Rulesets.Taiko/Judgements/TaikoHitResult.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseHitObjects.cs b/osu.Desktop.Tests/Visual/TestCaseHitObjects.cs index 13e05d6477..cb365962a3 100644 --- a/osu.Desktop.Tests/Visual/TestCaseHitObjects.cs +++ b/osu.Desktop.Tests/Visual/TestCaseHitObjects.cs @@ -6,7 +6,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using OpenTK; @@ -110,10 +109,7 @@ namespace osu.Desktop.Tests.Visual h.Depth = depth++; if (auto) - { h.State = ArmedState.Hit; - h.Judgement = new OsuJudgement { Result = HitResult.Hit }; - } playfieldContainer.Add(h); var proxyable = h as IDrawableHitObjectWithProxiedApproach; diff --git a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs index 444adf6c24..f04c237629 100644 --- a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs @@ -185,7 +185,7 @@ namespace osu.Desktop.Tests.Visual }); } - protected override TestJudgement CreateJudgement() => new TestJudgement(); + protected TestJudgement CreateJudgement() => new TestJudgement(); protected override void UpdateState(ArmedState state) { @@ -221,8 +221,6 @@ namespace osu.Desktop.Tests.Visual private class TestJudgement : Judgement { - public override string ResultString { get { throw new NotImplementedException(); } } - public override string MaxResultString { get { throw new NotImplementedException(); } } } } } diff --git a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs index 681805ced0..e40016b858 100644 --- a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs @@ -128,7 +128,7 @@ namespace osu.Desktop.Tests.Visual private void addHitJudgement(bool kiai) { - TaikoHitResult hitResult = RNG.Next(2) == 0 ? TaikoHitResult.Good : TaikoHitResult.Great; + HitResult hitResult = RNG.Next(2) == 0 ? HitResult.Good : HitResult.Great; var cpi = new ControlPointInfo(); cpi.EffectPoints.Add(new EffectControlPoint @@ -141,11 +141,10 @@ namespace osu.Desktop.Tests.Visual var h = new DrawableTestHit(hit) { - X = RNG.NextSingle(hitResult == TaikoHitResult.Good ? -0.1f : -0.05f, hitResult == TaikoHitResult.Good ? 0.1f : 0.05f), + X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f), Judgement = new TaikoJudgement { - Result = HitResult.Hit, - TaikoResult = hitResult, + Result = hitResult, TimeOffset = 0 } }; @@ -237,7 +236,7 @@ namespace osu.Desktop.Tests.Visual { } - protected override TaikoJudgement CreateJudgement() => new TaikoJudgement(); + protected TaikoJudgement CreateJudgement() => new TaikoJudgement(); protected override void UpdateState(ArmedState state) { diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs index f0125b4c3a..cc5b1eaaf4 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs @@ -7,8 +7,6 @@ namespace osu.Game.Rulesets.Catch.Judgements { public class CatchJudgement : Judgement { - public override string ResultString => string.Empty; - - public override string MaxResultString => string.Empty; + // todo: wangs } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 62e5c094be..c6c716a29d 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -98,14 +98,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable }; } - protected override CatchJudgement CreateJudgement() => new CatchJudgement(); - private const float preempt = 1000; protected override void CheckJudgement(bool userTriggered) { if (Judgement.TimeOffset > 0) - Judgement.Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Hit : HitResult.Miss; + Judgement.Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss; } protected override void UpdateState(ArmedState state) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 4ea6d180f3..292ddaca12 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.UI private void Fruit_OnJudgement(DrawableHitObject obj) { - if (obj.Judgement.Result == HitResult.Hit) + if (obj.Judgement.Result > HitResult.Miss) { Vector2 screenPosition = obj.ScreenSpaceDrawQuad.Centre; Remove(obj); diff --git a/osu.Game.Rulesets.Mania/Judgements/HitWindows.cs b/osu.Game.Rulesets.Mania/Judgements/HitWindows.cs index 52b55a4ff5..d7bfa9caa1 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HitWindows.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HitWindows.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Beatmaps; +using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Mania.Judgements { @@ -145,18 +146,18 @@ namespace osu.Game.Rulesets.Mania.Judgements /// /// The time offset. /// The hit result, or null if the time offset results in a miss. - public ManiaHitResult? ResultFor(double hitOffset) + public HitResult? ResultFor(double hitOffset) { if (hitOffset <= Perfect / 2) - return ManiaHitResult.Perfect; + return HitResult.Perfect; if (hitOffset <= Great / 2) - return ManiaHitResult.Great; + return HitResult.Great; if (hitOffset <= Good / 2) - return ManiaHitResult.Good; + return HitResult.Good; if (hitOffset <= Ok / 2) - return ManiaHitResult.Ok; + return HitResult.Ok; if (hitOffset <= Bad / 2) - return ManiaHitResult.Bad; + return HitResult.Meh; return null; } diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTailJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTailJudgement.cs index d5cf57a5da..cc7aa63f7e 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTailJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTailJudgement.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Rulesets.Objects.Drawables; + namespace osu.Game.Rulesets.Mania.Judgements { public class HoldNoteTailJudgement : ManiaJudgement @@ -10,27 +12,27 @@ namespace osu.Game.Rulesets.Mania.Judgements /// public bool HasBroken; - public override int NumericResultForScore(ManiaHitResult result) + protected override int NumericResultFor(HitResult result) { switch (result) { default: - return base.NumericResultForScore(result); - case ManiaHitResult.Great: - case ManiaHitResult.Perfect: - return base.NumericResultForScore(HasBroken ? ManiaHitResult.Good : result); + return base.NumericResultFor(result); + case HitResult.Great: + case HitResult.Perfect: + return base.NumericResultFor(HasBroken ? HitResult.Good : result); } } - public override int NumericResultForAccuracy(ManiaHitResult result) + protected override int NumericResultForAccuracy(HitResult result) { switch (result) { default: return base.NumericResultForAccuracy(result); - case ManiaHitResult.Great: - case ManiaHitResult.Perfect: - return base.NumericResultForAccuracy(HasBroken ? ManiaHitResult.Good : result); + case HitResult.Great: + case HitResult.Perfect: + return base.NumericResultForAccuracy(HasBroken ? HitResult.Good : result); } } } diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs index 852f97b3f2..c00572edff 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs @@ -1,13 +1,15 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Rulesets.Objects.Drawables; + namespace osu.Game.Rulesets.Mania.Judgements { public class HoldNoteTickJudgement : ManiaJudgement { public override bool AffectsCombo => false; - public override int NumericResultForScore(ManiaHitResult result) => 20; - public override int NumericResultForAccuracy(ManiaHitResult result) => 0; // Don't count ticks into accuracy + protected override int NumericResultFor(HitResult result) => 20; + protected override int NumericResultForAccuracy(HitResult result) => 0; // Don't count ticks into accuracy } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Judgements/ManiaHitResult.cs b/osu.Game.Rulesets.Mania/Judgements/ManiaHitResult.cs deleted file mode 100644 index 207a1fb251..0000000000 --- a/osu.Game.Rulesets.Mania/Judgements/ManiaHitResult.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System.ComponentModel; - -namespace osu.Game.Rulesets.Mania.Judgements -{ - public enum ManiaHitResult - { - [Description("PERFECT")] - Perfect, - [Description("GREAT")] - Great, - [Description("GOOD")] - Good, - [Description("OK")] - Ok, - [Description("BAD")] - Bad - } -} \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs index 33083ca0f5..e36146aa71 100644 --- a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs @@ -8,73 +8,49 @@ namespace osu.Game.Rulesets.Mania.Judgements { public class ManiaJudgement : Judgement { - /// - /// The maximum possible hit result. - /// - public const ManiaHitResult MAX_HIT_RESULT = ManiaHitResult.Perfect; - - /// - /// The result value for the combo portion of the score. - /// - public int ResultValueForScore => Result == HitResult.Miss ? 0 : NumericResultForScore(ManiaResult); - - /// - /// The result value for the accuracy portion of the score. - /// - public int ResultValueForAccuracy => Result == HitResult.Miss ? 0 : NumericResultForAccuracy(ManiaResult); - - /// - /// The maximum result value for the combo portion of the score. - /// - public int MaxResultValueForScore => NumericResultForScore(MAX_HIT_RESULT); - /// /// The maximum result value for the accuracy portion of the score. /// - public int MaxResultValueForAccuracy => NumericResultForAccuracy(MAX_HIT_RESULT); + public int MaxNumericAccuracyResult => NumericResultForAccuracy(HitResult.Perfect); - public override string ResultString => string.Empty; - - public override string MaxResultString => string.Empty; - - /// - /// The hit result. - /// - public ManiaHitResult ManiaResult; - - public virtual int NumericResultForScore(ManiaHitResult result) + protected override int NumericResultFor(HitResult result) { switch (result) { default: return 0; - case ManiaHitResult.Bad: + case HitResult.Meh: return 50; - case ManiaHitResult.Ok: + case HitResult.Ok: return 100; - case ManiaHitResult.Good: + case HitResult.Good: return 200; - case ManiaHitResult.Great: - case ManiaHitResult.Perfect: + case HitResult.Great: + case HitResult.Perfect: return 300; } } - public virtual int NumericResultForAccuracy(ManiaHitResult result) + public int NumericAccuracyResult => NumericResultForAccuracy(Result); + + /// + /// The result value for the accuracy portion of the score. + /// + protected virtual int NumericResultForAccuracy(HitResult result) { switch (result) { default: return 0; - case ManiaHitResult.Bad: + case HitResult.Meh: return 50; - case ManiaHitResult.Ok: + case HitResult.Ok: return 100; - case ManiaHitResult.Good: + case HitResult.Good: return 200; - case ManiaHitResult.Great: + case HitResult.Great: return 300; - case ManiaHitResult.Perfect: + case HitResult.Perfect: return 305; } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index e06f71cb64..4ce73e388b 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -192,7 +192,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Y = 0; } - protected override ManiaJudgement CreateJudgement() => new HoldNoteTailJudgement(); + protected ManiaJudgement CreateJudgement() => new HoldNoteTailJudgement(); protected override void CheckJudgement(bool userTriggered) { diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 39abbb6b3d..4bc925b99a 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } - protected override ManiaJudgement CreateJudgement() => new HoldNoteTickJudgement(); + protected ManiaJudgement CreateJudgement() => new HoldNoteTickJudgement(); protected override void CheckJudgement(bool userTriggered) { @@ -93,8 +93,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (HoldStartTime?.Invoke() > HitObject.StartTime) return; - Judgement.ManiaResult = ManiaHitResult.Perfect; - Judgement.Result = HitResult.Hit; + Judgement.Result = HitResult.Perfect; } protected override void UpdateState(ArmedState state) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index bfef05ea07..9b8234ea13 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -36,7 +36,5 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables base.AccentColour = value; } } - - protected override ManiaJudgement CreateJudgement() => new ManiaJudgement(); } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index c201ab7bd0..cfe3372c71 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -5,7 +5,6 @@ using System; using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; -using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; using osu.Game.Rulesets.Objects.Drawables; @@ -58,15 +57,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (offset > HitObject.HitWindows.Miss / 2) return; - ManiaHitResult? tmpResult = HitObject.HitWindows.ResultFor(offset); - - if (tmpResult.HasValue) - { - Judgement.Result = HitResult.Hit; - Judgement.ManiaResult = tmpResult.Value; - } - else - Judgement.Result = HitResult.Miss; + Judgement.Result = HitObject.HitWindows.ResultFor(offset) ?? HitResult.Miss; } protected override void UpdateState(ArmedState state) diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 63b443319f..4a71b8a77d 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -174,37 +174,19 @@ namespace osu.Game.Rulesets.Mania.Scoring if (obj is Note) { - AddJudgement(new ManiaJudgement - { - Result = HitResult.Hit, - ManiaResult = ManiaHitResult.Perfect - }); + AddJudgement(new ManiaJudgement { Result = HitResult.Perfect }); } else if (holdNote != null) { // Head - AddJudgement(new ManiaJudgement - { - Result = HitResult.Hit, - ManiaResult = ManiaJudgement.MAX_HIT_RESULT - }); + AddJudgement(new ManiaJudgement { Result = HitResult.Perfect }); // Ticks int tickCount = holdNote.Ticks.Count(); for (int i = 0; i < tickCount; i++) - { - AddJudgement(new HoldNoteTickJudgement - { - Result = HitResult.Hit, - ManiaResult = ManiaJudgement.MAX_HIT_RESULT, - }); - } + AddJudgement(new HoldNoteTickJudgement { Result = HitResult.Perfect }); - AddJudgement(new HoldNoteTailJudgement - { - Result = HitResult.Hit, - ManiaResult = ManiaJudgement.MAX_HIT_RESULT - }); + AddJudgement(new HoldNoteTailJudgement { Result = HitResult.Perfect }); } } @@ -225,46 +207,46 @@ namespace osu.Game.Rulesets.Mania.Scoring { bool isTick = judgement is HoldNoteTickJudgement; - if (!isTick) + if (isTick) + { + if (judgement.IsHit) + { + Health.Value += hpMultiplier * hp_increase_tick; + bonusScore += judgement.NumericResult; + } + } + else + { totalHits++; - switch (judgement.Result) - { - case HitResult.Miss: - Health.Value += hpMissMultiplier * hp_increase_miss; - break; - case HitResult.Hit: - if (isTick) - { - Health.Value += hpMultiplier * hp_increase_tick; - bonusScore += judgement.ResultValueForScore; - } - else - { - switch (judgement.ManiaResult) - { - case ManiaHitResult.Bad: - Health.Value += hpMultiplier * hp_increase_bad; - break; - case ManiaHitResult.Ok: - Health.Value += hpMultiplier * hp_increase_ok; - break; - case ManiaHitResult.Good: - Health.Value += hpMultiplier * hp_increase_good; - break; - case ManiaHitResult.Great: - Health.Value += hpMultiplier * hp_increase_great; - break; - case ManiaHitResult.Perfect: - Health.Value += hpMultiplier * hp_increase_perfect; - break; - } + switch (judgement.Result) + { + case HitResult.Miss: + Health.Value += hpMissMultiplier * hp_increase_miss; + break; + case HitResult.Meh: + Health.Value += hpMultiplier * hp_increase_bad; + break; + case HitResult.Ok: + Health.Value += hpMultiplier * hp_increase_ok; + break; + case HitResult.Good: + Health.Value += hpMultiplier * hp_increase_good; + break; + case HitResult.Great: + Health.Value += hpMultiplier * hp_increase_great; + break; + case HitResult.Perfect: + Health.Value += hpMultiplier * hp_increase_perfect; + break; + } - // A factor that is applied to make higher combos more relevant - double comboRelevance = Math.Min(Math.Max(0.5, Math.Log(Combo.Value, combo_base)), Math.Log(combo_relevance_cap, combo_base)); - comboPortion += judgement.ResultValueForScore * comboRelevance; - } - break; + if (judgement.IsHit) + { + // A factor that is applied to make higher combos more relevant + double comboRelevance = Math.Min(Math.Max(0.5, Math.Log(Combo.Value, combo_base)), Math.Log(combo_relevance_cap, combo_base)); + comboPortion += judgement.NumericResult * comboRelevance; + } } int scoreForAccuracy = 0; @@ -272,8 +254,8 @@ namespace osu.Game.Rulesets.Mania.Scoring foreach (var j in Judgements) { - scoreForAccuracy += j.ResultValueForAccuracy; - maxScoreForAccuracy += j.MaxResultValueForAccuracy; + scoreForAccuracy += j.NumericAccuracyResult; + maxScoreForAccuracy += j.MaxNumericAccuracyResult; } Accuracy.Value = (double)scoreForAccuracy / maxScoreForAccuracy; diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 890c9116cf..8644ad45ae 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -60,7 +60,6 @@ - diff --git a/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs b/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs index d61e179002..3d19d19546 100644 --- a/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs +++ b/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs @@ -4,10 +4,14 @@ using OpenTK; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Framework.Extensions; +using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Judgements { + public class SliderTickJudgement : OsuJudgement + { + } + public class OsuJudgement : Judgement { /// @@ -15,38 +19,18 @@ namespace osu.Game.Rulesets.Osu.Judgements /// public Vector2 PositionOffset; - /// - /// The score the user achieved. - /// - public OsuScoreResult Score; - - /// - /// The score which would be achievable on a perfect hit. - /// - public OsuScoreResult MaxScore = OsuScoreResult.Hit300; - - public override string ResultString => Score.GetDescription(); - - public override string MaxResultString => MaxScore.GetDescription(); - - public int ScoreValue => scoreToInt(Score); - - public int MaxScoreValue => scoreToInt(MaxScore); - - private int scoreToInt(OsuScoreResult result) + protected override int NumericResultFor(HitResult result) { switch (result) { default: return 0; - case OsuScoreResult.Hit50: + case HitResult.Meh: return 50; - case OsuScoreResult.Hit100: + case HitResult.Good: return 100; - case OsuScoreResult.Hit300: + case HitResult.Great: return 300; - case OsuScoreResult.SliderTick: - return 10; } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index f68a7a765b..43d7fb3016 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -69,20 +69,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { if (!userTriggered) { - if (Judgement.TimeOffset > HitObject.HitWindowFor(OsuScoreResult.Hit50)) + if (Judgement.TimeOffset > HitObject.HitWindowFor(HitResult.Meh)) Judgement.Result = HitResult.Miss; return; } - double hitOffset = Math.Abs(Judgement.TimeOffset); - - if (hitOffset < HitObject.HitWindowFor(OsuScoreResult.Hit50)) - { - Judgement.Result = HitResult.Hit; - Judgement.Score = HitObject.ScoreResultForOffset(hitOffset); - } - else - Judgement.Result = HitResult.Miss; + Judgement.Result = HitObject.ScoreResultForOffset(Math.Abs(Judgement.TimeOffset)); } protected override void UpdateInitialState() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index b3043d18f6..e18bcc856d 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -21,8 +21,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Alpha = 0; } - protected override OsuJudgement CreateJudgement() => new OsuJudgement { MaxScore = OsuScoreResult.Hit300 }; - protected sealed override void UpdateState(ArmedState state) { FinishTransforms(); @@ -65,18 +63,4 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables [Description(@"Amazing")] Perfect } - - public enum OsuScoreResult - { - [Description(@"Miss")] - Miss, - [Description(@"50")] - Hit50, - [Description(@"100")] - Hit100, - [Description(@"300")] - Hit300, - [Description(@"10")] - SliderTick - } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index d5583b0d9d..6f3cea7ac1 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables bouncer2.Position = slider.Curve.PositionAt(body.SnakedEnd ?? 0); //todo: we probably want to reconsider this before adding scoring, but it looks and feels nice. - if (initialCircle.Judgement?.Result != HitResult.Hit) + if (initialCircle.Judgement?.Result <= HitResult.Miss) initialCircle.Position = slider.Curve.PositionAt(progress); foreach (var c in components) c.UpdateProgress(progress, repeat); @@ -126,21 +126,19 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (!userTriggered && Time.Current >= slider.EndTime) { var ticksCount = ticks.Children.Count + 1; - var ticksHit = ticks.Children.Count(t => t.Judgement.Result == HitResult.Hit); - if (initialCircle.Judgement.Result == HitResult.Hit) + var ticksHit = ticks.Children.Count(t => t.Judgement.Result > HitResult.Miss); + if (initialCircle.Judgement.Result > HitResult.Miss) ticksHit++; var hitFraction = (double)ticksHit / ticksCount; - if (hitFraction == 1 && initialCircle.Judgement.Score == OsuScoreResult.Hit300) - Judgement.Score = OsuScoreResult.Hit300; - else if (hitFraction >= 0.5 && initialCircle.Judgement.Score >= OsuScoreResult.Hit100) - Judgement.Score = OsuScoreResult.Hit100; + if (hitFraction == 1 && initialCircle.Judgement.Result == HitResult.Great) + Judgement.Result = HitResult.Great; + else if (hitFraction >= 0.5 && initialCircle.Judgement.Result >= HitResult.Good) + Judgement.Result = HitResult.Good; else if (hitFraction > 0) - Judgement.Score = OsuScoreResult.Hit50; + Judgement.Result = HitResult.Meh; else - Judgement.Score = OsuScoreResult.Miss; - - Judgement.Result = Judgement.Score != OsuScoreResult.Miss ? HitResult.Hit : HitResult.Miss; + Judgement.Result = HitResult.Miss; } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index 2a50b23047..89d7cd1658 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -4,7 +4,6 @@ using System; using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Osu.Judgements; using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; @@ -22,8 +21,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public override bool RemoveWhenNotAlive => false; - protected override OsuJudgement CreateJudgement() => new OsuJudgement { MaxScore = OsuScoreResult.SliderTick }; - public DrawableSliderTick(SliderTick sliderTick) : base(sliderTick) { this.sliderTick = sliderTick; @@ -52,10 +49,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void CheckJudgement(bool userTriggered) { if (Judgement.TimeOffset >= 0) - { - Judgement.Result = Tracking ? HitResult.Hit : HitResult.Miss; - Judgement.Score = Tracking ? OsuScoreResult.SliderTick : OsuScoreResult.Miss; - } + Judgement.Result = Tracking ? HitResult.Perfect : HitResult.Miss; } protected override void UpdatePreemptState() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 8473cc2453..923f659d27 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -129,26 +129,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (!userTriggered && Time.Current >= spinner.EndTime) { if (Progress >= 1) - { - Judgement.Score = OsuScoreResult.Hit300; - Judgement.Result = HitResult.Hit; - } + Judgement.Result = HitResult.Great; else if (Progress > .9) - { - Judgement.Score = OsuScoreResult.Hit100; - Judgement.Result = HitResult.Hit; - } + Judgement.Result = HitResult.Good; else if (Progress > .75) - { - Judgement.Score = OsuScoreResult.Hit50; - Judgement.Result = HitResult.Hit; - } - else - { - Judgement.Score = OsuScoreResult.Miss; - if (Time.Current >= spinner.EndTime) - Judgement.Result = HitResult.Miss; - } + Judgement.Result = HitResult.Meh; + else if (Time.Current >= spinner.EndTime) + Judgement.Result = HitResult.Miss; } } diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index 7a311f1467..e6bfd8a277 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -4,10 +4,10 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; using OpenTK; -using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using OpenTK.Graphics; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Objects { @@ -42,30 +42,30 @@ namespace osu.Game.Rulesets.Osu.Objects public virtual bool NewCombo { get; set; } public int ComboIndex { get; set; } - public double HitWindowFor(OsuScoreResult result) + public double HitWindowFor(HitResult result) { switch (result) { default: return 300; - case OsuScoreResult.Hit50: + case HitResult.Meh: return 150; - case OsuScoreResult.Hit100: + case HitResult.Good: return 80; - case OsuScoreResult.Hit300: + case HitResult.Great: return 30; } } - public OsuScoreResult ScoreResultForOffset(double offset) + public HitResult ScoreResultForOffset(double offset) { - if (offset < HitWindowFor(OsuScoreResult.Hit300)) - return OsuScoreResult.Hit300; - if (offset < HitWindowFor(OsuScoreResult.Hit100)) - return OsuScoreResult.Hit100; - if (offset < HitWindowFor(OsuScoreResult.Hit50)) - return OsuScoreResult.Hit50; - return OsuScoreResult.Miss; + if (offset < HitWindowFor(HitResult.Great)) + return HitResult.Great; + if (offset < HitWindowFor(HitResult.Good)) + return HitResult.Good; + if (offset < HitWindowFor(HitResult.Meh)) + return HitResult.Meh; + return HitResult.Miss; } public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index b92f1bc60a..f82c6ce3b2 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -9,6 +9,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; using System; using System.Diagnostics; using osu.Framework.Graphics; +using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Replays; @@ -89,20 +90,20 @@ namespace osu.Game.Rulesets.Osu.Replays double endTime = (prev as IHasEndTime)?.EndTime ?? prev.StartTime; // Make the cursor stay at a hitObject as long as possible (mainly for autopilot). - if (h.StartTime - h.HitWindowFor(OsuScoreResult.Miss) > endTime + h.HitWindowFor(OsuScoreResult.Hit50) + 50) + if (h.StartTime - h.HitWindowFor(HitResult.Miss) > endTime + h.HitWindowFor(HitResult.Meh) + 50) { - if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(OsuScoreResult.Hit50), prev.StackedEndPosition.X, prev.StackedEndPosition.Y, ReplayButtonState.None)); - if (!(h is Spinner)) AddFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(OsuScoreResult.Miss), h.StackedPosition.X, h.StackedPosition.Y, ReplayButtonState.None)); + if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(HitResult.Meh), prev.StackedEndPosition.X, prev.StackedEndPosition.Y, ReplayButtonState.None)); + if (!(h is Spinner)) AddFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(HitResult.Miss), h.StackedPosition.X, h.StackedPosition.Y, ReplayButtonState.None)); } - else if (h.StartTime - h.HitWindowFor(OsuScoreResult.Hit50) > endTime + h.HitWindowFor(OsuScoreResult.Hit50) + 50) + else if (h.StartTime - h.HitWindowFor(HitResult.Meh) > endTime + h.HitWindowFor(HitResult.Meh) + 50) { - if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(OsuScoreResult.Hit50), prev.StackedEndPosition.X, prev.StackedEndPosition.Y, ReplayButtonState.None)); - if (!(h is Spinner)) AddFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(OsuScoreResult.Hit50), h.StackedPosition.X, h.StackedPosition.Y, ReplayButtonState.None)); + if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(HitResult.Meh), prev.StackedEndPosition.X, prev.StackedEndPosition.Y, ReplayButtonState.None)); + if (!(h is Spinner)) AddFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(HitResult.Meh), h.StackedPosition.X, h.StackedPosition.Y, ReplayButtonState.None)); } - else if (h.StartTime - h.HitWindowFor(OsuScoreResult.Hit100) > endTime + h.HitWindowFor(OsuScoreResult.Hit100) + 50) + else if (h.StartTime - h.HitWindowFor(HitResult.Good) > endTime + h.HitWindowFor(HitResult.Good) + 50) { - if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(OsuScoreResult.Hit100), prev.StackedEndPosition.X, prev.StackedEndPosition.Y, ReplayButtonState.None)); - if (!(h is Spinner)) AddFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(OsuScoreResult.Hit100), h.StackedPosition.X, h.StackedPosition.Y, ReplayButtonState.None)); + if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(HitResult.Good), prev.StackedEndPosition.X, prev.StackedEndPosition.Y, ReplayButtonState.None)); + if (!(h is Spinner)) AddFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(HitResult.Good), h.StackedPosition.X, h.StackedPosition.Y, ReplayButtonState.None)); } } diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 8432c5b26a..a2e9fa2624 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Scoring private int totalAccurateJudgements; - private readonly Dictionary scoreResultCounts = new Dictionary(); + private readonly Dictionary scoreResultCounts = new Dictionary(); private readonly Dictionary comboResultCounts = new Dictionary(); private double comboMaxScore; @@ -45,12 +45,7 @@ namespace osu.Game.Rulesets.Osu.Scoring foreach (var h in beatmap.HitObjects) { // TODO: add support for other object types. - AddJudgement(new OsuJudgement - { - MaxScore = OsuScoreResult.Hit300, - Score = OsuScoreResult.Hit300, - Result = HitResult.Hit - }); + AddJudgement(new OsuJudgement { Result = HitResult.Great }); } } @@ -69,10 +64,10 @@ namespace osu.Game.Rulesets.Osu.Scoring { base.PopulateScore(score); - score.Statistics[@"300"] = scoreResultCounts.GetOrDefault(OsuScoreResult.Hit300); - score.Statistics[@"100"] = scoreResultCounts.GetOrDefault(OsuScoreResult.Hit100); - score.Statistics[@"50"] = scoreResultCounts.GetOrDefault(OsuScoreResult.Hit50); - score.Statistics[@"x"] = scoreResultCounts.GetOrDefault(OsuScoreResult.Miss); + score.Statistics[@"300"] = scoreResultCounts.GetOrDefault(HitResult.Great); + score.Statistics[@"100"] = scoreResultCounts.GetOrDefault(HitResult.Good); + score.Statistics[@"50"] = scoreResultCounts.GetOrDefault(HitResult.Meh); + score.Statistics[@"x"] = scoreResultCounts.GetOrDefault(HitResult.Miss); } protected override void OnNewJudgement(OsuJudgement judgement) @@ -81,29 +76,29 @@ namespace osu.Game.Rulesets.Osu.Scoring { if (judgement.Result != HitResult.None) { - scoreResultCounts[judgement.Score] = scoreResultCounts.GetOrDefault(judgement.Score) + 1; + scoreResultCounts[judgement.Result] = scoreResultCounts.GetOrDefault(judgement.Result) + 1; comboResultCounts[judgement.Combo] = comboResultCounts.GetOrDefault(judgement.Combo) + 1; } - switch (judgement.Score) + switch (judgement.Result) { - case OsuScoreResult.Hit300: + case HitResult.Great: Health.Value += (10.2 - hpDrainRate) * 0.02; break; - case OsuScoreResult.Hit100: + case HitResult.Good: Health.Value += (8 - hpDrainRate) * 0.02; break; - case OsuScoreResult.Hit50: + case HitResult.Meh: Health.Value += (4 - hpDrainRate) * 0.02; break; - case OsuScoreResult.SliderTick: + /*case HitResult.SliderTick: Health.Value += Math.Max(7 - hpDrainRate, 0) * 0.01; - break; + break;*/ - case OsuScoreResult.Miss: + case HitResult.Miss: Health.Value -= hpDrainRate * 0.04; break; } @@ -123,10 +118,10 @@ namespace osu.Game.Rulesets.Osu.Scoring foreach (var j in Judgements) { - baseScore += j.ScoreValue; - baseMaxScore += j.MaxScoreValue; + baseScore += j.NumericResult; + baseMaxScore += j.MaxNumericResult; - comboScore += j.ScoreValue * (1 + Combo.Value / 10d); + comboScore += j.NumericResult * (1 + Combo.Value / 10d); } Accuracy.Value = (double)baseScore / baseMaxScore; diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs index 78a5b29d36..0d61494add 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs @@ -1,34 +1,26 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Rulesets.Objects.Drawables; + namespace osu.Game.Rulesets.Taiko.Judgements { public class TaikoDrumRollTickJudgement : TaikoJudgement { - /// - /// Drum roll ticks don't display judgement text. - /// - public override string ResultString => string.Empty; - - /// - /// Drum roll ticks don't display judgement text. - /// - public override string MaxResultString => string.Empty; - public override bool AffectsCombo => false; - protected override int NumericResultForScore(TaikoHitResult result) + protected override int NumericResultFor(HitResult result) { switch (result) { default: return 0; - case TaikoHitResult.Great: + case HitResult.Great: return 200; } } - protected override int NumericResultForAccuracy(TaikoHitResult result) + protected override int NumericResultForAccuracy(HitResult result) { return 0; } diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoHitResult.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoHitResult.cs deleted file mode 100644 index 5fd850d6b0..0000000000 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoHitResult.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System.ComponentModel; - -namespace osu.Game.Rulesets.Taiko.Judgements -{ - public enum TaikoHitResult - { - [Description("GOOD")] - Good, - [Description("GREAT")] - Great - } -} diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs index 7bca59bf11..3e48453460 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs @@ -2,46 +2,21 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Rulesets.Judgements; -using osu.Framework.Extensions; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.Judgements { public class TaikoJudgement : Judgement { - /// - /// The maximum result. - /// - public const TaikoHitResult MAX_HIT_RESULT = TaikoHitResult.Great; - - /// - /// The result. - /// - public TaikoHitResult TaikoResult; - - /// - /// The result value for the combo portion of the score. - /// - public int ResultValueForScore => Result == HitResult.Miss ? 0 : NumericResultForScore(TaikoResult); - /// /// The result value for the accuracy portion of the score. /// - public int ResultValueForAccuracy => Result == HitResult.Miss ? 0 : NumericResultForAccuracy(TaikoResult); - - /// - /// The maximum result value for the combo portion of the score. - /// - public int MaxResultValueForScore => NumericResultForScore(MAX_HIT_RESULT); + public int ResultNumericForAccuracy => Result == HitResult.Miss ? 0 : NumericResultForAccuracy(Result); /// /// The maximum result value for the accuracy portion of the score. /// - public int MaxResultValueForAccuracy => NumericResultForAccuracy(MAX_HIT_RESULT); - - public override string ResultString => TaikoResult.GetDescription(); - - public override string MaxResultString => MAX_HIT_RESULT.GetDescription(); + public int MaxResultValueForAccuracy => NumericResultForAccuracy(HitResult.Great); /// /// Whether this Judgement has a secondary hit in the case of strong hits. @@ -50,38 +25,38 @@ namespace osu.Game.Rulesets.Taiko.Judgements /// /// Computes the numeric result value for the combo portion of the score. - /// For the accuracy portion of the score (including accuracy percentage), see . + /// For the accuracy portion of the score (including accuracy percentage), see . /// /// The result to compute the value for. /// The numeric result value. - protected virtual int NumericResultForScore(TaikoHitResult result) + protected override int NumericResultFor(HitResult result) { switch (result) { default: return 0; - case TaikoHitResult.Good: + case HitResult.Good: return 100; - case TaikoHitResult.Great: + case HitResult.Great: return 300; } } /// /// Computes the numeric result value for the accuracy portion of the score. - /// For the combo portion of the score, see . + /// For the combo portion of the score, see . /// /// The result to compute the value for. /// The numeric result value. - protected virtual int NumericResultForAccuracy(TaikoHitResult result) + protected virtual int NumericResultForAccuracy(HitResult result) { switch (result) { default: return 0; - case TaikoHitResult.Good: + case HitResult.Good: return 150; - case TaikoHitResult.Great: + case HitResult.Great: return 300; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index 9df1b41a8b..9a25de713a 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -58,8 +58,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables }; } - protected override TaikoJudgement CreateJudgement() => null; - protected override void UpdateState(ArmedState state) { } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 5d6ea8f51e..c044ebeeb1 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } - protected override TaikoJudgement CreateJudgement() => new TaikoJudgement { SecondHit = HitObject.IsStrong }; + protected TaikoJudgement CreateJudgement() => new TaikoJudgement { SecondHit = HitObject.IsStrong }; protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece(); @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables private void onTickJudgement(DrawableHitObject obj) { - if (obj.Judgement.Result == HitResult.Hit) + if (obj.Judgement.Result > HitResult.Miss) rollingHits++; else rollingHits--; @@ -86,12 +86,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (Judgement.TimeOffset < 0) return; - int countHit = NestedHitObjects.Count(o => o.Judgement.Result == HitResult.Hit); + int countHit = NestedHitObjects.Count(o => o.Judgement.Result > HitResult.Miss); if (countHit > HitObject.RequiredGoodHits) { - Judgement.Result = HitResult.Hit; - Judgement.TaikoResult = countHit >= HitObject.RequiredGreatHits ? TaikoHitResult.Great : TaikoHitResult.Good; + Judgement.Result = countHit >= HitObject.RequiredGreatHits ? HitResult.Great : HitResult.Good; } else Judgement.Result = HitResult.Miss; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index e94886df16..97c0f6bf63 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Filled = HitObject.FirstTick }; - protected override TaikoJudgement CreateJudgement() => new TaikoDrumRollTickJudgement { SecondHit = HitObject.IsStrong }; + protected TaikoJudgement CreateJudgement() => new TaikoDrumRollTickJudgement { SecondHit = HitObject.IsStrong }; protected override void CheckJudgement(bool userTriggered) { @@ -42,10 +42,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return; if (Math.Abs(Judgement.TimeOffset) < HitObject.HitWindow) - { - Judgement.Result = HitResult.Hit; - Judgement.TaikoResult = TaikoHitResult.Great; - } + Judgement.Result = HitResult.Great; } protected override void UpdateState(ArmedState state) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 6b041dfe25..42195e31f3 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -5,7 +5,6 @@ using System; using System.Linq; using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; namespace osu.Game.Rulesets.Taiko.Objects.Drawables @@ -45,10 +44,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (!validKeyPressed) Judgement.Result = HitResult.Miss; else if (hitOffset < HitObject.HitWindowGood) - { - Judgement.Result = HitResult.Hit; - Judgement.TaikoResult = hitOffset < HitObject.HitWindowGreat ? TaikoHitResult.Great : TaikoHitResult.Good; - } + Judgement.Result = hitOffset < HitObject.HitWindowGreat ? HitResult.Great : HitResult.Good; else Judgement.Result = HitResult.Miss; } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs index 256c50d33a..855aa6fb0b 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { } - protected override TaikoJudgement CreateJudgement() => new TaikoStrongHitJudgement(); + protected TaikoJudgement CreateJudgement() => new TaikoStrongHitJudgement(); protected override void CheckJudgement(bool userTriggered) { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 4eb5c46838..a4fdf19c59 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using OpenTK; using OpenTK.Graphics; @@ -153,10 +152,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables expandingRing.ScaleTo(1f + Math.Min(target_ring_scale - 1f, (target_ring_scale - 1f) * completion * 1.3f), 260, Easing.OutQuint); if (userHits == HitObject.RequiredHits) - { - Judgement.Result = HitResult.Hit; - Judgement.TaikoResult = TaikoHitResult.Great; - } + Judgement.Result = HitResult.Great; } else { @@ -165,10 +161,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables //TODO: THIS IS SHIT AND CAN'T EXIST POST-TAIKO WORLD CUP if (userHits > HitObject.RequiredHits / 2) - { - Judgement.Result = HitResult.Hit; - Judgement.TaikoResult = TaikoHitResult.Good; - } + Judgement.Result = HitResult.Good; else Judgement.Result = HitResult.Miss; } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 46cdfcc365..e3ddefd05d 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -37,8 +37,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables MainPiece.KiaiMode = HitObject.Kiai; } - protected override TaikoJudgement CreateJudgement() => new TaikoJudgement(); - protected virtual TaikoPiece CreateMainPiece() => new CirclePiece(); public abstract bool OnPressed(TaikoAction action); diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index 647a1381c6..83f3745763 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -36,12 +36,12 @@ namespace osu.Game.Rulesets.Taiko.Scoring private const double combo_base = 4; /// - /// The HP awarded by a hit. + /// The HP awarded by a hit. /// private const double hp_hit_great = 0.03; /// - /// The HP awarded for a hit. + /// The HP awarded for a hit. /// private const double hp_hit_good = 0.011; @@ -140,8 +140,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring { AddJudgement(new TaikoJudgement { - Result = HitResult.Hit, - TaikoResult = TaikoHitResult.Great, + Result = HitResult.Great, SecondHit = obj.IsStrong }); } @@ -151,26 +150,20 @@ namespace osu.Game.Rulesets.Taiko.Scoring { AddJudgement(new TaikoDrumRollTickJudgement { - Result = HitResult.Hit, - TaikoResult = TaikoHitResult.Great, + Result = HitResult.Great, SecondHit = obj.IsStrong }); } AddJudgement(new TaikoJudgement { - Result = HitResult.Hit, - TaikoResult = TaikoHitResult.Great, + Result = HitResult.Great, SecondHit = obj.IsStrong }); } else if (obj is Swell) { - AddJudgement(new TaikoJudgement - { - Result = HitResult.Hit, - TaikoResult = TaikoHitResult.Great - }); + AddJudgement(new TaikoJudgement { Result = HitResult.Great }); } } @@ -197,19 +190,14 @@ namespace osu.Game.Rulesets.Taiko.Scoring if (!isTick) Health.Value += hpIncreaseMiss; break; - case HitResult.Hit: - switch (judgement.TaikoResult) - { - case TaikoHitResult.Good: - Health.Value += hpIncreaseGood; - break; - case TaikoHitResult.Great: - if (isTick) - Health.Value += hpIncreaseTick; - else - Health.Value += hpIncreaseGreat; - break; - } + case HitResult.Good: + Health.Value += hpIncreaseGood; + break; + case HitResult.Great: + if (isTick) + Health.Value += hpIncreaseTick; + else + Health.Value += hpIncreaseGreat; break; } @@ -226,10 +214,10 @@ namespace osu.Game.Rulesets.Taiko.Scoring private void addHitScore(TaikoJudgement judgement) { - if (judgement.Result != HitResult.Hit) + if (!judgement.IsHit) return; - double baseValue = judgement.ResultValueForScore; + double baseValue = judgement.NumericResult; // Add increased score for hitting a strong hit object with the second key if (judgement.SecondHit) @@ -255,7 +243,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring foreach (var j in Judgements) { - scoreForAccuracy += j.ResultValueForAccuracy; + scoreForAccuracy += j.ResultNumericForAccuracy; maxScoreForAccuracy += j.MaxResultValueForAccuracy; } diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs index 779471b8dc..d0ad343264 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs @@ -29,28 +29,19 @@ namespace osu.Game.Rulesets.Taiko.UI { switch (Judgement.Result) { - case HitResult.Hit: - switch (Judgement.TaikoResult) - { - case TaikoHitResult.Good: - Colour = colours.GreenLight; - break; - case TaikoHitResult.Great: - Colour = colours.BlueLight; - break; - } + case HitResult.Good: + Colour = colours.GreenLight; + break; + case HitResult.Great: + Colour = colours.BlueLight; break; } } protected override void LoadComplete() { - switch (Judgement.Result) - { - case HitResult.Hit: - this.MoveToY(-100, 500); - break; - } + if (Judgement.IsHit) + this.MoveToY(-100, 500); base.LoadComplete(); } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 678de7f713..4da00a58c6 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -220,7 +220,7 @@ namespace osu.Game.Rulesets.Taiko.UI public override void OnJudgement(DrawableHitObject judgedObject) { - bool wasHit = judgedObject.Judgement.Result == HitResult.Hit; + bool wasHit = judgedObject.Judgement.Result > HitResult.Miss; bool secondHit = judgedObject.Judgement.SecondHit; judgementContainer.Add(new DrawableTaikoJudgement(judgedObject.Judgement) diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 33748a267f..1e07907cc8 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -52,7 +52,6 @@ - diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index f0a53d677b..80311654be 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -34,15 +34,13 @@ namespace osu.Game.Rulesets.Judgements AutoSizeAxes = Axes.Both; - string resultString = judgement.Result == HitResult.Hit ? judgement.ResultString : judgement.Result.GetDescription(); - Children = new[] { JudgementText = new OsuSpriteText { Origin = Anchor.Centre, Anchor = Anchor.Centre, - Text = resultString.ToUpper(), + Text = judgement.Result.GetDescription().ToUpper(), Font = @"Venera", TextSize = 16 } @@ -68,6 +66,8 @@ namespace osu.Game.Rulesets.Judgements switch (Judgement.Result) { + case HitResult.None: + break; case HitResult.Miss: this.ScaleTo(1.6f); this.ScaleTo(1, 100, Easing.In); @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Judgements this.Delay(600).FadeOut(200); break; - case HitResult.Hit: + default: this.ScaleTo(0.9f); this.ScaleTo(1, 500, Easing.OutElastic); diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index ed33cee5d4..88b9600fac 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -5,13 +5,20 @@ using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Judgements { - public abstract class Judgement + public class Judgement { /// /// Whether this judgement is the result of a hit or a miss. /// public HitResult Result; + /// + /// The maximum that can be achieved. + /// + public virtual HitResult MaxResult => HitResult.Perfect; + + public bool IsHit => Result > HitResult.Miss; + /// /// The offset at which this judgement occurred. /// @@ -20,13 +27,20 @@ namespace osu.Game.Rulesets.Judgements public virtual bool AffectsCombo => true; /// - /// The string representation for the result achieved. + /// The numeric representation for the result achieved. /// - public abstract string ResultString { get; } + public int NumericResult => NumericResultFor(Result); /// - /// The string representation for the max result achievable. + /// The numeric representation for the maximum achievable result. /// - public abstract string MaxResultString { get; } + public int MaxNumericResult => NumericResultFor(MaxResult); + + /// + /// Convert a to a numeric score representation. + /// + /// The value to convert. + /// The number. + protected virtual int NumericResultFor(HitResult result) => result > HitResult.Miss ? 1 : 0; } } \ No newline at end of file diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 3fba168216..9d39efb8fe 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -178,10 +178,6 @@ namespace osu.Game.Rulesets.Objects.Drawables channel.Volume.Value = sample.Volume; Samples.Add(channel); } - - //we may be setting a custom judgement in test cases or what not. - if (Judgement == null) - Judgement = CreateJudgement(); } private List> nestedHitObjects; @@ -196,7 +192,6 @@ namespace osu.Game.Rulesets.Objects.Drawables nestedHitObjects.Add(h); } - protected abstract TJudgement CreateJudgement(); protected abstract void UpdateState(ArmedState state); } } diff --git a/osu.Game/Rulesets/Objects/Drawables/HitResult.cs b/osu.Game/Rulesets/Objects/Drawables/HitResult.cs index 7492c0ab96..961843cbd7 100644 --- a/osu.Game/Rulesets/Objects/Drawables/HitResult.cs +++ b/osu.Game/Rulesets/Objects/Drawables/HitResult.cs @@ -10,17 +10,34 @@ namespace osu.Game.Rulesets.Objects.Drawables /// /// Indicates that the object has not been judged yet. /// - [Description("")] + [Description(@"")] None, + /// /// Indicates that the object has been judged as a miss. /// [Description(@"Miss")] Miss, + + [Description(@"Meh")] + Meh, + /// - /// Indicates that the object has been judged as a hit. + /// Optional judgement. /// - [Description(@"Hit")] - Hit, + [Description(@"OK")] + Ok, + + [Description(@"Good")] + Good, + + [Description(@"Great")] + Great, + + /// + /// Optional judgement. + /// + [Description(@"Perfect")] + Perfect, } -} \ No newline at end of file +} diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index c343cdaf33..acf2e9d449 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -1,9 +1,11 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Objects @@ -30,6 +32,10 @@ namespace osu.Game.Rulesets.Objects /// public SampleInfoList Samples = new SampleInfoList(); + public virtual IEnumerable CreateJudgements() => new[] { new Judgement() }; + + public readonly List Children = new List(); + /// /// Applies default values to this HitObject. /// diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 5ccac2db32..42dabfbdff 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -181,10 +181,12 @@ namespace osu.Game.Rulesets.Scoring { switch (judgement.Result) { + case HitResult.None: + break; case HitResult.Miss: Combo.Value = 0; break; - case HitResult.Hit: + default: Combo.Value++; break; } From ac8ec31b61f9625a31ab8480e00ca5e718f16a66 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 6 Sep 2017 17:02:13 +0900 Subject: [PATCH 282/483] Make judgements able to be "added" plus make everything compile and run. --- .../Visual/TestCaseScrollingPlayfield.cs | 2 +- .../Visual/TestCaseTaikoPlayfield.cs | 25 +--- .../Objects/Drawable/DrawableFruit.cs | 7 +- .../Scoring/CatchScoreProcessor.cs | 3 +- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 11 +- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 5 +- .../Objects/Drawables/DrawableHoldNote.cs | 42 ++++--- .../Objects/Drawables/DrawableHoldNoteTick.cs | 7 +- .../Objects/Drawables/DrawableNote.cs | 11 +- .../Scoring/ManiaScoreProcessor.cs | 9 +- .../osu.Game.Rulesets.Mania.csproj | 4 - .../Objects/Drawables/DrawableHitCircle.cs | 17 ++- .../Objects/Drawables/DrawableOsuHitObject.cs | 4 +- .../Objects/Drawables/DrawableOsuJudgement.cs | 3 +- .../Objects/Drawables/DrawableSlider.cs | 21 ++-- .../Objects/Drawables/DrawableSliderTick.cs | 7 +- .../Objects/Drawables/DrawableSpinner.cs | 11 +- .../Scoring/OsuScoreProcessor.cs | 62 +++++----- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 10 +- .../Judgements/TaikoJudgement.cs | 5 - .../Judgements/TaikoStrongHitJudgement.cs | 20 +--- .../Objects/Drawables/DrawableDrumRoll.cs | 19 +-- .../Objects/Drawables/DrawableDrumRollTick.cs | 17 ++- .../Objects/Drawables/DrawableHit.cs | 21 ++-- .../Objects/Drawables/DrawableHitStrong.cs | 19 +-- .../Objects/Drawables/DrawableSwell.cs | 20 ++-- .../Scoring/TaikoScoreProcessor.cs | 102 +++++++--------- .../UI/DrawableTaikoJudgement.cs | 5 +- osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 8 +- .../UI/KiaiHitExplosion.cs | 8 +- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 31 ++--- .../Rulesets/Judgements/DrawableJudgement.cs | 4 +- osu.Game/Rulesets/Judgements/Judgement.cs | 2 +- .../Objects/Drawables/DrawableHitObject.cs | 110 ++++++++++-------- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 20 +--- osu.Game/Rulesets/UI/Playfield.cs | 2 +- osu.Game/Rulesets/UI/RulesetContainer.cs | 24 ++-- 37 files changed, 337 insertions(+), 361 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs index f04c237629..6565ca98f9 100644 --- a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs @@ -154,7 +154,7 @@ namespace osu.Desktop.Tests.Visual private class TestScoreProcessor : ScoreProcessor { - protected override void OnNewJudgement(TestJudgement judgement) + protected override void OnNewJudgement(Judgement judgement) { } } diff --git a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs index e40016b858..0bfa21a45e 100644 --- a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs @@ -139,35 +139,20 @@ namespace osu.Desktop.Tests.Visual Hit hit = new Hit(); hit.ApplyDefaults(cpi, new BeatmapDifficulty()); - var h = new DrawableTestHit(hit) - { - X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f), - Judgement = new TaikoJudgement - { - Result = hitResult, - TimeOffset = 0 - } - }; + var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) }; - rulesetContainer.Playfield.OnJudgement(h); + rulesetContainer.Playfield.OnJudgement(h, new TaikoJudgement { Result = hitResult }); if (RNG.Next(10) == 0) { - h.Judgement.SecondHit = true; - rulesetContainer.Playfield.OnJudgement(h); + rulesetContainer.Playfield.OnJudgement(h, new TaikoJudgement { Result = hitResult }); + rulesetContainer.Playfield.OnJudgement(h, new TaikoStrongHitJudgement()); } } private void addMissJudgement() { - rulesetContainer.Playfield.OnJudgement(new DrawableTestHit(new Hit()) - { - Judgement = new TaikoJudgement - { - Result = HitResult.Miss, - TimeOffset = 0 - } - }); + rulesetContainer.Playfield.OnJudgement(new DrawableTestHit(new Hit()), new TaikoJudgement { Result = HitResult.Miss }); } private void addBarLine(bool major, double delay = scroll_time) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index c6c716a29d..0cbece5544 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.MathUtils; using osu.Game.Graphics; using osu.Game.Rulesets.Catch.Judgements; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using OpenTK; using OpenTK.Graphics; @@ -100,10 +101,10 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable private const float preempt = 1000; - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { - if (Judgement.TimeOffset > 0) - Judgement.Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss; + if (timeOffset > 0) + AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss }); } protected override void UpdateState(ArmedState state) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 33c1355823..8a9e17de6e 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -3,6 +3,7 @@ using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; @@ -27,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Scoring Accuracy.Value = 1; } - protected override void OnNewJudgement(CatchJudgement judgement) + protected override void OnNewJudgement(Judgement judgement) { } } diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 292ddaca12..cf00f80e5e 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -8,6 +8,7 @@ using OpenTK; using osu.Game.Rulesets.Catch.Judgements; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.UI @@ -53,13 +54,13 @@ namespace osu.Game.Rulesets.Catch.UI fruit.OnJudgement += Fruit_OnJudgement; } - private void Fruit_OnJudgement(DrawableHitObject obj) + private void Fruit_OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { - if (obj.Judgement.Result > HitResult.Miss) + if (judgement.Result > HitResult.Miss) { - Vector2 screenPosition = obj.ScreenSpaceDrawQuad.Centre; - Remove(obj); - catcherArea.Add(obj, screenPosition); + Vector2 screenPosition = judgedObject.ScreenSpaceDrawQuad.Centre; + Remove(judgedObject); + catcherArea.Add(judgedObject, screenPosition); } } } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index f416f6acfb..f79733e9c0 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Input.Bindings; using osu.Framework.MathUtils; -using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Objects.Drawables; @@ -22,7 +21,7 @@ namespace osu.Game.Rulesets.Catch.UI { private Catcher catcher; - public void Add(DrawableHitObject fruit, Vector2 screenPosition) => catcher.AddToStack(fruit, screenPosition); + public void Add(DrawableHitObject fruit, Vector2 screenPosition) => catcher.AddToStack(fruit, screenPosition); public bool CheckIfWeCanCatch(CatchBaseHit obj) => Math.Abs(catcher.Position.X - obj.Position) < catcher.DrawSize.X / DrawSize.X / 2; @@ -152,7 +151,7 @@ namespace osu.Game.Rulesets.Catch.UI X = (float)MathHelper.Clamp(X + Math.Sign(currentDirection) * Clock.ElapsedFrameTime / 1800 * speed, 0, 1); } - public void AddToStack(DrawableHitObject fruit, Vector2 absolutePosition) + public void AddToStack(DrawableHitObject fruit, Vector2 absolutePosition) { fruit.RelativePositionAxes = Axes.None; fruit.Position = new Vector2(ToLocalSpace(absolutePosition).X - DrawSize.X / 2, 0); diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 4ce73e388b..6b3c6cbc20 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Linq; using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; @@ -133,7 +135,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables holdStartTime = null; // If the key has been released too early, the user should not receive full score for the release - if (!tail.Judged) + if (!tail.AllJudged) hasBroken = true; return true; @@ -160,12 +162,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (!base.OnPressed(action)) return false; - // We only want to trigger a holding state from the head if the head has received a judgement - if (!Judged) - return false; - // If the key has been released too early, the user should not receive full score for the release - if (Judgement.Result == HitResult.Miss) + if (Judgements.Any(j => j.Result == HitResult.Miss)) holdNote.hasBroken = true; // The head note also handles early hits before the body, but we want accurate early hits to count as the body being held @@ -192,17 +190,32 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Y = 0; } - protected ManiaJudgement CreateJudgement() => new HoldNoteTailJudgement(); - - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { - base.CheckJudgement(userTriggered); + if (!userTriggered) + { + if (timeOffset > HitObject.HitWindows.Bad / 2) + { + AddJudgement(new HoldNoteTailJudgement + { + Result = HitResult.Miss, + HasBroken = holdNote.hasBroken + }); + } - var tailJudgement = Judgement as HoldNoteTailJudgement; - if (tailJudgement == null) + return; + } + + double offset = Math.Abs(timeOffset); + + if (offset > HitObject.HitWindows.Miss / 2) return; - tailJudgement.HasBroken = holdNote.hasBroken; + AddJudgement(new HoldNoteTailJudgement + { + Result = HitObject.HitWindows.ResultFor(offset) ?? HitResult.Miss, + HasBroken = holdNote.hasBroken + }); } public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down @@ -213,9 +226,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (!holdNote.holdStartTime.HasValue) return false; - if (Judgement.Result != HitResult.None) - return false; - if (action != Action) return false; diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 4bc925b99a..1715bb06d7 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -82,7 +82,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected ManiaJudgement CreateJudgement() => new HoldNoteTickJudgement(); - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (!userTriggered) return; @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (HoldStartTime?.Invoke() > HitObject.StartTime) return; - Judgement.Result = HitResult.Perfect; + AddJudgement(new ManiaJudgement { Result = HitResult.Perfect }); } protected override void UpdateState(ArmedState state) @@ -108,9 +108,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected override void Update() { - if (Judgement.Result != HitResult.None) - return; - if (IsHolding?.Invoke() != true) return; diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index cfe3372c71..0d6647e0fb 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -5,6 +5,7 @@ using System; using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; +using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; using osu.Game.Rulesets.Objects.Drawables; @@ -43,21 +44,21 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (!userTriggered) { - if (Judgement.TimeOffset > HitObject.HitWindows.Bad / 2) - Judgement.Result = HitResult.Miss; + if (timeOffset > HitObject.HitWindows.Bad / 2) + AddJudgement(new ManiaJudgement { Result = HitResult.Miss }); return; } - double offset = Math.Abs(Judgement.TimeOffset); + double offset = Math.Abs(timeOffset); if (offset > HitObject.HitWindows.Miss / 2) return; - Judgement.Result = HitObject.HitWindows.ResultFor(offset) ?? HitResult.Miss; + AddJudgement(new ManiaJudgement { Result = HitObject.HitWindows.ResultFor(offset) ?? HitResult.Miss }); } protected override void UpdateState(ArmedState state) diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 4a71b8a77d..c30c20402a 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Objects.Drawables; @@ -203,7 +204,7 @@ namespace osu.Game.Rulesets.Mania.Scoring maxComboPortion = comboPortion; } - protected override void OnNewJudgement(ManiaJudgement judgement) + protected override void OnNewJudgement(Judgement judgement) { bool isTick = judgement is HoldNoteTickJudgement; @@ -254,8 +255,10 @@ namespace osu.Game.Rulesets.Mania.Scoring foreach (var j in Judgements) { - scoreForAccuracy += j.NumericAccuracyResult; - maxScoreForAccuracy += j.MaxNumericAccuracyResult; + var maniaJudgement = (ManiaJudgement)j; + + scoreForAccuracy += maniaJudgement.NumericAccuracyResult; + maxScoreForAccuracy += maniaJudgement.MaxNumericAccuracyResult; } Accuracy.Value = (double)scoreForAccuracy / maxScoreForAccuracy; diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 8644ad45ae..5c39139956 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -99,10 +99,6 @@ {C92A607B-1FDD-4954-9F92-03FF547D9080} osu.Game.Rulesets.Osu - - {F167E17A-7DE6-4AF5-B920-A5112296C695} - osu.Game.Rulesets.Taiko - {0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D} osu.Game diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 43d7fb3016..3184b83202 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -7,6 +7,7 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; using OpenTK; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Osu.Judgements; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -38,9 +39,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Colour = AccentColour, Hit = () => { - if (Judgement.Result != HitResult.None) return false; + if (AllJudged) + return false; - Judgement.PositionOffset = Vector2.Zero; //todo: set to correct value UpdateJudgement(true); return true; }, @@ -65,16 +66,20 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Size = circle.DrawSize; } - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (!userTriggered) { - if (Judgement.TimeOffset > HitObject.HitWindowFor(HitResult.Meh)) - Judgement.Result = HitResult.Miss; + if (timeOffset > HitObject.HitWindowFor(HitResult.Meh)) + AddJudgement(new OsuJudgement { Result = HitResult.Miss }); return; } - Judgement.Result = HitObject.ScoreResultForOffset(Math.Abs(Judgement.TimeOffset)); + AddJudgement(new OsuJudgement + { + Result = HitObject.ScoreResultForOffset(Math.Abs(timeOffset)), + PositionOffset = Vector2.Zero //todo: set to correct value + }); } protected override void UpdateInitialState() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index e18bcc856d..6870916b5b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -5,6 +5,7 @@ using System.ComponentModel; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Judgements; using osu.Framework.Graphics; +using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -31,7 +32,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables UpdatePreemptState(); - using (BeginDelayedSequence(TIME_PREEMPT + Judgement.TimeOffset, true)) + var offset = Time.Current - ((HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime); + using (BeginDelayedSequence(TIME_PREEMPT + offset, true)) UpdateCurrentState(state); } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs index 892d106b02..0cd30e34ac 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs @@ -11,7 +11,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { public class DrawableOsuJudgement : DrawableJudgement { - public DrawableOsuJudgement(OsuJudgement judgement) : base(judgement) + public DrawableOsuJudgement(OsuJudgement judgement) + : base(judgement) { } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 6f3cea7ac1..7cb06df679 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -8,6 +8,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces; using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Osu.Judgements; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -114,31 +115,31 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables bouncer2.Position = slider.Curve.PositionAt(body.SnakedEnd ?? 0); //todo: we probably want to reconsider this before adding scoring, but it looks and feels nice. - if (initialCircle.Judgement?.Result <= HitResult.Miss) + if (!initialCircle.Judgements.Any(j => j.IsHit)) initialCircle.Position = slider.Curve.PositionAt(progress); foreach (var c in components) c.UpdateProgress(progress, repeat); foreach (var t in ticks.Children) t.Tracking = ball.Tracking; } - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (!userTriggered && Time.Current >= slider.EndTime) { var ticksCount = ticks.Children.Count + 1; - var ticksHit = ticks.Children.Count(t => t.Judgement.Result > HitResult.Miss); - if (initialCircle.Judgement.Result > HitResult.Miss) + var ticksHit = ticks.Children.Count(t => t.Judgements.Any(j => j.IsHit)); + if (initialCircle.Judgements.Any(j => j.IsHit)) ticksHit++; var hitFraction = (double)ticksHit / ticksCount; - if (hitFraction == 1 && initialCircle.Judgement.Result == HitResult.Great) - Judgement.Result = HitResult.Great; - else if (hitFraction >= 0.5 && initialCircle.Judgement.Result >= HitResult.Good) - Judgement.Result = HitResult.Good; + if (hitFraction == 1 && initialCircle.Judgements.Any(j => j.Result == HitResult.Great)) + AddJudgement(new OsuJudgement { Result = HitResult.Great }); + else if (hitFraction >= 0.5 && initialCircle.Judgements.Any(j => j.Result >= HitResult.Good)) + AddJudgement(new OsuJudgement { Result = HitResult.Good }); else if (hitFraction > 0) - Judgement.Result = HitResult.Meh; + AddJudgement(new OsuJudgement { Result = HitResult.Meh }); else - Judgement.Result = HitResult.Miss; + AddJudgement(new OsuJudgement { Result = HitResult.Miss }); } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index 89d7cd1658..0938f78843 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -7,6 +7,7 @@ using osu.Game.Rulesets.Objects.Drawables; using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Osu.Judgements; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -46,10 +47,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables }; } - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { - if (Judgement.TimeOffset >= 0) - Judgement.Result = Tracking ? HitResult.Perfect : HitResult.Miss; + if (timeOffset >= 0) + AddJudgement(new SliderTickJudgement { Result = Tracking ? HitResult.Perfect : HitResult.Miss }); } protected override void UpdatePreemptState() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 923f659d27..98dd40b0e6 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -11,6 +11,7 @@ using OpenTK.Graphics; using osu.Game.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Allocation; +using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Screens.Ranking; namespace osu.Game.Rulesets.Osu.Objects.Drawables @@ -107,7 +108,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public float Progress => MathHelper.Clamp(disc.RotationAbsolute / 360 / spinner.SpinsRequired, 0, 1); - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (Time.Current < HitObject.StartTime) return; @@ -129,13 +130,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (!userTriggered && Time.Current >= spinner.EndTime) { if (Progress >= 1) - Judgement.Result = HitResult.Great; + AddJudgement(new OsuJudgement { Result = HitResult.Great }); else if (Progress > .9) - Judgement.Result = HitResult.Good; + AddJudgement(new OsuJudgement { Result = HitResult.Good }); else if (Progress > .75) - Judgement.Result = HitResult.Meh; + AddJudgement(new OsuJudgement { Result = HitResult.Meh }); else if (Time.Current >= spinner.EndTime) - Judgement.Result = HitResult.Miss; + AddJudgement(new OsuJudgement { Result = HitResult.Miss }); } } diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index a2e9fa2624..b6922cbf3b 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using osu.Framework.Configuration; using osu.Framework.Extensions; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; @@ -42,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Scoring hpDrainRate = beatmap.BeatmapInfo.Difficulty.DrainRate; totalAccurateJudgements = beatmap.HitObjects.Count; - foreach (var h in beatmap.HitObjects) + foreach (var unused in beatmap.HitObjects) { // TODO: add support for other object types. AddJudgement(new OsuJudgement { Result = HitResult.Great }); @@ -70,41 +71,38 @@ namespace osu.Game.Rulesets.Osu.Scoring score.Statistics[@"x"] = scoreResultCounts.GetOrDefault(HitResult.Miss); } - protected override void OnNewJudgement(OsuJudgement judgement) + protected override void OnNewJudgement(Judgement judgement) { - if (judgement != null) + var osuJudgement = (OsuJudgement)judgement; + + if (judgement.Result != HitResult.None) { - if (judgement.Result != HitResult.None) - { - scoreResultCounts[judgement.Result] = scoreResultCounts.GetOrDefault(judgement.Result) + 1; - comboResultCounts[judgement.Combo] = comboResultCounts.GetOrDefault(judgement.Combo) + 1; - } - - switch (judgement.Result) - { - case HitResult.Great: - Health.Value += (10.2 - hpDrainRate) * 0.02; - break; - - case HitResult.Good: - Health.Value += (8 - hpDrainRate) * 0.02; - break; - - case HitResult.Meh: - Health.Value += (4 - hpDrainRate) * 0.02; - break; - - /*case HitResult.SliderTick: - Health.Value += Math.Max(7 - hpDrainRate, 0) * 0.01; - break;*/ - - case HitResult.Miss: - Health.Value -= hpDrainRate * 0.04; - break; - } + scoreResultCounts[judgement.Result] = scoreResultCounts.GetOrDefault(judgement.Result) + 1; + comboResultCounts[osuJudgement.Combo] = comboResultCounts.GetOrDefault(osuJudgement.Combo) + 1; } - calculateScore(); + switch (judgement.Result) + { + case HitResult.Great: + Health.Value += (10.2 - hpDrainRate) * 0.02; + break; + + case HitResult.Good: + Health.Value += (8 - hpDrainRate) * 0.02; + break; + + case HitResult.Meh: + Health.Value += (4 - hpDrainRate) * 0.02; + break; + + /*case HitResult.SliderTick: + Health.Value += Math.Max(7 - hpDrainRate, 0) * 0.01; + break;*/ + + case HitResult.Miss: + Health.Value -= hpDrainRate * 0.04; + break; + } calculateScore(); } diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 9b88c9d1b3..6b367b8be2 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -10,6 +10,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables.Connections; using osu.Game.Rulesets.UI; using System.Linq; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.UI.Cursor; @@ -85,12 +86,15 @@ namespace osu.Game.Rulesets.Osu.UI .OrderBy(h => h.StartTime).OfType(); } - public override void OnJudgement(DrawableHitObject judgedObject) + public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { - DrawableOsuJudgement explosion = new DrawableOsuJudgement(judgedObject.Judgement) + var osuJudgement = (OsuJudgement)judgement; + var osuObject = (OsuHitObject)judgedObject.HitObject; + + DrawableOsuJudgement explosion = new DrawableOsuJudgement(osuJudgement) { Origin = Anchor.Centre, - Position = judgedObject.HitObject.StackedEndPosition + judgedObject.Judgement.PositionOffset + Position = osuObject.StackedEndPosition + osuJudgement.PositionOffset }; judgementLayer.Add(explosion); diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs index 3e48453460..9d6b5ca535 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs @@ -18,11 +18,6 @@ namespace osu.Game.Rulesets.Taiko.Judgements /// public int MaxResultValueForAccuracy => NumericResultForAccuracy(HitResult.Great); - /// - /// Whether this Judgement has a secondary hit in the case of strong hits. - /// - public virtual bool SecondHit { get; set; } - /// /// Computes the numeric result value for the combo portion of the score. /// For the accuracy portion of the score (including accuracy percentage), see . diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs index 4996cac39e..bb67784ab1 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs @@ -1,25 +1,17 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.Judgements { - public class TaikoStrongHitJudgement : TaikoJudgement, IPartialJudgement + public class TaikoStrongHitJudgement : TaikoJudgement { - public bool Changed { get; set; } - - public override bool SecondHit + public TaikoStrongHitJudgement() { - get { return base.SecondHit; } - set - { - if (base.SecondHit == value) - return; - base.SecondHit = value; - - Changed = true; - } + base.Result = HitResult.Perfect; } + + public new HitResult Result => base.Result; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index c044ebeeb1..2396f3bf91 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -12,6 +12,7 @@ using OpenTK.Graphics; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Judgements; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -52,8 +53,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } - protected TaikoJudgement CreateJudgement() => new TaikoJudgement { SecondHit = HitObject.IsStrong }; - protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece(); public override bool OnPressed(TaikoAction action) => false; @@ -65,9 +64,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables accentDarkColour = colours.YellowDarker; } - private void onTickJudgement(DrawableHitObject obj) + private void onTickJudgement(DrawableHitObject obj, Judgement judgement) { - if (obj.Judgement.Result > HitResult.Miss) + if (judgement.Result > HitResult.Miss) rollingHits++; else rollingHits--; @@ -78,22 +77,24 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables MainPiece.FadeAccent(newAccent, 100); } - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (userTriggered) return; - if (Judgement.TimeOffset < 0) + if (timeOffset < 0) return; - int countHit = NestedHitObjects.Count(o => o.Judgement.Result > HitResult.Miss); + int countHit = NestedHitObjects.Count(o => o.AllJudged); if (countHit > HitObject.RequiredGoodHits) { - Judgement.Result = countHit >= HitObject.RequiredGreatHits ? HitResult.Great : HitResult.Good; + AddJudgement(new TaikoJudgement { Result = countHit >= HitObject.RequiredGreatHits ? HitResult.Great : HitResult.Good }); + if (HitObject.IsStrong) + AddJudgement(new TaikoStrongHitJudgement()); } else - Judgement.Result = HitResult.Miss; + AddJudgement(new TaikoJudgement { Result = HitResult.Miss }); } protected override void UpdateState(ArmedState state) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 97c0f6bf63..8ac67ba0a6 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -34,15 +34,17 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Filled = HitObject.FirstTick }; - protected TaikoJudgement CreateJudgement() => new TaikoDrumRollTickJudgement { SecondHit = HitObject.IsStrong }; - - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (!userTriggered) return; - if (Math.Abs(Judgement.TimeOffset) < HitObject.HitWindow) - Judgement.Result = HitResult.Great; + if (!(Math.Abs(timeOffset) < HitObject.HitWindow)) + return; + + AddJudgement(new TaikoDrumRollTickJudgement { Result = HitResult.Great }); + if (HitObject.IsStrong) + AddJudgement(new TaikoStrongHitJudgement()); } protected override void UpdateState(ArmedState state) @@ -55,9 +57,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } - public override bool OnPressed(TaikoAction action) - { - return Judgement.Result == HitResult.None && UpdateJudgement(true); - } + public override bool OnPressed(TaikoAction action) => UpdateJudgement(true); } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 42195e31f3..675fa7be33 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; namespace osu.Game.Rulesets.Taiko.Objects.Drawables @@ -27,33 +28,30 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables FillMode = FillMode.Fit; } - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (!userTriggered) { - if (Judgement.TimeOffset > HitObject.HitWindowGood) - Judgement.Result = HitResult.Miss; + if (timeOffset > HitObject.HitWindowGood) + AddJudgement(new TaikoJudgement { Result = HitResult.Miss }); return; } - double hitOffset = Math.Abs(Judgement.TimeOffset); + double hitOffset = Math.Abs(timeOffset); if (hitOffset > HitObject.HitWindowMiss) return; if (!validKeyPressed) - Judgement.Result = HitResult.Miss; + AddJudgement(new TaikoJudgement { Result = HitResult.Miss }); else if (hitOffset < HitObject.HitWindowGood) - Judgement.Result = hitOffset < HitObject.HitWindowGreat ? HitResult.Great : HitResult.Good; + AddJudgement(new TaikoJudgement { Result = hitOffset < HitObject.HitWindowGreat ? HitResult.Great : HitResult.Good }); else - Judgement.Result = HitResult.Miss; + AddJudgement(new TaikoJudgement { Result = HitResult.Miss }); } public override bool OnPressed(TaikoAction action) { - if (Judgement.Result != HitResult.None) - return false; - validKeyPressed = HitActions.Contains(action); return UpdateJudgement(true); @@ -71,7 +69,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables var circlePiece = MainPiece as CirclePiece; circlePiece?.FlashBox.FinishTransforms(); - using (BeginDelayedSequence(HitObject.StartTime - Time.Current + Judgement.TimeOffset, true)) + var offset = Time.Current - HitObject.StartTime; + using (BeginDelayedSequence(HitObject.StartTime - Time.Current + offset, true)) { switch (State) { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs index 855aa6fb0b..48812093c4 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs @@ -3,7 +3,6 @@ using System; using System.Linq; -using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Judgements; namespace osu.Game.Rulesets.Taiko.Objects.Drawables @@ -25,13 +24,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { } - protected TaikoJudgement CreateJudgement() => new TaikoStrongHitJudgement(); + private bool processedSecondHit; + public override bool AllJudged => processedSecondHit && base.AllJudged; - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { - if (Judgement.Result == HitResult.None) + if (!base.AllJudged) { - base.CheckJudgement(userTriggered); + base.CheckForJudgements(userTriggered, timeOffset); return; } @@ -41,7 +41,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables // If we get here, we're assured that the key pressed is the correct secondary key if (Math.Abs(firstHitTime - Time.Current) < second_hit_window) - Judgement.SecondHit = true; + { + AddJudgement(new TaikoStrongHitJudgement()); + processedSecondHit = true; + } } public override bool OnReleased(TaikoAction action) @@ -54,7 +57,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public override bool OnPressed(TaikoAction action) { // Check if we've handled the first key - if (Judgement.Result == HitResult.None) + if (!base.AllJudged) { // First key hasn't been handled yet, attempt to handle it bool handled = base.OnPressed(action); @@ -70,7 +73,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } // If we've already hit the second key, don't handle this object any further - if (Judgement.SecondHit) + if (processedSecondHit) return false; // Don't handle represses of the first key diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index a4fdf19c59..9c6fb1ec3d 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Taiko.Judgements; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -134,7 +135,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Width *= Parent.RelativeChildSize.X; } - protected override void CheckJudgement(bool userTriggered) + protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (userTriggered) { @@ -152,18 +153,17 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables expandingRing.ScaleTo(1f + Math.Min(target_ring_scale - 1f, (target_ring_scale - 1f) * completion * 1.3f), 260, Easing.OutQuint); if (userHits == HitObject.RequiredHits) - Judgement.Result = HitResult.Great; + AddJudgement(new TaikoJudgement { Result = HitResult.Great }); } else { - if (Judgement.TimeOffset < 0) + if (timeOffset < 0) return; //TODO: THIS IS SHIT AND CAN'T EXIST POST-TAIKO WORLD CUP - if (userHits > HitObject.RequiredHits / 2) - Judgement.Result = HitResult.Good; - else - Judgement.Result = HitResult.Miss; + AddJudgement(userHits > HitObject.RequiredHits / 2 + ? new TaikoJudgement { Result = HitResult.Good } + : new TaikoJudgement { Result = HitResult.Miss }); } } @@ -172,8 +172,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables const float preempt = 100; const float out_transition_time = 300; + var offset = Time.Current - HitObject.EndTime; double untilStartTime = HitObject.StartTime - Time.Current; - double untilJudgement = untilStartTime + Judgement.TimeOffset + HitObject.Duration; + double untilJudgement = untilStartTime + offset + HitObject.Duration; targetRing.Delay(untilStartTime - preempt).ScaleTo(target_ring_scale, preempt * 4, Easing.OutQuint); this.Delay(untilJudgement).FadeOut(out_transition_time, Easing.Out); @@ -207,9 +208,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public override bool OnPressed(TaikoAction action) { - if (Judgement.Result != HitResult.None) - return false; - // Don't handle keys before the swell starts if (Time.Current < HitObject.StartTime) return false; diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index 83f3745763..ca3dcc8984 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -3,6 +3,7 @@ using System; using osu.Game.Beatmaps; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Judgements; @@ -138,28 +139,24 @@ namespace osu.Game.Rulesets.Taiko.Scoring { if (obj is Hit) { - AddJudgement(new TaikoJudgement - { - Result = HitResult.Great, - SecondHit = obj.IsStrong - }); + AddJudgement(new TaikoJudgement { Result = HitResult.Great }); + if (obj.IsStrong) + AddJudgement(new TaikoStrongHitJudgement()); } else if (obj is DrumRoll) { for (int i = 0; i < ((DrumRoll)obj).TotalTicks; i++) { - AddJudgement(new TaikoDrumRollTickJudgement - { - Result = HitResult.Great, - SecondHit = obj.IsStrong - }); + AddJudgement(new TaikoDrumRollTickJudgement { Result = HitResult.Great }); + + if (obj.IsStrong) + AddJudgement(new TaikoStrongHitJudgement()); } - AddJudgement(new TaikoJudgement - { - Result = HitResult.Great, - SecondHit = obj.IsStrong - }); + AddJudgement(new TaikoJudgement { Result = HitResult.Great }); + + if (obj.IsStrong) + AddJudgement(new TaikoStrongHitJudgement()); } else if (obj is Swell) { @@ -171,16 +168,40 @@ namespace osu.Game.Rulesets.Taiko.Scoring maxComboPortion = comboPortion; } - protected override void OnNewJudgement(TaikoJudgement judgement) + protected override void OnNewJudgement(Judgement judgement) { + bool isStrong = judgement is TaikoStrongHitJudgement; bool isTick = judgement is TaikoDrumRollTickJudgement; - // Don't consider ticks as a type of hit that counts towards map completion - if (!isTick) + // Don't consider ticks and strong hits as a type of hit that counts towards map completion + if (!isTick && !isStrong) totalHits++; // Apply score changes - addHitScore(judgement); + if (judgement.IsHit) + { + double baseValue = judgement.NumericResult; + + if (isStrong) + { + // Add increased score for the previous judgement by hitting a strong hit object with the second key + var prevJudgement = Judgements[Judgements.Count - 1]; + baseValue = prevJudgement.NumericResult * strongHitScale; + + } + + // Add score to portions + if (judgement is TaikoDrumRollTickJudgement) + bonusScore += baseValue; + else + { + // A relevance factor that needs to be applied to make higher combos more relevant + // Value is capped at 400 combo + double comboRelevance = Math.Min(Math.Log(400, combo_base), Math.Max(0.5, Math.Log(Combo.Value, combo_base))); + + comboPortion += baseValue * comboRelevance; + } + } // Apply HP changes switch (judgement.Result) @@ -201,50 +222,15 @@ namespace osu.Game.Rulesets.Taiko.Scoring break; } - calculateScore(); - } - - protected override void OnJudgementChanged(TaikoJudgement judgement) - { - // Apply score changes - addHitScore(judgement); - - calculateScore(); - } - - private void addHitScore(TaikoJudgement judgement) - { - if (!judgement.IsHit) - return; - - double baseValue = judgement.NumericResult; - - // Add increased score for hitting a strong hit object with the second key - if (judgement.SecondHit) - baseValue *= strongHitScale; - - // Add score to portions - if (judgement is TaikoDrumRollTickJudgement) - bonusScore += baseValue; - else - { - // A relevance factor that needs to be applied to make higher combos more relevant - // Value is capped at 400 combo - double comboRelevance = Math.Min(Math.Log(400, combo_base), Math.Max(0.5, Math.Log(Combo.Value, combo_base))); - - comboPortion += baseValue * comboRelevance; - } - } - - private void calculateScore() - { int scoreForAccuracy = 0; int maxScoreForAccuracy = 0; foreach (var j in Judgements) { - scoreForAccuracy += j.ResultNumericForAccuracy; - maxScoreForAccuracy += j.MaxResultValueForAccuracy; + var taikoJudgement = (TaikoJudgement)j; + + scoreForAccuracy += taikoJudgement.ResultNumericForAccuracy; + maxScoreForAccuracy += taikoJudgement.MaxResultValueForAccuracy; } Accuracy.Value = (double)scoreForAccuracy / maxScoreForAccuracy; diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs index d0ad343264..ea9c59c2a5 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs @@ -15,13 +15,16 @@ namespace osu.Game.Rulesets.Taiko.UI /// public class DrawableTaikoJudgement : DrawableJudgement { + public readonly DrawableHitObject JudgedObject; + /// /// Creates a new judgement text. /// /// The judgement to visualise. - public DrawableTaikoJudgement(TaikoJudgement judgement) + public DrawableTaikoJudgement(DrawableHitObject judgedObject, Judgement judgement) : base(judgement) { + JudgedObject = judgedObject; } [BackgroundDependencyLoader] diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index cb849a11c7..830a01bfbc 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; -using osu.Game.Rulesets.Taiko.Judgements; +using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects; namespace osu.Game.Rulesets.Taiko.UI @@ -18,17 +18,17 @@ namespace osu.Game.Rulesets.Taiko.UI /// internal class HitExplosion : CircularContainer { - public readonly TaikoJudgement Judgement; + public readonly DrawableHitObject JudgedObject; private readonly Box innerFill; private readonly bool isRim; - public HitExplosion(TaikoJudgement judgement, bool isRim) + public HitExplosion(DrawableHitObject judgedObject, bool isRim) { this.isRim = isRim; - Judgement = judgement; + JudgedObject = judgedObject; Anchor = Anchor.CentreLeft; Origin = Anchor.Centre; diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index bac956a25b..e3e1d485d8 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -7,22 +7,22 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; -using osu.Game.Rulesets.Taiko.Judgements; +using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects; namespace osu.Game.Rulesets.Taiko.UI { public class KiaiHitExplosion : CircularContainer { - public readonly TaikoJudgement Judgement; + public readonly DrawableHitObject JudgedObject; private readonly bool isRim; - public KiaiHitExplosion(TaikoJudgement judgement, bool isRim) + public KiaiHitExplosion(DrawableHitObject judgedObject, bool isRim) { this.isRim = isRim; - Judgement = judgement; + JudgedObject = judgedObject; Anchor = Anchor.CentreLeft; Origin = Anchor.Centre; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 4da00a58c6..1fce2b3a48 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -14,6 +14,7 @@ using osu.Game.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Extensions.Color4Extensions; using System.Linq; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.UI @@ -218,18 +219,22 @@ namespace osu.Game.Rulesets.Taiko.UI swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy()); } - public override void OnJudgement(DrawableHitObject judgedObject) + public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { - bool wasHit = judgedObject.Judgement.Result > HitResult.Miss; - bool secondHit = judgedObject.Judgement.SecondHit; + bool wasHit = judgement.Result > HitResult.Miss; + bool secondHit = judgement is TaikoStrongHitJudgement; + var taikoObject = (TaikoHitObject)judgedObject.HitObject; - judgementContainer.Add(new DrawableTaikoJudgement(judgedObject.Judgement) + if (judgementContainer.FirstOrDefault(j => j.JudgedObject == judgedObject) == null) { - Anchor = wasHit ? Anchor.TopLeft : Anchor.CentreLeft, - Origin = wasHit ? Anchor.BottomCentre : Anchor.Centre, - RelativePositionAxes = Axes.X, - X = wasHit ? judgedObject.Position.X : 0, - }); + judgementContainer.Add(new DrawableTaikoJudgement(judgedObject, judgement) + { + Anchor = wasHit ? Anchor.TopLeft : Anchor.CentreLeft, + Origin = wasHit ? Anchor.BottomCentre : Anchor.Centre, + RelativePositionAxes = Axes.X, + X = wasHit ? judgedObject.Position.X : 0, + }); + } if (!wasHit) return; @@ -244,13 +249,13 @@ namespace osu.Game.Rulesets.Taiko.UI topLevelHitContainer.Add(judgedObject.CreateProxy()); } - hitExplosionContainer.Add(new HitExplosion(judgedObject.Judgement, isRim)); + hitExplosionContainer.Add(new HitExplosion(judgedObject, isRim)); - if (judgedObject.HitObject.Kiai) - kiaiExplosionContainer.Add(new KiaiHitExplosion(judgedObject.Judgement, isRim)); + if (taikoObject.Kiai) + kiaiExplosionContainer.Add(new KiaiHitExplosion(judgedObject, isRim)); } else - hitExplosionContainer.Children.FirstOrDefault(e => e.Judgement == judgedObject.Judgement)?.VisualiseSecondHit(); + hitExplosionContainer.Children.FirstOrDefault(e => e.JudgedObject == judgedObject)?.VisualiseSecondHit(); } } } diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index 80311654be..795acdc0cf 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Judgements public class DrawableJudgement : Container where TJudgement : Judgement { - protected readonly TJudgement Judgement; + protected readonly Judgement Judgement; protected readonly SpriteText JudgementText; @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Judgements /// Creates a drawable which visualises a . /// /// The judgement to visualise. - public DrawableJudgement(TJudgement judgement) + public DrawableJudgement(Judgement judgement) { Judgement = judgement; diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index 88b9600fac..cbdea5caf1 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -43,4 +43,4 @@ namespace osu.Game.Rulesets.Judgements /// The number. protected virtual int NumericResultFor(HitResult result) => result > HitResult.Miss ? 1 : 0; } -} \ No newline at end of file +} diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 9d39efb8fe..940e7a4839 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -46,13 +46,19 @@ namespace osu.Game.Rulesets.Objects.Drawables where TObject : HitObject where TJudgement : Judgement { - public event Action> OnJudgement; + public event Action OnJudgement; public override bool HandleInput => Interactive; public bool Interactive = true; - public TJudgement Judgement; + /// + /// Whether this can be judged. + /// + protected virtual bool ProvidesJudgement => true; + + private readonly List judgements = new List(); + public IReadOnlyList Judgements => judgements; protected List Samples = new List(); @@ -95,69 +101,73 @@ namespace osu.Game.Rulesets.Objects.Drawables UpdateState(State); } - /// - /// Whether this hit object and all of its nested hit objects have been judged. - /// - public bool Judged => (Judgement?.Result ?? HitResult.None) != HitResult.None && (NestedHitObjects?.All(h => h.Judged) ?? true); + private bool hasJudgementResult; + private bool judgementOccurred; /// - /// Process a hit of this hitobject. Carries out judgement. + /// Whether this and all of its nested s have been judged. /// - /// Whether a hit was processed. - protected bool UpdateJudgement(bool userTriggered) + public virtual bool AllJudged => (!ProvidesJudgement || hasJudgementResult) && (NestedHitObjects?.All(h => h.AllJudged) ?? true); + + /// + /// Notifies that a new judgement has occurred for this . + /// + /// The . + protected void AddJudgement(Judgement judgement) { - if (Judgement == null) - return false; + hasJudgementResult = judgement.Result >= HitResult.Miss; + judgementOccurred = true; - var partial = Judgement as IPartialJudgement; + // Ensure that the judgement is given a valid time offset, because this may not get set by the caller + var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; + judgement.TimeOffset = Time.Current - endTime; - // Never re-process non-partial hits - if (Judgement.Result != HitResult.None && partial == null) - return false; + judgements.Add(judgement); - // Update the judgement state - double endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; - Judgement.TimeOffset = Time.Current - endTime; - - // Update the judgement state - bool hadResult = Judgement.Result != HitResult.None; - CheckJudgement(userTriggered); - - // Don't process judgements with no result - if (Judgement.Result == HitResult.None) - return false; - - // Don't process judgements that previously had results but the results were unchanged - if (hadResult && partial?.Changed != true) - return false; - - switch (Judgement.Result) - { - default: - State = ArmedState.Hit; - break; - case HitResult.Miss: - State = ArmedState.Miss; - break; - } - - OnJudgement?.Invoke(this); - - if (partial != null) - partial.Changed = false; - - return true; + OnJudgement?.Invoke(this, judgement); } - protected virtual void CheckJudgement(bool userTriggered) + /// + /// Processes this , checking if any judgements have occurred. + /// + /// Whether the user triggered this process. + /// Whether a judgement has occurred from this or any nested s. + protected bool UpdateJudgement(bool userTriggered) { + judgementOccurred = false; + + if (AllJudged) + return false; + if (NestedHitObjects != null) { foreach (var d in NestedHitObjects) - d.CheckJudgement(userTriggered); + { + if (d.AllJudged) + continue; + + d.UpdateJudgement(userTriggered); + + if (d.AllJudged) + return true; + } } + + var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; + CheckForJudgements(userTriggered, Time.Current - endTime); + + return judgementOccurred; } + /// + /// Checks if any judgements have occurred for this . This method must construct + /// all s and notify of them through . + /// + /// Whether the user triggered this check. + /// The offset from the end time at which this check occurred. A > 0 + /// implies that this check occurred after the end time of . + protected virtual void CheckForJudgements(bool userTriggered, double timeOffset) { } + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); @@ -188,7 +198,7 @@ namespace osu.Game.Rulesets.Objects.Drawables if (nestedHitObjects == null) nestedHitObjects = new List>(); - h.OnJudgement += d => OnJudgement?.Invoke(d); + h.OnJudgement += (d, j) => OnJudgement?.Invoke(d, j); nestedHitObjects.Add(h); } diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 42dabfbdff..aea7e40df4 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -142,7 +142,7 @@ namespace osu.Game.Rulesets.Scoring /// /// All judgements held by this ScoreProcessor. /// - protected readonly List Judgements = new List(); + protected readonly List Judgements = new List(); public override bool HasFailed => Health.Value == Health.MinValue; @@ -171,7 +171,7 @@ namespace osu.Game.Rulesets.Scoring /// Adds a judgement to this ScoreProcessor. /// /// The judgement to add. - protected void AddJudgement(TJudgement judgement) + protected void AddJudgement(Judgement judgement) { bool exists = Judgements.Contains(judgement); @@ -197,8 +197,6 @@ namespace osu.Game.Rulesets.Scoring NotifyNewJudgement(judgement); } - else - OnJudgementChanged(judgement); UpdateFailed(); } @@ -212,20 +210,8 @@ namespace osu.Game.Rulesets.Scoring /// /// Updates any values that need post-processing. Invoked when a new judgement has occurred. - /// - /// This is not triggered when existing judgements are changed - for that see . - /// /// /// The judgement that triggered this calculation. - protected abstract void OnNewJudgement(TJudgement judgement); - - /// - /// Updates any values that need post-processing. Invoked when an existing judgement has changed. - /// - /// This is not triggered when a new judgement has occurred - for that see . - /// - /// - /// The judgement that triggered this calculation. - protected virtual void OnJudgementChanged(TJudgement judgement) { } + protected abstract void OnNewJudgement(Judgement judgement); } } diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index cc16eff6d6..ba526e2178 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -94,7 +94,7 @@ namespace osu.Game.Rulesets.UI /// Triggered when an object's Judgement is updated. /// /// The object that Judgement has been updated for. - public virtual void OnJudgement(DrawableHitObject judgedObject) { } + public virtual void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { } public class HitObjectContainer : CompositeDrawable { diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index a7472f4dbc..d87e47794f 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -230,7 +230,7 @@ namespace osu.Game.Rulesets.UI where TObject : HitObject where TJudgement : Judgement { - public event Action OnJudgement; + public event Action OnJudgement; public sealed override bool ProvidingUserCursor => !HasReplayLoaded && Playfield.ProvidingUserCursor; @@ -239,7 +239,7 @@ namespace osu.Game.Rulesets.UI /// public new IEnumerable Objects => Beatmap.HitObjects; - protected override bool AllObjectsJudged => drawableObjects.All(h => h.Judged); + protected override bool AllObjectsJudged => drawableObjects.All(h => h.AllJudged); /// /// The playfield. @@ -298,7 +298,12 @@ namespace osu.Game.Rulesets.UI if (drawableObject == null) continue; - drawableObject.OnJudgement += onJudgement; + drawableObject.OnJudgement += (d, j) => + { + Playfield.OnJudgement(d, j); + OnJudgement?.Invoke(j); + CheckAllJudged(); + }; drawableObjects.Add(drawableObject); Playfield.Add(drawableObject); @@ -320,19 +325,6 @@ namespace osu.Game.Rulesets.UI /// protected virtual Vector2 GetPlayfieldAspectAdjust() => new Vector2(0.75f); //a sane default - /// - /// Triggered when an object's Judgement is updated. - /// - /// The object that Judgement has been updated for. - private void onJudgement(DrawableHitObject judgedObject) - { - Playfield.OnJudgement(judgedObject); - - OnJudgement?.Invoke(judgedObject.Judgement); - - CheckAllJudged(); - } - /// /// Creates a DrawableHitObject from a HitObject. /// From f158ce814ca6b222546e3539dc3655881d8a379b Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 6 Sep 2017 17:20:41 +0900 Subject: [PATCH 283/483] Fix state never getting set. --- .../Rulesets/Objects/Drawables/DrawableHitObject.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 940e7a4839..836113b017 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -124,6 +124,18 @@ namespace osu.Game.Rulesets.Objects.Drawables judgements.Add(judgement); + switch (judgement.Result) + { + case HitResult.None: + break; + case HitResult.Miss: + State = ArmedState.Miss; + break; + default: + State = ArmedState.Hit; + break; + } + OnJudgement?.Invoke(this, judgement); } From 63b61ce6694ed6f1f72cc81083b18307c131f42c Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 6 Sep 2017 17:20:51 +0900 Subject: [PATCH 284/483] Make TimeOffset internal set. --- osu.Game/Rulesets/Judgements/Judgement.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index cbdea5caf1..2732c5e778 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Judgements /// /// The offset at which this judgement occurred. /// - public double TimeOffset; + public double TimeOffset { get; internal set; } public virtual bool AffectsCombo => true; From 29941019a56d11821ab921e368049fba47b96fe9 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 6 Sep 2017 17:44:51 +0900 Subject: [PATCH 285/483] Hacky way to make osu! and taiko work again. --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs | 2 +- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs | 2 +- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 6870916b5b..9faecadbf1 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables UpdatePreemptState(); - var offset = Time.Current - ((HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime); + var offset = !AllJudged ? 0 : Time.Current - ((HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime); using (BeginDelayedSequence(TIME_PREEMPT + offset, true)) UpdateCurrentState(state); } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 675fa7be33..55eaa8dbb8 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables var circlePiece = MainPiece as CirclePiece; circlePiece?.FlashBox.FinishTransforms(); - var offset = Time.Current - HitObject.StartTime; + var offset = !AllJudged ? 0 : Time.Current - HitObject.StartTime; using (BeginDelayedSequence(HitObject.StartTime - Time.Current + offset, true)) { switch (State) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 9c6fb1ec3d..ab13478286 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -172,7 +172,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables const float preempt = 100; const float out_transition_time = 300; - var offset = Time.Current - HitObject.EndTime; + var offset = !AllJudged ? 0 : Time.Current - HitObject.EndTime; double untilStartTime = HitObject.StartTime - Time.Current; double untilJudgement = untilStartTime + offset + HitObject.Duration; From e85d51164531f9f6aaf6bf53f3254c2ccf20ad49 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 6 Sep 2017 17:48:01 +0900 Subject: [PATCH 286/483] No more partial judgements. --- .../Rulesets/Judgements/IPartialJudgement.cs | 19 ------------------- osu.Game/osu.Game.csproj | 1 - 2 files changed, 20 deletions(-) delete mode 100644 osu.Game/Rulesets/Judgements/IPartialJudgement.cs diff --git a/osu.Game/Rulesets/Judgements/IPartialJudgement.cs b/osu.Game/Rulesets/Judgements/IPartialJudgement.cs deleted file mode 100644 index 38080835e0..0000000000 --- a/osu.Game/Rulesets/Judgements/IPartialJudgement.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -namespace osu.Game.Rulesets.Judgements -{ - /// - /// Inidicates that the judgement this is attached to is a partial judgement and the scoring value may change. - /// - public interface IPartialJudgement - { - /// - /// Indicates that this partial judgement has changed and requires reprocessing. - /// - /// This is set to false once the judgement has been re-processed. - /// - /// - bool Changed { get; set; } - } -} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 325cfba986..3c522ca0e8 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -210,7 +210,6 @@ - From 0cc443e618bbd7eb9b9dc97b8614c80aada72eac Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 6 Sep 2017 18:05:51 +0900 Subject: [PATCH 287/483] Remove all generic judgements. --- .../Visual/TestCaseScrollingPlayfield.cs | 20 +-- .../Visual/TestCaseTaikoPlayfield.cs | 4 +- .../Objects/Drawable/DrawableFruit.cs | 3 +- .../Scoring/CatchScoreProcessor.cs | 5 +- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 5 +- .../UI/CatchRulesetContainer.cs | 7 +- .../Drawables/DrawableManiaHitObject.cs | 3 +- .../Scoring/ManiaScoreProcessor.cs | 4 +- osu.Game.Rulesets.Mania/UI/Column.cs | 5 +- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 5 +- .../UI/ManiaRulesetContainer.cs | 7 +- .../Objects/Drawables/DrawableOsuHitObject.cs | 3 +- .../Objects/Drawables/DrawableOsuJudgement.cs | 2 +- .../Scoring/OsuScoreProcessor.cs | 4 +- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 6 +- .../UI/OsuRulesetContainer.cs | 7 +- .../Objects/Drawables/DrawableBarLine.cs | 3 +- .../Drawables/DrawableTaikoHitObject.cs | 6 +- .../Scoring/TaikoScoreProcessor.cs | 4 +- .../UI/DrawableTaikoJudgement.cs | 3 +- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 4 +- .../UI/TaikoRulesetContainer.cs | 7 +- .../Rulesets/Judgements/DrawableJudgement.cs | 4 +- .../Objects/Drawables/DrawableHitObject.cs | 25 +--- .../Drawables/DrawableScrollingHitObject.cs | 8 +- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 5 +- osu.Game/Rulesets/UI/Playfield.cs | 14 +- osu.Game/Rulesets/UI/RulesetContainer.cs | 130 +++++++----------- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 28 ++-- .../Rulesets/UI/ScrollingRulesetContainer.cs | 14 +- 30 files changed, 137 insertions(+), 208 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs index 6565ca98f9..a431531427 100644 --- a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs @@ -72,7 +72,7 @@ namespace osu.Desktop.Tests.Visual [Test] public void TestSpeedAdjustmentOrdering() { - var hitObjectContainer = new ScrollingPlayfield.ScrollingHitObjectContainer(Axes.X); + var hitObjectContainer = new ScrollingPlayfield.ScrollingHitObjectContainer(Axes.X); var speedAdjustments = new[] { @@ -129,7 +129,7 @@ namespace osu.Desktop.Tests.Visual Assert.IsTrue(hitObjectContainer.SpeedAdjustments[3].Contains(hitObjects[1])); } - private class TestRulesetContainer : ScrollingRulesetContainer + private class TestRulesetContainer : ScrollingRulesetContainer { private readonly Axes scrollingAxes; @@ -147,12 +147,12 @@ namespace osu.Desktop.Tests.Visual protected override BeatmapConverter CreateBeatmapConverter() => new TestBeatmapConverter(); - protected override Playfield CreatePlayfield() => new TestPlayfield(scrollingAxes); + protected override Playfield CreatePlayfield() => new TestPlayfield(scrollingAxes); - protected override DrawableHitObject GetVisualRepresentation(TestHitObject h) => new DrawableTestHitObject(scrollingAxes, h); + protected override DrawableHitObject GetVisualRepresentation(TestHitObject h) => new DrawableTestHitObject(scrollingAxes, h); } - private class TestScoreProcessor : ScoreProcessor + private class TestScoreProcessor : ScoreProcessor { protected override void OnNewJudgement(Judgement judgement) { @@ -169,7 +169,7 @@ namespace osu.Desktop.Tests.Visual } } - private class DrawableTestHitObject : DrawableScrollingHitObject + private class DrawableTestHitObject : DrawableScrollingHitObject { public DrawableTestHitObject(Axes scrollingAxes, TestHitObject hitObject) : base(hitObject) @@ -185,14 +185,12 @@ namespace osu.Desktop.Tests.Visual }); } - protected TestJudgement CreateJudgement() => new TestJudgement(); - protected override void UpdateState(ArmedState state) { } } - private class TestPlayfield : ScrollingPlayfield + private class TestPlayfield : ScrollingPlayfield { protected override Container Content => content; private readonly Container content; @@ -218,9 +216,5 @@ namespace osu.Desktop.Tests.Visual private class TestHitObject : HitObject { } - - private class TestJudgement : Judgement - { - } } } diff --git a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs index 0bfa21a45e..764cf7a1f8 100644 --- a/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseTaikoPlayfield.cs @@ -214,15 +214,13 @@ namespace osu.Desktop.Tests.Visual rulesetContainer.Playfield.Add(new DrawableRimHit(h)); } - private class DrawableTestHit : DrawableHitObject + private class DrawableTestHit : DrawableHitObject { public DrawableTestHit(TaikoHitObject hitObject) : base(hitObject) { } - protected TaikoJudgement CreateJudgement() => new TaikoJudgement(); - protected override void UpdateState(ArmedState state) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 0cbece5544..3dd086fb48 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.MathUtils; using osu.Game.Graphics; -using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using OpenTK; @@ -17,7 +16,7 @@ using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { - public class DrawableFruit : DrawableScrollingHitObject + public class DrawableFruit : DrawableScrollingHitObject { private const float pulp_size = 30; diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 8a9e17de6e..2637a98fe2 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; @@ -9,13 +8,13 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Catch.Scoring { - internal class CatchScoreProcessor : ScoreProcessor + internal class CatchScoreProcessor : ScoreProcessor { public CatchScoreProcessor() { } - public CatchScoreProcessor(RulesetContainer rulesetContainer) + public CatchScoreProcessor(RulesetContainer rulesetContainer) : base(rulesetContainer) { } diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index cf00f80e5e..83d22454cb 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -5,7 +5,6 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.UI; using OpenTK; -using osu.Game.Rulesets.Catch.Judgements; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Judgements; @@ -13,7 +12,7 @@ using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.UI { - public class CatchPlayfield : ScrollingPlayfield + public class CatchPlayfield : ScrollingPlayfield { protected override Container Content => content; private readonly Container content; @@ -45,7 +44,7 @@ namespace osu.Game.Rulesets.Catch.UI }; } - public override void Add(DrawableHitObject h) + public override void Add(DrawableHitObject h) { base.Add(h); diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index f8f74af6c9..eb7abf9248 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -5,7 +5,6 @@ using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Rulesets.Beatmaps; using osu.Game.Rulesets.Catch.Beatmaps; -using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Catch.Scoring; @@ -15,7 +14,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Catch.UI { - public class CatchRulesetContainer : ScrollingRulesetContainer + public class CatchRulesetContainer : ScrollingRulesetContainer { public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) : base(ruleset, beatmap, isForCurrentRuleset) @@ -26,11 +25,11 @@ namespace osu.Game.Rulesets.Catch.UI protected override BeatmapConverter CreateBeatmapConverter() => new CatchBeatmapConverter(); - protected override Playfield CreatePlayfield() => new CatchPlayfield(); + protected override Playfield CreatePlayfield() => new CatchPlayfield(); public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo); - protected override DrawableHitObject GetVisualRepresentation(CatchBaseHit h) + protected override DrawableHitObject GetVisualRepresentation(CatchBaseHit h) { if (h is Fruit) return new DrawableFruit(h); diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index 9b8234ea13..5b57be1499 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -2,12 +2,11 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK.Graphics; -using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Mania.Objects.Drawables { - public abstract class DrawableManiaHitObject : DrawableScrollingHitObject + public abstract class DrawableManiaHitObject : DrawableScrollingHitObject where TObject : ManiaHitObject { /// diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index c30c20402a..9ea9dc90fa 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mania.Scoring { - internal class ManiaScoreProcessor : ScoreProcessor + internal class ManiaScoreProcessor : ScoreProcessor { /// /// The maximum score achievable. @@ -156,7 +156,7 @@ namespace osu.Game.Rulesets.Mania.Scoring { } - public ManiaScoreProcessor(RulesetContainer rulesetContainer) + public ManiaScoreProcessor(RulesetContainer rulesetContainer) : base(rulesetContainer) { } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index a8f5b4919d..ce4a84dc80 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -14,11 +14,10 @@ using System; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.Mania.Objects; -using osu.Game.Rulesets.Mania.Judgements; namespace osu.Game.Rulesets.Mania.UI { - public class Column : ScrollingPlayfield, IHasAccentColour + public class Column : ScrollingPlayfield, IHasAccentColour { private const float key_icon_size = 10; private const float key_icon_corner_radius = 3; @@ -188,7 +187,7 @@ namespace osu.Game.Rulesets.Mania.UI /// Adds a DrawableHitObject to this Playfield. /// /// The DrawableHitObject to add. - public override void Add(DrawableHitObject hitObject) + public override void Add(DrawableHitObject hitObject) { hitObject.AccentColour = AccentColour; HitObjects.Add(hitObject); diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index d3dc920fc6..15f65b5545 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -6,7 +6,6 @@ using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.UI; using OpenTK; using OpenTK.Graphics; -using osu.Game.Rulesets.Mania.Judgements; using osu.Framework.Graphics.Containers; using System; using osu.Game.Graphics; @@ -21,7 +20,7 @@ using osu.Framework.Graphics.Shapes; namespace osu.Game.Rulesets.Mania.UI { - public class ManiaPlayfield : ScrollingPlayfield + public class ManiaPlayfield : ScrollingPlayfield { public const float HIT_TARGET_POSITION = 50; @@ -203,7 +202,7 @@ namespace osu.Game.Rulesets.Mania.UI } } - public override void Add(DrawableHitObject h) => Columns.ElementAt(h.HitObject.Column).Add(h); + public override void Add(DrawableHitObject h) => Columns.ElementAt(h.HitObject.Column).Add(h); public void Add(DrawableBarLine barline) => HitObjects.Add(barline); protected override void Update() diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 5a3da6d074..49e53a07c9 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -15,7 +15,6 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps; -using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Scoring; @@ -28,7 +27,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mania.UI { - public class ManiaRulesetContainer : ScrollingRulesetContainer + public class ManiaRulesetContainer : ScrollingRulesetContainer { /// /// The number of columns which the should display, and which @@ -75,7 +74,7 @@ namespace osu.Game.Rulesets.Mania.UI BarLines.ForEach(Playfield.Add); } - protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(availableColumns) + protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(availableColumns) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -105,7 +104,7 @@ namespace osu.Game.Rulesets.Mania.UI return new ManiaBeatmapConverter(IsForCurrentRuleset, availableColumns); } - protected override DrawableHitObject GetVisualRepresentation(ManiaHitObject h) + protected override DrawableHitObject GetVisualRepresentation(ManiaHitObject h) { ManiaAction action = Playfield.Columns.ElementAt(h.Column).Action; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 9faecadbf1..d18b3dd65e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -3,13 +3,12 @@ using System.ComponentModel; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Osu.Judgements; using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableOsuHitObject : DrawableHitObject + public class DrawableOsuHitObject : DrawableHitObject { public const float TIME_PREEMPT = 600; public const float TIME_FADEIN = 400; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs index 0cd30e34ac..7755a54e88 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Judgements; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableOsuJudgement : DrawableJudgement + public class DrawableOsuJudgement : DrawableJudgement { public DrawableOsuJudgement(OsuJudgement judgement) : base(judgement) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index b6922cbf3b..59d4492480 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -16,7 +16,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Scoring { - internal class OsuScoreProcessor : ScoreProcessor + internal class OsuScoreProcessor : ScoreProcessor { public readonly Bindable Mode = new Bindable(ScoringMode.Exponential); @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Scoring { } - public OsuScoreProcessor(RulesetContainer rulesetContainer) + public OsuScoreProcessor(RulesetContainer rulesetContainer) : base(rulesetContainer) { } diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 6b367b8be2..e9d9e0e3de 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -16,7 +16,7 @@ using osu.Game.Rulesets.Osu.UI.Cursor; namespace osu.Game.Rulesets.Osu.UI { - public class OsuPlayfield : Playfield + public class OsuPlayfield : Playfield { private readonly Container approachCircles; private readonly Container judgementLayer; @@ -68,11 +68,11 @@ namespace osu.Game.Rulesets.Osu.UI AddInternal(new GameplayCursor()); } - public override void Add(DrawableHitObject h) + public override void Add(DrawableHitObject h) { h.Depth = (float)h.HitObject.StartTime; - IDrawableHitObjectWithProxiedApproach c = h as IDrawableHitObjectWithProxiedApproach; + var c = h as IDrawableHitObjectWithProxiedApproach; if (c != null) approachCircles.Add(c.ProxiedLayer.CreateProxy()); diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs index 0b87bf7346..edf7e014a3 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs @@ -7,7 +7,6 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Beatmaps; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Beatmaps; -using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Replays; @@ -18,7 +17,7 @@ using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Osu.UI { - public class OsuRulesetContainer : RulesetContainer + public class OsuRulesetContainer : RulesetContainer { public OsuRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) : base(ruleset, beatmap, isForCurrentRuleset) @@ -31,11 +30,11 @@ namespace osu.Game.Rulesets.Osu.UI protected override BeatmapProcessor CreateBeatmapProcessor() => new OsuBeatmapProcessor(); - protected override Playfield CreatePlayfield() => new OsuPlayfield(); + protected override Playfield CreatePlayfield() => new OsuPlayfield(); public override PassThroughInputManager CreateInputManager() => new OsuInputManager(Ruleset.RulesetInfo); - protected override DrawableHitObject GetVisualRepresentation(OsuHitObject h) + protected override DrawableHitObject GetVisualRepresentation(OsuHitObject h) { var circle = h as HitCircle; if (circle != null) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index 9a25de713a..b30b3a1aca 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -5,14 +5,13 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using OpenTK; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Taiko.Judgements; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { /// /// A line that scrolls alongside hit objects in the playfield and visualises control points. /// - public class DrawableBarLine : DrawableScrollingHitObject + public class DrawableBarLine : DrawableScrollingHitObject { /// /// The width of the line tracker. diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index e3ddefd05d..7976cbbbc1 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -4,15 +4,13 @@ using osu.Framework.Graphics; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using OpenTK; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public abstract class DrawableTaikoHitObject - : DrawableScrollingHitObject, IKeyBindingHandler - where TaikoHitType : TaikoHitObject + public abstract class DrawableTaikoHitObject : DrawableScrollingHitObject, IKeyBindingHandler + where TaikoHitType : TaikoHitObject { public override Vector2 OriginPosition => new Vector2(DrawHeight / 2); diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index ca3dcc8984..21d790169c 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -13,7 +13,7 @@ using OpenTK; namespace osu.Game.Rulesets.Taiko.Scoring { - internal class TaikoScoreProcessor : ScoreProcessor + internal class TaikoScoreProcessor : ScoreProcessor { /// /// The maximum score achievable. @@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring { } - public TaikoScoreProcessor(RulesetContainer rulesetContainer) + public TaikoScoreProcessor(RulesetContainer rulesetContainer) : base(rulesetContainer) { } diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs index ea9c59c2a5..fb64b667e6 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Allocation; using osu.Game.Graphics; @@ -13,7 +12,7 @@ namespace osu.Game.Rulesets.Taiko.UI /// /// Text that is shown as judgement when a hit object is hit or missed. /// - public class DrawableTaikoJudgement : DrawableJudgement + public class DrawableTaikoJudgement : DrawableJudgement { public readonly DrawableHitObject JudgedObject; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 1fce2b3a48..96ca4c10eb 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -19,7 +19,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.UI { - public class TaikoPlayfield : ScrollingPlayfield + public class TaikoPlayfield : ScrollingPlayfield { /// /// Default height of a when inside a . @@ -203,7 +203,7 @@ namespace osu.Game.Rulesets.Taiko.UI background.Colour = colours.Gray0; } - public override void Add(DrawableHitObject h) + public override void Add(DrawableHitObject h) { h.Depth = (float)h.HitObject.StartTime; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index 96e5df12cd..ccb6531b00 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -9,7 +9,6 @@ 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.Judgements; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Game.Rulesets.Taiko.Scoring; @@ -22,7 +21,7 @@ using osu.Framework.Input; namespace osu.Game.Rulesets.Taiko.UI { - public class TaikoRulesetContainer : ScrollingRulesetContainer + public class TaikoRulesetContainer : ScrollingRulesetContainer { public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset) : base(ruleset, beatmap, isForCurrentRuleset) @@ -95,13 +94,13 @@ namespace osu.Game.Rulesets.Taiko.UI public override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo); - protected override Playfield CreatePlayfield() => new TaikoPlayfield + protected override Playfield CreatePlayfield() => new TaikoPlayfield { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft }; - protected override DrawableHitObject GetVisualRepresentation(TaikoHitObject h) + protected override DrawableHitObject GetVisualRepresentation(TaikoHitObject h) { var centreHit = h as CentreHit; if (centreHit != null) diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index 795acdc0cf..12edfd802a 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -16,9 +16,7 @@ namespace osu.Game.Rulesets.Judgements /// /// A drawable object which visualises the hit result of a . /// - /// The type of judgement to visualise. - public class DrawableJudgement : Container - where TJudgement : Judgement + public class DrawableJudgement : Container { protected readonly Judgement Judgement; diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 836113b017..90f6a0ad04 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -32,24 +32,12 @@ namespace osu.Game.Rulesets.Objects.Drawables public abstract class DrawableHitObject : DrawableHitObject where TObject : HitObject - { - public new readonly TObject HitObject; - - protected DrawableHitObject(TObject hitObject) - : base(hitObject) - { - HitObject = hitObject; - } - } - - public abstract class DrawableHitObject : DrawableHitObject - where TObject : HitObject - where TJudgement : Judgement { public event Action OnJudgement; - public override bool HandleInput => Interactive; + public new readonly TObject HitObject; + public override bool HandleInput => Interactive; public bool Interactive = true; /// @@ -65,6 +53,7 @@ namespace osu.Game.Rulesets.Objects.Drawables protected DrawableHitObject(TObject hitObject) : base(hitObject) { + HitObject = hitObject; } private ArmedState state; @@ -202,13 +191,13 @@ namespace osu.Game.Rulesets.Objects.Drawables } } - private List> nestedHitObjects; - protected IEnumerable> NestedHitObjects => nestedHitObjects; + private List> nestedHitObjects; + protected IEnumerable> NestedHitObjects => nestedHitObjects; - protected virtual void AddNested(DrawableHitObject h) + protected virtual void AddNested(DrawableHitObject h) { if (nestedHitObjects == null) - nestedHitObjects = new List>(); + nestedHitObjects = new List>(); h.OnJudgement += (d, j) => OnJudgement?.Invoke(d, j); nestedHitObjects.Add(h); diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs index a7c4dd0333..5ba9c2ff4d 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs @@ -3,19 +3,17 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Objects.Drawables { /// - /// A basic class that overrides and implements . + /// A basic class that overrides and implements . /// This object does not need to have its set to be able to scroll, as this will /// will be set by the scrolling container that contains it. /// - public abstract class DrawableScrollingHitObject : DrawableHitObject, IScrollingHitObject + public abstract class DrawableScrollingHitObject : DrawableHitObject, IScrollingHitObject where TObject : HitObject - where TJudgement : Judgement { public BindableDouble LifetimeOffset { get; } = new BindableDouble(); @@ -57,7 +55,7 @@ namespace osu.Game.Rulesets.Objects.Drawables set { lifetimeEnd = value; } } - protected override void AddNested(DrawableHitObject h) + protected override void AddNested(DrawableHitObject h) { var scrollingHitObject = h as IScrollingHitObject; scrollingHitObject?.LifetimeOffset.BindTo(LifetimeOffset); diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index aea7e40df4..2ca733d82a 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -135,9 +135,8 @@ namespace osu.Game.Rulesets.Scoring } } - public abstract class ScoreProcessor : ScoreProcessor + public abstract class ScoreProcessor : ScoreProcessor where TObject : HitObject - where TJudgement : Judgement { /// /// All judgements held by this ScoreProcessor. @@ -150,7 +149,7 @@ namespace osu.Game.Rulesets.Scoring { } - protected ScoreProcessor(RulesetContainer rulesetContainer) + protected ScoreProcessor(RulesetContainer rulesetContainer) { Judgements.Capacity = rulesetContainer.Beatmap.HitObjects.Count; diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index ba526e2178..ce800b76b1 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -14,9 +14,8 @@ using System.Linq; namespace osu.Game.Rulesets.UI { - public abstract class Playfield : Container + public abstract class Playfield : Container where TObject : HitObject - where TJudgement : Judgement { /// /// The HitObjects contained in this Playfield. @@ -70,7 +69,7 @@ namespace osu.Game.Rulesets.UI public override Axes RelativeSizeAxes { get { return Axes.Both; } - set { throw new InvalidOperationException($@"{nameof(Playfield)}'s {nameof(RelativeSizeAxes)} should never be changed from {Axes.Both}"); } + set { throw new InvalidOperationException($@"{nameof(Playfield)}'s {nameof(RelativeSizeAxes)} should never be changed from {Axes.Both}"); } } /// @@ -82,18 +81,19 @@ namespace osu.Game.Rulesets.UI /// Adds a DrawableHitObject to this Playfield. /// /// The DrawableHitObject to add. - public virtual void Add(DrawableHitObject h) => HitObjects.Add(h); + public virtual void Add(DrawableHitObject h) => HitObjects.Add(h); /// /// Remove a DrawableHitObject from this Playfield. /// /// The DrawableHitObject to remove. - public virtual void Remove(DrawableHitObject h) => HitObjects.Remove(h); + public virtual void Remove(DrawableHitObject h) => HitObjects.Remove(h); /// - /// Triggered when an object's Judgement is updated. + /// Triggered when a new occurs on a . /// - /// The object that Judgement has been updated for. + /// The object that occured for. + /// The that occurred. public virtual void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { } public class HitObjectContainer : CompositeDrawable diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index d87e47794f..9503ac1e0b 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.UI /// /// Base RulesetContainer. Doesn't hold objects. /// - /// Should not be derived - derive instead. + /// Should not be derived - derive instead. /// /// public abstract class RulesetContainer : Container @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.UI public event Action OnAllJudged; /// - /// Whether to apply adjustments to the child based on our own size. + /// Whether to apply adjustments to the child based on our own size. /// public bool AspectAdjust = true; @@ -119,13 +119,15 @@ namespace osu.Game.Rulesets.UI /// RulesetContainer that applies conversion to Beatmaps. Does not contain a Playfield /// and does not load drawable hit objects. /// - /// Should not be derived - derive instead. + /// Should not be derived - derive instead. /// /// /// The type of HitObject contained by this RulesetContainer. public abstract class RulesetContainer : RulesetContainer where TObject : HitObject { + public event Action OnJudgement; + /// /// The Beatmap /// @@ -151,6 +153,20 @@ namespace osu.Game.Rulesets.UI /// protected readonly bool IsForCurrentRuleset; + public sealed override bool ProvidingUserCursor => !HasReplayLoaded && Playfield.ProvidingUserCursor; + + protected override bool AllObjectsJudged => drawableObjects.All(h => h.AllJudged); + + /// + /// The playfield. + /// + public Playfield Playfield { get; private set; } + + protected override Container Content => content; + private Container content; + + private readonly List> drawableObjects = new List>(); + /// /// Whether to assume the beatmap passed into this is for the current ruleset. /// Creates a hit renderer for a beatmap. @@ -158,7 +174,7 @@ 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. - internal RulesetContainer(Ruleset ruleset, WorkingBeatmap workingBeatmap, bool isForCurrentRuleset) + protected RulesetContainer(Ruleset ruleset, WorkingBeatmap workingBeatmap, bool isForCurrentRuleset) : base(ruleset) { Debug.Assert(workingBeatmap != null, "RulesetContainer initialized with a null beatmap."); @@ -194,74 +210,6 @@ namespace osu.Game.Rulesets.UI applyMods(Mods); } - /// - /// Applies the active mods to this RulesetContainer. - /// - /// - private void applyMods(IEnumerable mods) - { - if (mods == null) - return; - - foreach (var mod in mods.OfType>()) - mod.ApplyToRulesetContainer(this); - } - - /// - /// Creates a processor to perform post-processing operations - /// on HitObjects in converted Beatmaps. - /// - /// The Beatmap processor. - protected virtual BeatmapProcessor CreateBeatmapProcessor() => new BeatmapProcessor(); - - /// - /// Creates a converter to convert Beatmap to a specific mode. - /// - /// The Beatmap converter. - protected abstract BeatmapConverter CreateBeatmapConverter(); - } - - /// - /// A derivable RulesetContainer that manages the Playfield and HitObjects. - /// - /// The type of HitObject contained by this RulesetContainer. - /// The type of Judgement of DrawableHitObjects contained by this RulesetContainer. - public abstract class RulesetContainer : RulesetContainer - where TObject : HitObject - where TJudgement : Judgement - { - public event Action OnJudgement; - - public sealed override bool ProvidingUserCursor => !HasReplayLoaded && Playfield.ProvidingUserCursor; - - /// - /// All the converted hit objects contained by this hit renderer. - /// - public new IEnumerable Objects => Beatmap.HitObjects; - - protected override bool AllObjectsJudged => drawableObjects.All(h => h.AllJudged); - - /// - /// The playfield. - /// - public Playfield Playfield { get; private set; } - - protected override Container Content => content; - private Container content; - - private readonly List> drawableObjects = new List>(); - - /// - /// Creates a hit renderer for a beatmap. - /// - /// 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) - { - } - [BackgroundDependencyLoader] private void load() { @@ -276,6 +224,19 @@ namespace osu.Game.Rulesets.UI loadObjects(); } + /// + /// Applies the active mods to this RulesetContainer. + /// + /// + private void applyMods(IEnumerable mods) + { + if (mods == null) + return; + + foreach (var mod in mods.OfType>()) + mod.ApplyToRulesetContainer(this); + } + public override void SetReplay(Replay replay) { base.SetReplay(replay); @@ -320,23 +281,36 @@ namespace osu.Game.Rulesets.UI } /// - /// In some cases we want to apply changes to the relative size of our contained based on custom conditions. + /// Creates a processor to perform post-processing operations + /// on HitObjects in converted Beatmaps. + /// + /// The Beatmap processor. + protected virtual BeatmapProcessor CreateBeatmapProcessor() => new BeatmapProcessor(); + + /// + /// In some cases we want to apply changes to the relative size of our contained based on custom conditions. /// /// protected virtual Vector2 GetPlayfieldAspectAdjust() => 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. /// /// The HitObject to make drawable. /// The DrawableHitObject. - protected abstract DrawableHitObject GetVisualRepresentation(TObject h); + protected abstract DrawableHitObject GetVisualRepresentation(TObject h); /// /// Creates a Playfield. /// /// The Playfield. - protected abstract Playfield CreatePlayfield(); + protected abstract Playfield CreatePlayfield(); } /// @@ -344,11 +318,9 @@ namespace osu.Game.Rulesets.UI /// /// The type of Playfield contained by this RulesetContainer. /// The type of HitObject contained by this RulesetContainer. - /// The type of Judgement of DrawableHitObjects contained by this RulesetContainer. - public abstract class RulesetContainer : RulesetContainer + public abstract class RulesetContainer : RulesetContainer where TObject : HitObject - where TJudgement : Judgement - where TPlayfield : Playfield + where TPlayfield : Playfield { /// /// The playfield. diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 1d13e2abb1..2162d650db 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Transforms; using osu.Framework.Input; using osu.Framework.MathUtils; -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; @@ -19,11 +18,10 @@ using osu.Game.Rulesets.Timing; namespace osu.Game.Rulesets.UI { /// - /// A type of specialized towards scrolling s. + /// A type of specialized towards scrolling s. /// - public class ScrollingPlayfield : Playfield + public class ScrollingPlayfield : Playfield where TObject : HitObject - where TJudgement : Judgement { /// /// The default span of time visible by the length of the scrolling axes. @@ -65,7 +63,7 @@ namespace osu.Game.Rulesets.UI public new readonly ScrollingHitObjectContainer HitObjects; /// - /// Creates a new . + /// Creates a new . /// /// The axes on which s in this container should scroll. /// Whether we want our internal coordinate system to be scaled to a specified width @@ -77,21 +75,21 @@ namespace osu.Game.Rulesets.UI HitObjects.Reversed.BindTo(Reversed); } - private List> nestedPlayfields; + private List> nestedPlayfields; /// - /// All the s nested inside this playfield. + /// All the s nested inside this playfield. /// - public IEnumerable> NestedPlayfields => nestedPlayfields; + public IEnumerable> NestedPlayfields => nestedPlayfields; /// - /// Adds a to this playfield. The nested + /// Adds a to this playfield. The nested /// will be given all of the same speed adjustments as this playfield. /// - /// The to add. - protected void AddNested(ScrollingPlayfield otherPlayfield) + /// The to add. + protected void AddNested(ScrollingPlayfield otherPlayfield) { if (nestedPlayfields == null) - nestedPlayfields = new List>(); + nestedPlayfields = new List>(); nestedPlayfields.Add(otherPlayfield); } @@ -119,7 +117,7 @@ namespace osu.Game.Rulesets.UI this.TransformTo(this.PopulateTransform(new TransformVisibleTimeRange(), newTimeRange, duration, easing)); } - private class TransformVisibleTimeRange : Transform> + private class TransformVisibleTimeRange : Transform> { private double valueAt(double time) { @@ -131,8 +129,8 @@ namespace osu.Game.Rulesets.UI 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; + protected override void Apply(ScrollingPlayfield d, double time) => d.VisibleTimeRange.Value = valueAt(time); + protected override void ReadIntoStartValue(ScrollingPlayfield d) => StartValue = d.VisibleTimeRange.Value; } /// diff --git a/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs b/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs index ff156f788c..c199c90f4a 100644 --- a/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs +++ b/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs @@ -9,7 +9,6 @@ using osu.Framework.Lists; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.IO.Serialization; -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Timing; @@ -17,17 +16,16 @@ using osu.Game.Rulesets.Timing; namespace osu.Game.Rulesets.UI { /// - /// A type of that supports a . - /// s inside this will scroll within the playfield. + /// A type of that supports a . + /// s inside this will scroll within the playfield. /// - public abstract class ScrollingRulesetContainer : RulesetContainer + public abstract class ScrollingRulesetContainer : RulesetContainer where TObject : HitObject - where TJudgement : Judgement - where TPlayfield : ScrollingPlayfield + where TPlayfield : ScrollingPlayfield { /// /// Provides the default s that adjust the scrolling rate of s - /// inside this . + /// inside this . /// /// protected readonly SortedList DefaultControlPoints = new SortedList(Comparer.Default); @@ -88,7 +86,7 @@ namespace osu.Game.Rulesets.UI DefaultControlPoints.ForEach(c => applySpeedAdjustment(c, Playfield)); } - private void applySpeedAdjustment(MultiplierControlPoint controlPoint, ScrollingPlayfield playfield) + private void applySpeedAdjustment(MultiplierControlPoint controlPoint, ScrollingPlayfield playfield) { playfield.HitObjects.AddSpeedAdjustment(CreateSpeedAdjustmentContainer(controlPoint)); playfield.NestedPlayfields.ForEach(p => applySpeedAdjustment(controlPoint, p)); From 4f4b0a1f351bca177c094a190e274e5ed50cc72d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 20:26:01 +0900 Subject: [PATCH 288/483] Allow posting to chat in all channels --- osu.Game/Online/Chat/Channel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index bec4aadb18..77683ae857 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -30,7 +30,7 @@ namespace osu.Game.Online.Chat public Bindable Joined = new Bindable(); - public bool ReadOnly => Name != "#lazer"; + public bool ReadOnly => false; public const int MAX_HISTORY = 300; From e834e0e9580aa3762812be9ac29e6a6be1e959d2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 21:07:53 +0900 Subject: [PATCH 289/483] Fix incorrect initialisation order causing mania key bindings to not work --- osu.Game/Rulesets/UI/RulesetContainer.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index a7472f4dbc..e2701faca0 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -75,7 +75,11 @@ namespace osu.Game.Rulesets.UI internal RulesetContainer(Ruleset ruleset) { Ruleset = ruleset; + } + [BackgroundDependencyLoader] + private void load() + { KeyBindingInputManager = CreateInputManager(); KeyBindingInputManager.RelativeSizeAxes = Axes.Both; } From 06fac913bfe5c03e479fca450a5f45ac0ad006cf Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 6 Sep 2017 21:14:29 +0900 Subject: [PATCH 290/483] Re-implement EditorMenuBar. --- osu-framework | 2 +- osu.Game/Graphics/UserInterface/OsuMenu.cs | 6 +- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 160 +++++++++---------- 3 files changed, 83 insertions(+), 85 deletions(-) diff --git a/osu-framework b/osu-framework index 3edf658577..3e91706ad5 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 3edf65857759f32d5a6d07ed523a2892b09c3c6a +Subproject commit 3e91706ad54609c9477588730b5de7db9d1311f8 diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index 3c9b9797ba..4e23a8939d 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -46,6 +46,11 @@ namespace osu.Game.Graphics.UserInterface protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuMenuItem(item); + protected override Menu CreateSubMenu() => new OsuMenu(Direction.Vertical) + { + Anchor = Direction == Direction.Horizontal ? Anchor.BottomLeft : Anchor.TopRight + }; + protected class DrawableOsuMenuItem : DrawableMenuItem { private const int margin_horizontal = 17; @@ -61,7 +66,6 @@ namespace osu.Game.Graphics.UserInterface public DrawableOsuMenuItem(MenuItem item) : base(item) { - } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 9fd8669922..15610fcebd 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -5,125 +5,119 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using OpenTK; using OpenTK.Graphics; namespace osu.Game.Screens.Edit.Menus { - public class EditorMenuBar : MenuBar + public class EditorMenuBar : OsuMenu { - protected override DrawableMenuBarItem CreateDrawableMenuBarItem(MenuItem item) => new DrawableEditorMenuBarItem(item); - - private class DrawableEditorMenuBarItem : DrawableMenuBarItem + public EditorMenuBar() + : base(Direction.Horizontal) { - private const int fade_duration = 250; - private const float text_size = 14; + AlwaysOpen = true; + RequireClickToOpen = true; - private readonly Container background; + ItemsContainer.Padding = new MarginPadding(0); + BackgroundColour = Color4.Transparent; + } - private Color4 normalColour; + protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu(); - public DrawableEditorMenuBarItem(MenuItem item) + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorBarMenuItem(item); + + private class DrawableEditorBarMenuItem : DrawableOsuMenuItem + { + private Color4 openedForegroundColour; + private Color4 openedBackgroundColour; + + public DrawableEditorBarMenuItem(MenuItem item) : base(item) { - Text.Padding = new MarginPadding(8); - - AddInternal(background = new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Depth = float.MaxValue, - Alpha = 0, - Child = new Container - { - // The following is done so we can have top rounded corners but not bottom corners - RelativeSizeAxes = Axes.Both, - Height = 2, - Masking = true, - CornerRadius = 5, - Child = new Box { RelativeSizeAxes = Axes.Both } - } - }); - - Menu.OnOpen += menuOpen; - Menu.OnClose += menuClose; } [BackgroundDependencyLoader] private void load(OsuColour colours) { - background.Colour = colours.Gray3; - Text.Colour = normalColour = colours.BlueLight; + ForegroundColour = ForegroundColourHover = colours.BlueLight; + BackgroundColour = BackgroundColourHover = Color4.Transparent; + openedForegroundColour = Color4.White; + openedBackgroundColour = colours.Gray3; } - private void menuOpen() + protected override void UpdateBackgroundColour() { - background.FadeIn(fade_duration, Easing.OutQuint); - Text.FadeColour(Color4.White, fade_duration, Easing.OutQuint); + if (State == MenuItemState.Selected) + Background.FadeColour(openedBackgroundColour); + else + base.UpdateBackgroundColour(); } - private void menuClose() + protected override void UpdateForegroundColour() { - background.FadeOut(fade_duration, Easing.OutQuint); - Text.FadeColour(normalColour, fade_duration, Easing.OutQuint); + if (State == MenuItemState.Selected) + Foreground.FadeColour(openedForegroundColour); + else + base.UpdateForegroundColour(); } - protected override SpriteText CreateText() => new OsuSpriteText { TextSize = text_size }; - - protected override Framework.Graphics.UserInterface.Menu CreateMenu() => new EditorMenu(); - - private class EditorMenu : OsuMenu + protected override Drawable CreateBackground() => new Container { - public EditorMenu() + RelativeSizeAxes = Axes.Both, + Masking = true, + Child = new Container + { + RelativeSizeAxes = Axes.Both, + Height = 2, + Masking = true, + CornerRadius = 4, + Child = new Box { RelativeSizeAxes = Axes.Both } + } + }; + } + + private class SubMenu : OsuMenu + { + public SubMenu() + : base(Direction.Vertical) + { + OriginPosition = new Vector2(5, 1); + ItemsContainer.Padding = new MarginPadding { Top = 5, Bottom = 5 }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + BackgroundColour = colours.Gray3; + } + + protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu(); + + protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableSubMenuItem(item); + + private class DrawableSubMenuItem : DrawableOsuMenuItem + { + public DrawableSubMenuItem(MenuItem item) + : base(item) { - Anchor = Anchor.BottomLeft; - BypassAutoSizeAxes = Axes.Both; - OriginPosition = new Vector2(8, 0); } - [BackgroundDependencyLoader] - private void load(OsuColour colours) + protected override bool OnHover(InputState state) { - BackgroundColour = colours.Gray3; + if (Item is EditorMenuSpacer) + return true; + return base.OnHover(state); } - protected override MarginPadding ItemFlowContainerPadding => new MarginPadding { Top = 5, Bottom = 5 }; - - protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorMenuItem(item); - - private class DrawableEditorMenuItem : DrawableOsuMenuItem + protected override bool OnClick(InputState state) { - public override bool HandleInput => !isSpacer; - private readonly bool isSpacer; - - public DrawableEditorMenuItem(MenuItem item) - : base(item) - { - isSpacer = item is EditorMenuSpacer; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - BackgroundColour = colours.Gray3; - BackgroundColourHover = colours.Gray2; - } - - protected override TextContainer CreateTextContainer() => new EditorTextContainer(); - - private class EditorTextContainer : TextContainer - { - public EditorTextContainer() - { - BoldText.TextSize = text_size; - NormalText.TextSize = text_size; - } - } + if (Item is EditorMenuSpacer) + return true; + return base.OnClick(state); } } } From f70b4839bd80834720e2d205f097d014ec30bfb8 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 6 Sep 2017 21:22:23 +0900 Subject: [PATCH 291/483] Remove a few unnecessary attributes in OsuTestCase. --- osu.Desktop.Tests/Visual/OsuTestCase.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Desktop.Tests/Visual/OsuTestCase.cs b/osu.Desktop.Tests/Visual/OsuTestCase.cs index e366aecb21..1b48ded4e2 100644 --- a/osu.Desktop.Tests/Visual/OsuTestCase.cs +++ b/osu.Desktop.Tests/Visual/OsuTestCase.cs @@ -1,17 +1,14 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using NUnit.Framework; using osu.Framework.Desktop.Platform; using osu.Framework.Testing; using osu.Game; namespace osu.Desktop.Tests.Visual { - [TestFixture] public abstract class OsuTestCase : TestCase { - [Test] public override void RunTest() { using (var host = new HeadlessGameHost(realtime: false)) From 940c45b6d199fafcec8f440a9c68ae93746eb361 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 21:43:20 +0900 Subject: [PATCH 292/483] Fix visual styling and code styling --- osu.Game/Overlays/Chat/ChatTabControl.cs | 72 ++++++++++++++++++------ 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 5b65f7c036..6498761832 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -64,10 +64,10 @@ namespace osu.Game.Overlays.Chat protected override TabItem CreateTabItem(Channel value) { - ChannelTabItem tab = new ChannelTabItem(value); - tab.OnRequestClose = () => onTabClose(tab); + ChannelTabItem tab = new ChannelTabItem(value); + tab.OnRequestClose = () => onTabClose(tab); - return tab; + return tab; } protected override void SelectTab(TabItem tab) @@ -108,7 +108,7 @@ namespace osu.Game.Overlays.Chat private readonly SpriteText text; private readonly SpriteText textBold; - private readonly Button closeButton; + private readonly ClickableContainer closeButton; private readonly Box box; private readonly Box highlightBox; private readonly SpriteIcon icon; @@ -129,7 +129,6 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1.1f), transition_length, Easing.OutQuint); - closeButton.MoveToX(-5f, 0.5f, Easing.OutElastic); box.FadeColour(backgroundActive, transition_length, Easing.OutQuint); highlightBox.FadeIn(transition_length, Easing.OutQuint); @@ -141,7 +140,6 @@ namespace osu.Game.Overlays.Chat { this.ResizeTo(new Vector2(Width, 1), transition_length, Easing.OutQuint); - closeButton.MoveToX(5f, 0.5f, Easing.InElastic); box.FadeColour(backgroundInactive, transition_length, Easing.OutQuint); highlightBox.FadeOut(transition_length, Easing.OutQuint); @@ -152,7 +150,7 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(InputState state) { if (IsRemovable) - closeButton.FadeIn(1f, Easing.InBounce); + closeButton.FadeIn(200, Easing.OutQuint); if (!Active) box.FadeColour(backgroundHover, transition_length, Easing.OutQuint); @@ -161,9 +159,7 @@ namespace osu.Game.Overlays.Chat protected override void OnHoverLost(InputState state) { - if (closeButton.IsPresent) - closeButton.FadeOut(1f, Easing.OutBounce); - + closeButton.FadeOut(200, Easing.OutQuint); updateState(); } @@ -253,23 +249,65 @@ namespace osu.Game.Overlays.Chat Font = @"Exo2.0-Bold", TextSize = 18, }, - closeButton = new Button + closeButton = new CloseButton { Alpha = 0, - Width = 20, - Height = 20, - Margin = new MarginPadding { Right = 10 }, + Margin = new MarginPadding { Right = 20 }, Origin = Anchor.CentreRight, Anchor = Anchor.CentreRight, - Text = @"x", - BackgroundColour = Color4.Transparent, - Action = delegate { if (IsRemovable) OnRequestClose?.Invoke(); }, + Action = delegate + { + if (IsRemovable) OnRequestClose?.Invoke(); + }, }, }, }, }; } + public class CloseButton : ClickableContainer + { + private SpriteIcon icon; + + public CloseButton() + { + Size = new Vector2(20); + + Child = icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(0.75f), + Icon = FontAwesome.fa_close, + RelativeSizeAxes = Axes.Both, + }; + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + icon.ScaleTo(0.5f, 1000, Easing.OutQuint); + return base.OnMouseDown(state, args); + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + icon.ScaleTo(0.75f, 1000, Easing.OutElastic); + return base.OnMouseUp(state, args); + } + + protected override bool OnHover(InputState state) + { + icon.FadeColour(Color4.Red, 200, Easing.OutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + icon.FadeColour(Color4.White, 200, Easing.OutQuint); + base.OnHoverLost(state); + } + } + public class ChannelSelectorTabItem : ChannelTabItem { public override bool IsRemovable => false; From a7fa66b9f91b710ba9969757b6c6d21159879bc2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 22:41:03 +0900 Subject: [PATCH 293/483] Fix CI issue --- osu.Game/Overlays/Chat/ChatTabControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 6498761832..b68bdac3b3 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -267,7 +267,7 @@ namespace osu.Game.Overlays.Chat public class CloseButton : ClickableContainer { - private SpriteIcon icon; + private readonly SpriteIcon icon; public CloseButton() { From 4f49a0c18387f6c4d3d2f3ea124f9742c468d1bb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 22:58:21 +0900 Subject: [PATCH 294/483] Simplify action --- osu.Game/Overlays/Chat/ChatTabControl.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index b68bdac3b3..83c0c17bc2 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -62,13 +62,7 @@ namespace osu.Game.Overlays.Chat SelectTab(item); } - protected override TabItem CreateTabItem(Channel value) - { - ChannelTabItem tab = new ChannelTabItem(value); - tab.OnRequestClose = () => onTabClose(tab); - - return tab; - } + protected override TabItem CreateTabItem(Channel value) => new ChannelTabItem(value) { OnRequestClose = onTabClose }; protected override void SelectTab(TabItem tab) { @@ -113,7 +107,7 @@ namespace osu.Game.Overlays.Chat private readonly Box highlightBox; private readonly SpriteIcon icon; - public Action OnRequestClose; + public Action OnRequestClose; private void updateState() { @@ -257,7 +251,7 @@ namespace osu.Game.Overlays.Chat Anchor = Anchor.CentreRight, Action = delegate { - if (IsRemovable) OnRequestClose?.Invoke(); + if (IsRemovable) OnRequestClose?.Invoke(this); }, }, }, From da294c96051fa950a1634ac64daaa1adeeeda51e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 23:10:08 +0900 Subject: [PATCH 295/483] Don't use base call when we don't have to --- osu.Game/Overlays/Chat/ChatTabControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index 83c0c17bc2..ca195a7830 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Chat Margin = new MarginPadding(10), }); - base.AddTabItem(selectorTab = new ChannelTabItem.ChannelSelectorTabItem(new Channel { Name = "+" })); + AddTabItem(selectorTab = new ChannelTabItem.ChannelSelectorTabItem(new Channel { Name = "+" })); ChannelSelectorActive.BindTo(selectorTab.Active); } From e5308b624700cd77bb3f56e68cd844906cf15e6a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Sep 2017 23:12:32 +0900 Subject: [PATCH 296/483] Method rename --- osu.Game/Overlays/Chat/ChatTabControl.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index ca195a7830..9f1028c168 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Chat SelectTab(item); } - protected override TabItem CreateTabItem(Channel value) => new ChannelTabItem(value) { OnRequestClose = onTabClose }; + protected override TabItem CreateTabItem(Channel value) => new ChannelTabItem(value) { OnRequestClose = tabCloseRequested }; protected override void SelectTab(TabItem tab) { @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Chat base.SelectTab(tab); } - private void onTabClose(TabItem tab) + private void tabCloseRequested(TabItem tab) { int totalTabs = TabContainer.Count - 1; // account for selectorTab int currentIndex = MathHelper.Clamp(TabContainer.IndexOf(tab), 1, totalTabs); From 69ff4bfa46cc51aab72dd6e17260c376fb0704c6 Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 6 Sep 2017 20:04:21 +0530 Subject: [PATCH 297/483] Fix startup crash on mono. --- osu.Game/Graphics/UserInterface/OsuDropdown.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index b69186e8b0..f605804aaa 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -96,7 +96,7 @@ namespace osu.Game.Graphics.UserInterface protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuDropdownMenuItem(item) { AccentColour = accentColour }; #region DrawableOsuDropdownMenuItem - protected class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem, IHasAccentColour + public class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem, IHasAccentColour { private Color4? accentColour; public Color4 AccentColour From af0eaab78c49b667e94065701a5a53e2f20f04b7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Sep 2017 01:46:07 +0900 Subject: [PATCH 298/483] maybe fix --- osu.Game/Beatmaps/WorkingBeatmap.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 462f94ed7c..3793f20222 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -87,7 +87,9 @@ namespace osu.Game.Beatmaps { if (track != null) return track; - track = GetTrack(); + // we want to ensure that we always have a track, even if it's a fake one. + track = GetTrack() ?? new TrackVirtual(); + applyRateAdjustments(); return track; } From b98346c79feddd797cf6a6dc1718c27727a7bf5a Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 7 Sep 2017 15:32:28 +0900 Subject: [PATCH 299/483] Update framework. --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 3e91706ad5..23d1932eae 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 3e91706ad54609c9477588730b5de7db9d1311f8 +Subproject commit 23d1932eae87a871d65624eac3e6e8deb7e286c2 From ef9b87e8c7b32b0cdcedaf2b52280731a0efa5e4 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 7 Sep 2017 16:15:25 +0900 Subject: [PATCH 300/483] Make column lights not increase in brightness when successfully pressed --- osu.Game.Rulesets.Mania/UI/Column.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index a8f5b4919d..d5bc7cc659 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -198,7 +198,7 @@ namespace osu.Game.Rulesets.Mania.UI { if (action == Action) { - background.FadeTo(background.Alpha + 0.2f, 50, Easing.OutQuint); + background.FadeTo(0.6f, 50, Easing.OutQuint); keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint); } From b085208d247d9a78fb66d659321a3a6e46a5d1a7 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 7 Sep 2017 16:15:33 +0900 Subject: [PATCH 301/483] Remove unused code --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index d3dc920fc6..ce91fda023 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Containers; using System; using osu.Game.Graphics; using osu.Framework.Allocation; -using OpenTK.Input; using System.Linq; using System.Collections.Generic; using osu.Framework.Configuration; @@ -25,12 +24,6 @@ namespace osu.Game.Rulesets.Mania.UI { public const float HIT_TARGET_POSITION = 50; - /// - /// Default column keys, expanding outwards from the middle as more column are added. - /// E.g. 2 columns use FJ, 4 columns use DFJK, 6 use SDFJKL, etc... - /// - private static readonly Key[] default_keys = { Key.A, Key.S, Key.D, Key.F, Key.J, Key.K, Key.L, Key.Semicolon }; - private SpecialColumnPosition specialColumnPosition; /// /// The style to use for the special column. From 41398f57d65cfb8462f8e646c1453ef4e46b44e4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Sep 2017 20:36:32 +0900 Subject: [PATCH 302/483] Changes in line with framework --- osu.Game/Graphics/UserInterface/OsuMenu.cs | 4 ++-- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index 4e23a8939d..3fd5481152 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -18,8 +18,8 @@ namespace osu.Game.Graphics.UserInterface { public class OsuMenu : Menu { - public OsuMenu(Direction direction) - : base(direction) + public OsuMenu(Direction direction, bool topLevelMenu = false) + : base(direction, topLevelMenu) { BackgroundColour = Color4.Black.Opacity(0.5f); diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 15610fcebd..24625570a1 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -17,11 +17,8 @@ namespace osu.Game.Screens.Edit.Menus public class EditorMenuBar : OsuMenu { public EditorMenuBar() - : base(Direction.Horizontal) + : base(Direction.Horizontal, true) { - AlwaysOpen = true; - RequireClickToOpen = true; - ItemsContainer.Padding = new MarginPadding(0); BackgroundColour = Color4.Transparent; } From 19db7a8f721b07f9e8fb153449aa2eccc0e5ab94 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 7 Sep 2017 22:46:21 +0900 Subject: [PATCH 303/483] Update in line with framework changes. --- osu-framework | 2 +- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 2 +- .../Objects/Drawables/Connections/FollowPoint.cs | 2 +- .../Objects/Drawables/Pieces/CirclePiece.cs | 2 +- .../Objects/Drawables/Pieces/ExplodePiece.cs | 4 ++-- .../Objects/Drawables/Pieces/FlashPiece.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs | 2 +- .../Objects/Drawables/Pieces/SliderBall.cs | 2 +- .../Objects/Drawables/Pieces/SliderBody.cs | 2 +- .../Objects/Drawables/Pieces/SliderBouncer.cs | 2 +- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs | 4 ++-- .../Objects/Drawables/Pieces/CirclePiece.cs | 2 +- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 4 ++-- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 6 +++--- osu.Game/Graphics/Cursor/MenuCursor.cs | 2 +- osu.Game/Graphics/UserInterface/DialogButton.cs | 5 +++-- osu.Game/Graphics/UserInterface/OsuButton.cs | 2 +- osu.Game/Overlays/Settings/SidebarButton.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs | 2 +- osu.Game/Screens/Menu/Button.cs | 2 +- osu.Game/Screens/Menu/Intro.cs | 2 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 2 +- osu.Game/Screens/Menu/MenuSideFlashes.cs | 4 ++-- osu.Game/Screens/Menu/OsuLogo.cs | 4 ++-- osu.Game/Screens/ScreenWhiteBox.cs | 2 +- osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs | 2 +- osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs | 2 +- osu.sln.DotSettings | 1 + 29 files changed, 38 insertions(+), 36 deletions(-) diff --git a/osu-framework b/osu-framework index 14a33d110e..673e7f72c5 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 14a33d110e2ed32e3a875bc2acd2bade244ba045 +Subproject commit 673e7f72c572b51102f26468c7c8cb54e9a217c4 diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index f416f6acfb..0e7fbffbb6 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.Catch.UI var additive = createCatcherSprite(); additive.RelativePositionAxes = Axes.Both; - additive.BlendingMode = BlendingMode.Additive; + additive.Blending = BlendingMode.Additive; additive.Position = Position; additive.Scale = Scale; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs index 30e6172802..dbf5c6c541 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections new Box { Size = new Vector2(width), - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Origin = Anchor.Centre, Anchor = Anchor.Centre, Alpha = 0.5f, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs index 0c3c4f0a6d..a7384b8f8e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces new TrianglesPiece { RelativeSizeAxes = Axes.Both, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Alpha = 0.5f, } }; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs index e5cf10b88a..7912108901 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs @@ -16,14 +16,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Anchor = Anchor.Centre; Origin = Anchor.Centre; - BlendingMode = BlendingMode.Additive; + Blending = BlendingMode.Additive; Alpha = 0; Children = new Drawable[] { new TrianglesPiece { - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, RelativeSizeAxes = Axes.Both, Alpha = 0.2f, } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs index 97d7de35cf..a80d163246 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Anchor = Anchor.Centre; Origin = Anchor.Centre; - BlendingMode = BlendingMode.Additive; + Blending = BlendingMode.Additive; Alpha = 0; Children = new Drawable[] diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs index 8a7b353da1..0adfed2710 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { Anchor = Anchor.Centre, Origin = Anchor.Centre, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Alpha = 0.5f } }; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index 0bcb8a4986..1986b1431b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces this.slider = slider; Masking = true; AutoSizeAxes = Axes.Both; - BlendingMode = BlendingMode.Additive; + Blending = BlendingMode.Additive; Origin = Anchor.Centre; BorderThickness = 10; BorderColour = Color4.Orange; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs index 680f987274..2082e9a27b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { path = new Path { - BlendingMode = BlendingMode.None, + Blending = BlendingMode.None, }, } }, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs index 942f166241..a06aaff7fb 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces this.isEnd = isEnd; AutoSizeAxes = Axes.Both; - BlendingMode = BlendingMode.Additive; + Blending = BlendingMode.Additive; Origin = Anchor.Centre; Children = new Drawable[] diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 4eb5c46838..9648f50b22 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Origin = Anchor.Centre, Alpha = 0, RelativeSizeAxes = Axes.Both, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Masking = true, Children = new[] { @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables RelativeSizeAxes = Axes.Both, Masking = true, BorderThickness = target_ring_thick_border, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Children = new Drawable[] { new Box diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs index ba717371dd..3264b77bc4 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs @@ -111,7 +111,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Colour = Color4.White, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Alpha = 0, AlwaysPresent = true } diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 659f421ebe..5e79166bec 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Taiko.UI Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Alpha = 0, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, }, centre = new Sprite { @@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Size = new Vector2(0.7f), Alpha = 0, - BlendingMode = BlendingMode.Additive + Blending = BlendingMode.Additive } }; } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 678de7f713..cfb8a67408 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -97,7 +97,7 @@ namespace osu.Game.Rulesets.Taiko.UI { RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, }, new HitTarget { @@ -126,14 +126,14 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, Margin = new MarginPadding { Left = HIT_TARGET_OFFSET }, - BlendingMode = BlendingMode.Additive + Blending = BlendingMode.Additive }, judgementContainer = new Container { Name = "Judgements", RelativeSizeAxes = Axes.Y, Margin = new MarginPadding { Left = HIT_TARGET_OFFSET }, - BlendingMode = BlendingMode.Additive + Blending = BlendingMode.Additive }, } }, diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index ea02feef0e..053ed9c191 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -131,7 +131,7 @@ namespace osu.Game.Graphics.Cursor }, AdditiveLayer = new Sprite { - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Colour = colour.Pink, Alpha = 0, Texture = textures.Get(@"Cursor/menu-cursor-additive"), diff --git a/osu.Game/Graphics/UserInterface/DialogButton.cs b/osu.Game/Graphics/UserInterface/DialogButton.cs index 1cbf77d8f2..289ccbf5cd 100644 --- a/osu.Game/Graphics/UserInterface/DialogButton.cs +++ b/osu.Game/Graphics/UserInterface/DialogButton.cs @@ -99,7 +99,8 @@ namespace osu.Game.Graphics.UserInterface colourContainer.ResizeTo(new Vector2(1.5f, 1f), click_duration, Easing.In); flash(); - this.Delay(click_duration).Schedule(delegate { + this.Delay(click_duration).Schedule(delegate + { colourContainer.ResizeTo(new Vector2(0.8f, 1f)); spriteText.Spacing = Vector2.Zero; glowContainer.FadeOut(); @@ -140,7 +141,7 @@ namespace osu.Game.Graphics.UserInterface colourContainer.Add(flash); flash.Colour = ButtonColour; - flash.BlendingMode = BlendingMode.Additive; + flash.Blending = BlendingMode.Additive; flash.Alpha = 0.3f; flash.FadeOutFromOne(click_duration); flash.Expire(); diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index abc1b036bc..32a37a4910 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -63,7 +63,7 @@ namespace osu.Game.Graphics.UserInterface hover = new Box { RelativeSizeAxes = Axes.Both, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Colour = Color4.White.Opacity(0.1f), Alpha = 0, }, diff --git a/osu.Game/Overlays/Settings/SidebarButton.cs b/osu.Game/Overlays/Settings/SidebarButton.cs index 7af7363dda..b39c8ab7cf 100644 --- a/osu.Game/Overlays/Settings/SidebarButton.cs +++ b/osu.Game/Overlays/Settings/SidebarButton.cs @@ -68,7 +68,7 @@ namespace osu.Game.Overlays.Settings backgroundBox = new Box { RelativeSizeAxes = Axes.Both, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Colour = OsuColour.Gray(60), Alpha = 0, }, diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index f2df2721d3..cb17216679 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -85,7 +85,7 @@ namespace osu.Game.Overlays.Toolbar { RelativeSizeAxes = Axes.Both, Colour = OsuColour.Gray(80).Opacity(180), - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Alpha = 0, }, Flow = new FillFlowContainer diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs index c530e8d7ff..28ecf6ad03 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs @@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Toolbar { RelativeSizeAxes = Axes.Both, Colour = OsuColour.Gray(150).Opacity(180), - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Depth = 2, Alpha = 0, }); diff --git a/osu.Game/Screens/Menu/Button.cs b/osu.Game/Screens/Menu/Button.cs index aca169c3dc..6952f66f95 100644 --- a/osu.Game/Screens/Menu/Button.cs +++ b/osu.Game/Screens/Menu/Button.cs @@ -83,7 +83,7 @@ namespace osu.Game.Screens.Menu { EdgeSmoothness = new Vector2(1.5f, 0), RelativeSizeAxes = Axes.Both, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Colour = Color4.White, Alpha = 0, }, diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index a0cf6eec66..3aeef4bbc9 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Menu { Alpha = 0, Triangles = false, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Interactive = false, Colour = Color4.DarkGray, Ripple = false diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 2de4c1b21f..bc94f88866 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -73,7 +73,7 @@ namespace osu.Game.Screens.Menu { texture = Texture.WhitePixel; AccentColour = new Color4(1, 1, 1, 0.2f); - BlendingMode = BlendingMode.Additive; + Blending = BlendingMode.Additive; } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs index 49c777f09a..9317780eac 100644 --- a/osu.Game/Screens/Menu/MenuSideFlashes.cs +++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Menu RelativeSizeAxes = Axes.Y, Width = box_width, Alpha = 0, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, }, rightBox = new Box { @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Menu RelativeSizeAxes = Axes.Y, Width = box_width, Alpha = 0, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, } }; } diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 64c28816d8..55c25d4c54 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -108,7 +108,7 @@ namespace osu.Game.Screens.Menu { Anchor = Anchor.Centre, Origin = Anchor.Centre, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Alpha = 0 } } @@ -169,7 +169,7 @@ namespace osu.Game.Screens.Menu flashLayer = new Box { RelativeSizeAxes = Axes.Both, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Colour = Color4.White, Alpha = 0, }, diff --git a/osu.Game/Screens/ScreenWhiteBox.cs b/osu.Game/Screens/ScreenWhiteBox.cs index 408dbd8f16..fcf87de655 100644 --- a/osu.Game/Screens/ScreenWhiteBox.cs +++ b/osu.Game/Screens/ScreenWhiteBox.cs @@ -100,7 +100,7 @@ namespace osu.Game.Screens Colour = getColourFor(GetType()), Alpha = 0.2f, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, }, textContainer = new FillFlowContainer { diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index 2987f4476c..a4d7f8b20a 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -302,7 +302,7 @@ namespace osu.Game.Screens.Select.Leaderboards BlurSigma = new Vector2(4), CacheDrawnFrameBuffer = true, RelativeSizeAxes = Axes.Both, - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Size = new Vector2(3f), Children = new[] { diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index 306e7fb3dc..5f1bdcc9bb 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Select.Options { RelativeSizeAxes = Axes.Both, EdgeSmoothness = new Vector2(1.5f, 0), - BlendingMode = BlendingMode.Additive, + Blending = BlendingMode.Additive, Colour = Color4.White, Alpha = 0, }, diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 06d160ad31..0b8c196ec8 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -190,6 +190,7 @@ IPC LTRB MD5 + RGB RNG SHA SRGB From b9bec6a983a48f6e39ccb594effe1bf1dd6a3542 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Sep 2017 23:06:35 +0900 Subject: [PATCH 304/483] CI fixes --- .../Visual/TestCaseEditorMenuBar.cs | 18 +++++----- osu.Game/Screens/Edit/Editor.cs | 34 +++++++++---------- osu.Game/Screens/Edit/Menus/EditorMenuBar.cs | 4 +-- .../Edit/Menus/EditorMenuItemSpacer.cs | 4 +-- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index 9ff4f4c591..d04a12501e 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -27,22 +27,22 @@ namespace osu.Desktop.Tests.Visual new EditorMenuItem("Open Difficulty..."), new EditorMenuItem("Save"), new EditorMenuItem("Create a new Difficulty..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Revert to Saved"), new EditorMenuItem("Revert to Saved (Full)"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Test Beatmap"), new EditorMenuItem("Open AiMod"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Upload Beatmap..."), new EditorMenuItem("Export Package"), new EditorMenuItem("Export Map Package"), new EditorMenuItem("Import from..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Open Song Folder"), new EditorMenuItem("Open .osu in Notepad"), new EditorMenuItem("Open .osb in Notepad"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Exit"), } }, @@ -52,20 +52,20 @@ namespace osu.Desktop.Tests.Visual { new EditorMenuItem("Time Signature"), new EditorMenuItem("Metronome Clicks"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Add Timing Section"), new EditorMenuItem("Add Inheriting Section"), new EditorMenuItem("Reset Current Section"), new EditorMenuItem("Delete Timing Section"), new EditorMenuItem("Resnap Current Section"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Timing Setup"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Resnap All Notes", MenuItemType.Destructive), new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive), new EditorMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive), new EditorMenuItem("Delete All Timing Sections", MenuItemType.Destructive), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Set Current Position as Preview Point"), } }, diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 0454609689..be9098e3be 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -52,22 +52,22 @@ namespace osu.Game.Screens.Edit new EditorMenuItem("Open difficulty..."), new EditorMenuItem("Save"), new EditorMenuItem("Create new difficulty..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Revert to saved"), new EditorMenuItem("Revert to saved (full"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Test beatmap"), new EditorMenuItem("Open AiMod"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Upload Beatmap..."), new EditorMenuItem("Export package"), new EditorMenuItem("Export map package"), new EditorMenuItem("Import from..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Open song folder"), new EditorMenuItem("Open .osu in Notepad"), new EditorMenuItem("Open .osb in Notepad"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Exit", MenuItemType.Standard, Exit) } }, @@ -77,15 +77,15 @@ namespace osu.Game.Screens.Edit { new EditorMenuItem("Undo"), new EditorMenuItem("Redo"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Cut"), new EditorMenuItem("Copy"), new EditorMenuItem("Paste"), new EditorMenuItem("Delete"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Select all"), new EditorMenuItem("Clone"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Reverse selection"), new EditorMenuItem("Flip horizontally"), new EditorMenuItem("Flip vertically"), @@ -93,12 +93,12 @@ namespace osu.Game.Screens.Edit new EditorMenuItem("Rotate 90deg anticlockwise"), new EditorMenuItem("Rotate by..."), new EditorMenuItem("Scale by..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Reset selected objects' samples"), new EditorMenuItem("Reset all samples", MenuItemType.Destructive), new EditorMenuItem("Reset combo colours", MenuItemType.Destructive), new EditorMenuItem("Reset breaks", MenuItemType.Destructive), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Nudge backward"), new EditorMenuItem("Nudge forward") } @@ -110,10 +110,10 @@ namespace osu.Game.Screens.Edit new EditorMenuItem("Compose"), new EditorMenuItem("Design"), new EditorMenuItem("Timing"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Song setup..."), new EditorMenuItem("Timing setup..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Volume"), new EditorMenuItem("Grid level"), new EditorMenuItem("Show video"), @@ -131,7 +131,7 @@ namespace osu.Game.Screens.Edit new EditorMenuItem("Snap divisor"), new EditorMenuItem("Audio rate"), new EditorMenuItem("Grid snapping"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Create polygon cricles..."), new EditorMenuItem("Convert slider to stream"), new EditorMenuItem("Enable live mapping mode"), @@ -151,20 +151,20 @@ namespace osu.Game.Screens.Edit { new EditorMenuItem("Time signature"), new EditorMenuItem("Metronome clicks"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Add timing section"), new EditorMenuItem("Add inheriting section"), new EditorMenuItem("Reset current section"), new EditorMenuItem("Delete timing section"), new EditorMenuItem("Resnap current section"), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Timing setup..."), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Resnap all notes", MenuItemType.Destructive), new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive), new EditorMenuItem("Recalculate slider lengths", MenuItemType.Destructive), new EditorMenuItem("Delete all timing sections", MenuItemType.Destructive), - new EditorMenuSpacer(), + new EditorMenuItemSpacer(), new EditorMenuItem("Set current position as preview point") } }, diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs index 24625570a1..bb349b1531 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuBar.cs @@ -105,14 +105,14 @@ namespace osu.Game.Screens.Edit.Menus protected override bool OnHover(InputState state) { - if (Item is EditorMenuSpacer) + if (Item is EditorMenuItemSpacer) return true; return base.OnHover(state); } protected override bool OnClick(InputState state) { - if (Item is EditorMenuSpacer) + if (Item is EditorMenuItemSpacer) return true; return base.OnClick(state); } diff --git a/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs b/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs index 0e01992846..5060165ef7 100644 --- a/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs +++ b/osu.Game/Screens/Edit/Menus/EditorMenuItemSpacer.cs @@ -3,9 +3,9 @@ namespace osu.Game.Screens.Edit.Menus { - public class EditorMenuSpacer : EditorMenuItem + public class EditorMenuItemSpacer : EditorMenuItem { - public EditorMenuSpacer() + public EditorMenuItemSpacer() : base(" ") { } From 439cbd09a0a9b84af357151232c9bcb525b81ca2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Sep 2017 23:23:51 +0900 Subject: [PATCH 305/483] Fix incorrect TestCase type --- osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs index d04a12501e..9cb3053ff2 100644 --- a/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs +++ b/osu.Desktop.Tests/Visual/TestCaseEditorMenuBar.cs @@ -2,13 +2,12 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; -using osu.Framework.Testing; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Edit.Menus; namespace osu.Desktop.Tests.Visual { - public class TestCaseEditorMenuBar : TestCase + public class TestCaseEditorMenuBar : OsuTestCase { public TestCaseEditorMenuBar() { From 709aa1ed3dc315e6b751784e06e509e3a83bde77 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Thu, 7 Sep 2017 18:20:14 +0200 Subject: [PATCH 306/483] Moved all online score related parsing to its own class --- .../Online/API/Requests/GetScoresRequest.cs | 11 ++++------ osu.Game/Rulesets/Scoring/OnlineScore.cs | 19 +++++++++++++++++ osu.Game/Rulesets/Scoring/Score.cs | 21 +------------------ osu.Game/osu.Game.csproj | 1 + 4 files changed, 25 insertions(+), 27 deletions(-) create mode 100644 osu.Game/Rulesets/Scoring/OnlineScore.cs diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index a902c8c807..72b8649ae0 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -22,11 +22,8 @@ namespace osu.Game.Online.API.Requests private void onSuccess(GetScoresResponse r) { - foreach (Score score in r.Scores) - { - score.Beatmap = beatmap; - score.Ruleset = beatmap.Ruleset; - } + foreach (OnlineScore score in r.Scores) + score.GetModsFor(beatmap.Ruleset); } protected override WebRequest CreateWebRequest() @@ -43,6 +40,6 @@ namespace osu.Game.Online.API.Requests public class GetScoresResponse { [JsonProperty(@"scores")] - public IEnumerable Scores; + public IEnumerable Scores; } -} \ No newline at end of file +} diff --git a/osu.Game/Rulesets/Scoring/OnlineScore.cs b/osu.Game/Rulesets/Scoring/OnlineScore.cs new file mode 100644 index 0000000000..1f652e3d6c --- /dev/null +++ b/osu.Game/Rulesets/Scoring/OnlineScore.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Linq; +using Newtonsoft.Json; + +namespace osu.Game.Rulesets.Scoring +{ + public class OnlineScore : Score + { + [JsonProperty(@"mods")] + private string[] modStrings { get; set; } + + public void GetModsFor(RulesetInfo ruleset) + { + Mods = ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); + } + } +} diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index 154188a2fa..ecc7b60986 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Linq; using System.Collections.Generic; using Newtonsoft.Json; using osu.Game.Beatmaps; @@ -28,27 +27,9 @@ namespace osu.Game.Rulesets.Scoring public int Combo { get; set; } - [JsonProperty(@"mods")] - private string[] modStrings { get; set; } - public RulesetInfo Ruleset; - private Mod[] mods; - public Mod[] Mods - { - get - { - // Evaluate the mod strings if necessary - return mods ?? (mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray()); - } - set - { - mods = value; - - // Assign the mod strings - modStrings = mods.Select(mod => mod.ShortenedName).ToArray(); - } - } + public Mod[] Mods; [JsonProperty(@"user")] public User User; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 07ab58bffc..16812c3467 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -128,6 +128,7 @@ + From e71f907f899352f656d8a55236834e4c266385f1 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Thu, 7 Sep 2017 18:36:16 +0200 Subject: [PATCH 307/483] CI fix --- osu.Game/Rulesets/Ruleset.cs | 1 - osu.Game/Rulesets/Scoring/Score.cs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 3d89afb7ff..33621662af 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -12,7 +12,6 @@ using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Play; namespace osu.Game.Rulesets { diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index ecc7b60986..c09df06633 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -27,9 +27,9 @@ namespace osu.Game.Rulesets.Scoring public int Combo { get; set; } - public RulesetInfo Ruleset; + public RulesetInfo Ruleset { get; set; } - public Mod[] Mods; + public Mod[] Mods { get; set; } [JsonProperty(@"user")] public User User; From 5e685ff5b12e33b4cb7932e67744a80f70b19cef Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 7 Sep 2017 14:53:53 -0300 Subject: [PATCH 308/483] Rewrite BeatmapDetails to be more modular for future code sharing. --- osu.Game/Screens/Select/BeatmapDetailArea.cs | 13 +- osu.Game/Screens/Select/BeatmapDetails.cs | 676 ++++++++---------- .../Screens/Select/Details/AdvancedStats.cs | 152 ++++ osu.Game/Screens/Select/Details/BasicStats.cs | 120 ++++ .../Screens/Select/Details/FailRetryGraph.cs | 62 ++ .../Screens/Select/Details/SuccessRate.cs | 114 +++ .../Screens/Select/Details/UserRatings.cs | 122 ++++ osu.Game/osu.Game.csproj | 5 + 8 files changed, 871 insertions(+), 393 deletions(-) create mode 100644 osu.Game/Screens/Select/Details/AdvancedStats.cs create mode 100644 osu.Game/Screens/Select/Details/BasicStats.cs create mode 100644 osu.Game/Screens/Select/Details/FailRetryGraph.cs create mode 100644 osu.Game/Screens/Select/Details/SuccessRate.cs create mode 100644 osu.Game/Screens/Select/Details/UserRatings.cs diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index 47d25585ad..9e244e1268 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; @@ -10,6 +11,8 @@ namespace osu.Game.Screens.Select { public class BeatmapDetailArea : Container { + private const float details_padding = 10; + private readonly Container content; protected override Container Content => content; @@ -66,9 +69,8 @@ namespace osu.Game.Screens.Select Details = new BeatmapDetails { RelativeSizeAxes = Axes.X, - Masking = true, - Height = 352, Alpha = 0, + Margin = new MarginPadding { Top = details_padding }, }, Leaderboard = new Leaderboard { @@ -76,5 +78,12 @@ namespace osu.Game.Screens.Select } }); } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + Details.Height = Math.Min(DrawHeight - (details_padding * 3) - BeatmapDetailAreaTabControl.HEIGHT, 450); + } } } diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index a5486efa96..8f564bb794 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -9,71 +9,188 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; -using System.Globalization; using System.Linq; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Framework.Threading; using osu.Framework.Graphics.Shapes; +using osu.Framework.Extensions.Color4Extensions; +using osu.Game.Screens.Select.Details; using osu.Game.Beatmaps; namespace osu.Game.Screens.Select { public class BeatmapDetails : Container { - private readonly MetadataSegment description; - private readonly MetadataSegment source; - private readonly MetadataSegment tags; + private const float spacing = 10; + private const float transition_duration = 250; - private readonly DifficultyRow circleSize; - private readonly DifficultyRow drainRate; - private readonly DifficultyRow overallDifficulty; - private readonly DifficultyRow approachRate; - private readonly DifficultyRow stars; + private readonly FillFlowContainer top, statsFlow; + private readonly AdvancedStats advanced; + private readonly DetailBox ratingsContainer; + private readonly UserRatings ratings; + private readonly ScrollContainer metadataScroll; + private readonly MetadataSection description, source, tags; + private readonly Container failRetryContainer; + private readonly FailRetryGraph failRetryGraph; + private readonly DimmedLoadingAnimation loading; - private readonly Container ratingsContainer; - private readonly Bar ratingsBar; - private readonly OsuSpriteText negativeRatings; - private readonly OsuSpriteText positiveRatings; - private readonly BarGraph ratingsGraph; - - private readonly FillFlowContainer retryFailContainer; - private readonly BarGraph retryGraph; - private readonly BarGraph failGraph; + private APIAccess api; private ScheduledDelegate pendingBeatmapSwitch; private BeatmapInfo beatmap; - public BeatmapInfo Beatmap { get { return beatmap; } - set { - if (beatmap == value) return; - + if (value == beatmap) return; beatmap = value; pendingBeatmapSwitch?.Cancel(); - pendingBeatmapSwitch = Schedule(updateStats); + pendingBeatmapSwitch = Schedule(updateStatistics); } } - private void updateStats() + public BeatmapDetails() { - if (beatmap == null) return; + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = spacing }, + Children = new Drawable[] + { + top = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + statsFlow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Width = 0.5f, + Spacing = new Vector2(spacing), + Padding = new MarginPadding { Right = spacing / 2 }, + Children = new[] + { + new DetailBox + { + Child = advanced = new AdvancedStats + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = spacing, Top = spacing * 2, Bottom = spacing }, + }, + }, + ratingsContainer = new DetailBox + { + Child = ratings = new UserRatings + { + RelativeSizeAxes = Axes.X, + Height = 134, + Padding = new MarginPadding { Horizontal = spacing, Top = spacing }, + }, + }, + }, + }, + metadataScroll = new ScrollContainer + { + RelativeSizeAxes = Axes.X, + Width = 0.5f, + ScrollbarVisible = false, + Padding = new MarginPadding { Left = spacing / 2 }, + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + LayoutDuration = transition_duration, + Spacing = new Vector2(spacing * 2), + Margin = new MarginPadding { Top = spacing * 2 }, + Children = new[] + { + description = new MetadataSection("Description") + { + TextColour = Color4.White.Opacity(0.75f), + }, + source = new MetadataSection("Source") + { + TextColour = Color4.White.Opacity(0.75f), + }, + tags = new MetadataSection("Tags"), + }, + }, + }, + }, + }, + failRetryContainer = new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Children = new Drawable[] + { + new OsuSpriteText + { + Text = "Points of Failure", + Font = @"Exo2.0-Bold", + TextSize = 14, + }, + failRetryGraph = new FailRetryGraph + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 14 + spacing / 2 }, + }, + }, + }, + }, + }, + loading = new DimmedLoadingAnimation + { + RelativeSizeAxes = Axes.Both, + }, + }; + } - description.Text = beatmap.Version; - source.Text = beatmap.Metadata.Source; - tags.Text = beatmap.Metadata.Tags; + [BackgroundDependencyLoader] + private void load(OsuColour colours, APIAccess api) + { + this.api = api; + tags.TextColour = colours.Yellow; + } - circleSize.Value = beatmap.Difficulty.CircleSize; - drainRate.Value = beatmap.Difficulty.DrainRate; - overallDifficulty.Value = beatmap.Difficulty.OverallDifficulty; - approachRate.Value = beatmap.Difficulty.ApproachRate; - stars.Value = (float)beatmap.StarDifficulty; + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); - var requestedBeatmap = beatmap; + metadataScroll.Height = statsFlow.DrawHeight; + failRetryContainer.Height = DrawHeight - Padding.TotalVertical - (top.DrawHeight + spacing / 2); + } + + private void updateStatistics() + { + if (Beatmap == null) + { + clearStats(); + return; + } + + ratingsContainer.FadeIn(transition_duration); + advanced.Beatmap = Beatmap; + description.Text = Beatmap.Version; + source.Text = Beatmap.Metadata.Source; + tags.Text = Beatmap.Metadata.Tags; + + var requestedBeatmap = Beatmap; if (requestedBeatmap.Metrics == null) { var lookup = new GetBeatmapDetailsRequest(requestedBeatmap); @@ -84,413 +201,190 @@ namespace osu.Game.Screens.Select return; requestedBeatmap.Metrics = res; - Schedule(() => updateMetrics(res)); + Schedule(() => displayMetrics(res)); }; - lookup.Failure += e => Schedule(() => updateMetrics(null)); + lookup.Failure += e => Schedule(() => displayMetrics(null)); api.Queue(lookup); loading.Show(); } - updateMetrics(requestedBeatmap.Metrics, false); + displayMetrics(requestedBeatmap.Metrics, false); } - /// - /// Update displayed metrics. - /// - /// New metrics to overwrite the existing display. Can be null. - /// Whether to hide the display on null or empty metrics. If false, we will dim as if waiting for further updates. - private void updateMetrics(BeatmapMetrics metrics, bool failOnMissing = true) + private void displayMetrics(BeatmapMetrics metrics, bool failOnMissing = true) { var hasRatings = metrics?.Ratings.Any() ?? false; var hasRetriesFails = (metrics?.Retries.Any() ?? false) && metrics.Fails.Any(); - if (failOnMissing) - loading.Hide(); + if (failOnMissing) loading.Hide(); if (hasRatings) { - var ratings = metrics.Ratings.ToList(); - ratingsContainer.Show(); - - negativeRatings.Text = ratings.GetRange(0, ratings.Count / 2).Sum().ToString(); - positiveRatings.Text = ratings.GetRange(ratings.Count / 2, ratings.Count / 2).Sum().ToString(); - ratingsBar.Length = (float)ratings.GetRange(0, ratings.Count / 2).Sum() / ratings.Sum(); - - ratingsGraph.Values = ratings.Select(rating => (float)rating); - - ratingsContainer.FadeColour(Color4.White, 500, Easing.Out); - } - else if (failOnMissing) - ratingsGraph.Values = new float[10]; - else - ratingsContainer.FadeColour(Color4.Gray, 500, Easing.Out); - - if (hasRetriesFails) - { - var retries = metrics.Retries; - var fails = metrics.Fails; - retryFailContainer.Show(); - - float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max(); - failGraph.MaxValue = maxValue; - retryGraph.MaxValue = maxValue; - - failGraph.Values = fails.Select(fail => (float)fail); - retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + MathHelper.Clamp(fail, 0, maxValue)); - - retryFailContainer.FadeColour(Color4.White, 500, Easing.Out); + ratings.Metrics = metrics; + ratings.FadeIn(transition_duration); } else if (failOnMissing) { - failGraph.Values = new float[100]; - retryGraph.Values = new float[100]; - } - else - retryFailContainer.FadeColour(Color4.Gray, 500, Easing.Out); - } - - public BeatmapDetails() - { - Children = new Drawable[] - { - new Box + ratings.FadeTo(0.25f, transition_duration); + ratings.Metrics = new BeatmapMetrics { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.5f, - }, - new FillFlowContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Width = 0.4f, - Direction = FillDirection.Vertical, - LayoutDuration = 200, - LayoutEasing = Easing.OutQuint, - Children = new[] - { - description = new MetadataSegment("Description"), - source = new MetadataSegment("Source"), - tags = new MetadataSegment("Tags") - }, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Width = 0.6f, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 15), - Padding = new MarginPadding(10) { Top = 0 }, - Children = new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.5f, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 5), - Padding = new MarginPadding(10), - Children = new[] - { - circleSize = new DifficultyRow("Circle Size", 7), - drainRate = new DifficultyRow("HP Drain"), - overallDifficulty = new DifficultyRow("Accuracy"), - approachRate = new DifficultyRow("Approach Rate"), - stars = new DifficultyRow("Star Difficulty"), - }, - }, - }, - }, - ratingsContainer = new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Alpha = 0, - AlwaysPresent = true, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.5f, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Padding = new MarginPadding - { - Top = 25, - Left = 15, - Right = 15, - }, - Children = new Drawable[] - { - new OsuSpriteText - { - Text = "User Rating", - Font = @"Exo2.0-Medium", - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - }, - ratingsBar = new Bar - { - RelativeSizeAxes = Axes.X, - Height = 5, - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new[] - { - negativeRatings = new OsuSpriteText - { - Font = @"Exo2.0-Regular", - Text = "0", - }, - positiveRatings = new OsuSpriteText - { - Font = @"Exo2.0-Regular", - Text = "0", - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - }, - }, - }, - new OsuSpriteText - { - Text = "Rating Spread", - TextSize = 14, - Font = @"Exo2.0-Regular", - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - }, - ratingsGraph = new BarGraph - { - RelativeSizeAxes = Axes.X, - Height = 50, - }, - }, - }, - }, - }, - retryFailContainer = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Alpha = 0, - Children = new Drawable[] - { - new OsuSpriteText - { - Text = "Points of Failure", - Font = @"Exo2.0-Regular", - }, - new Container - { - RelativeSizeAxes = Axes.X, - Size = new Vector2(1 / 0.6f, 50), - Children = new[] - { - retryGraph = new BarGraph - { - RelativeSizeAxes = Axes.Both, - }, - failGraph = new BarGraph - { - RelativeSizeAxes = Axes.Both, - }, - }, - }, - } - }, - }, - }, - loading = new LoadingAnimation() - }; - } - - private APIAccess api; - private readonly LoadingAnimation loading; - - [BackgroundDependencyLoader] - private void load(OsuColour colour, APIAccess api) - { - this.api = api; - - description.AccentColour = colour.GrayB; - source.AccentColour = colour.GrayB; - tags.AccentColour = colour.YellowLight; - - stars.AccentColour = colour.Yellow; - - ratingsBar.BackgroundColour = colour.Green; - ratingsBar.AccentColour = colour.YellowDark; - ratingsGraph.Colour = colour.BlueDark; - - failGraph.Colour = colour.YellowDarker; - retryGraph.Colour = colour.Yellow; - } - - private class DifficultyRow : Container, IHasAccentColour - { - private readonly OsuSpriteText name; - private readonly Bar bar; - private readonly OsuSpriteText valueText; - - private readonly float maxValue; - - private float difficultyValue; - public float Value - { - get - { - return difficultyValue; - } - set - { - difficultyValue = value; - bar.Length = value / maxValue; - valueText.Text = value.ToString("N1", CultureInfo.CurrentCulture); - } - } - - public Color4 AccentColour - { - get - { - return bar.AccentColour; - } - set - { - bar.AccentColour = value; - } - } - - public DifficultyRow(string difficultyName, float maxValue = 10) - { - this.maxValue = maxValue; - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Children = new Drawable[] - { - name = new OsuSpriteText - { - Font = @"Exo2.0-Regular", - Text = difficultyName, - }, - bar = new Bar - { - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Both, - Size = new Vector2(1, 0.35f), - Padding = new MarginPadding { Left = 100, Right = 25 }, - }, - valueText = new OsuSpriteText - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Font = @"Exo2.0-Regular", - }, + Ratings = new int[10], }; } - [BackgroundDependencyLoader] - private void load(OsuColour colour) + if (hasRetriesFails) { - name.Colour = colour.GrayB; - bar.BackgroundColour = colour.Gray7; - valueText.Colour = colour.GrayB; + failRetryGraph.Metrics = metrics; + failRetryContainer.FadeIn(transition_duration); + } + else if (failOnMissing) + { + failRetryContainer.FadeTo(0.25f, transition_duration); + failRetryGraph.Metrics = new BeatmapMetrics + { + Fails = new int[100], + Retries = new int[100], + }; } } - private class MetadataSegment : Container, IHasAccentColour + private void clearStats() { - private readonly OsuSpriteText header; - private readonly FillFlowContainer content; + description.Text = null; + source.Text = null; + tags.Text = null; + advanced.Beatmap = new BeatmapInfo + { + StarDifficulty = 0, + Difficulty = new BeatmapDifficulty + { + CircleSize = 0, + DrainRate = 0, + OverallDifficulty = 0, + ApproachRate = 0, + }, + }; + + loading.Hide(); + ratingsContainer.FadeOut(transition_duration); + failRetryContainer.FadeOut(transition_duration); + } + + private class DetailBox : Container + { + private readonly Container content; + protected override Container Content => content; + + public DetailBox() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), + }, + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }, + }; + } + } + + private class MetadataSection : Container + { + private readonly OsuSpriteText title; + private readonly TextFlowContainer textFlow; public string Text { set { if (string.IsNullOrEmpty(value)) - Hide(); - else { - Show(); - if (header.Text == "Tags") - content.ChildrenEnumerable = value.Split(' ').Select(text => new OsuSpriteText - { - Text = text, - Font = "Exo2.0-Regular", - }); - else - content.Children = new[] - { - new OsuSpriteText - { - Text = value, - Font = "Exo2.0-Regular", - } - }; + this.FadeOut(transition_duration); + return; } + + this.FadeIn(transition_duration); + textFlow.Clear(); + textFlow.AddText(value, s => s.TextSize = 14); } } - public Color4 AccentColour + public Color4 TextColour { - get - { - return content.Colour; - } - set - { - content.Colour = value; - } + get { return textFlow.Colour; } + set { textFlow.Colour = value; } } - public MetadataSegment(string headerText) + public MetadataSection(string title) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Margin = new MarginPadding { Top = 10 }; + + InternalChild = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(spacing / 2), + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = this.title = new OsuSpriteText + { + Text = title, + Font = @"Exo2.0-Bold", + TextSize = 14, + }, + }, + textFlow = new TextFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }, + }, + }; + } + } + + private class DimmedLoadingAnimation : VisibilityContainer + { + private readonly LoadingAnimation loading; + + public DimmedLoadingAnimation() + { Children = new Drawable[] { - header = new OsuSpriteText + new Box { - Font = @"Exo2.0-Bold", - Text = headerText, + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f), }, - content = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Full, - Spacing = new Vector2(5, 0), - Margin = new MarginPadding { Top = header.TextSize } - } + loading = new LoadingAnimation(), }; } + + protected override void PopIn() + { + this.FadeIn(transition_duration, Easing.OutQuint); + loading.State = Visibility.Visible; + } + + protected override void PopOut() + { + this.FadeOut(transition_duration, Easing.OutQuint); + loading.State = Visibility.Hidden; + } } } } diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs new file mode 100644 index 0000000000..5f7377ec09 --- /dev/null +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -0,0 +1,152 @@ +// Copyright (c) 2007-2017 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.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using System; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Select.Details +{ + public class AdvancedStats : Container + { + private readonly StatRow firstValue, hpDrain, accuracy, approachRate, starDifficulty; + + private BeatmapInfo beatmap; + public BeatmapInfo Beatmap + { + get { return beatmap; } + set + { + if (value == beatmap) return; + beatmap = value; + + //mania specific + if ((Beatmap?.Ruleset?.ID ?? 0) == 3) + { + firstValue.Title = "Key Amount"; + firstValue.Value = (int)Math.Round(Beatmap.Difficulty.CircleSize); + } + else + { + firstValue.Title = "Circle Size"; + firstValue.Value = Beatmap.Difficulty.CircleSize; + } + + hpDrain.Value = beatmap.Difficulty.DrainRate; + accuracy.Value = beatmap.Difficulty.OverallDifficulty; + approachRate.Value = beatmap.Difficulty.ApproachRate; + starDifficulty.Value = (float)beatmap.StarDifficulty; + } + } + + public AdvancedStats() + { + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(4f), + Children = new[] + { + firstValue = new StatRow(), //circle size/key amount + hpDrain = new StatRow { Title = "HP Drain" }, + accuracy = new StatRow { Title = "Accuracy" }, + approachRate = new StatRow { Title = "Approach Rate" }, + starDifficulty = new StatRow(10, true) { Title = "Star Difficulty" }, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + starDifficulty.AccentColour = colours.Yellow; + } + + private class StatRow : Container, IHasAccentColour + { + private const float value_width = 25; + private const float name_width = 70; + + private readonly float maxValue; + private readonly bool forceDecimalPlaces; + private readonly OsuSpriteText name, value; + private readonly Bar bar; + + public string Title + { + get { return name.Text; } + set { name.Text = value; } + } + + private float difficultyValue; + public float Value + { + get { return difficultyValue; } + set + { + difficultyValue = value; + bar.Length = value / maxValue; + this.value.Text = value.ToString(forceDecimalPlaces ? "#.00" : "0.##"); + } + } + + public Color4 AccentColour + { + get { return bar.AccentColour; } + set { bar.AccentColour = value; } + } + + public StatRow(float maxValue = 10, bool forceDecimalPlaces = false) + { + this.maxValue = maxValue; + this.forceDecimalPlaces = forceDecimalPlaces; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Children = new Drawable[] + { + new Container + { + Width = name_width, + AutoSizeAxes = Axes.Y, + Child = this.name = new OsuSpriteText + { + TextSize = 13, + }, + }, + bar = new Bar + { + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + Height = 5, + BackgroundColour = Color4.White.Opacity(0.5f), + Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 }, + }, + new Container + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Width = value_width, + RelativeSizeAxes = Axes.Y, + Child = value = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + TextSize = 13, + }, + }, + }; + } + } + } +} diff --git a/osu.Game/Screens/Select/Details/BasicStats.cs b/osu.Game/Screens/Select/Details/BasicStats.cs new file mode 100644 index 0000000000..bfdecf28b5 --- /dev/null +++ b/osu.Game/Screens/Select/Details/BasicStats.cs @@ -0,0 +1,120 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Screens.Select.Details +{ + public class BasicStats : Container + { + private const float stat_count = 4; + + private readonly Statistic length, bpm, circleCount, sliderCount; + + private BeatmapInfo beatmap; + public BeatmapInfo Beatmap + { + get { return beatmap; } + set + { + if (value == beatmap) return; + beatmap = value; + + //length.Value = TimeSpan.FromMilliseconds(Beatmap.OnlineInfo.Length).ToString(@"m\:ss"); + //bpm.Value = Beatmap.BeatmapSet.OnlineInfo.BPM.ToString(@"0.##"); + //circleCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.CircleCount); + //sliderCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.SliderCount); + } + } + + public BasicStats() + { + var statWidth = 1 / stat_count; + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Children = new[] + { + length = new Statistic(FontAwesome.fa_clock_o, "Length") { Width = statWidth }, + bpm = new Statistic(FontAwesome.fa_circle, "BPM") { Width = statWidth }, + circleCount = new Statistic(FontAwesome.fa_circle_o, "Circle Count") { Width = statWidth }, + sliderCount = new Statistic(FontAwesome.fa_circle, "Slider Count") { Width = statWidth }, + }, + }; + } + + private class Statistic : Container, IHasTooltip + { + private readonly string name; + private readonly OsuSpriteText value; + + public string TooltipText => name; + public string Value + { + get { return value.Text; } + set { this.value.Text = value; } + } + + public Statistic(FontAwesome icon, string name) + { + this.name = name; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Children = new Drawable[] + { + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.Centre, + Icon = FontAwesome.fa_square, + Size = new Vector2(13), + Rotation = 45, + Colour = OsuColour.FromHex(@"441288"), + }, + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.Centre, + Icon = icon, + Size = new Vector2(13), + Colour = OsuColour.FromHex(@"f7dd55"), + Scale = new Vector2(0.8f), + }, + value = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + TextSize = 13, + Font = @"Exo2.0-Bold", + Margin = new MarginPadding { Left = 10 }, + }, + }, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + value.Colour = colour.Yellow; + } + } + } +} diff --git a/osu.Game/Screens/Select/Details/FailRetryGraph.cs b/osu.Game/Screens/Select/Details/FailRetryGraph.cs new file mode 100644 index 0000000000..4d75c49d17 --- /dev/null +++ b/osu.Game/Screens/Select/Details/FailRetryGraph.cs @@ -0,0 +1,62 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using System.Linq; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Select.Details +{ + public class FailRetryGraph : Container + { + private readonly BarGraph retryGraph, failGraph; + + private BeatmapMetrics metrics; + public BeatmapMetrics Metrics + { + get { return metrics; } + set + { + if (value == metrics) return; + metrics = value; + + var retries = Metrics.Retries; + var fails = Metrics.Fails; + + float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max(); + failGraph.MaxValue = maxValue; + retryGraph.MaxValue = maxValue; + + failGraph.Values = fails.Select(f => (float)f); + retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + MathHelper.Clamp(fail, 0, maxValue)); + } + } + + public FailRetryGraph() + { + Children = new[] + { + retryGraph = new BarGraph + { + RelativeSizeAxes = Axes.Both, + }, + failGraph = new BarGraph + { + RelativeSizeAxes = Axes.Both, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + retryGraph.Colour = colours.Yellow; + failGraph.Colour = colours.YellowDarker; + } + } +} diff --git a/osu.Game/Screens/Select/Details/SuccessRate.cs b/osu.Game/Screens/Select/Details/SuccessRate.cs new file mode 100644 index 0000000000..1d84fdbd48 --- /dev/null +++ b/osu.Game/Screens/Select/Details/SuccessRate.cs @@ -0,0 +1,114 @@ +// Copyright (c) 2007-2017 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.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Select.Details +{ + public class SuccessRate : Container + { + private readonly FillFlowContainer header; + private readonly OsuSpriteText successRateLabel, successPercent, graphLabel; + private readonly Bar successRate; + private readonly Container percentContainer; + private readonly FailRetryGraph graph; + + private BeatmapInfo beatmap; + public BeatmapInfo Beatmap + { + get { return beatmap; } + set + { + if (value == beatmap) return; + beatmap = value; + + //successPercent.Text = $"{beatmap.OnlineInfo.SuccessRate}%"; + //successRate.Length = (float)beatmap.OnlineInfo.SuccessRate / 100f; + + graph.Metrics = Beatmap.Metrics; + } + } + + public SuccessRate() + { + Children = new Drawable[] + { + header = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + successRateLabel = new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "Success Rate", + TextSize = 13, + }, + successRate = new Bar + { + RelativeSizeAxes = Axes.X, + Height = 5, + Margin = new MarginPadding { Top = 5 }, + }, + percentContainer = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = successPercent = new OsuSpriteText + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopCentre, + TextSize = 13, + }, + }, + graphLabel = new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "Points of Failure", + TextSize = 13, + Margin = new MarginPadding { Vertical = 20 }, + }, + }, + }, + graph = new FailRetryGraph + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + successRateLabel.Colour = successPercent.Colour = graphLabel.Colour = colours.Gray5; + successRate.AccentColour = colours.Green; + successRate.BackgroundColour = colours.GrayD; + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + graph.Padding = new MarginPadding { Top = header.DrawHeight }; + } + + protected override void Update() + { + base.Update(); + + percentContainer.Width = successRate.Length; + } + } +} diff --git a/osu.Game/Screens/Select/Details/UserRatings.cs b/osu.Game/Screens/Select/Details/UserRatings.cs new file mode 100644 index 0000000000..db6d932464 --- /dev/null +++ b/osu.Game/Screens/Select/Details/UserRatings.cs @@ -0,0 +1,122 @@ +// Copyright (c) 2007-2017 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.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using System.Linq; +using osu.Game.Beatmaps; + +namespace osu.Game.Screens.Select.Details +{ + public class UserRatings : Container + { + private readonly FillFlowContainer header; + private readonly Bar ratingsBar; + private readonly OsuSpriteText negativeRatings, positiveRatings; + private readonly Container graphContainer; + private readonly BarGraph graph; + + private BeatmapMetrics metrics; + public BeatmapMetrics Metrics + { + get { return metrics; } + set + { + if (value == metrics) return; + metrics = value; + + var ratings = Metrics.Ratings.ToList(); + negativeRatings.Text = ratings.GetRange(0, ratings.Count / 2).Sum().ToString(); + positiveRatings.Text = ratings.GetRange(ratings.Count / 2, ratings.Count / 2).Sum().ToString(); + ratingsBar.Length = (float)ratings.GetRange(0, ratings.Count / 2).Sum() / ratings.Sum(); + graph.Values = Metrics.Ratings.Select(r => (float)r); + } + } + + public UserRatings() + { + Children = new Drawable[] + { + header = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "User Rating", + TextSize = 13, + }, + ratingsBar = new Bar + { + RelativeSizeAxes = Axes.X, + Height = 5, + Margin = new MarginPadding { Top = 5 }, + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new[] + { + negativeRatings = new OsuSpriteText + { + Text = "0", + TextSize = 13, + }, + positiveRatings = new OsuSpriteText + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Text = @"0", + TextSize = 13, + }, + }, + }, + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "Rating Spread", + TextSize = 13, + Margin = new MarginPadding { Top = 10, Bottom = 5 }, + }, + }, + }, + graphContainer = new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, + Child = graph = new BarGraph + { + RelativeSizeAxes = Axes.Both, + }, + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + ratingsBar.BackgroundColour = colours.Green; + ratingsBar.AccentColour = colours.Yellow; + graph.Colour = colours.BlueDark; + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + graphContainer.Padding = new MarginPadding { Top = header.DrawHeight }; + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 05ba3e25ab..4782464fbb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -538,6 +538,11 @@ + + + + + From fd2700a5b4971a476d0fdd8ab79aa2cf5702a1d5 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 7 Sep 2017 15:01:31 -0300 Subject: [PATCH 309/483] Fix .00 being displayed for star difficulty when the value is 0. --- osu.Game/Screens/Select/Details/AdvancedStats.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 5f7377ec09..eb9e1d2c78 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Select.Details { difficultyValue = value; bar.Length = value / maxValue; - this.value.Text = value.ToString(forceDecimalPlaces ? "#.00" : "0.##"); + this.value.Text = value.ToString(forceDecimalPlaces ? "0.00" : "0.##"); } } From 2153865de5ecd13bbe253212ae9e8ac309dfddd5 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 7 Sep 2017 15:09:50 -0300 Subject: [PATCH 310/483] Adjust fail on missing logic to match original. --- osu.Game/Screens/Select/BeatmapDetails.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 8f564bb794..a11a662e41 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -38,6 +38,7 @@ namespace osu.Game.Screens.Select private APIAccess api; private ScheduledDelegate pendingBeatmapSwitch; + private BeatmapInfo beatmap; public BeatmapInfo Beatmap { @@ -226,12 +227,15 @@ namespace osu.Game.Screens.Select } else if (failOnMissing) { - ratings.FadeTo(0.25f, transition_duration); ratings.Metrics = new BeatmapMetrics { Ratings = new int[10], }; } + else + { + ratings.FadeTo(0.25f, transition_duration); + } if (hasRetriesFails) { @@ -240,13 +244,16 @@ namespace osu.Game.Screens.Select } else if (failOnMissing) { - failRetryContainer.FadeTo(0.25f, transition_duration); failRetryGraph.Metrics = new BeatmapMetrics { Fails = new int[100], Retries = new int[100], }; } + else + { + failRetryContainer.FadeTo(0.25f, transition_duration); + } } private void clearStats() From 109531b66c639eff988c4558b9a03f1ec8b2ff11 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 7 Sep 2017 15:21:18 -0300 Subject: [PATCH 311/483] Cleanup, remove unneeded files. --- .../Screens/Select/Details/AdvancedStats.cs | 16 +-- osu.Game/Screens/Select/Details/BasicStats.cs | 120 ------------------ .../Screens/Select/Details/SuccessRate.cs | 114 ----------------- osu.Game/osu.Game.csproj | 2 - 4 files changed, 8 insertions(+), 244 deletions(-) delete mode 100644 osu.Game/Screens/Select/Details/BasicStats.cs delete mode 100644 osu.Game/Screens/Select/Details/SuccessRate.cs diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index eb9e1d2c78..6969ba1319 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Select.Details { public class AdvancedStats : Container { - private readonly StatRow firstValue, hpDrain, accuracy, approachRate, starDifficulty; + private readonly StatisticRow firstValue, hpDrain, accuracy, approachRate, starDifficulty; private BeatmapInfo beatmap; public BeatmapInfo Beatmap @@ -56,11 +56,11 @@ namespace osu.Game.Screens.Select.Details Spacing = new Vector2(4f), Children = new[] { - firstValue = new StatRow(), //circle size/key amount - hpDrain = new StatRow { Title = "HP Drain" }, - accuracy = new StatRow { Title = "Accuracy" }, - approachRate = new StatRow { Title = "Approach Rate" }, - starDifficulty = new StatRow(10, true) { Title = "Star Difficulty" }, + firstValue = new StatisticRow(), //circle size/key amount + hpDrain = new StatisticRow { Title = "HP Drain" }, + accuracy = new StatisticRow { Title = "Accuracy" }, + approachRate = new StatisticRow { Title = "Approach Rate" }, + starDifficulty = new StatisticRow(10, true) { Title = "Star Difficulty" }, }, }; } @@ -71,7 +71,7 @@ namespace osu.Game.Screens.Select.Details starDifficulty.AccentColour = colours.Yellow; } - private class StatRow : Container, IHasAccentColour + private class StatisticRow : Container, IHasAccentColour { private const float value_width = 25; private const float name_width = 70; @@ -105,7 +105,7 @@ namespace osu.Game.Screens.Select.Details set { bar.AccentColour = value; } } - public StatRow(float maxValue = 10, bool forceDecimalPlaces = false) + public StatisticRow(float maxValue = 10, bool forceDecimalPlaces = false) { this.maxValue = maxValue; this.forceDecimalPlaces = forceDecimalPlaces; diff --git a/osu.Game/Screens/Select/Details/BasicStats.cs b/osu.Game/Screens/Select/Details/BasicStats.cs deleted file mode 100644 index bfdecf28b5..0000000000 --- a/osu.Game/Screens/Select/Details/BasicStats.cs +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using OpenTK; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; - -namespace osu.Game.Screens.Select.Details -{ - public class BasicStats : Container - { - private const float stat_count = 4; - - private readonly Statistic length, bpm, circleCount, sliderCount; - - private BeatmapInfo beatmap; - public BeatmapInfo Beatmap - { - get { return beatmap; } - set - { - if (value == beatmap) return; - beatmap = value; - - //length.Value = TimeSpan.FromMilliseconds(Beatmap.OnlineInfo.Length).ToString(@"m\:ss"); - //bpm.Value = Beatmap.BeatmapSet.OnlineInfo.BPM.ToString(@"0.##"); - //circleCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.CircleCount); - //sliderCount.Value = string.Format(@"{0:n0}", beatmap.OnlineInfo.SliderCount); - } - } - - public BasicStats() - { - var statWidth = 1 / stat_count; - Child = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Horizontal, - Children = new[] - { - length = new Statistic(FontAwesome.fa_clock_o, "Length") { Width = statWidth }, - bpm = new Statistic(FontAwesome.fa_circle, "BPM") { Width = statWidth }, - circleCount = new Statistic(FontAwesome.fa_circle_o, "Circle Count") { Width = statWidth }, - sliderCount = new Statistic(FontAwesome.fa_circle, "Slider Count") { Width = statWidth }, - }, - }; - } - - private class Statistic : Container, IHasTooltip - { - private readonly string name; - private readonly OsuSpriteText value; - - public string TooltipText => name; - public string Value - { - get { return value.Text; } - set { this.value.Text = value; } - } - - public Statistic(FontAwesome icon, string name) - { - this.name = name; - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - - Children = new Drawable[] - { - new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] - { - new SpriteIcon - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.Centre, - Icon = FontAwesome.fa_square, - Size = new Vector2(13), - Rotation = 45, - Colour = OsuColour.FromHex(@"441288"), - }, - new SpriteIcon - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.Centre, - Icon = icon, - Size = new Vector2(13), - Colour = OsuColour.FromHex(@"f7dd55"), - Scale = new Vector2(0.8f), - }, - value = new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - TextSize = 13, - Font = @"Exo2.0-Bold", - Margin = new MarginPadding { Left = 10 }, - }, - }, - }, - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colour) - { - value.Colour = colour.Yellow; - } - } - } -} diff --git a/osu.Game/Screens/Select/Details/SuccessRate.cs b/osu.Game/Screens/Select/Details/SuccessRate.cs deleted file mode 100644 index 1d84fdbd48..0000000000 --- a/osu.Game/Screens/Select/Details/SuccessRate.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2007-2017 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.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Beatmaps; - -namespace osu.Game.Screens.Select.Details -{ - public class SuccessRate : Container - { - private readonly FillFlowContainer header; - private readonly OsuSpriteText successRateLabel, successPercent, graphLabel; - private readonly Bar successRate; - private readonly Container percentContainer; - private readonly FailRetryGraph graph; - - private BeatmapInfo beatmap; - public BeatmapInfo Beatmap - { - get { return beatmap; } - set - { - if (value == beatmap) return; - beatmap = value; - - //successPercent.Text = $"{beatmap.OnlineInfo.SuccessRate}%"; - //successRate.Length = (float)beatmap.OnlineInfo.SuccessRate / 100f; - - graph.Metrics = Beatmap.Metrics; - } - } - - public SuccessRate() - { - Children = new Drawable[] - { - header = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - successRateLabel = new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Text = "Success Rate", - TextSize = 13, - }, - successRate = new Bar - { - RelativeSizeAxes = Axes.X, - Height = 5, - Margin = new MarginPadding { Top = 5 }, - }, - percentContainer = new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = successPercent = new OsuSpriteText - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopCentre, - TextSize = 13, - }, - }, - graphLabel = new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Text = "Points of Failure", - TextSize = 13, - Margin = new MarginPadding { Vertical = 20 }, - }, - }, - }, - graph = new FailRetryGraph - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.Both, - }, - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - successRateLabel.Colour = successPercent.Colour = graphLabel.Colour = colours.Gray5; - successRate.AccentColour = colours.Green; - successRate.BackgroundColour = colours.GrayD; - } - - protected override void UpdateAfterChildren() - { - base.UpdateAfterChildren(); - - graph.Padding = new MarginPadding { Top = header.DrawHeight }; - } - - protected override void Update() - { - base.Update(); - - percentContainer.Width = successRate.Length; - } - } -} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4782464fbb..cf5d1f7026 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -539,9 +539,7 @@ - - From 55e8bdfb0580575ec6909721cae28bf174f15ab1 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 7 Sep 2017 15:38:23 -0300 Subject: [PATCH 312/483] CI fixes. --- osu.Game/Screens/Select/BeatmapDetailArea.cs | 2 +- osu.Game/Screens/Select/BeatmapDetails.cs | 3 +-- osu.Game/Screens/Select/Details/AdvancedStats.cs | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index 9e244e1268..a676516300 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -83,7 +83,7 @@ namespace osu.Game.Screens.Select { base.UpdateAfterChildren(); - Details.Height = Math.Min(DrawHeight - (details_padding * 3) - BeatmapDetailAreaTabControl.HEIGHT, 450); + Details.Height = Math.Min(DrawHeight - details_padding * 3 - BeatmapDetailAreaTabControl.HEIGHT, 450); } } } diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index a11a662e41..7c3b8ba905 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -306,7 +306,6 @@ namespace osu.Game.Screens.Select private class MetadataSection : Container { - private readonly OsuSpriteText title; private readonly TextFlowContainer textFlow; public string Text @@ -347,7 +346,7 @@ namespace osu.Game.Screens.Select { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = this.title = new OsuSpriteText + Child = new OsuSpriteText { Text = title, Font = @"Exo2.0-Bold", diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 6969ba1319..d92c8ed509 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -32,12 +32,12 @@ namespace osu.Game.Screens.Select.Details if ((Beatmap?.Ruleset?.ID ?? 0) == 3) { firstValue.Title = "Key Amount"; - firstValue.Value = (int)Math.Round(Beatmap.Difficulty.CircleSize); + firstValue.Value = (int)Math.Round(Beatmap?.Difficulty?.CircleSize ?? 0); } else { firstValue.Title = "Circle Size"; - firstValue.Value = Beatmap.Difficulty.CircleSize; + firstValue.Value = Beatmap?.Difficulty?.CircleSize ?? 0; } hpDrain.Value = beatmap.Difficulty.DrainRate; @@ -118,7 +118,7 @@ namespace osu.Game.Screens.Select.Details { Width = name_width, AutoSizeAxes = Axes.Y, - Child = this.name = new OsuSpriteText + Child = name = new OsuSpriteText { TextSize = 13, }, From 01553fc9ef9d6bdddfac28f68986f5db169fbd69 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 8 Sep 2017 02:46:54 +0200 Subject: [PATCH 313/483] Moved all online related score parsing to its class --- .../Online/API/Requests/GetScoresRequest.cs | 7 +- osu.Game/Rulesets/Scoring/OnlineScore.cs | 75 ++++++++++++++++++- osu.Game/Rulesets/Scoring/Score.cs | 38 ---------- 3 files changed, 79 insertions(+), 41 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index 72b8649ae0..6e22bd6989 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -23,7 +23,12 @@ namespace osu.Game.Online.API.Requests private void onSuccess(GetScoresResponse r) { foreach (OnlineScore score in r.Scores) - score.GetModsFor(beatmap.Ruleset); + { + score.Beatmap = beatmap; + score.Ruleset = beatmap.Ruleset; + + score.ResolveModString(); + } } protected override WebRequest CreateWebRequest() diff --git a/osu.Game/Rulesets/Scoring/OnlineScore.cs b/osu.Game/Rulesets/Scoring/OnlineScore.cs index 1f652e3d6c..694ce023d1 100644 --- a/osu.Game/Rulesets/Scoring/OnlineScore.cs +++ b/osu.Game/Rulesets/Scoring/OnlineScore.cs @@ -1,19 +1,90 @@ // Copyright (c) 2007-2017 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 Newtonsoft.Json; +using osu.Game.Users; +using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Scoring { public class OnlineScore : Score { + [JsonProperty(@"score")] + private double totalScore + { + set { TotalScore = value; } + } + + [JsonProperty(@"max_combo")] + private int maxCombo + { + set { MaxCombo = value; } + } + + [JsonProperty(@"user")] + private User user + { + set { User = value; } + } + + [JsonProperty(@"replay_data")] + private Replay replay + { + set { Replay = value; } + } + + [JsonProperty(@"score_id")] + private long onlineScoreID + { + set { OnlineScoreID = value; } + } + + [JsonProperty(@"created_at")] + private DateTimeOffset date + { + set { Date = value; } + } + + [JsonProperty(@"statistics")] + private Dictionary jsonStats + { + set + { + foreach (var kvp in value) + { + string key = kvp.Key; + switch (key) + { + case @"count_300": + key = @"300"; + break; + case @"count_100": + key = @"100"; + break; + case @"count_50": + key = @"50"; + break; + case @"count_miss": + key = @"x"; + break; + default: + continue; + } + + Statistics.Add(key, kvp.Value); + } + } + } + [JsonProperty(@"mods")] private string[] modStrings { get; set; } - public void GetModsFor(RulesetInfo ruleset) + public void ResolveModString() { - Mods = ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); + Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); } } } diff --git a/osu.Game/Rulesets/Scoring/Score.cs b/osu.Game/Rulesets/Scoring/Score.cs index c09df06633..ff4632a9c2 100644 --- a/osu.Game/Rulesets/Scoring/Score.cs +++ b/osu.Game/Rulesets/Scoring/Score.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; using osu.Game.Users; @@ -15,14 +14,12 @@ namespace osu.Game.Rulesets.Scoring { public ScoreRank Rank { get; set; } - [JsonProperty(@"score")] public double TotalScore { get; set; } public double Accuracy { get; set; } public double Health { get; set; } = 1; - [JsonProperty(@"max_combo")] public int MaxCombo { get; set; } public int Combo { get; set; } @@ -31,51 +28,16 @@ namespace osu.Game.Rulesets.Scoring public Mod[] Mods { get; set; } - [JsonProperty(@"user")] public User User; - [JsonProperty(@"replay_data")] public Replay Replay; public BeatmapInfo Beatmap; - [JsonProperty(@"score_id")] public long OnlineScoreID; - [JsonProperty(@"created_at")] public DateTimeOffset Date; - [JsonProperty(@"statistics")] - private Dictionary jsonStats - { - set - { - foreach (var kvp in value) - { - string key = kvp.Key; - switch (key) - { - case @"count_300": - key = @"300"; - break; - case @"count_100": - key = @"100"; - break; - case @"count_50": - key = @"50"; - break; - case @"count_miss": - key = @"x"; - break; - default: - continue; - } - - Statistics.Add(key, kvp.Value); - } - } - } - public Dictionary Statistics = new Dictionary(); } } From e54741619331b81a002a3d58cbc520e35a5ccf64 Mon Sep 17 00:00:00 2001 From: Damnae Date: Thu, 7 Sep 2017 23:55:05 +0200 Subject: [PATCH 314/483] Storyboards implementation. --- .../Visual/TestCaseStoryboard.cs | 91 +++++++ osu.Desktop.Tests/osu.Desktop.Tests.csproj | 1 + osu.Game/Beatmaps/Beatmap.cs | 6 + osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 222 ++++++++++++++++-- osu.Game/Storyboards/AnimationDefinition.cs | 33 +++ osu.Game/Storyboards/CommandLoop.cs | 27 +++ osu.Game/Storyboards/CommandTimeline.cs | 61 +++++ osu.Game/Storyboards/CommandTimelineGroup.cs | 94 ++++++++ osu.Game/Storyboards/CommandTrigger.cs | 24 ++ osu.Game/Storyboards/Drawables/IFlippable.cs | 11 + osu.Game/Storyboards/Drawables/Storyboard.cs | 59 +++++ .../Drawables/StoryboardAnimation.cs | 55 +++++ .../Storyboards/Drawables/StoryboardLayer.cs | 37 +++ .../Storyboards/Drawables/StoryboardSprite.cs | 49 ++++ osu.Game/Storyboards/ElementDefinition.cs | 13 + osu.Game/Storyboards/LayerDefinition.cs | 33 +++ osu.Game/Storyboards/SampleDefinition.cs | 24 ++ osu.Game/Storyboards/SpriteDefinition.cs | 59 +++++ osu.Game/Storyboards/StoryboardDefinition.cs | 36 +++ osu.Game/osu.Game.csproj | 15 ++ 20 files changed, 925 insertions(+), 25 deletions(-) create mode 100644 osu.Desktop.Tests/Visual/TestCaseStoryboard.cs create mode 100644 osu.Game/Storyboards/AnimationDefinition.cs create mode 100644 osu.Game/Storyboards/CommandLoop.cs create mode 100644 osu.Game/Storyboards/CommandTimeline.cs create mode 100644 osu.Game/Storyboards/CommandTimelineGroup.cs create mode 100644 osu.Game/Storyboards/CommandTrigger.cs create mode 100644 osu.Game/Storyboards/Drawables/IFlippable.cs create mode 100644 osu.Game/Storyboards/Drawables/Storyboard.cs create mode 100644 osu.Game/Storyboards/Drawables/StoryboardAnimation.cs create mode 100644 osu.Game/Storyboards/Drawables/StoryboardLayer.cs create mode 100644 osu.Game/Storyboards/Drawables/StoryboardSprite.cs create mode 100644 osu.Game/Storyboards/ElementDefinition.cs create mode 100644 osu.Game/Storyboards/LayerDefinition.cs create mode 100644 osu.Game/Storyboards/SampleDefinition.cs create mode 100644 osu.Game/Storyboards/SpriteDefinition.cs create mode 100644 osu.Game/Storyboards/StoryboardDefinition.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs b/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs new file mode 100644 index 0000000000..1d7b3dffd2 --- /dev/null +++ b/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs @@ -0,0 +1,91 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK.Graphics; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Timing; +using osu.Game; +using osu.Game.Beatmaps; +using osu.Game.Overlays; +using osu.Game.Storyboards.Drawables; + +namespace osu.Desktop.Tests.Visual +{ + internal class TestCaseStoryboard : OsuTestCase + { + public override string Description => @"Tests storyboards."; + + private readonly Bindable beatmapBacking = new Bindable(); + + private MusicController musicController; + private Container storyboardContainer; + private Storyboard storyboard; + + public TestCaseStoryboard() + { + Clock = new FramedClock(); + + Add(new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + storyboardContainer = new Container + { + RelativeSizeAxes = Axes.Both, + }, + }, + }); + Add(musicController = new MusicController + { + Origin = Anchor.TopRight, + Anchor = Anchor.TopRight, + State = Visibility.Visible, + }); + + AddStep("Restart", restart); + AddToggleStep("Passing", passing => { if (storyboard != null) storyboard.Passing = passing; }); + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase game) + { + beatmapBacking.BindTo(game.Beatmap); + beatmapBacking.ValueChanged += beatmapChanged; + } + + private void beatmapChanged(WorkingBeatmap working) + => loadStoryboard(working); + + private void restart() + { + var track = beatmapBacking.Value.Track; + + track.Reset(); + loadStoryboard(beatmapBacking.Value); + track.Start(); + } + + private void loadStoryboard(WorkingBeatmap working) + { + if (storyboard != null) + storyboardContainer.Remove(storyboard); + + var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true }; + decoupledClock.ChangeSource(working.Track); + storyboardContainer.Clock = decoupledClock; + + storyboardContainer.Add(storyboard = working.Beatmap.Storyboard.CreateDrawable()); + storyboard.Passing = false; + } + } +} diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj index 86268e6110..6bd190a1f6 100644 --- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj +++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj @@ -91,6 +91,7 @@ + diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 82777734bb..e4568a1919 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Linq; using osu.Game.Beatmaps.ControlPoints; using osu.Game.IO.Serialization; +using osu.Game.Storyboards; namespace osu.Game.Beatmaps { @@ -40,6 +41,11 @@ namespace osu.Game.Beatmaps /// public double TotalBreakTime => Breaks.Sum(b => b.Duration); + /// + /// The Beatmap's Storyboard. + /// + public StoryboardDefinition Storyboard = new StoryboardDefinition(); + /// /// Constructs a new beatmap. /// diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index b51ea607dd..08e1d06621 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -10,6 +10,10 @@ using osu.Game.Beatmaps.Timing; using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Storyboards; +using OpenTK; +using osu.Framework.Graphics; +using osu.Framework.IO.File; namespace osu.Game.Beatmaps.Formats { @@ -238,42 +242,208 @@ namespace osu.Game.Beatmaps.Formats } } - private void handleEvents(Beatmap beatmap, string line) + private void handleEvents(Beatmap beatmap, string line, ref SpriteDefinition spriteDefinition, ref CommandTimelineGroup timelineGroup) { + var depth = 0; + while (line.StartsWith(" ") || line.StartsWith("_")) + { + ++depth; + line = line.Substring(depth); + } + decodeVariables(ref line); string[] split = line.Split(','); - EventType type; - if (!Enum.TryParse(split[0], out type)) - throw new InvalidDataException($@"Unknown event type {split[0]}"); - - // Todo: Implement the rest - switch (type) + if (depth == 0) { - case EventType.Video: - case EventType.Background: - string filename = split[2].Trim('"'); + spriteDefinition = null; - if (type == EventType.Background) - beatmap.BeatmapInfo.Metadata.BackgroundFile = filename; + EventType type; + if (!Enum.TryParse(split[0], out type)) + throw new InvalidDataException($@"Unknown event type {split[0]}"); - break; - case EventType.Break: - var breakEvent = new BreakPeriod - { - StartTime = double.Parse(split[1], NumberFormatInfo.InvariantInfo), - EndTime = double.Parse(split[2], NumberFormatInfo.InvariantInfo) - }; + switch (type) + { + case EventType.Video: + case EventType.Background: + string filename = split[2].Trim('"'); - if (!breakEvent.HasEffect) - return; + if (type == EventType.Background) + beatmap.BeatmapInfo.Metadata.BackgroundFile = filename; - beatmap.Breaks.Add(breakEvent); - break; + break; + case EventType.Break: + var breakEvent = new BreakPeriod + { + StartTime = double.Parse(split[1], NumberFormatInfo.InvariantInfo), + EndTime = double.Parse(split[2], NumberFormatInfo.InvariantInfo) + }; + + if (!breakEvent.HasEffect) + return; + + beatmap.Breaks.Add(breakEvent); + break; + case EventType.Sprite: + { + var layer = split[1]; + var origin = (Anchor)Enum.Parse(typeof(Anchor), split[2]); + var path = cleanFilename(split[3]); + var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo); + var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo); + spriteDefinition = new SpriteDefinition(path, origin, new Vector2(x, y)); + beatmap.Storyboard.GetLayer(layer).Add(spriteDefinition); + } + break; + case EventType.Animation: + { + var layer = split[1]; + var origin = (Anchor)Enum.Parse(typeof(Anchor), split[2]); + var path = cleanFilename(split[3]); + var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo); + var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo); + var frameCount = int.Parse(split[6]); + var frameDelay = double.Parse(split[7], NumberFormatInfo.InvariantInfo); + var loopType = (AnimationLoopType)Enum.Parse(typeof(AnimationLoopType), split[8]); + spriteDefinition = new AnimationDefinition(path, origin, new Vector2(x, y), frameCount, frameDelay, loopType); + beatmap.Storyboard.GetLayer(layer).Add(spriteDefinition); + } + break; + case EventType.Sample: + { + var time = double.Parse(split[1], CultureInfo.InvariantCulture); + var layer = split[2]; + var path = cleanFilename(split[3]); + var volume = float.Parse(split[4], CultureInfo.InvariantCulture); + beatmap.Storyboard.GetLayer(layer).Add(new SampleDefinition(path, time, volume)); + } + break; + } + } + else + { + if (depth < 2) + timelineGroup = spriteDefinition; + + switch (split[0]) + { + case "T": + { + var triggerName = split[1]; + var startTime = double.Parse(split[2], CultureInfo.InvariantCulture); + var endTime = double.Parse(split[3], CultureInfo.InvariantCulture); + var groupNumber = split.Length > 4 ? int.Parse(split[4]) : 0; + timelineGroup = spriteDefinition?.AddTrigger(triggerName, startTime, endTime, groupNumber); + } + break; + case "L": + { + var startTime = double.Parse(split[1], CultureInfo.InvariantCulture); + var loopCount = int.Parse(split[2]); + timelineGroup = spriteDefinition?.AddLoop(startTime, loopCount); + } + break; + default: + { + if (string.IsNullOrEmpty(split[3])) + split[3] = split[2]; + + var commandType = split[0]; + var easing = (Easing)int.Parse(split[1]); + var startTime = double.Parse(split[2], CultureInfo.InvariantCulture); + var endTime = double.Parse(split[3], CultureInfo.InvariantCulture); + + switch (commandType) + { + case "F": + { + var startValue = float.Parse(split[4], CultureInfo.InvariantCulture); + var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue; + timelineGroup?.Alpha.Add(easing, startTime, endTime, startValue, endValue); + } + break; + case "S": + { + var startValue = float.Parse(split[4], CultureInfo.InvariantCulture); + var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue; + timelineGroup?.Scale.Add(easing, startTime, endTime, new Vector2(startValue), new Vector2(endValue)); + } + break; + case "V": + { + var startX = float.Parse(split[4], CultureInfo.InvariantCulture); + var startY = float.Parse(split[5], CultureInfo.InvariantCulture); + var endX = split.Length > 6 ? float.Parse(split[6], CultureInfo.InvariantCulture) : startX; + var endY = split.Length > 7 ? float.Parse(split[7], CultureInfo.InvariantCulture) : startY; + timelineGroup?.Scale.Add(easing, startTime, endTime, new Vector2(startX, startY), new Vector2(startX, endY)); + } + break; + case "R": + { + var startValue = float.Parse(split[4], CultureInfo.InvariantCulture); + var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue; + timelineGroup?.Rotation.Add(easing, startTime, endTime, MathHelper.RadiansToDegrees(startValue), MathHelper.RadiansToDegrees(endValue)); + } + break; + case "M": + { + var startX = float.Parse(split[4], CultureInfo.InvariantCulture); + var startY = float.Parse(split[5], CultureInfo.InvariantCulture); + var endX = split.Length > 6 ? float.Parse(split[6], CultureInfo.InvariantCulture) : startX; + var endY = split.Length > 7 ? float.Parse(split[7], CultureInfo.InvariantCulture) : startY; + timelineGroup?.X.Add(easing, startTime, endTime, startX, endX); + timelineGroup?.Y.Add(easing, startTime, endTime, startY, endY); + } + break; + case "MX": + { + var startValue = float.Parse(split[4], CultureInfo.InvariantCulture); + var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue; + timelineGroup?.X.Add(easing, startTime, endTime, startValue, endValue); + } + break; + case "MY": + { + var startValue = float.Parse(split[4], CultureInfo.InvariantCulture); + var endValue = split.Length > 5 ? float.Parse(split[5], CultureInfo.InvariantCulture) : startValue; + timelineGroup?.Y.Add(easing, startTime, endTime, startValue, endValue); + } + break; + case "C": + { + var startRed = float.Parse(split[4], CultureInfo.InvariantCulture); + var startGreen = float.Parse(split[5], CultureInfo.InvariantCulture); + var startBlue = float.Parse(split[6], CultureInfo.InvariantCulture); + var endRed = split.Length > 7 ? float.Parse(split[7], CultureInfo.InvariantCulture) : startRed; + var endGreen = split.Length > 8 ? float.Parse(split[8], CultureInfo.InvariantCulture) : startGreen; + var endBlue = split.Length > 9 ? float.Parse(split[9], CultureInfo.InvariantCulture) : startBlue; + timelineGroup?.Colour.Add(easing, startTime, endTime, + new Color4(startRed / 255f, startGreen / 255f, startBlue / 255f, 1), + new Color4(endRed / 255f, endGreen / 255f, endBlue / 255f, 1)); + } + break; + case "P": + { + var type = split[4]; + switch (type) + { + case "A": timelineGroup?.Additive.Add(easing, startTime, endTime, true, true); break; + case "H": timelineGroup?.FlipH.Add(easing, startTime, endTime, true, true); break; + case "V": timelineGroup?.FlipV.Add(easing, startTime, endTime, true, true); break; + } + } + break; + } + } + break; + } } } + private static string cleanFilename(string path) + => FileSafety.PathStandardise(path.Trim('\"')); + private void handleTimingPoints(Beatmap beatmap, string line) { string[] split = line.Split(','); @@ -414,6 +584,8 @@ namespace osu.Game.Beatmaps.Formats Section section = Section.None; bool hasCustomColours = false; + SpriteDefinition spriteDefinition = null; + CommandTimelineGroup timelineGroup = null; string line; while ((line = stream.ReadLine()) != null) @@ -421,7 +593,7 @@ namespace osu.Game.Beatmaps.Formats if (string.IsNullOrEmpty(line)) continue; - if (line.StartsWith(" ") || line.StartsWith("_") || line.StartsWith("//")) + if (line.StartsWith("//")) continue; if (line.StartsWith(@"osu file format v")) @@ -452,7 +624,7 @@ namespace osu.Game.Beatmaps.Formats handleDifficulty(beatmap, line); break; case Section.Events: - handleEvents(beatmap, line); + handleEvents(beatmap, line, ref spriteDefinition, ref timelineGroup); break; case Section.TimingPoints: handleTimingPoints(beatmap, line); diff --git a/osu.Game/Storyboards/AnimationDefinition.cs b/osu.Game/Storyboards/AnimationDefinition.cs new file mode 100644 index 0000000000..3ac9cbfe0e --- /dev/null +++ b/osu.Game/Storyboards/AnimationDefinition.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Graphics; +using osu.Game.Storyboards.Drawables; + +namespace osu.Game.Storyboards +{ + public class AnimationDefinition : SpriteDefinition + { + public int FrameCount; + public double FrameDelay; + public AnimationLoopType LoopType; + + public AnimationDefinition(string path, Anchor origin, Vector2 initialPosition, int frameCount, double frameDelay, AnimationLoopType loopType) + : base(path, origin, initialPosition) + { + FrameCount = frameCount; + FrameDelay = frameDelay; + LoopType = loopType; + } + + public override Drawable CreateDrawable() + => new StoryboardAnimation(this); + } + + public enum AnimationLoopType + { + LoopForever, + LoopOnce, + } +} diff --git a/osu.Game/Storyboards/CommandLoop.cs b/osu.Game/Storyboards/CommandLoop.cs new file mode 100644 index 0000000000..b93a04cea1 --- /dev/null +++ b/osu.Game/Storyboards/CommandLoop.cs @@ -0,0 +1,27 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; + +namespace osu.Game.Storyboards +{ + public class CommandLoop : CommandTimelineGroup + { + private double startTime; + private int loopCount; + + public CommandLoop(double startTime, int loopCount) + { + this.startTime = startTime; + this.loopCount = loopCount; + } + + public override void ApplyTransforms(Drawable drawable) + { + //base.ApplyTransforms(drawable); + } + + public override string ToString() + => $"{startTime} x{loopCount}"; + } +} diff --git a/osu.Game/Storyboards/CommandTimeline.cs b/osu.Game/Storyboards/CommandTimeline.cs new file mode 100644 index 0000000000..04e165aa38 --- /dev/null +++ b/osu.Game/Storyboards/CommandTimeline.cs @@ -0,0 +1,61 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Caching; +using osu.Framework.Graphics; +using System.Collections.Generic; +using System.Linq; + +namespace osu.Game.Storyboards +{ + public class CommandTimeline : CommandTimeline + { + private readonly List commands = new List(); + public IEnumerable Commands => commands.OrderBy(c => c.StartTime); + public bool HasCommands => commands.Count > 0; + + private Cached startTimeBacking; + public double StartTime => startTimeBacking.IsValid ? startTimeBacking : (startTimeBacking.Value = HasCommands ? commands.Min(c => c.StartTime) : double.MinValue); + + private Cached endTimeBacking; + public double EndTime => endTimeBacking.IsValid ? endTimeBacking : (endTimeBacking.Value = HasCommands ? commands.Max(c => c.EndTime) : double.MaxValue); + + public T StartValue => HasCommands ? commands.OrderBy(c => c.StartTime).First().StartValue : default(T); + public T EndValue => HasCommands ? commands.OrderByDescending(c => c.EndTime).First().EndValue : default(T); + + public void Add(Easing easing, double startTime, double endTime, T startValue, T endValue) + { + if (endTime < startTime) + return; + + commands.Add(new Command { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue, }); + + startTimeBacking.Invalidate(); + endTimeBacking.Invalidate(); + } + + public override string ToString() + => $"{commands.Count} command(s)"; + + public class Command + { + public Easing Easing; + public double StartTime; + public double EndTime; + public T StartValue; + public T EndValue; + + public double Duration => EndTime - StartTime; + + public override string ToString() + => $"{StartTime} -> {EndTime}, {StartValue} -> {EndValue} {Easing}"; + } + } + + public interface CommandTimeline + { + double StartTime { get; } + double EndTime { get; } + bool HasCommands { get; } + } +} diff --git a/osu.Game/Storyboards/CommandTimelineGroup.cs b/osu.Game/Storyboards/CommandTimelineGroup.cs new file mode 100644 index 0000000000..cc67c9dd68 --- /dev/null +++ b/osu.Game/Storyboards/CommandTimelineGroup.cs @@ -0,0 +1,94 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Graphics; +using osu.Game.Storyboards.Drawables; +using System.Collections.Generic; +using System.Linq; + +namespace osu.Game.Storyboards +{ + public class CommandTimelineGroup + { + public CommandTimeline X = new CommandTimeline(); + public CommandTimeline Y = new CommandTimeline(); + public CommandTimeline Scale = new CommandTimeline(); + public CommandTimeline Rotation = new CommandTimeline(); + public CommandTimeline Colour = new CommandTimeline(); + public CommandTimeline Alpha = new CommandTimeline(); + public CommandTimeline Additive = new CommandTimeline(); + public CommandTimeline FlipH = new CommandTimeline(); + public CommandTimeline FlipV = new CommandTimeline(); + + public IEnumerable Timelines + { + get + { + yield return X; + yield return Y; + yield return Scale; + yield return Rotation; + yield return Colour; + yield return Alpha; + yield return Additive; + yield return FlipH; + yield return FlipV; + } + } + + public double StartTime => Timelines.Where(t => t.HasCommands).Min(t => t.StartTime); + public double EndTime => Timelines.Where(t => t.HasCommands).Max(t => t.EndTime); + public bool HasCommands => Timelines.Any(t => t.HasCommands); + + public virtual void ApplyTransforms(Drawable drawable) + { + if (X.HasCommands) drawable.X = X.StartValue; + foreach (var command in X.Commands) + using (drawable.BeginAbsoluteSequence(command.StartTime)) + drawable.MoveToX(command.StartValue) + .MoveToX(command.EndValue, command.Duration, command.Easing); + + if (Y.HasCommands) drawable.Y = Y.StartValue; + foreach (var command in Y.Commands) + using (drawable.BeginAbsoluteSequence(command.StartTime)) + drawable.MoveToY(command.StartValue) + .MoveToY(command.EndValue, command.Duration, command.Easing); + + if (Scale.HasCommands) drawable.Scale = Scale.StartValue; + foreach (var command in Scale.Commands) + using (drawable.BeginAbsoluteSequence(command.StartTime)) + drawable.ScaleTo(command.StartValue) + .ScaleTo(command.EndValue, command.Duration, command.Easing); + + if (Rotation.HasCommands) drawable.Rotation = Rotation.StartValue; + foreach (var command in Rotation.Commands) + using (drawable.BeginAbsoluteSequence(command.StartTime)) + drawable.RotateTo(command.StartValue) + .RotateTo(command.EndValue, command.Duration, command.Easing); + + if (Colour.HasCommands) drawable.Colour = Colour.StartValue; + foreach (var command in Colour.Commands) + using (drawable.BeginAbsoluteSequence(command.StartTime)) + drawable.FadeColour(command.StartValue) + .FadeColour(command.EndValue, command.Duration, command.Easing); + + if (Alpha.HasCommands) drawable.Alpha = Alpha.StartValue; + foreach (var command in Alpha.Commands) + using (drawable.BeginAbsoluteSequence(command.StartTime)) + drawable.FadeTo(command.StartValue) + .FadeTo(command.EndValue, command.Duration, command.Easing); + + if (Additive.HasCommands) + drawable.BlendingMode = BlendingMode.Additive; + + var flippable = drawable as IFlippable; + if (flippable != null) + { + flippable.FlipH = FlipH.HasCommands; + flippable.FlipV = FlipV.HasCommands; + } + } + } +} diff --git a/osu.Game/Storyboards/CommandTrigger.cs b/osu.Game/Storyboards/CommandTrigger.cs new file mode 100644 index 0000000000..e7133e170f --- /dev/null +++ b/osu.Game/Storyboards/CommandTrigger.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Storyboards +{ + public class CommandTrigger : CommandTimelineGroup + { + private string triggerName; + private double startTime; + private double endTime; + private int groupNumber; + + public CommandTrigger(string triggerName, double startTime, double endTime, int groupNumber) + { + this.triggerName = triggerName; + this.startTime = startTime; + this.endTime = endTime; + this.groupNumber = groupNumber; + } + + public override string ToString() + => $"{triggerName} {startTime} -> {endTime} ({groupNumber})"; + } +} diff --git a/osu.Game/Storyboards/Drawables/IFlippable.cs b/osu.Game/Storyboards/Drawables/IFlippable.cs new file mode 100644 index 0000000000..a1899d1411 --- /dev/null +++ b/osu.Game/Storyboards/Drawables/IFlippable.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Storyboards.Drawables +{ + public interface IFlippable + { + bool FlipH { get; set; } + bool FlipV { get; set; } + } +} diff --git a/osu.Game/Storyboards/Drawables/Storyboard.cs b/osu.Game/Storyboards/Drawables/Storyboard.cs new file mode 100644 index 0000000000..a5b242357f --- /dev/null +++ b/osu.Game/Storyboards/Drawables/Storyboard.cs @@ -0,0 +1,59 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Textures; +using osu.Game.IO; + +namespace osu.Game.Storyboards.Drawables +{ + public class Storyboard : Container + { + public StoryboardDefinition Definition { get; private set; } + + protected override Vector2 DrawScale => new Vector2(Parent.DrawHeight / 480); + public override bool HandleInput => false; + + private bool passing = true; + public bool Passing + { + get { return passing; } + set + { + if (passing == value) return; + passing = value; + updateLayerVisibility(); + } + } + + private DependencyContainer dependencies; + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => + dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + + public Storyboard(StoryboardDefinition definition) + { + Definition = definition; + Size = new Vector2(640, 480); + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + } + + [BackgroundDependencyLoader] + private void load(FileStore fileStore) + { + dependencies.Cache(new TextureStore(new RawTextureLoaderStore(fileStore.Store), false) { ScaleAdjust = 1, }); + + foreach (var layerDefinition in Definition.Layers) + Add(layerDefinition.CreateDrawable()); + } + + private void updateLayerVisibility() + { + foreach (var layer in Children) + layer.Enabled = passing ? layer.Definition.EnabledWhenPassing : layer.Definition.ShowWhenFailing; + } + } +} diff --git a/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs new file mode 100644 index 0000000000..583a0d13c3 --- /dev/null +++ b/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs @@ -0,0 +1,55 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Animations; +using osu.Framework.Graphics.Textures; +using osu.Framework.IO.File; +using System.Linq; + +namespace osu.Game.Storyboards.Drawables +{ + public class StoryboardAnimation : TextureAnimation, IFlippable + { + public AnimationDefinition Definition { get; private set; } + + protected override bool ShouldBeAlive => Definition.HasCommands && base.ShouldBeAlive; + public override bool RemoveWhenNotAlive => !Definition.HasCommands || base.RemoveWhenNotAlive; + + public bool FlipH { get; set; } + public bool FlipV { get; set; } + protected override Vector2 DrawScale => new Vector2(FlipH ? -base.DrawScale.X : base.DrawScale.X, FlipV ? -base.DrawScale.Y : base.DrawScale.Y); + + public StoryboardAnimation(AnimationDefinition definition) + { + Definition = definition; + Origin = definition.Origin; + Position = definition.InitialPosition; + Repeat = definition.LoopType == AnimationLoopType.LoopForever; + + if (definition.HasCommands) + { + LifetimeStart = definition.StartTime; + LifetimeEnd = definition.EndTime; + } + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase game, TextureStore textureStore) + { + for (var frame = 0; frame < Definition.FrameCount; frame++) + { + var framePath = Definition.Path.Replace(".", frame + "."); + + var path = game.Beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename == framePath)?.FileInfo.StoragePath; + if (path == null) + continue; + + var texture = textureStore.Get(path); + AddFrame(texture, Definition.FrameDelay); + } + Definition.ApplyTransforms(this); + } + } +} diff --git a/osu.Game/Storyboards/Drawables/StoryboardLayer.cs b/osu.Game/Storyboards/Drawables/StoryboardLayer.cs new file mode 100644 index 0000000000..48532e0418 --- /dev/null +++ b/osu.Game/Storyboards/Drawables/StoryboardLayer.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2007-2017 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; + +namespace osu.Game.Storyboards.Drawables +{ + public class StoryboardLayer : Container + { + public LayerDefinition Definition { get; private set; } + public bool Enabled; + + public override bool IsPresent => Enabled && base.IsPresent; + + public StoryboardLayer(LayerDefinition definition) + { + Definition = definition; + RelativeSizeAxes = Axes.Both; + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + Enabled = definition.EnabledWhenPassing; + } + + [BackgroundDependencyLoader] + private void load() + { + foreach (var element in Definition.Elements) + { + var drawable = element.CreateDrawable(); + if (drawable != null) + Add(drawable); + } + } + } +} diff --git a/osu.Game/Storyboards/Drawables/StoryboardSprite.cs b/osu.Game/Storyboards/Drawables/StoryboardSprite.cs new file mode 100644 index 0000000000..927996d750 --- /dev/null +++ b/osu.Game/Storyboards/Drawables/StoryboardSprite.cs @@ -0,0 +1,49 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Framework.IO.File; +using System.Linq; + +namespace osu.Game.Storyboards.Drawables +{ + public class StoryboardSprite : Sprite, IFlippable + { + public SpriteDefinition Definition { get; private set; } + + protected override bool ShouldBeAlive => Definition.HasCommands && base.ShouldBeAlive; + public override bool RemoveWhenNotAlive => !Definition.HasCommands || base.RemoveWhenNotAlive; + + public bool FlipH { get; set; } + public bool FlipV { get; set; } + protected override Vector2 DrawScale => new Vector2(FlipH ? -base.DrawScale.X : base.DrawScale.X, FlipV ? -base.DrawScale.Y : base.DrawScale.Y); + + public StoryboardSprite(SpriteDefinition definition) + { + Definition = definition; + Origin = definition.Origin; + Position = definition.InitialPosition; + + if (definition.HasCommands) + { + LifetimeStart = definition.StartTime; + LifetimeEnd = definition.EndTime; + } + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase game, TextureStore textureStore) + { + var spritePath = Definition.Path; + var path = game.Beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename == spritePath)?.FileInfo.StoragePath; + if (path == null) + return; + + Texture = textureStore.Get(path); + Definition.ApplyTransforms(this); + } + } +} diff --git a/osu.Game/Storyboards/ElementDefinition.cs b/osu.Game/Storyboards/ElementDefinition.cs new file mode 100644 index 0000000000..1a8de9a120 --- /dev/null +++ b/osu.Game/Storyboards/ElementDefinition.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; + +namespace osu.Game.Storyboards +{ + public interface ElementDefinition + { + string Path { get; } + Drawable CreateDrawable(); + } +} diff --git a/osu.Game/Storyboards/LayerDefinition.cs b/osu.Game/Storyboards/LayerDefinition.cs new file mode 100644 index 0000000000..e632a700f1 --- /dev/null +++ b/osu.Game/Storyboards/LayerDefinition.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Storyboards.Drawables; +using System.Collections.Generic; + +namespace osu.Game.Storyboards +{ + public class LayerDefinition + { + public string Name; + public int Depth; + public bool EnabledWhenPassing = true; + public bool ShowWhenFailing = true; + + private List elements = new List(); + public IEnumerable Elements => elements; + + public LayerDefinition(string name, int depth) + { + Name = name; + Depth = depth; + } + + public void Add(ElementDefinition element) + { + elements.Add(element); + } + + public StoryboardLayer CreateDrawable() + => new StoryboardLayer(this) { Depth = Depth, }; + } +} diff --git a/osu.Game/Storyboards/SampleDefinition.cs b/osu.Game/Storyboards/SampleDefinition.cs new file mode 100644 index 0000000000..26d2c4b029 --- /dev/null +++ b/osu.Game/Storyboards/SampleDefinition.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; + +namespace osu.Game.Storyboards +{ + public class SampleDefinition : ElementDefinition + { + public string Path { get; private set; } + public double Time; + public float Volume; + + public SampleDefinition(string path, double time, float volume) + { + Path = path; + Time = time; + Volume = volume; + } + + public Drawable CreateDrawable() + => null; + } +} diff --git a/osu.Game/Storyboards/SpriteDefinition.cs b/osu.Game/Storyboards/SpriteDefinition.cs new file mode 100644 index 0000000000..2574e7adb6 --- /dev/null +++ b/osu.Game/Storyboards/SpriteDefinition.cs @@ -0,0 +1,59 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.Graphics; +using osu.Game.Storyboards.Drawables; +using System.Collections.Generic; + +namespace osu.Game.Storyboards +{ + public class SpriteDefinition : CommandTimelineGroup, ElementDefinition + { + public string Path { get; private set; } + public Anchor Origin; + public Vector2 InitialPosition; + + private List loops = new List(); + private List triggers = new List(); + + public SpriteDefinition(string path, Anchor origin, Vector2 initialPosition) + { + Path = path; + Origin = origin; + InitialPosition = initialPosition; + } + + public CommandLoop AddLoop(double startTime, int loopCount) + { + var loop = new CommandLoop(startTime, loopCount); + loops.Add(loop); + return loop; + } + + public CommandTrigger AddTrigger(string triggerName, double startTime, double endTime, int groupNumber) + { + var trigger = new CommandTrigger(triggerName, startTime, endTime, groupNumber); + triggers.Add(trigger); + return trigger; + } + + public virtual Drawable CreateDrawable() + => new StoryboardSprite(this); + + public override void ApplyTransforms(Drawable target) + { + base.ApplyTransforms(target); + foreach (var loop in loops) + loop.ApplyTransforms(target); + + // TODO + return; + foreach (var trigger in triggers) + trigger.ApplyTransforms(target); + } + + public override string ToString() + => $"{Path}, {Origin}, {InitialPosition}"; + } +} diff --git a/osu.Game/Storyboards/StoryboardDefinition.cs b/osu.Game/Storyboards/StoryboardDefinition.cs new file mode 100644 index 0000000000..853ebe42dc --- /dev/null +++ b/osu.Game/Storyboards/StoryboardDefinition.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Storyboards.Drawables; +using System.Collections.Generic; +using System.Linq; +using System; + +namespace osu.Game.Storyboards +{ + public class StoryboardDefinition + { + private Dictionary layers = new Dictionary(); + public IEnumerable Layers => layers.Values; + + public StoryboardDefinition() + { + layers.Add("Background", new LayerDefinition("Background", 3)); + layers.Add("Fail", new LayerDefinition("Fail", 2) { EnabledWhenPassing = false, }); + layers.Add("Pass", new LayerDefinition("Pass", 1) { ShowWhenFailing = false, }); + layers.Add("Foreground", new LayerDefinition("Foreground", 0)); + } + + public LayerDefinition GetLayer(string name) + { + LayerDefinition layer; + if (!layers.TryGetValue(name, out layer)) + layers[name] = layer = new LayerDefinition(name, layers.Values.Min(l => l.Depth) - 1); + + return layer; + } + + public Storyboard CreateDrawable() + => new Storyboard(this); + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 05ba3e25ab..2703798a6c 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -80,6 +80,21 @@ + + + + + + + + + + + + + + + From 80c35801a62a21289aff1053759c4f51dc0c05bc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Sep 2017 16:15:41 +0900 Subject: [PATCH 315/483] Hide all overlays when home button is pressed --- osu.Game/OsuGame.cs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index c020675881..b4fbdfb252 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -245,7 +245,11 @@ namespace osu.Game LoadComponentAsync(Toolbar = new Toolbar { Depth = -4, - OnHome = delegate { intro?.ChildScreen?.MakeCurrent(); }, + OnHome = delegate + { + hideAllOverlays(); + intro?.ChildScreen?.MakeCurrent(); + }, }, overlayContent.Add); settings.StateChanged += delegate @@ -310,6 +314,16 @@ namespace osu.Game private OsuScreen currentScreen; private FrameworkConfigManager frameworkConfig; + private void hideAllOverlays() + { + settings.State = Visibility.Hidden; + chat.State = Visibility.Hidden; + direct.State = Visibility.Hidden; + social.State = Visibility.Hidden; + userProfile.State = Visibility.Hidden; + notificationOverlay.State = Visibility.Hidden; + } + private void screenChanged(Screen newScreen) { currentScreen = newScreen as OsuScreen; @@ -323,19 +337,12 @@ namespace osu.Game //central game screen change logic. if (!currentScreen.ShowOverlays) { - settings.State = Visibility.Hidden; - Toolbar.State = Visibility.Hidden; + hideAllOverlays(); musicController.State = Visibility.Hidden; - chat.State = Visibility.Hidden; - direct.State = Visibility.Hidden; - social.State = Visibility.Hidden; - userProfile.State = Visibility.Hidden; - notificationOverlay.State = Visibility.Hidden; + Toolbar.State = Visibility.Hidden; } else - { Toolbar.State = Visibility.Visible; - } ScreenChanged?.Invoke(newScreen); } From a5281739438f0c4bc38f52ce3a7f57cb980e0f98 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Sep 2017 19:04:24 +0900 Subject: [PATCH 316/483] Ensure that WorkingBeatmap's Beatmap is never null Also ensures some extra fields inside Beatmap have non-null defaults. --- osu.Game/Beatmaps/Beatmap.cs | 8 ++++---- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 6 +----- osu.Game/Beatmaps/Formats/BeatmapDecoder.cs | 4 +--- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 82777734bb..15953fcd82 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps public class Beatmap where T : HitObject { - public BeatmapInfo BeatmapInfo; + public BeatmapInfo BeatmapInfo = new BeatmapInfo(); public ControlPointInfo ControlPointInfo = new ControlPointInfo(); public List Breaks = new List(); public readonly List ComboColors = new List @@ -33,7 +33,7 @@ namespace osu.Game.Beatmaps /// /// The HitObjects this Beatmap contains. /// - public List HitObjects; + public List HitObjects = new List(); /// /// Total amount of break time in the beatmap. @@ -44,12 +44,13 @@ namespace osu.Game.Beatmaps /// Constructs a new beatmap. /// /// The original beatmap to use the parameters of. - public Beatmap(Beatmap original = null) + public Beatmap(Beatmap original = null) { BeatmapInfo = original?.BeatmapInfo.DeepClone() ?? BeatmapInfo; ControlPointInfo = original?.ControlPointInfo ?? ControlPointInfo; Breaks = original?.Breaks ?? Breaks; ComboColors = original?.ComboColors ?? ComboColors; + HitObjects = original?.HitObjects ?? HitObjects; } } @@ -65,7 +66,6 @@ namespace osu.Game.Beatmaps public Beatmap(Beatmap original = null) : base(original) { - HitObjects = original?.HitObjects; } } } diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 479f274efb..cc982c7a70 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -7,7 +7,6 @@ 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.Scoring; using osu.Game.Rulesets.UI; @@ -42,10 +41,7 @@ namespace osu.Game.Beatmaps this.game = game; } - protected override Beatmap GetBeatmap() => new Beatmap - { - HitObjects = new List(), - }; + protected override Beatmap GetBeatmap() => new Beatmap(); protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4"); diff --git a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs index 234d65eee4..81695c3b5a 100644 --- a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.IO; -using osu.Game.Rulesets.Objects; namespace osu.Game.Beatmaps.Formats { @@ -21,7 +20,7 @@ namespace osu.Game.Beatmaps.Formats { string line; do { line = stream.ReadLine()?.Trim(); } - while (line != null && line.Length == 0); + while (line != null && line.Length == 0); if (line == null || !decoders.ContainsKey(line)) throw new IOException(@"Unknown file format"); @@ -47,7 +46,6 @@ namespace osu.Game.Beatmaps.Formats { var beatmap = new Beatmap { - HitObjects = new List(), BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata(), diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 462f94ed7c..4797f438d0 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps { if (beatmap != null) return beatmap; - beatmap = GetBeatmap(); + beatmap = GetBeatmap() ?? new Beatmap(); // use the database-backed info. beatmap.BeatmapInfo = BeatmapInfo; From 13322b4293ad27ed6a672f2492c21b2bf5f5a12e Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 8 Sep 2017 12:09:45 +0200 Subject: [PATCH 317/483] Improve compatibility with older storyboards. --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 08e1d06621..bcb2c6f666 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -248,7 +248,7 @@ namespace osu.Game.Beatmaps.Formats while (line.StartsWith(" ") || line.StartsWith("_")) { ++depth; - line = line.Substring(depth); + line = line.Substring(1); } decodeVariables(ref line); @@ -305,7 +305,7 @@ namespace osu.Game.Beatmaps.Formats var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo); var frameCount = int.Parse(split[6]); var frameDelay = double.Parse(split[7], NumberFormatInfo.InvariantInfo); - var loopType = (AnimationLoopType)Enum.Parse(typeof(AnimationLoopType), split[8]); + var loopType = split.Length > 8 ? (AnimationLoopType)Enum.Parse(typeof(AnimationLoopType), split[8]) : AnimationLoopType.LoopForever; spriteDefinition = new AnimationDefinition(path, origin, new Vector2(x, y), frameCount, frameDelay, loopType); beatmap.Storyboard.GetLayer(layer).Add(spriteDefinition); } @@ -315,7 +315,7 @@ namespace osu.Game.Beatmaps.Formats var time = double.Parse(split[1], CultureInfo.InvariantCulture); var layer = split[2]; var path = cleanFilename(split[3]); - var volume = float.Parse(split[4], CultureInfo.InvariantCulture); + var volume = split.Length > 4 ? float.Parse(split[4], CultureInfo.InvariantCulture) : 100; beatmap.Storyboard.GetLayer(layer).Add(new SampleDefinition(path, time, volume)); } break; @@ -326,13 +326,14 @@ namespace osu.Game.Beatmaps.Formats if (depth < 2) timelineGroup = spriteDefinition; - switch (split[0]) + var commandType = split[0]; + switch (commandType) { case "T": { var triggerName = split[1]; - var startTime = double.Parse(split[2], CultureInfo.InvariantCulture); - var endTime = double.Parse(split[3], CultureInfo.InvariantCulture); + var startTime = split.Length > 2 ? double.Parse(split[2], CultureInfo.InvariantCulture) : double.MinValue; + var endTime = split.Length > 3 ? double.Parse(split[3], CultureInfo.InvariantCulture) : double.MaxValue; var groupNumber = split.Length > 4 ? int.Parse(split[4]) : 0; timelineGroup = spriteDefinition?.AddTrigger(triggerName, startTime, endTime, groupNumber); } @@ -349,7 +350,6 @@ namespace osu.Game.Beatmaps.Formats if (string.IsNullOrEmpty(split[3])) split[3] = split[2]; - var commandType = split[0]; var easing = (Easing)int.Parse(split[1]); var startTime = double.Parse(split[2], CultureInfo.InvariantCulture); var endTime = double.Parse(split[3], CultureInfo.InvariantCulture); @@ -434,6 +434,8 @@ namespace osu.Game.Beatmaps.Formats } } break; + default: + throw new InvalidDataException($@"Unknown command type: {commandType}"); } } break; From e02b481c6907e17526e53a3edfa9c296583d1934 Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 8 Sep 2017 12:11:57 +0200 Subject: [PATCH 318/483] An attempt at implementing storyboard loops. --- osu.Game/Storyboards/CommandLoop.cs | 20 ++++---- osu.Game/Storyboards/CommandTimeline.cs | 28 +++++++---- osu.Game/Storyboards/CommandTimelineGroup.cs | 50 ++++++++++++-------- osu.Game/Storyboards/Drawables/Storyboard.cs | 2 +- osu.Game/Storyboards/LayerDefinition.cs | 4 +- osu.Game/Storyboards/SpriteDefinition.cs | 16 +++---- osu.Game/Storyboards/StoryboardDefinition.cs | 5 +- 7 files changed, 71 insertions(+), 54 deletions(-) diff --git a/osu.Game/Storyboards/CommandLoop.cs b/osu.Game/Storyboards/CommandLoop.cs index b93a04cea1..d8d059aaed 100644 --- a/osu.Game/Storyboards/CommandLoop.cs +++ b/osu.Game/Storyboards/CommandLoop.cs @@ -2,26 +2,28 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; +using osu.Framework.Graphics.Transforms; namespace osu.Game.Storyboards { public class CommandLoop : CommandTimelineGroup { - private double startTime; - private int loopCount; + public double LoopStartTime; + public int LoopCount; public CommandLoop(double startTime, int loopCount) { - this.startTime = startTime; - this.loopCount = loopCount; + LoopStartTime = startTime; + LoopCount = loopCount; } - public override void ApplyTransforms(Drawable drawable) - { - //base.ApplyTransforms(drawable); - } + public override void ApplyTransforms(Drawable drawable, double offset = 0) + => base.ApplyTransforms(drawable, offset + LoopStartTime); + + protected override void PostProcess(Command command, TransformSequence sequence) + => sequence.Loop(Duration - command.Duration, LoopCount); public override string ToString() - => $"{startTime} x{loopCount}"; + => $"{LoopStartTime} x{LoopCount}"; } } diff --git a/osu.Game/Storyboards/CommandTimeline.cs b/osu.Game/Storyboards/CommandTimeline.cs index 04e165aa38..a533f213fc 100644 --- a/osu.Game/Storyboards/CommandTimeline.cs +++ b/osu.Game/Storyboards/CommandTimeline.cs @@ -10,8 +10,8 @@ namespace osu.Game.Storyboards { public class CommandTimeline : CommandTimeline { - private readonly List commands = new List(); - public IEnumerable Commands => commands.OrderBy(c => c.StartTime); + private readonly List commands = new List(); + public IEnumerable Commands => commands.OrderBy(c => c.StartTime); public bool HasCommands => commands.Count > 0; private Cached startTimeBacking; @@ -19,7 +19,7 @@ namespace osu.Game.Storyboards private Cached endTimeBacking; public double EndTime => endTimeBacking.IsValid ? endTimeBacking : (endTimeBacking.Value = HasCommands ? commands.Max(c => c.EndTime) : double.MaxValue); - + public T StartValue => HasCommands ? commands.OrderBy(c => c.StartTime).First().StartValue : default(T); public T EndValue => HasCommands ? commands.OrderByDescending(c => c.EndTime).First().EndValue : default(T); @@ -28,7 +28,7 @@ namespace osu.Game.Storyboards if (endTime < startTime) return; - commands.Add(new Command { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue, }); + commands.Add(new TypedCommand { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue, }); startTimeBacking.Invalidate(); endTimeBacking.Invalidate(); @@ -37,16 +37,16 @@ namespace osu.Game.Storyboards public override string ToString() => $"{commands.Count} command(s)"; - public class Command + public class TypedCommand : Command { - public Easing Easing; - public double StartTime; - public double EndTime; + public Easing Easing { get; set; } + public double StartTime { get; set; } + public double EndTime { get; set; } + public double Duration => EndTime - StartTime; + public T StartValue; public T EndValue; - public double Duration => EndTime - StartTime; - public override string ToString() => $"{StartTime} -> {EndTime}, {StartValue} -> {EndValue} {Easing}"; } @@ -58,4 +58,12 @@ namespace osu.Game.Storyboards double EndTime { get; } bool HasCommands { get; } } + + public interface Command + { + Easing Easing { get; set; } + double StartTime { get; set; } + double EndTime { get; set; } + double Duration { get; } + } } diff --git a/osu.Game/Storyboards/CommandTimelineGroup.cs b/osu.Game/Storyboards/CommandTimelineGroup.cs index cc67c9dd68..109104b120 100644 --- a/osu.Game/Storyboards/CommandTimelineGroup.cs +++ b/osu.Game/Storyboards/CommandTimelineGroup.cs @@ -4,6 +4,7 @@ using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics; +using osu.Framework.Graphics.Transforms; using osu.Game.Storyboards.Drawables; using System.Collections.Generic; using System.Linq; @@ -40,45 +41,52 @@ namespace osu.Game.Storyboards public double StartTime => Timelines.Where(t => t.HasCommands).Min(t => t.StartTime); public double EndTime => Timelines.Where(t => t.HasCommands).Max(t => t.EndTime); + public double Duration => EndTime - StartTime; public bool HasCommands => Timelines.Any(t => t.HasCommands); - public virtual void ApplyTransforms(Drawable drawable) + public virtual void ApplyTransforms(Drawable drawable, double offset = 0) { if (X.HasCommands) drawable.X = X.StartValue; foreach (var command in X.Commands) - using (drawable.BeginAbsoluteSequence(command.StartTime)) - drawable.MoveToX(command.StartValue) - .MoveToX(command.EndValue, command.Duration, command.Easing); + using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) + PostProcess(command, + drawable.MoveToX(command.StartValue) + .MoveToX(command.EndValue, command.Duration, command.Easing)); if (Y.HasCommands) drawable.Y = Y.StartValue; foreach (var command in Y.Commands) - using (drawable.BeginAbsoluteSequence(command.StartTime)) - drawable.MoveToY(command.StartValue) - .MoveToY(command.EndValue, command.Duration, command.Easing); + using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) + PostProcess(command, + drawable.MoveToY(command.StartValue) + .MoveToY(command.EndValue, command.Duration, command.Easing)); if (Scale.HasCommands) drawable.Scale = Scale.StartValue; foreach (var command in Scale.Commands) - using (drawable.BeginAbsoluteSequence(command.StartTime)) - drawable.ScaleTo(command.StartValue) - .ScaleTo(command.EndValue, command.Duration, command.Easing); + using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) + PostProcess(command, + drawable.ScaleTo(command.StartValue) + .ScaleTo(command.EndValue, command.Duration, command.Easing)); if (Rotation.HasCommands) drawable.Rotation = Rotation.StartValue; foreach (var command in Rotation.Commands) - using (drawable.BeginAbsoluteSequence(command.StartTime)) - drawable.RotateTo(command.StartValue) - .RotateTo(command.EndValue, command.Duration, command.Easing); + using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) + PostProcess(command, + drawable.RotateTo(command.StartValue) + .RotateTo(command.EndValue, command.Duration, command.Easing)); if (Colour.HasCommands) drawable.Colour = Colour.StartValue; foreach (var command in Colour.Commands) - using (drawable.BeginAbsoluteSequence(command.StartTime)) - drawable.FadeColour(command.StartValue) - .FadeColour(command.EndValue, command.Duration, command.Easing); + using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) + PostProcess(command, + drawable.FadeColour(command.StartValue) + .FadeColour(command.EndValue, command.Duration, command.Easing)); if (Alpha.HasCommands) drawable.Alpha = Alpha.StartValue; foreach (var command in Alpha.Commands) - using (drawable.BeginAbsoluteSequence(command.StartTime)) - drawable.FadeTo(command.StartValue) - .FadeTo(command.EndValue, command.Duration, command.Easing); + using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) + PostProcess(command, + drawable.FadeTo(command.StartValue) + .FadeTo(command.EndValue, command.Duration, command.Easing)); if (Additive.HasCommands) drawable.BlendingMode = BlendingMode.Additive; @@ -90,5 +98,9 @@ namespace osu.Game.Storyboards flippable.FlipV = FlipV.HasCommands; } } + + protected virtual void PostProcess(Command command, TransformSequence sequence) + { + } } } diff --git a/osu.Game/Storyboards/Drawables/Storyboard.cs b/osu.Game/Storyboards/Drawables/Storyboard.cs index a5b242357f..45aa063f79 100644 --- a/osu.Game/Storyboards/Drawables/Storyboard.cs +++ b/osu.Game/Storyboards/Drawables/Storyboard.cs @@ -53,7 +53,7 @@ namespace osu.Game.Storyboards.Drawables private void updateLayerVisibility() { foreach (var layer in Children) - layer.Enabled = passing ? layer.Definition.EnabledWhenPassing : layer.Definition.ShowWhenFailing; + layer.Enabled = passing ? layer.Definition.EnabledWhenPassing : layer.Definition.EnabledWhenFailing; } } } diff --git a/osu.Game/Storyboards/LayerDefinition.cs b/osu.Game/Storyboards/LayerDefinition.cs index e632a700f1..871462c3fd 100644 --- a/osu.Game/Storyboards/LayerDefinition.cs +++ b/osu.Game/Storyboards/LayerDefinition.cs @@ -11,11 +11,11 @@ namespace osu.Game.Storyboards public string Name; public int Depth; public bool EnabledWhenPassing = true; - public bool ShowWhenFailing = true; + public bool EnabledWhenFailing = true; private List elements = new List(); public IEnumerable Elements => elements; - + public LayerDefinition(string name, int depth) { Name = name; diff --git a/osu.Game/Storyboards/SpriteDefinition.cs b/osu.Game/Storyboards/SpriteDefinition.cs index 2574e7adb6..b47b6c935e 100644 --- a/osu.Game/Storyboards/SpriteDefinition.cs +++ b/osu.Game/Storyboards/SpriteDefinition.cs @@ -5,6 +5,7 @@ using OpenTK; using osu.Framework.Graphics; using osu.Game.Storyboards.Drawables; using System.Collections.Generic; +using System.Linq; namespace osu.Game.Storyboards { @@ -16,7 +17,7 @@ namespace osu.Game.Storyboards private List loops = new List(); private List triggers = new List(); - + public SpriteDefinition(string path, Anchor origin, Vector2 initialPosition) { Path = path; @@ -41,16 +42,11 @@ namespace osu.Game.Storyboards public virtual Drawable CreateDrawable() => new StoryboardSprite(this); - public override void ApplyTransforms(Drawable target) + public override void ApplyTransforms(Drawable target, double offset = 0) { - base.ApplyTransforms(target); - foreach (var loop in loops) - loop.ApplyTransforms(target); - - // TODO - return; - foreach (var trigger in triggers) - trigger.ApplyTransforms(target); + base.ApplyTransforms(target, offset); + foreach (var loop in loops.OrderBy(l => l.StartTime)) + loop.ApplyTransforms(target, offset); } public override string ToString() diff --git a/osu.Game/Storyboards/StoryboardDefinition.cs b/osu.Game/Storyboards/StoryboardDefinition.cs index 853ebe42dc..e357440bc9 100644 --- a/osu.Game/Storyboards/StoryboardDefinition.cs +++ b/osu.Game/Storyboards/StoryboardDefinition.cs @@ -4,7 +4,6 @@ using osu.Game.Storyboards.Drawables; using System.Collections.Generic; using System.Linq; -using System; namespace osu.Game.Storyboards { @@ -12,12 +11,12 @@ namespace osu.Game.Storyboards { private Dictionary layers = new Dictionary(); public IEnumerable Layers => layers.Values; - + public StoryboardDefinition() { layers.Add("Background", new LayerDefinition("Background", 3)); layers.Add("Fail", new LayerDefinition("Fail", 2) { EnabledWhenPassing = false, }); - layers.Add("Pass", new LayerDefinition("Pass", 1) { ShowWhenFailing = false, }); + layers.Add("Pass", new LayerDefinition("Pass", 1) { EnabledWhenFailing = false, }); layers.Add("Foreground", new LayerDefinition("Foreground", 0)); } From 526ee107b8102ad0dd815e59e8d543f00cc52436 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 8 Sep 2017 12:17:16 +0200 Subject: [PATCH 319/483] Use a method to apply a beatmap, its ruleset and the mods. --- osu.Game/Online/API/Requests/GetScoresRequest.cs | 7 +------ osu.Game/Rulesets/Scoring/OnlineScore.cs | 7 ++++++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index 6e22bd6989..d5ba22b9ac 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -23,12 +23,7 @@ namespace osu.Game.Online.API.Requests private void onSuccess(GetScoresResponse r) { foreach (OnlineScore score in r.Scores) - { - score.Beatmap = beatmap; - score.Ruleset = beatmap.Ruleset; - - score.ResolveModString(); - } + score.ApplyBeatmap(beatmap); } protected override WebRequest CreateWebRequest() diff --git a/osu.Game/Rulesets/Scoring/OnlineScore.cs b/osu.Game/Rulesets/Scoring/OnlineScore.cs index 694ce023d1..a58d682d05 100644 --- a/osu.Game/Rulesets/Scoring/OnlineScore.cs +++ b/osu.Game/Rulesets/Scoring/OnlineScore.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; +using osu.Game.Beatmaps; using osu.Game.Users; using osu.Game.Rulesets.Replays; @@ -82,8 +83,12 @@ namespace osu.Game.Rulesets.Scoring [JsonProperty(@"mods")] private string[] modStrings { get; set; } - public void ResolveModString() + public void ApplyBeatmap(BeatmapInfo beatmap) { + Beatmap = beatmap; + Ruleset = beatmap.Ruleset; + + // Evaluate the mod string Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); } } From 0b1403683bc9a806a152067707eaba56052e273e Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 8 Sep 2017 12:21:35 +0200 Subject: [PATCH 320/483] Moved OnlineScore inside GetScoresRequest.cs --- .../Online/API/Requests/GetScoresRequest.cs | 86 +++++++++++++++++ osu.Game/Rulesets/Scoring/OnlineScore.cs | 95 ------------------- osu.Game/osu.Game.csproj | 1 - 3 files changed, 86 insertions(+), 96 deletions(-) delete mode 100644 osu.Game/Rulesets/Scoring/OnlineScore.cs diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index d5ba22b9ac..ef9ee85d25 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -1,10 +1,14 @@ // Copyright (c) 2007-2017 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 Newtonsoft.Json; using osu.Framework.IO.Network; using osu.Game.Beatmaps; +using osu.Game.Users; +using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; namespace osu.Game.Online.API.Requests @@ -42,4 +46,86 @@ namespace osu.Game.Online.API.Requests [JsonProperty(@"scores")] public IEnumerable Scores; } + + public class OnlineScore : Score + { + [JsonProperty(@"score")] + private double totalScore + { + set { TotalScore = value; } + } + + [JsonProperty(@"max_combo")] + private int maxCombo + { + set { MaxCombo = value; } + } + + [JsonProperty(@"user")] + private User user + { + set { User = value; } + } + + [JsonProperty(@"replay_data")] + private Replay replay + { + set { Replay = value; } + } + + [JsonProperty(@"score_id")] + private long onlineScoreID + { + set { OnlineScoreID = value; } + } + + [JsonProperty(@"created_at")] + private DateTimeOffset date + { + set { Date = value; } + } + + [JsonProperty(@"statistics")] + private Dictionary jsonStats + { + set + { + foreach (var kvp in value) + { + string key = kvp.Key; + switch (key) + { + case @"count_300": + key = @"300"; + break; + case @"count_100": + key = @"100"; + break; + case @"count_50": + key = @"50"; + break; + case @"count_miss": + key = @"x"; + break; + default: + continue; + } + + Statistics.Add(key, kvp.Value); + } + } + } + + [JsonProperty(@"mods")] + private string[] modStrings { get; set; } + + public void ApplyBeatmap(BeatmapInfo beatmap) + { + Beatmap = beatmap; + Ruleset = beatmap.Ruleset; + + // Evaluate the mod string + Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); + } + } } diff --git a/osu.Game/Rulesets/Scoring/OnlineScore.cs b/osu.Game/Rulesets/Scoring/OnlineScore.cs deleted file mode 100644 index a58d682d05..0000000000 --- a/osu.Game/Rulesets/Scoring/OnlineScore.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2007-2017 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 Newtonsoft.Json; -using osu.Game.Beatmaps; -using osu.Game.Users; -using osu.Game.Rulesets.Replays; - -namespace osu.Game.Rulesets.Scoring -{ - public class OnlineScore : Score - { - [JsonProperty(@"score")] - private double totalScore - { - set { TotalScore = value; } - } - - [JsonProperty(@"max_combo")] - private int maxCombo - { - set { MaxCombo = value; } - } - - [JsonProperty(@"user")] - private User user - { - set { User = value; } - } - - [JsonProperty(@"replay_data")] - private Replay replay - { - set { Replay = value; } - } - - [JsonProperty(@"score_id")] - private long onlineScoreID - { - set { OnlineScoreID = value; } - } - - [JsonProperty(@"created_at")] - private DateTimeOffset date - { - set { Date = value; } - } - - [JsonProperty(@"statistics")] - private Dictionary jsonStats - { - set - { - foreach (var kvp in value) - { - string key = kvp.Key; - switch (key) - { - case @"count_300": - key = @"300"; - break; - case @"count_100": - key = @"100"; - break; - case @"count_50": - key = @"50"; - break; - case @"count_miss": - key = @"x"; - break; - default: - continue; - } - - Statistics.Add(key, kvp.Value); - } - } - } - - [JsonProperty(@"mods")] - private string[] modStrings { get; set; } - - public void ApplyBeatmap(BeatmapInfo beatmap) - { - Beatmap = beatmap; - Ruleset = beatmap.Ruleset; - - // Evaluate the mod string - Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); - } - } -} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 66a892406f..05ba3e25ab 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -244,7 +244,6 @@ - From 6cde687d87fd27e16fc8754ad3d8d0bdd51cad25 Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 8 Sep 2017 12:36:13 +0200 Subject: [PATCH 321/483] Fix V commands parsing. --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index bcb2c6f666..6fde7263da 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -376,7 +376,7 @@ namespace osu.Game.Beatmaps.Formats var startY = float.Parse(split[5], CultureInfo.InvariantCulture); var endX = split.Length > 6 ? float.Parse(split[6], CultureInfo.InvariantCulture) : startX; var endY = split.Length > 7 ? float.Parse(split[7], CultureInfo.InvariantCulture) : startY; - timelineGroup?.Scale.Add(easing, startTime, endTime, new Vector2(startX, startY), new Vector2(startX, endY)); + timelineGroup?.Scale.Add(easing, startTime, endTime, new Vector2(startX, startY), new Vector2(endX, endY)); } break; case "R": From e63fb5720c219aafdeaac3f76c3d2f34a8ea3b71 Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 8 Sep 2017 13:04:53 +0200 Subject: [PATCH 322/483] Make CI happy. --- osu.Desktop.Tests/Visual/TestCaseStoryboard.cs | 5 ++--- osu.Game/Storyboards/CommandLoop.cs | 2 +- osu.Game/Storyboards/CommandTimeline.cs | 8 ++++---- osu.Game/Storyboards/CommandTimelineGroup.cs | 4 ++-- osu.Game/Storyboards/CommandTrigger.cs | 18 +++++++++--------- .../Drawables/StoryboardAnimation.cs | 1 - .../Storyboards/Drawables/StoryboardSprite.cs | 1 - ...mentDefinition.cs => IElementDefinition.cs} | 2 +- osu.Game/Storyboards/LayerDefinition.cs | 6 +++--- osu.Game/Storyboards/SampleDefinition.cs | 4 ++-- osu.Game/Storyboards/SpriteDefinition.cs | 8 ++++---- osu.Game/osu.Game.csproj | 2 +- 12 files changed, 29 insertions(+), 32 deletions(-) rename osu.Game/Storyboards/{ElementDefinition.cs => IElementDefinition.cs} (84%) diff --git a/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs b/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs index 1d7b3dffd2..10dd706f62 100644 --- a/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs +++ b/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs @@ -21,8 +21,7 @@ namespace osu.Desktop.Tests.Visual private readonly Bindable beatmapBacking = new Bindable(); - private MusicController musicController; - private Container storyboardContainer; + private readonly Container storyboardContainer; private Storyboard storyboard; public TestCaseStoryboard() @@ -45,7 +44,7 @@ namespace osu.Desktop.Tests.Visual }, }, }); - Add(musicController = new MusicController + Add(new MusicController { Origin = Anchor.TopRight, Anchor = Anchor.TopRight, diff --git a/osu.Game/Storyboards/CommandLoop.cs b/osu.Game/Storyboards/CommandLoop.cs index d8d059aaed..d7eb041de1 100644 --- a/osu.Game/Storyboards/CommandLoop.cs +++ b/osu.Game/Storyboards/CommandLoop.cs @@ -20,7 +20,7 @@ namespace osu.Game.Storyboards public override void ApplyTransforms(Drawable drawable, double offset = 0) => base.ApplyTransforms(drawable, offset + LoopStartTime); - protected override void PostProcess(Command command, TransformSequence sequence) + protected override void PostProcess(ICommand command, TransformSequence sequence) => sequence.Loop(Duration - command.Duration, LoopCount); public override string ToString() diff --git a/osu.Game/Storyboards/CommandTimeline.cs b/osu.Game/Storyboards/CommandTimeline.cs index a533f213fc..909a629ad2 100644 --- a/osu.Game/Storyboards/CommandTimeline.cs +++ b/osu.Game/Storyboards/CommandTimeline.cs @@ -8,7 +8,7 @@ using System.Linq; namespace osu.Game.Storyboards { - public class CommandTimeline : CommandTimeline + public class CommandTimeline : ICommandTimeline { private readonly List commands = new List(); public IEnumerable Commands => commands.OrderBy(c => c.StartTime); @@ -37,7 +37,7 @@ namespace osu.Game.Storyboards public override string ToString() => $"{commands.Count} command(s)"; - public class TypedCommand : Command + public class TypedCommand : ICommand { public Easing Easing { get; set; } public double StartTime { get; set; } @@ -52,14 +52,14 @@ namespace osu.Game.Storyboards } } - public interface CommandTimeline + public interface ICommandTimeline { double StartTime { get; } double EndTime { get; } bool HasCommands { get; } } - public interface Command + public interface ICommand { Easing Easing { get; set; } double StartTime { get; set; } diff --git a/osu.Game/Storyboards/CommandTimelineGroup.cs b/osu.Game/Storyboards/CommandTimelineGroup.cs index 109104b120..cff8d54d29 100644 --- a/osu.Game/Storyboards/CommandTimelineGroup.cs +++ b/osu.Game/Storyboards/CommandTimelineGroup.cs @@ -23,7 +23,7 @@ namespace osu.Game.Storyboards public CommandTimeline FlipH = new CommandTimeline(); public CommandTimeline FlipV = new CommandTimeline(); - public IEnumerable Timelines + public IEnumerable Timelines { get { @@ -99,7 +99,7 @@ namespace osu.Game.Storyboards } } - protected virtual void PostProcess(Command command, TransformSequence sequence) + protected virtual void PostProcess(ICommand command, TransformSequence sequence) { } } diff --git a/osu.Game/Storyboards/CommandTrigger.cs b/osu.Game/Storyboards/CommandTrigger.cs index e7133e170f..e2731f9c45 100644 --- a/osu.Game/Storyboards/CommandTrigger.cs +++ b/osu.Game/Storyboards/CommandTrigger.cs @@ -5,20 +5,20 @@ namespace osu.Game.Storyboards { public class CommandTrigger : CommandTimelineGroup { - private string triggerName; - private double startTime; - private double endTime; - private int groupNumber; + public string TriggerName; + public double TriggerStartTime; + public double TriggerEndTime; + public int GroupNumber; public CommandTrigger(string triggerName, double startTime, double endTime, int groupNumber) { - this.triggerName = triggerName; - this.startTime = startTime; - this.endTime = endTime; - this.groupNumber = groupNumber; + TriggerName = triggerName; + TriggerStartTime = startTime; + TriggerEndTime = endTime; + GroupNumber = groupNumber; } public override string ToString() - => $"{triggerName} {startTime} -> {endTime} ({groupNumber})"; + => $"{TriggerName} {TriggerStartTime} -> {TriggerEndTime} ({GroupNumber})"; } } diff --git a/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs index 583a0d13c3..c3a4e8b865 100644 --- a/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs @@ -5,7 +5,6 @@ using OpenTK; using osu.Framework.Allocation; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Textures; -using osu.Framework.IO.File; using System.Linq; namespace osu.Game.Storyboards.Drawables diff --git a/osu.Game/Storyboards/Drawables/StoryboardSprite.cs b/osu.Game/Storyboards/Drawables/StoryboardSprite.cs index 927996d750..35cd19474e 100644 --- a/osu.Game/Storyboards/Drawables/StoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/StoryboardSprite.cs @@ -5,7 +5,6 @@ using OpenTK; using osu.Framework.Allocation; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Framework.IO.File; using System.Linq; namespace osu.Game.Storyboards.Drawables diff --git a/osu.Game/Storyboards/ElementDefinition.cs b/osu.Game/Storyboards/IElementDefinition.cs similarity index 84% rename from osu.Game/Storyboards/ElementDefinition.cs rename to osu.Game/Storyboards/IElementDefinition.cs index 1a8de9a120..93c9a473f7 100644 --- a/osu.Game/Storyboards/ElementDefinition.cs +++ b/osu.Game/Storyboards/IElementDefinition.cs @@ -5,7 +5,7 @@ using osu.Framework.Graphics; namespace osu.Game.Storyboards { - public interface ElementDefinition + public interface IElementDefinition { string Path { get; } Drawable CreateDrawable(); diff --git a/osu.Game/Storyboards/LayerDefinition.cs b/osu.Game/Storyboards/LayerDefinition.cs index 871462c3fd..baefe1626a 100644 --- a/osu.Game/Storyboards/LayerDefinition.cs +++ b/osu.Game/Storyboards/LayerDefinition.cs @@ -13,8 +13,8 @@ namespace osu.Game.Storyboards public bool EnabledWhenPassing = true; public bool EnabledWhenFailing = true; - private List elements = new List(); - public IEnumerable Elements => elements; + private readonly List elements = new List(); + public IEnumerable Elements => elements; public LayerDefinition(string name, int depth) { @@ -22,7 +22,7 @@ namespace osu.Game.Storyboards Depth = depth; } - public void Add(ElementDefinition element) + public void Add(IElementDefinition element) { elements.Add(element); } diff --git a/osu.Game/Storyboards/SampleDefinition.cs b/osu.Game/Storyboards/SampleDefinition.cs index 26d2c4b029..5d5e8ef1e9 100644 --- a/osu.Game/Storyboards/SampleDefinition.cs +++ b/osu.Game/Storyboards/SampleDefinition.cs @@ -5,9 +5,9 @@ using osu.Framework.Graphics; namespace osu.Game.Storyboards { - public class SampleDefinition : ElementDefinition + public class SampleDefinition : IElementDefinition { - public string Path { get; private set; } + public string Path { get; set; } public double Time; public float Volume; diff --git a/osu.Game/Storyboards/SpriteDefinition.cs b/osu.Game/Storyboards/SpriteDefinition.cs index b47b6c935e..8529d66c7f 100644 --- a/osu.Game/Storyboards/SpriteDefinition.cs +++ b/osu.Game/Storyboards/SpriteDefinition.cs @@ -9,14 +9,14 @@ using System.Linq; namespace osu.Game.Storyboards { - public class SpriteDefinition : CommandTimelineGroup, ElementDefinition + public class SpriteDefinition : CommandTimelineGroup, IElementDefinition { - public string Path { get; private set; } + public string Path { get; set; } public Anchor Origin; public Vector2 InitialPosition; - private List loops = new List(); - private List triggers = new List(); + private readonly List loops = new List(); + private readonly List triggers = new List(); public SpriteDefinition(string path, Anchor origin, Vector2 initialPosition) { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2703798a6c..8c91a9e80a 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -86,7 +86,7 @@ - + From 7b497c0ecbc40b9979e6a340c8a9726738f89357 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Sep 2017 23:24:47 +0900 Subject: [PATCH 323/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 5f2d5a57e5..4e7ea6af4f 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 5f2d5a57e5d506d7e5d87eeeb442adf10be061f6 +Subproject commit 4e7ea6af4f59f21f6afc522fb063c05417e1a5fe From 5c125737cb6a52b8a9c025fcdc1c7274d94120a0 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 8 Sep 2017 17:47:23 +0200 Subject: [PATCH 324/483] Fix wrong initial topic color of not joined channels in the channel selection --- osu.Game/Overlays/Chat/ChannelListItem.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChannelListItem.cs b/osu.Game/Overlays/Chat/ChannelListItem.cs index f43154ea20..8360e793d8 100644 --- a/osu.Game/Overlays/Chat/ChannelListItem.cs +++ b/osu.Game/Overlays/Chat/ChannelListItem.cs @@ -76,7 +76,6 @@ namespace osu.Game.Overlays.Chat Size = new Vector2(text_size), Shadow = false, Margin = new MarginPadding { Right = 10f }, - Alpha = 0f, }, }, }, @@ -109,7 +108,6 @@ namespace osu.Game.Overlays.Chat TextSize = text_size, Font = @"Exo2.0-SemiBold", Shadow = false, - Alpha = 0.8f, }, }, }, @@ -151,6 +149,9 @@ namespace osu.Game.Overlays.Chat joinedBind.ValueChanged += updateColour; joinedBind.BindTo(channel.Joined); + + joinedBind.TriggerChange(); + FinishTransforms(true); } protected override bool OnHover(InputState state) From 3f2598543c563fdb8765124088d7c7b03001173f Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 8 Sep 2017 18:03:04 +0200 Subject: [PATCH 325/483] Fix CommandLoop start and end time. --- osu.Game/Storyboards/CommandLoop.cs | 5 ++++- osu.Game/Storyboards/CommandTimelineGroup.cs | 9 +++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/osu.Game/Storyboards/CommandLoop.cs b/osu.Game/Storyboards/CommandLoop.cs index d7eb041de1..a93903f4a9 100644 --- a/osu.Game/Storyboards/CommandLoop.cs +++ b/osu.Game/Storyboards/CommandLoop.cs @@ -11,6 +11,9 @@ namespace osu.Game.Storyboards public double LoopStartTime; public int LoopCount; + public override double StartTime => LoopStartTime; + public override double EndTime => LoopStartTime + CommandsDuration * LoopCount; + public CommandLoop(double startTime, int loopCount) { LoopStartTime = startTime; @@ -21,7 +24,7 @@ namespace osu.Game.Storyboards => base.ApplyTransforms(drawable, offset + LoopStartTime); protected override void PostProcess(ICommand command, TransformSequence sequence) - => sequence.Loop(Duration - command.Duration, LoopCount); + => sequence.Loop(CommandsDuration - command.Duration, LoopCount); public override string ToString() => $"{LoopStartTime} x{LoopCount}"; diff --git a/osu.Game/Storyboards/CommandTimelineGroup.cs b/osu.Game/Storyboards/CommandTimelineGroup.cs index cff8d54d29..badd9a810a 100644 --- a/osu.Game/Storyboards/CommandTimelineGroup.cs +++ b/osu.Game/Storyboards/CommandTimelineGroup.cs @@ -39,9 +39,14 @@ namespace osu.Game.Storyboards } } - public double StartTime => Timelines.Where(t => t.HasCommands).Min(t => t.StartTime); - public double EndTime => Timelines.Where(t => t.HasCommands).Max(t => t.EndTime); + public double CommandsStartTime => Timelines.Where(t => t.HasCommands).Min(t => t.StartTime); + public double CommandsEndTime => Timelines.Where(t => t.HasCommands).Max(t => t.EndTime); + public double CommandsDuration => CommandsEndTime - CommandsStartTime; + + public virtual double StartTime => CommandsStartTime; + public virtual double EndTime => CommandsEndTime; public double Duration => EndTime - StartTime; + public bool HasCommands => Timelines.Any(t => t.HasCommands); public virtual void ApplyTransforms(Drawable drawable, double offset = 0) From 15dd8d9071597c872e3d9296d2fcd3fe597a2e9f Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Fri, 8 Sep 2017 18:21:42 +0200 Subject: [PATCH 326/483] Mind the minimum size of the channel selection overlay --- osu.Game/Overlays/ChatOverlay.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index b1deae8272..af5c6d9916 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -212,7 +212,13 @@ namespace osu.Game.Overlays { Trace.Assert(state.Mouse.PositionMouseDown != null); - chatHeight.Value = startDragChatHeight - (state.Mouse.Position.Y - state.Mouse.PositionMouseDown.Value.Y) / Parent.DrawSize.Y; + double targetChatHeight = startDragChatHeight - (state.Mouse.Position.Y - state.Mouse.PositionMouseDown.Value.Y) / Parent.DrawSize.Y; + + // If the channel selection screen is shown, mind its minimum height + if (channelSelection.State == Visibility.Visible && targetChatHeight > 1f - channel_selection_min_height) + targetChatHeight = 1f - channel_selection_min_height; + + chatHeight.Value = targetChatHeight; } return true; From ce68b6661e3e957d28a5af0eee817be92b3e9d14 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 8 Sep 2017 14:15:28 -0300 Subject: [PATCH 327/483] Update visual test. --- .../Visual/TestCaseBeatmapDetails.cs | 117 +++++++++++++----- osu.Game/Screens/Select/BeatmapDetails.cs | 4 +- 2 files changed, 88 insertions(+), 33 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs b/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs index 11a15cf56f..7f447337bd 100644 --- a/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs +++ b/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs @@ -20,42 +20,97 @@ namespace osu.Desktop.Tests.Visual { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding(150), - Beatmap = new BeatmapInfo + }); + + AddStep("beatmap all metrics", () => details.Beatmap = new BeatmapInfo + { + Version = "All Metrics", + Metadata = new BeatmapMetadata { - Version = "VisualTest", - Metadata = new BeatmapMetadata - { - Source = "Some guy", - Tags = "beatmap metadata example with a very very long list of tags and not much creativity", - }, - Difficulty = new BeatmapDifficulty - { - CircleSize = 7, - ApproachRate = 3.5f, - OverallDifficulty = 5.7f, - DrainRate = 1, - }, - StarDifficulty = 5.3f, - Metrics = new BeatmapMetrics - { - Ratings = Enumerable.Range(0, 10), - Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6), - Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6), - }, + Source = "osu!lazer", + Tags = "this beatmap has all the metrics", + }, + Difficulty = new BeatmapDifficulty + { + CircleSize = 7, + DrainRate = 1, + OverallDifficulty = 5.7f, + ApproachRate = 3.5f, + }, + StarDifficulty = 5.3f, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), }, }); - AddRepeatStep("fail values", newRetryAndFailValues, 10); - } + AddStep("beatmap ratings", () => details.Beatmap = new BeatmapInfo + { + Version = "Only Ratings", + Metadata = new BeatmapMetadata + { + Source = "osu!lazer", + Tags = "this beatmap has ratings metrics but not retries or fails", + }, + Difficulty = new BeatmapDifficulty + { + CircleSize = 6, + DrainRate = 9, + OverallDifficulty = 6, + ApproachRate = 6, + }, + StarDifficulty = 4.8f, + Metrics = new BeatmapMetrics + { + Ratings = Enumerable.Range(0, 10), + }, + }); - private int lastRange = 1; + AddStep("beatmap fails retries", () => details.Beatmap = new BeatmapInfo + { + Version = "Only Retries and Fails", + Metadata = new BeatmapMetadata + { + Source = "osu!lazer", + Tags = "this beatmap has retries and fails but no ratings", + }, + Difficulty = new BeatmapDifficulty + { + CircleSize = 3.7f, + DrainRate = 6, + OverallDifficulty = 6, + ApproachRate = 7, + }, + StarDifficulty = 2.91f, + Metrics = new BeatmapMetrics + { + Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6), + Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6), + }, + }); - private void newRetryAndFailValues() - { - details.Beatmap.Metrics.Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6); - details.Beatmap.Metrics.Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6); - details.Beatmap = details.Beatmap; - lastRange += 100; + AddStep("beatmap no metrics", () => details.Beatmap = new BeatmapInfo + { + Version = "No Metrics", + Metadata = new BeatmapMetadata + { + Source = "osu!lazer", + Tags = "this beatmap has no metrics", + }, + Difficulty = new BeatmapDifficulty + { + CircleSize = 5, + DrainRate = 5, + OverallDifficulty = 5.5f, + ApproachRate = 6.5f, + }, + StarDifficulty = 1.97f, + Metrics = new BeatmapMetrics(), + }); + + AddStep("null beatmap", () => details.Beatmap = null); } } -} \ No newline at end of file +} diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 7c3b8ba905..b389489e0f 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -215,8 +215,8 @@ namespace osu.Game.Screens.Select private void displayMetrics(BeatmapMetrics metrics, bool failOnMissing = true) { - var hasRatings = metrics?.Ratings.Any() ?? false; - var hasRetriesFails = (metrics?.Retries.Any() ?? false) && metrics.Fails.Any(); + var hasRatings = metrics?.Ratings?.Any() ?? false; + var hasRetriesFails = (metrics?.Retries?.Any() ?? false) && (metrics?.Fails?.Any() ?? false); if (failOnMissing) loading.Hide(); From d95940ed5e2eec4a1b67cd50d28945891174bd2a Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 8 Sep 2017 14:25:41 -0300 Subject: [PATCH 328/483] CI fixes. --- osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs | 3 +-- osu.Game/Screens/Select/BeatmapDetails.cs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs b/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs index 7f447337bd..d0f631201a 100644 --- a/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs +++ b/osu.Desktop.Tests/Visual/TestCaseBeatmapDetails.cs @@ -12,10 +12,9 @@ namespace osu.Desktop.Tests.Visual { public override string Description => "BeatmapDetails tab of BeatmapDetailArea"; - private readonly BeatmapDetails details; - public TestCaseBeatmapDetails() { + BeatmapDetails details; Add(details = new BeatmapDetails { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index b389489e0f..a98362e89c 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -216,7 +216,7 @@ namespace osu.Game.Screens.Select private void displayMetrics(BeatmapMetrics metrics, bool failOnMissing = true) { var hasRatings = metrics?.Ratings?.Any() ?? false; - var hasRetriesFails = (metrics?.Retries?.Any() ?? false) && (metrics?.Fails?.Any() ?? false); + var hasRetriesFails = (metrics?.Retries?.Any() ?? false) && (metrics.Fails?.Any() ?? false); if (failOnMissing) loading.Hide(); From e4a2ad5eb5a31e41bc83e2db385f985ec1606497 Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 8 Sep 2017 20:39:17 +0200 Subject: [PATCH 329/483] Fix storyboard sprite flipping. --- .../Drawables/StoryboardAnimation.cs | 31 ++++++++++++++++++- .../Storyboards/Drawables/StoryboardSprite.cs | 31 ++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs index c3a4e8b865..eb2ba59397 100644 --- a/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs @@ -3,6 +3,7 @@ using OpenTK; using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Textures; using System.Linq; @@ -18,7 +19,35 @@ namespace osu.Game.Storyboards.Drawables public bool FlipH { get; set; } public bool FlipV { get; set; } - protected override Vector2 DrawScale => new Vector2(FlipH ? -base.DrawScale.X : base.DrawScale.X, FlipV ? -base.DrawScale.Y : base.DrawScale.Y); + + protected override Vector2 DrawScale + => new Vector2(FlipH ? -base.DrawScale.X : base.DrawScale.X, FlipV ? -base.DrawScale.Y : base.DrawScale.Y); + + public override Anchor Origin + { + get + { + var origin = base.Origin; + + if (FlipH) + { + if (origin.HasFlag(Anchor.x0)) + origin = Anchor.x2 | (origin & (Anchor.y0 | Anchor.y1 | Anchor.y2)); + else if (origin.HasFlag(Anchor.x2)) + origin = Anchor.x0 | (origin & (Anchor.y0 | Anchor.y1 | Anchor.y2)); + } + + if (FlipV) + { + if (origin.HasFlag(Anchor.y0)) + origin = Anchor.y2 | (origin & (Anchor.x0 | Anchor.x1 | Anchor.x2)); + else if (origin.HasFlag(Anchor.y2)) + origin = Anchor.y0 | (origin & (Anchor.x0 | Anchor.x1 | Anchor.x2)); + } + + return origin; + } + } public StoryboardAnimation(AnimationDefinition definition) { diff --git a/osu.Game/Storyboards/Drawables/StoryboardSprite.cs b/osu.Game/Storyboards/Drawables/StoryboardSprite.cs index 35cd19474e..565b5a5069 100644 --- a/osu.Game/Storyboards/Drawables/StoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/StoryboardSprite.cs @@ -3,6 +3,7 @@ using OpenTK; using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using System.Linq; @@ -18,7 +19,35 @@ namespace osu.Game.Storyboards.Drawables public bool FlipH { get; set; } public bool FlipV { get; set; } - protected override Vector2 DrawScale => new Vector2(FlipH ? -base.DrawScale.X : base.DrawScale.X, FlipV ? -base.DrawScale.Y : base.DrawScale.Y); + + protected override Vector2 DrawScale + => new Vector2(FlipH ? -base.DrawScale.X : base.DrawScale.X, FlipV ? -base.DrawScale.Y : base.DrawScale.Y); + + public override Anchor Origin + { + get + { + var origin = base.Origin; + + if (FlipH) + { + if (origin.HasFlag(Anchor.x0)) + origin = Anchor.x2 | (origin & (Anchor.y0 | Anchor.y1 | Anchor.y2)); + else if (origin.HasFlag(Anchor.x2)) + origin = Anchor.x0 | (origin & (Anchor.y0 | Anchor.y1 | Anchor.y2)); + } + + if (FlipV) + { + if (origin.HasFlag(Anchor.y0)) + origin = Anchor.y2 | (origin & (Anchor.x0 | Anchor.x1 | Anchor.x2)); + else if (origin.HasFlag(Anchor.y2)) + origin = Anchor.y0 | (origin & (Anchor.x0 | Anchor.x1 | Anchor.x2)); + } + + return origin; + } + } public StoryboardSprite(SpriteDefinition definition) { From e8ab853f6f4ec4c630dfdfa7caa0b722aa765f58 Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 8 Sep 2017 18:00:17 +0200 Subject: [PATCH 330/483] Make storyboard loops work. --- osu.Game/Storyboards/CommandLoop.cs | 17 +++-- osu.Game/Storyboards/CommandTimelineGroup.cs | 72 ++++---------------- osu.Game/Storyboards/SpriteDefinition.cs | 61 +++++++++++++++-- 3 files changed, 81 insertions(+), 69 deletions(-) diff --git a/osu.Game/Storyboards/CommandLoop.cs b/osu.Game/Storyboards/CommandLoop.cs index a93903f4a9..02b5eb0122 100644 --- a/osu.Game/Storyboards/CommandLoop.cs +++ b/osu.Game/Storyboards/CommandLoop.cs @@ -1,8 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Graphics; -using osu.Framework.Graphics.Transforms; +using System.Collections.Generic; namespace osu.Game.Storyboards { @@ -20,11 +19,15 @@ namespace osu.Game.Storyboards LoopCount = loopCount; } - public override void ApplyTransforms(Drawable drawable, double offset = 0) - => base.ApplyTransforms(drawable, offset + LoopStartTime); - - protected override void PostProcess(ICommand command, TransformSequence sequence) - => sequence.Loop(CommandsDuration - command.Duration, LoopCount); + public override IEnumerable.TypedCommand> GetCommands(CommandTimelineSelector timelineSelector, double offset = 0) + { + for (var loop = 0; loop < LoopCount; loop++) + { + var loopOffset = LoopStartTime + loop * CommandsDuration; + foreach (var command in base.GetCommands(timelineSelector, offset + loopOffset)) + yield return command; + } + } public override string ToString() => $"{LoopStartTime} x{LoopCount}"; diff --git a/osu.Game/Storyboards/CommandTimelineGroup.cs b/osu.Game/Storyboards/CommandTimelineGroup.cs index badd9a810a..a42aca7c28 100644 --- a/osu.Game/Storyboards/CommandTimelineGroup.cs +++ b/osu.Game/Storyboards/CommandTimelineGroup.cs @@ -3,14 +3,13 @@ using OpenTK; using OpenTK.Graphics; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Transforms; -using osu.Game.Storyboards.Drawables; using System.Collections.Generic; using System.Linq; namespace osu.Game.Storyboards { + public delegate CommandTimeline CommandTimelineSelector(CommandTimelineGroup commandTimelineGroup); + public class CommandTimelineGroup { public CommandTimeline X = new CommandTimeline(); @@ -49,63 +48,20 @@ namespace osu.Game.Storyboards public bool HasCommands => Timelines.Any(t => t.HasCommands); - public virtual void ApplyTransforms(Drawable drawable, double offset = 0) + public virtual IEnumerable.TypedCommand> GetCommands(CommandTimelineSelector timelineSelector, double offset = 0) { - if (X.HasCommands) drawable.X = X.StartValue; - foreach (var command in X.Commands) - using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) - PostProcess(command, - drawable.MoveToX(command.StartValue) - .MoveToX(command.EndValue, command.Duration, command.Easing)); + if (offset != 0) + return timelineSelector(this).Commands.Select(command => + new CommandTimeline.TypedCommand + { + Easing = command.Easing, + StartTime = offset + command.StartTime, + EndTime = offset + command.EndTime, + StartValue = command.StartValue, + EndValue = command.EndValue, + }); - if (Y.HasCommands) drawable.Y = Y.StartValue; - foreach (var command in Y.Commands) - using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) - PostProcess(command, - drawable.MoveToY(command.StartValue) - .MoveToY(command.EndValue, command.Duration, command.Easing)); - - if (Scale.HasCommands) drawable.Scale = Scale.StartValue; - foreach (var command in Scale.Commands) - using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) - PostProcess(command, - drawable.ScaleTo(command.StartValue) - .ScaleTo(command.EndValue, command.Duration, command.Easing)); - - if (Rotation.HasCommands) drawable.Rotation = Rotation.StartValue; - foreach (var command in Rotation.Commands) - using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) - PostProcess(command, - drawable.RotateTo(command.StartValue) - .RotateTo(command.EndValue, command.Duration, command.Easing)); - - if (Colour.HasCommands) drawable.Colour = Colour.StartValue; - foreach (var command in Colour.Commands) - using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) - PostProcess(command, - drawable.FadeColour(command.StartValue) - .FadeColour(command.EndValue, command.Duration, command.Easing)); - - if (Alpha.HasCommands) drawable.Alpha = Alpha.StartValue; - foreach (var command in Alpha.Commands) - using (drawable.BeginAbsoluteSequence(offset + command.StartTime)) - PostProcess(command, - drawable.FadeTo(command.StartValue) - .FadeTo(command.EndValue, command.Duration, command.Easing)); - - if (Additive.HasCommands) - drawable.BlendingMode = BlendingMode.Additive; - - var flippable = drawable as IFlippable; - if (flippable != null) - { - flippable.FlipH = FlipH.HasCommands; - flippable.FlipV = FlipV.HasCommands; - } - } - - protected virtual void PostProcess(ICommand command, TransformSequence sequence) - { + return timelineSelector(this).Commands; } } } diff --git a/osu.Game/Storyboards/SpriteDefinition.cs b/osu.Game/Storyboards/SpriteDefinition.cs index 8529d66c7f..c1a3588960 100644 --- a/osu.Game/Storyboards/SpriteDefinition.cs +++ b/osu.Game/Storyboards/SpriteDefinition.cs @@ -4,6 +4,7 @@ using OpenTK; using osu.Framework.Graphics; using osu.Game.Storyboards.Drawables; +using System; using System.Collections.Generic; using System.Linq; @@ -18,6 +19,9 @@ namespace osu.Game.Storyboards private readonly List loops = new List(); private readonly List triggers = new List(); + private delegate void DrawablePropertyInitializer(Drawable drawable, T value); + private delegate void DrawableTransformer(Drawable drawable, T value, double duration, Easing easing); + public SpriteDefinition(string path, Anchor origin, Vector2 initialPosition) { Path = path; @@ -42,11 +46,60 @@ namespace osu.Game.Storyboards public virtual Drawable CreateDrawable() => new StoryboardSprite(this); - public override void ApplyTransforms(Drawable target, double offset = 0) + public override IEnumerable.TypedCommand> GetCommands(CommandTimelineSelector timelineSelector, double offset = 0) { - base.ApplyTransforms(target, offset); - foreach (var loop in loops.OrderBy(l => l.StartTime)) - loop.ApplyTransforms(target, offset); + var result = base.GetCommands(timelineSelector, offset); + foreach (var loop in loops) + result = result.Concat(loop.GetCommands(timelineSelector, offset)); + return result; + } + + public void ApplyTransforms(Drawable drawable, IEnumerable> triggeredGroups = null) + { + applyCommands(drawable, triggeredGroups, g => g.X, (d, value) => d.X = value, (d, value, duration, easing) => d.MoveToX(value, duration, easing)); + applyCommands(drawable, triggeredGroups, g => g.Y, (d, value) => d.Y = value, (d, value, duration, easing) => d.MoveToY(value, duration, easing)); + applyCommands(drawable, triggeredGroups, g => g.Scale, (d, value) => d.Scale = value, (d, value, duration, easing) => d.ScaleTo(value, duration, easing)); + applyCommands(drawable, triggeredGroups, g => g.Rotation, (d, value) => d.Rotation = value, (d, value, duration, easing) => d.RotateTo(value, duration, easing)); + applyCommands(drawable, triggeredGroups, g => g.Colour, (d, value) => d.Colour = value, (d, value, duration, easing) => d.FadeColour(value, duration, easing)); + applyCommands(drawable, triggeredGroups, g => g.Alpha, (d, value) => d.Alpha = value, (d, value, duration, easing) => d.FadeTo(value, duration, easing)); + + if (getAggregatedCommands(g => g.Additive, triggeredGroups).Any()) + drawable.BlendingMode = BlendingMode.Additive; + + var flippable = drawable as IFlippable; + if (flippable != null) + { + flippable.FlipH = getAggregatedCommands(g => g.FlipH, triggeredGroups).Any(); + flippable.FlipV = getAggregatedCommands(g => g.FlipV, triggeredGroups).Any(); + } + } + + private void applyCommands(Drawable drawable, IEnumerable> triggeredGroups, + CommandTimelineSelector timelineSelector, DrawablePropertyInitializer initializeProperty, DrawableTransformer transform) + { + var initialized = false; + foreach (var command in getAggregatedCommands(timelineSelector, triggeredGroups)) + { + if (!initialized) + { + initializeProperty(drawable, command.StartValue); + initialized = true; + } + using (drawable.BeginAbsoluteSequence(command.StartTime)) + { + transform(drawable, command.StartValue, 0, Easing.None); + transform(drawable, command.EndValue, command.Duration, command.Easing); + } + } + } + + private IEnumerable.TypedCommand> getAggregatedCommands(CommandTimelineSelector timelineSelector, IEnumerable> triggeredGroups) + { + var commands = GetCommands(timelineSelector); + if (triggeredGroups != null) + foreach (var pair in triggeredGroups) + commands = commands.Concat(pair.Item1.GetCommands(timelineSelector, pair.Item2)); + return commands.OrderBy(l => l.StartTime); } public override string ToString() From 4ab243d885f78dc0595c57318216b4cac1fea2db Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 8 Sep 2017 21:23:24 +0200 Subject: [PATCH 331/483] CI fixes. --- osu.Game/Storyboards/SpriteDefinition.cs | 4 ++-- osu.Game/Storyboards/StoryboardDefinition.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Storyboards/SpriteDefinition.cs b/osu.Game/Storyboards/SpriteDefinition.cs index c1a3588960..4f161a34f4 100644 --- a/osu.Game/Storyboards/SpriteDefinition.cs +++ b/osu.Game/Storyboards/SpriteDefinition.cs @@ -19,8 +19,8 @@ namespace osu.Game.Storyboards private readonly List loops = new List(); private readonly List triggers = new List(); - private delegate void DrawablePropertyInitializer(Drawable drawable, T value); - private delegate void DrawableTransformer(Drawable drawable, T value, double duration, Easing easing); + private delegate void DrawablePropertyInitializer(Drawable drawable, T value); + private delegate void DrawableTransformer(Drawable drawable, T value, double duration, Easing easing); public SpriteDefinition(string path, Anchor origin, Vector2 initialPosition) { diff --git a/osu.Game/Storyboards/StoryboardDefinition.cs b/osu.Game/Storyboards/StoryboardDefinition.cs index e357440bc9..4ef24cda91 100644 --- a/osu.Game/Storyboards/StoryboardDefinition.cs +++ b/osu.Game/Storyboards/StoryboardDefinition.cs @@ -9,7 +9,7 @@ namespace osu.Game.Storyboards { public class StoryboardDefinition { - private Dictionary layers = new Dictionary(); + private readonly Dictionary layers = new Dictionary(); public IEnumerable Layers => layers.Values; public StoryboardDefinition() From 20f93c83d694b17f86c0343e86bdf96811796d2e Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 8 Sep 2017 22:37:28 +0530 Subject: [PATCH 332/483] Make downloads happen in BeatmapManager. --- .../Visual/TestCasePlaySongSelect.cs | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 74 ++++++++++++++++++- .../API/Requests/DownloadBeatmapSetRequest.cs | 21 ++++++ osu.Game/OsuGameBase.cs | 14 ++-- osu.Game/Overlays/Direct/DirectPanel.cs | 68 +++-------------- osu.Game/osu.Game.csproj | 1 + 6 files changed, 115 insertions(+), 65 deletions(-) create mode 100644 osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs diff --git a/osu.Desktop.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Desktop.Tests/Visual/TestCasePlaySongSelect.cs index 379100b543..8d1ae7d913 100644 --- a/osu.Desktop.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Desktop.Tests/Visual/TestCasePlaySongSelect.cs @@ -32,7 +32,7 @@ namespace osu.Desktop.Tests.Visual backingDatabase.CreateTable(); rulesets = new RulesetStore(backingDatabase); - manager = new BeatmapManager(storage, null, backingDatabase, rulesets); + manager = new BeatmapManager(storage, null, backingDatabase, rulesets, null); for (int i = 0; i < 100; i += 10) manager.Import(createTestBeatmapSet(i)); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 551612330b..fbbc94a8f5 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -20,6 +20,9 @@ using osu.Game.IPC; using osu.Game.Overlays.Notifications; using osu.Game.Rulesets; using SQLite.Net; +using osu.Game.Online.API.Requests; +using System.Threading.Tasks; +using osu.Game.Online.API; namespace osu.Game.Beatmaps { @@ -63,6 +66,10 @@ namespace osu.Game.Beatmaps private readonly BeatmapStore beatmaps; + private readonly APIAccess api; + + private readonly Dictionary downloadsMap; + // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private BeatmapIPCChannel ipc; @@ -76,7 +83,7 @@ namespace osu.Game.Beatmaps /// public Func GetStableStorage { private get; set; } - public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, IIpcHost importHost = null) + public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, APIAccess api, IIpcHost importHost = null) { beatmaps = new BeatmapStore(connection); beatmaps.BeatmapSetAdded += s => BeatmapSetAdded?.Invoke(s); @@ -88,9 +95,12 @@ namespace osu.Game.Beatmaps this.files = files; this.connection = connection; this.rulesets = rulesets; + this.api = api; if (importHost != null) ipc = new BeatmapIPCChannel(importHost, this); + + downloadsMap = new Dictionary(); } /// @@ -177,6 +187,68 @@ namespace osu.Game.Beatmaps beatmaps.Add(beatmapSetInfo); } + /// + /// Download a beatmap + /// + /// The beatmap to be downloaded + public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) + { + if (api == null || downloadsMap.ContainsKey(beatmapSetInfo)) return null; + + ProgressNotification downloadNotification = new ProgressNotification + { + Text = $"Downloading {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}", + }; + + var request = new DownloadBeatmapSetRequest(beatmapSetInfo); + + request.DownloadProgressed += progress => + { + downloadNotification.State = ProgressNotificationState.Active; + downloadNotification.Progress = progress; + }; + + request.Success += data => + { + downloadNotification.State = ProgressNotificationState.Completed; + + using (var stream = new MemoryStream(data)) + using (var archive = new OszArchiveReader(stream)) + Import(archive); + + downloadsMap.Remove(beatmapSetInfo); + }; + + request.Failure += data => + { + downloadNotification.State = ProgressNotificationState.Completed; + Logger.Error(data, "Failed to get beatmap download information"); + downloadsMap.Remove(beatmapSetInfo); + }; + + downloadNotification.CancelRequested += () => + { + Logger.Log("Cancel requested"); + downloadsMap.Remove(beatmapSetInfo); + return true; + }; + + downloadsMap[beatmapSetInfo] = request; + PostNotification?.Invoke(downloadNotification); + + // don't run in the main api queue as this is a long-running task. + Task.Run(() => request.Perform(api)); + + return request; + } + + /// + /// Check if a beatmap is already downloading. + /// + /// The to check against. + /// true if a download request already exists, false if it doesn't. + public bool IsDownloading(BeatmapSetInfo beatmap) => downloadsMap.ContainsKey(beatmap); + /// /// Delete a beatmap from the manager. /// Is a no-op for already deleted beatmaps. diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs new file mode 100644 index 0000000000..28473d9f66 --- /dev/null +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -0,0 +1,21 @@ +using osu.Game.Beatmaps; +using System; + +namespace osu.Game.Online.API.Requests +{ + public class DownloadBeatmapSetRequest : APIDownloadRequest + { + private readonly BeatmapSetInfo beatmapSet; + + public Action DownloadProgressed; + + public DownloadBeatmapSetRequest(BeatmapSetInfo beatmapSet) + { + this.beatmapSet = beatmapSet; + + Progress += (current, total) => DownloadProgressed?.Invoke((float) current / total); + } + + protected override string Target => $@"beatmapsets/{beatmapSet.OnlineBeatmapSetID}/download"; + } +} diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index a7136ce803..76eb7d5101 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -106,9 +106,15 @@ namespace osu.Game connection.CreateTable(); + dependencies.Cache(API = new APIAccess + { + Username = LocalConfig.Get(OsuSetting.Username), + Token = LocalConfig.Get(OsuSetting.Token) + }); + dependencies.Cache(RulesetStore = new RulesetStore(connection)); dependencies.Cache(FileStore = new FileStore(connection, Host.Storage)); - dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host)); + dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, API, Host)); dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager, RulesetStore)); dependencies.Cache(KeyBindingStore = new KeyBindingStore(connection, RulesetStore)); dependencies.Cache(new OsuColour()); @@ -144,12 +150,6 @@ namespace osu.Game Beatmap = new NonNullableBindable(defaultBeatmap); BeatmapManager.DefaultBeatmap = defaultBeatmap; - dependencies.Cache(API = new APIAccess - { - Username = LocalConfig.Get(OsuSetting.Username), - Token = LocalConfig.Get(OsuSetting.Token) - }); - Beatmap.ValueChanged += b => { // compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index a642f72821..746cd39085 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -115,23 +115,8 @@ namespace osu.Game.Overlays.Direct base.OnHoverLost(state); } - // this should eventually be moved to a more central place, like BeatmapManager. - private DownloadBeatmapSetRequest downloadRequest; - protected void StartDownload() { - if (api == null) return; - - // we already have an active download running. - if (downloadRequest != null) - { - content.MoveToX(-5, 50, Easing.OutSine).Then() - .MoveToX(5, 100, Easing.InOutSine).Then() - .MoveToX(-5, 100, Easing.InOutSine).Then() - .MoveToX(0, 50, Easing.InSine).Then(); - return; - } - if (!api.LocalUser.Value.IsSupporter) { notifications.Post(new SimpleNotification @@ -142,25 +127,28 @@ namespace osu.Game.Overlays.Direct return; } + // we already have an active download running. + if (beatmaps.IsDownloading(SetInfo)) + { + content.MoveToX(-5, 50, Easing.OutSine).Then() + .MoveToX(5, 100, Easing.InOutSine).Then() + .MoveToX(-5, 100, Easing.InOutSine).Then() + .MoveToX(0, 50, Easing.InSine).Then(); + return; + } + + var downloadRequest = beatmaps.Download(SetInfo); + progressBar.FadeIn(400, Easing.OutQuint); progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); progressBar.Current.Value = 0; - ProgressNotification downloadNotification = new ProgressNotification - { - Text = $"Downloading {SetInfo.Metadata.Artist} - {SetInfo.Metadata.Title}", - }; - - downloadRequest = new DownloadBeatmapSetRequest(SetInfo); downloadRequest.Failure += e => { progressBar.Current.Value = 0; progressBar.FadeOut(500); - downloadNotification.State = ProgressNotificationState.Completed; Logger.Error(e, "Failed to get beatmap download information"); - - downloadRequest = null; }; downloadRequest.Progress += (current, total) => @@ -169,45 +157,13 @@ namespace osu.Game.Overlays.Direct progressBar.Current.Value = progress; - downloadNotification.State = ProgressNotificationState.Active; - downloadNotification.Progress = progress; }; downloadRequest.Success += data => { progressBar.Current.Value = 1; progressBar.FadeOut(500); - - downloadNotification.State = ProgressNotificationState.Completed; - - using (var stream = new MemoryStream(data)) - using (var archive = new OszArchiveReader(stream)) - beatmaps.Import(archive); }; - - downloadNotification.CancelRequested += () => - { - downloadRequest.Cancel(); - downloadRequest = null; - return true; - }; - - notifications.Post(downloadNotification); - - // don't run in the main api queue as this is a long-running task. - Task.Run(() => downloadRequest.Perform(api)); - } - - public class DownloadBeatmapSetRequest : APIDownloadRequest - { - private readonly BeatmapSetInfo beatmapSet; - - public DownloadBeatmapSetRequest(BeatmapSetInfo beatmapSet) - { - this.beatmapSet = beatmapSet; - } - - protected override string Target => $@"beatmapsets/{beatmapSet.OnlineBeatmapSetID}/download"; } protected override void LoadComplete() diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 05ba3e25ab..5e1c5426ec 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -98,6 +98,7 @@ + From 31a507372a0795f850c76a9e717978d6ab75d3fa Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 8 Sep 2017 23:16:48 +0530 Subject: [PATCH 333/483] Don't show beatmaps that are already added. --- osu.Game/Overlays/DirectOverlay.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index f734e43826..8bbb937641 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -27,6 +27,7 @@ namespace osu.Game.Overlays private APIAccess api; private RulesetStore rulesets; + private BeatmapManager beatmaps; private readonly FillFlowContainer resultCountsContainer; private readonly OsuSpriteText resultCountsText; @@ -147,6 +148,8 @@ namespace osu.Game.Overlays { this.api = api; this.rulesets = rulesets; + this.beatmaps = beatmaps; + resultCountsContainer.Colour = colours.Yellow; beatmaps.BeatmapSetAdded += setAdded; @@ -237,7 +240,10 @@ namespace osu.Game.Overlays getSetsRequest.Success += r => { - BeatmapSets = r?.Select(response => response.ToBeatmapSet(rulesets)); + BeatmapSets = r?. + Select(response => response.ToBeatmapSet(rulesets)). + Where(b => (beatmaps.QueryBeatmapSet(q => q.OnlineBeatmapSetID == b.OnlineBeatmapSetID) == null)); + if (BeatmapSets == null) return; var artists = new List(); From 00306b6e3807d08867a2f09aef9623308b565fbf Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 8 Sep 2017 23:55:20 +0530 Subject: [PATCH 334/483] Maintain download progress between switching result views. - Check for existing download requests on creating DirectPanel - Actually remove downloaded beatmap from results --- osu.Game/Beatmaps/BeatmapManager.cs | 25 +++++---- osu.Game/Overlays/Direct/DirectPanel.cs | 71 +++++++++++++++---------- osu.Game/Overlays/DirectOverlay.cs | 30 ++++++----- 3 files changed, 72 insertions(+), 54 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index fbbc94a8f5..22402ba76a 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -68,7 +68,7 @@ namespace osu.Game.Beatmaps private readonly APIAccess api; - private readonly Dictionary downloadsMap; + private readonly Dictionary downloadsMap; // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private BeatmapIPCChannel ipc; @@ -100,7 +100,7 @@ namespace osu.Game.Beatmaps if (importHost != null) ipc = new BeatmapIPCChannel(importHost, this); - downloadsMap = new Dictionary(); + downloadsMap = new Dictionary(); } /// @@ -191,9 +191,10 @@ namespace osu.Game.Beatmaps /// Download a beatmap /// /// The beatmap to be downloaded + /// The new , or null if a download already exists for the same beatmap. public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) { - if (api == null || downloadsMap.ContainsKey(beatmapSetInfo)) return null; + if (api == null || downloadsMap.ContainsKey(beatmapSetInfo.OnlineBeatmapSetID)) return null; ProgressNotification downloadNotification = new ProgressNotification { @@ -216,24 +217,26 @@ namespace osu.Game.Beatmaps using (var archive = new OszArchiveReader(stream)) Import(archive); - downloadsMap.Remove(beatmapSetInfo); + downloadsMap.Remove(beatmapSetInfo.OnlineBeatmapSetID); }; request.Failure += data => { downloadNotification.State = ProgressNotificationState.Completed; Logger.Error(data, "Failed to get beatmap download information"); - downloadsMap.Remove(beatmapSetInfo); + downloadsMap.Remove(beatmapSetInfo.OnlineBeatmapSetID); }; downloadNotification.CancelRequested += () => { Logger.Log("Cancel requested"); - downloadsMap.Remove(beatmapSetInfo); + downloadsMap[beatmapSetInfo.OnlineBeatmapSetID].Cancel(); + downloadsMap.Remove(beatmapSetInfo.OnlineBeatmapSetID); + downloadNotification.State = ProgressNotificationState.Cancelled; return true; }; - downloadsMap[beatmapSetInfo] = request; + downloadsMap[beatmapSetInfo.OnlineBeatmapSetID] = request; PostNotification?.Invoke(downloadNotification); // don't run in the main api queue as this is a long-running task. @@ -243,11 +246,11 @@ namespace osu.Game.Beatmaps } /// - /// Check if a beatmap is already downloading. + /// Get an existing download request if it exists. /// - /// The to check against. - /// true if a download request already exists, false if it doesn't. - public bool IsDownloading(BeatmapSetInfo beatmap) => downloadsMap.ContainsKey(beatmap); + /// The whose download request is wanted. + /// The object if it exists, or null. + public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => downloadsMap.GetOrDefault(beatmap.OnlineBeatmapSetID); /// /// Delete a beatmap from the manager. diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 746cd39085..0f87d22123 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -22,6 +22,7 @@ using osu.Game.Online.API; using osu.Framework.Logging; using osu.Game.Beatmaps.IO; using osu.Game.Overlays.Notifications; +using osu.Game.Online.API.Requests; namespace osu.Game.Overlays.Direct { @@ -40,6 +41,44 @@ namespace osu.Game.Overlays.Direct private BeatmapManager beatmaps; private NotificationOverlay notifications; + private DownloadBeatmapSetRequest downloadRequest; + protected DownloadBeatmapSetRequest DownloadRequest + { + get { return downloadRequest; } + set + { + if (value == null) return; + + downloadRequest = value; + + progressBar.FadeIn(400, Easing.OutQuint); + progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); + + progressBar.Current.Value = 0; + + downloadRequest.Failure += e => + { + progressBar.Current.Value = 0; + progressBar.FadeOut(500); + Logger.Error(e, "Failed to get beatmap download information"); + }; + + downloadRequest.Progress += (current, total) => + { + float progress = (float)current / total; + + progressBar.Current.Value = progress; + + }; + + downloadRequest.Success += data => + { + progressBar.Current.Value = 1; + progressBar.FadeOut(500); + }; + } + } + protected override Container Content => content; protected DirectPanel(BeatmapSetInfo setInfo) @@ -97,6 +136,8 @@ namespace osu.Game.Overlays.Direct }, } }); + + DownloadRequest = beatmaps.GetExistingDownload(SetInfo); } protected override bool OnHover(InputState state) @@ -128,7 +169,7 @@ namespace osu.Game.Overlays.Direct } // we already have an active download running. - if (beatmaps.IsDownloading(SetInfo)) + if ((DownloadRequest = beatmaps.Download(SetInfo)) == null) { content.MoveToX(-5, 50, Easing.OutSine).Then() .MoveToX(5, 100, Easing.InOutSine).Then() @@ -136,34 +177,6 @@ namespace osu.Game.Overlays.Direct .MoveToX(0, 50, Easing.InSine).Then(); return; } - - var downloadRequest = beatmaps.Download(SetInfo); - - progressBar.FadeIn(400, Easing.OutQuint); - progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); - - progressBar.Current.Value = 0; - - downloadRequest.Failure += e => - { - progressBar.Current.Value = 0; - progressBar.FadeOut(500); - Logger.Error(e, "Failed to get beatmap download information"); - }; - - downloadRequest.Progress += (current, total) => - { - float progress = (float)current / total; - - progressBar.Current.Value = progress; - - }; - - downloadRequest.Success += data => - { - progressBar.Current.Value = 1; - progressBar.FadeOut(500); - }; } protected override void LoadComplete() diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 8bbb937641..2aa64e2b99 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -47,9 +47,22 @@ namespace osu.Game.Overlays set { if (beatmapSets?.Equals(value) ?? false) return; + beatmapSets = value; - recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); + if (beatmapSets == null) return; + + var artists = new List(); + var songs = new List(); + var tags = new List(); + foreach (var s in beatmapSets) + { + artists.Add(s.Metadata.Artist); + songs.Add(s.Metadata.Title); + tags.AddRange(s.Metadata.Tags.Split(' ')); + } + + ResultAmounts = new ResultCounts(distinctCount(artists), distinctCount(songs), distinctCount(tags)); } } @@ -159,6 +172,7 @@ namespace osu.Game.Overlays { // if a new map was imported, we should remove it from search results (download completed etc.) panels?.FirstOrDefault(p => p.SetInfo.OnlineBeatmapSetID == set.OnlineBeatmapSetID)?.FadeOut(400).Expire(); + BeatmapSets = BeatmapSets.Where(b => b.OnlineBeatmapSetID != set.OnlineBeatmapSetID); } private void updateResultCounts() @@ -244,19 +258,7 @@ namespace osu.Game.Overlays Select(response => response.ToBeatmapSet(rulesets)). Where(b => (beatmaps.QueryBeatmapSet(q => q.OnlineBeatmapSetID == b.OnlineBeatmapSetID) == null)); - if (BeatmapSets == null) return; - - var artists = new List(); - var songs = new List(); - var tags = new List(); - foreach (var s in BeatmapSets) - { - artists.Add(s.Metadata.Artist); - songs.Add(s.Metadata.Title); - tags.AddRange(s.Metadata.Tags.Split(' ')); - } - - ResultAmounts = new ResultCounts(distinctCount(artists), distinctCount(songs), distinctCount(tags)); + recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); }; api.Queue(getSetsRequest); From 0e4973020aaf65f8c3c7f1075af932cbfd63c2d9 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 00:17:38 +0530 Subject: [PATCH 335/483] Resharper and test case fixes. --- osu.Desktop.Tests/Visual/TestCaseDirect.cs | 8 ++++++++ osu.Game/Overlays/Direct/DirectPanel.cs | 4 ---- osu.Game/Overlays/DirectOverlay.cs | 6 +++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseDirect.cs b/osu.Desktop.Tests/Visual/TestCaseDirect.cs index b78ea02767..9fd93c3f1e 100644 --- a/osu.Desktop.Tests/Visual/TestCaseDirect.cs +++ b/osu.Desktop.Tests/Visual/TestCaseDirect.cs @@ -41,12 +41,14 @@ namespace osu.Desktop.Tests.Visual { new BeatmapSetInfo { + OnlineBeatmapSetID = 578332, Metadata = new BeatmapMetadata { Title = @"OrVid", Artist = @"An", Author = @"RLC", Source = @"", + Tags = @"acuticnotes an-fillnote revid tear tearvid encrpted encryption axi axivid quad her hervid recoll", }, OnlineInfo = new BeatmapSetOnlineInfo { @@ -71,12 +73,14 @@ namespace osu.Desktop.Tests.Visual }, new BeatmapSetInfo { + OnlineBeatmapSetID = 599627, Metadata = new BeatmapMetadata { Title = @"tiny lamp", Artist = @"fhana", Author = @"Sotarks", Source = @"ぎんぎつね", + Tags = @"lantis junichi sato yuxuki waga kevin mitsunaga towana gingitsune opening op full ver version kalibe collab collaboration", }, OnlineInfo = new BeatmapSetOnlineInfo { @@ -101,12 +105,14 @@ namespace osu.Desktop.Tests.Visual }, new BeatmapSetInfo { + OnlineBeatmapSetID = 513268, Metadata = new BeatmapMetadata { Title = @"At Gwanghwamun", Artist = @"KYUHYUN", Author = @"Cerulean Veyron", Source = @"", + Tags = @"soul ballad kh super junior sj suju 슈퍼주니어 kt뮤직 sm엔터테인먼트 s.m.entertainment kt music 1st mini album ep", }, OnlineInfo = new BeatmapSetOnlineInfo { @@ -146,12 +152,14 @@ namespace osu.Desktop.Tests.Visual }, new BeatmapSetInfo { + OnlineBeatmapSetID = 586841, Metadata = new BeatmapMetadata { Title = @"RHAPSODY OF BLUE SKY", Artist = @"fhana", Author = @"[Kamiya]", Source = @"小林さんちのメイドラゴン", + Tags = @"kobayashi san chi no maidragon aozora no opening anime maid dragon oblivion karen dynamix imoutosan pata-mon gxytcgxytc", }, OnlineInfo = new BeatmapSetOnlineInfo { diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 0f87d22123..4bbba27d99 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -4,8 +4,6 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; -using System.IO; -using System.Threading.Tasks; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -20,7 +18,6 @@ using osu.Framework.Input; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Framework.Logging; -using osu.Game.Beatmaps.IO; using osu.Game.Overlays.Notifications; using osu.Game.Online.API.Requests; @@ -175,7 +172,6 @@ namespace osu.Game.Overlays.Direct .MoveToX(5, 100, Easing.InOutSine).Then() .MoveToX(-5, 100, Easing.InOutSine).Then() .MoveToX(0, 50, Easing.InSine).Then(); - return; } } diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 2aa64e2b99..54fda5a38d 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -63,6 +63,10 @@ namespace osu.Game.Overlays } ResultAmounts = new ResultCounts(distinctCount(artists), distinctCount(songs), distinctCount(tags)); + + if (beatmapSets.Any() && panels == null) + // real use case? currently only seems to be for test case + recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); } } @@ -256,7 +260,7 @@ namespace osu.Game.Overlays { BeatmapSets = r?. Select(response => response.ToBeatmapSet(rulesets)). - Where(b => (beatmaps.QueryBeatmapSet(q => q.OnlineBeatmapSetID == b.OnlineBeatmapSetID) == null)); + Where(b => beatmaps.QueryBeatmapSet(q => q.OnlineBeatmapSetID == b.OnlineBeatmapSetID) == null); recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); }; From 5a3814b02e765e8b34491fed43b8d91ad2eb4032 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 01:04:55 +0530 Subject: [PATCH 336/483] XMLdoc fixes and a cautionary check. --- osu.Game/Beatmaps/BeatmapManager.cs | 4 ++-- osu.Game/Overlays/Direct/DirectPanel.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 22402ba76a..4de5d49b1e 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -188,9 +188,9 @@ namespace osu.Game.Beatmaps } /// - /// Download a beatmap + /// Downloads a beatmap. /// - /// The beatmap to be downloaded + /// The to be downloaded. /// The new , or null if a download already exists for the same beatmap. public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) { diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 4bbba27d99..7f0c8ac350 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -44,7 +44,7 @@ namespace osu.Game.Overlays.Direct get { return downloadRequest; } set { - if (value == null) return; + if (value == null || downloadRequest == value) return; downloadRequest = value; From 57e53ff03a7ca3d2b310eda2de4eec0d277209dc Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 8 Sep 2017 21:36:30 +0200 Subject: [PATCH 337/483] Fix diff-specific storyboard content being lost after loading. --- osu.Game/Beatmaps/Beatmap.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index e4568a1919..9b32a65453 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -56,6 +56,7 @@ namespace osu.Game.Beatmaps ControlPointInfo = original?.ControlPointInfo ?? ControlPointInfo; Breaks = original?.Breaks ?? Breaks; ComboColors = original?.ComboColors ?? ComboColors; + Storyboard = original?.Storyboard ?? Storyboard; } } From 20becbe5760fa2c5d9f07c00558513aa4c59f00a Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 01:53:42 +0530 Subject: [PATCH 338/483] Use the specifically created progress action, add license header. --- osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs | 5 ++++- osu.Game/Overlays/Direct/DirectPanel.cs | 8 +------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs index 28473d9f66..0ba4adf9c9 100644 --- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -1,4 +1,7 @@ -using osu.Game.Beatmaps; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps; using System; namespace osu.Game.Online.API.Requests diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 7f0c8ac350..4bf3442453 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -60,13 +60,7 @@ namespace osu.Game.Overlays.Direct Logger.Error(e, "Failed to get beatmap download information"); }; - downloadRequest.Progress += (current, total) => - { - float progress = (float)current / total; - - progressBar.Current.Value = progress; - - }; + downloadRequest.DownloadProgressed += progress => progressBar.Current.Value = progress; downloadRequest.Success += data => { From 5f5dd54f9d1e99971218ad4910ab13c0df421dc5 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 09:51:37 +0530 Subject: [PATCH 339/483] Use a List instead of a Dictionary. --- osu.Game/Beatmaps/BeatmapManager.cs | 21 ++++++++++--------- .../API/Requests/DownloadBeatmapSetRequest.cs | 8 +++---- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 4de5d49b1e..8e7b38a50c 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -68,7 +68,7 @@ namespace osu.Game.Beatmaps private readonly APIAccess api; - private readonly Dictionary downloadsMap; + private readonly List downloadsList; // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private BeatmapIPCChannel ipc; @@ -100,7 +100,7 @@ namespace osu.Game.Beatmaps if (importHost != null) ipc = new BeatmapIPCChannel(importHost, this); - downloadsMap = new Dictionary(); + downloadsList = new List(); } /// @@ -194,7 +194,8 @@ namespace osu.Game.Beatmaps /// The new , or null if a download already exists for the same beatmap. public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) { - if (api == null || downloadsMap.ContainsKey(beatmapSetInfo.OnlineBeatmapSetID)) return null; + if (api == null || downloadsList.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmapSetInfo.OnlineBeatmapSetID) != null) + return null; ProgressNotification downloadNotification = new ProgressNotification { @@ -217,29 +218,29 @@ namespace osu.Game.Beatmaps using (var archive = new OszArchiveReader(stream)) Import(archive); - downloadsMap.Remove(beatmapSetInfo.OnlineBeatmapSetID); + downloadsList.Remove(request); }; request.Failure += data => { downloadNotification.State = ProgressNotificationState.Completed; Logger.Error(data, "Failed to get beatmap download information"); - downloadsMap.Remove(beatmapSetInfo.OnlineBeatmapSetID); + downloadsList.Remove(request); }; downloadNotification.CancelRequested += () => { - Logger.Log("Cancel requested"); - downloadsMap[beatmapSetInfo.OnlineBeatmapSetID].Cancel(); - downloadsMap.Remove(beatmapSetInfo.OnlineBeatmapSetID); + request.Cancel(); + downloadsList.Remove(request); downloadNotification.State = ProgressNotificationState.Cancelled; return true; }; - downloadsMap[beatmapSetInfo.OnlineBeatmapSetID] = request; + downloadsList.Add(request); PostNotification?.Invoke(downloadNotification); // don't run in the main api queue as this is a long-running task. + // TODO: ensure the Success/Failure callbacks are being scheduled to the main thread for thread safety. Task.Run(() => request.Perform(api)); return request; @@ -250,7 +251,7 @@ namespace osu.Game.Beatmaps /// /// The whose download request is wanted. /// The object if it exists, or null. - public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => downloadsMap.GetOrDefault(beatmap.OnlineBeatmapSetID); + public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => downloadsList.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID); /// /// Delete a beatmap from the manager. diff --git a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs index 0ba4adf9c9..5a9f609bca 100644 --- a/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/DownloadBeatmapSetRequest.cs @@ -8,17 +8,17 @@ namespace osu.Game.Online.API.Requests { public class DownloadBeatmapSetRequest : APIDownloadRequest { - private readonly BeatmapSetInfo beatmapSet; + public readonly BeatmapSetInfo BeatmapSet; public Action DownloadProgressed; - public DownloadBeatmapSetRequest(BeatmapSetInfo beatmapSet) + public DownloadBeatmapSetRequest(BeatmapSetInfo set) { - this.beatmapSet = beatmapSet; + BeatmapSet = set; Progress += (current, total) => DownloadProgressed?.Invoke((float) current / total); } - protected override string Target => $@"beatmapsets/{beatmapSet.OnlineBeatmapSetID}/download"; + protected override string Target => $@"beatmapsets/{BeatmapSet.OnlineBeatmapSetID}/download"; } } From e67606e2031722830b89c63ef0bd5d24d24aca94 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 10:25:28 +0530 Subject: [PATCH 340/483] Return existing download if it exists. --- osu.Game/Beatmaps/BeatmapManager.cs | 9 ++++++--- osu.Game/Overlays/Direct/DirectPanel.cs | 6 +++++- osu.Game/Overlays/DirectOverlay.cs | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 8e7b38a50c..472e44f36b 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -191,11 +191,14 @@ namespace osu.Game.Beatmaps /// Downloads a beatmap. /// /// The to be downloaded. - /// The new , or null if a download already exists for the same beatmap. + /// A new , or an existing one if a download is already in progress. public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) { - if (api == null || downloadsList.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmapSetInfo.OnlineBeatmapSetID) != null) - return null; + var existing = downloadsList.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmapSetInfo.OnlineBeatmapSetID); + + if (existing != null) return existing; + + if (api == null) return null; ProgressNotification downloadNotification = new ProgressNotification { diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 4bf3442453..66b3ff8bf9 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -160,13 +160,17 @@ namespace osu.Game.Overlays.Direct } // we already have an active download running. - if ((DownloadRequest = beatmaps.Download(SetInfo)) == null) + if (beatmaps.GetExistingDownload(SetInfo) != null) { content.MoveToX(-5, 50, Easing.OutSine).Then() .MoveToX(5, 100, Easing.InOutSine).Then() .MoveToX(-5, 100, Easing.InOutSine).Then() .MoveToX(0, 50, Easing.InSine).Then(); + + return; } + + DownloadRequest = beatmaps.Download(SetInfo); } protected override void LoadComplete() diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 54fda5a38d..9c07e1087f 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -176,7 +176,7 @@ namespace osu.Game.Overlays { // if a new map was imported, we should remove it from search results (download completed etc.) panels?.FirstOrDefault(p => p.SetInfo.OnlineBeatmapSetID == set.OnlineBeatmapSetID)?.FadeOut(400).Expire(); - BeatmapSets = BeatmapSets.Where(b => b.OnlineBeatmapSetID != set.OnlineBeatmapSetID); + BeatmapSets = BeatmapSets?.Where(b => b.OnlineBeatmapSetID != set.OnlineBeatmapSetID); } private void updateResultCounts() From d12a5e927a2154449583ad7b9015ade70b30cdeb Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 11:03:25 +0530 Subject: [PATCH 341/483] Rename property. --- osu.Game/Beatmaps/BeatmapManager.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 472e44f36b..6c3a703c19 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -68,7 +68,7 @@ namespace osu.Game.Beatmaps private readonly APIAccess api; - private readonly List downloadsList; + private readonly List currentDownloads; // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private BeatmapIPCChannel ipc; @@ -100,7 +100,7 @@ namespace osu.Game.Beatmaps if (importHost != null) ipc = new BeatmapIPCChannel(importHost, this); - downloadsList = new List(); + currentDownloads = new List(); } /// @@ -194,7 +194,7 @@ namespace osu.Game.Beatmaps /// A new , or an existing one if a download is already in progress. public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) { - var existing = downloadsList.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmapSetInfo.OnlineBeatmapSetID); + var existing = currentDownloads.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmapSetInfo.OnlineBeatmapSetID); if (existing != null) return existing; @@ -221,25 +221,25 @@ namespace osu.Game.Beatmaps using (var archive = new OszArchiveReader(stream)) Import(archive); - downloadsList.Remove(request); + currentDownloads.Remove(request); }; request.Failure += data => { downloadNotification.State = ProgressNotificationState.Completed; Logger.Error(data, "Failed to get beatmap download information"); - downloadsList.Remove(request); + currentDownloads.Remove(request); }; downloadNotification.CancelRequested += () => { request.Cancel(); - downloadsList.Remove(request); + currentDownloads.Remove(request); downloadNotification.State = ProgressNotificationState.Cancelled; return true; }; - downloadsList.Add(request); + currentDownloads.Add(request); PostNotification?.Invoke(downloadNotification); // don't run in the main api queue as this is a long-running task. @@ -254,7 +254,7 @@ namespace osu.Game.Beatmaps /// /// The whose download request is wanted. /// The object if it exists, or null. - public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => downloadsList.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID); + public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => currentDownloads.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID); /// /// Delete a beatmap from the manager. From 0c2bad1de4abce4610b6e4d263b3ef103709b8f6 Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 9 Sep 2017 12:44:27 +0530 Subject: [PATCH 342/483] Get rid of some properties and todos. --- osu.Game/Beatmaps/BeatmapManager.cs | 7 +-- osu.Game/Overlays/Direct/DirectPanel.cs | 66 ++++++++++++------------- 2 files changed, 33 insertions(+), 40 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 6c3a703c19..f58b3505c5 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -68,7 +68,7 @@ namespace osu.Game.Beatmaps private readonly APIAccess api; - private readonly List currentDownloads; + private readonly List currentDownloads = new List(); // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) private BeatmapIPCChannel ipc; @@ -99,8 +99,6 @@ namespace osu.Game.Beatmaps if (importHost != null) ipc = new BeatmapIPCChannel(importHost, this); - - currentDownloads = new List(); } /// @@ -194,7 +192,7 @@ namespace osu.Game.Beatmaps /// A new , or an existing one if a download is already in progress. public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo) { - var existing = currentDownloads.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmapSetInfo.OnlineBeatmapSetID); + var existing = GetExistingDownload(beatmapSetInfo); if (existing != null) return existing; @@ -243,7 +241,6 @@ namespace osu.Game.Beatmaps PostNotification?.Invoke(downloadNotification); // don't run in the main api queue as this is a long-running task. - // TODO: ensure the Success/Failure callbacks are being scheduled to the main thread for thread safety. Task.Run(() => request.Perform(api)); return request; diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index 66b3ff8bf9..6f1f581d0b 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -38,38 +38,6 @@ namespace osu.Game.Overlays.Direct private BeatmapManager beatmaps; private NotificationOverlay notifications; - private DownloadBeatmapSetRequest downloadRequest; - protected DownloadBeatmapSetRequest DownloadRequest - { - get { return downloadRequest; } - set - { - if (value == null || downloadRequest == value) return; - - downloadRequest = value; - - progressBar.FadeIn(400, Easing.OutQuint); - progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); - - progressBar.Current.Value = 0; - - downloadRequest.Failure += e => - { - progressBar.Current.Value = 0; - progressBar.FadeOut(500); - Logger.Error(e, "Failed to get beatmap download information"); - }; - - downloadRequest.DownloadProgressed += progress => progressBar.Current.Value = progress; - - downloadRequest.Success += data => - { - progressBar.Current.Value = 1; - progressBar.FadeOut(500); - }; - } - } - protected override Container Content => content; protected DirectPanel(BeatmapSetInfo setInfo) @@ -128,7 +96,10 @@ namespace osu.Game.Overlays.Direct } }); - DownloadRequest = beatmaps.GetExistingDownload(SetInfo); + var downloadRequest = beatmaps.GetExistingDownload(SetInfo); + + if (downloadRequest != null) + attachDownload(downloadRequest); } protected override bool OnHover(InputState state) @@ -159,9 +130,9 @@ namespace osu.Game.Overlays.Direct return; } - // we already have an active download running. if (beatmaps.GetExistingDownload(SetInfo) != null) { + // we already have an active download running. content.MoveToX(-5, 50, Easing.OutSine).Then() .MoveToX(5, 100, Easing.InOutSine).Then() .MoveToX(-5, 100, Easing.InOutSine).Then() @@ -170,7 +141,32 @@ namespace osu.Game.Overlays.Direct return; } - DownloadRequest = beatmaps.Download(SetInfo); + var request = beatmaps.Download(SetInfo); + + attachDownload(request); + } + + private void attachDownload(DownloadBeatmapSetRequest request) + { + progressBar.FadeIn(400, Easing.OutQuint); + progressBar.ResizeHeightTo(4, 400, Easing.OutQuint); + + progressBar.Current.Value = 0; + + request.Failure += e => + { + progressBar.Current.Value = 0; + progressBar.FadeOut(500); + Logger.Error(e, "Failed to get beatmap download information"); + }; + + request.DownloadProgressed += progress => progressBar.Current.Value = progress; + + request.Success += data => + { + progressBar.Current.Value = 1; + progressBar.FadeOut(500); + }; } protected override void LoadComplete() From 8d55cb7f922968761a17bf4748050ca93da053c9 Mon Sep 17 00:00:00 2001 From: Damnae Date: Sat, 9 Sep 2017 11:00:58 +0200 Subject: [PATCH 343/483] Improve command sorting. --- osu.Game/Storyboards/CommandTimeline.cs | 10 +++++++++- osu.Game/Storyboards/SpriteDefinition.cs | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/osu.Game/Storyboards/CommandTimeline.cs b/osu.Game/Storyboards/CommandTimeline.cs index 909a629ad2..b9bb6629d1 100644 --- a/osu.Game/Storyboards/CommandTimeline.cs +++ b/osu.Game/Storyboards/CommandTimeline.cs @@ -3,6 +3,7 @@ using osu.Framework.Caching; using osu.Framework.Graphics; +using System; using System.Collections.Generic; using System.Linq; @@ -47,6 +48,13 @@ namespace osu.Game.Storyboards public T StartValue; public T EndValue; + public int CompareTo(ICommand other) + { + var result = StartTime.CompareTo(other.StartTime); + if (result != 0) return result; + return EndTime.CompareTo(other.EndTime); + } + public override string ToString() => $"{StartTime} -> {EndTime}, {StartValue} -> {EndValue} {Easing}"; } @@ -59,7 +67,7 @@ namespace osu.Game.Storyboards bool HasCommands { get; } } - public interface ICommand + public interface ICommand : IComparable { Easing Easing { get; set; } double StartTime { get; set; } diff --git a/osu.Game/Storyboards/SpriteDefinition.cs b/osu.Game/Storyboards/SpriteDefinition.cs index 4f161a34f4..a4697aabfb 100644 --- a/osu.Game/Storyboards/SpriteDefinition.cs +++ b/osu.Game/Storyboards/SpriteDefinition.cs @@ -78,7 +78,7 @@ namespace osu.Game.Storyboards CommandTimelineSelector timelineSelector, DrawablePropertyInitializer initializeProperty, DrawableTransformer transform) { var initialized = false; - foreach (var command in getAggregatedCommands(timelineSelector, triggeredGroups)) + foreach (var command in getAggregatedCommands(timelineSelector, triggeredGroups).OrderBy(l => l)) { if (!initialized) { @@ -99,7 +99,7 @@ namespace osu.Game.Storyboards if (triggeredGroups != null) foreach (var pair in triggeredGroups) commands = commands.Concat(pair.Item1.GetCommands(timelineSelector, pair.Item2)); - return commands.OrderBy(l => l.StartTime); + return commands; } public override string ToString() From bc01d9a1b04f5909eac2e9829c25243b79cbb7ea Mon Sep 17 00:00:00 2001 From: Damnae Date: Sat, 9 Sep 2017 15:34:26 +0200 Subject: [PATCH 344/483] Animate Additive / FlipH and FlipV. --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 6 +-- osu.Game/Storyboards/CommandTimelineGroup.cs | 5 +- .../Drawables/DrawablesExtensions.cs | 27 +++++++++++ osu.Game/Storyboards/Drawables/IFlippable.cs | 46 ++++++++++++++++++- osu.Game/Storyboards/SpriteDefinition.cs | 14 +++--- osu.Game/osu.Game.csproj | 1 + 6 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 osu.Game/Storyboards/Drawables/DrawablesExtensions.cs diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 6fde7263da..d538960a37 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -428,9 +428,9 @@ namespace osu.Game.Beatmaps.Formats var type = split[4]; switch (type) { - case "A": timelineGroup?.Additive.Add(easing, startTime, endTime, true, true); break; - case "H": timelineGroup?.FlipH.Add(easing, startTime, endTime, true, true); break; - case "V": timelineGroup?.FlipV.Add(easing, startTime, endTime, true, true); break; + case "A": timelineGroup?.BlendingMode.Add(easing, startTime, endTime, BlendingMode.Additive, startTime == endTime ? BlendingMode.Additive : BlendingMode.Inherit); break; + case "H": timelineGroup?.FlipH.Add(easing, startTime, endTime, true, startTime == endTime); break; + case "V": timelineGroup?.FlipV.Add(easing, startTime, endTime, true, startTime == endTime); break; } } break; diff --git a/osu.Game/Storyboards/CommandTimelineGroup.cs b/osu.Game/Storyboards/CommandTimelineGroup.cs index a42aca7c28..332a6f79cb 100644 --- a/osu.Game/Storyboards/CommandTimelineGroup.cs +++ b/osu.Game/Storyboards/CommandTimelineGroup.cs @@ -3,6 +3,7 @@ using OpenTK; using OpenTK.Graphics; +using osu.Framework.Graphics; using System.Collections.Generic; using System.Linq; @@ -18,7 +19,7 @@ namespace osu.Game.Storyboards public CommandTimeline Rotation = new CommandTimeline(); public CommandTimeline Colour = new CommandTimeline(); public CommandTimeline Alpha = new CommandTimeline(); - public CommandTimeline Additive = new CommandTimeline(); + public CommandTimeline BlendingMode = new CommandTimeline(); public CommandTimeline FlipH = new CommandTimeline(); public CommandTimeline FlipV = new CommandTimeline(); @@ -32,7 +33,7 @@ namespace osu.Game.Storyboards yield return Rotation; yield return Colour; yield return Alpha; - yield return Additive; + yield return BlendingMode; yield return FlipH; yield return FlipV; } diff --git a/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs b/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs new file mode 100644 index 0000000000..436b4aafeb --- /dev/null +++ b/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs @@ -0,0 +1,27 @@ +using osu.Framework.Graphics; +using osu.Framework.Graphics.Transforms; + +namespace osu.Game.Storyboards.Drawables +{ + public static class DrawablesExtensions + { + /// + /// Adjusts after a delay. + /// + /// A to which further transforms can be added. + public static TransformSequence TransformBlendingMode(this T drawable, BlendingMode newValue, double delay = 0) + where T : Drawable + => drawable.TransformTo(drawable.PopulateTransform(new TransformBlendingMode(), newValue, delay)); + } + + public class TransformBlendingMode : Transform + { + private BlendingMode valueAt(double time) + => time < EndTime ? StartValue : EndValue; + + public override string TargetMember => nameof(Drawable.BlendingMode); + + protected override void Apply(Drawable d, double time) => d.BlendingMode = valueAt(time); + protected override void ReadIntoStartValue(Drawable d) => StartValue = d.BlendingMode; + } +} diff --git a/osu.Game/Storyboards/Drawables/IFlippable.cs b/osu.Game/Storyboards/Drawables/IFlippable.cs index a1899d1411..4d21c9d140 100644 --- a/osu.Game/Storyboards/Drawables/IFlippable.cs +++ b/osu.Game/Storyboards/Drawables/IFlippable.cs @@ -1,11 +1,55 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Graphics; +using osu.Framework.Graphics.Transforms; + namespace osu.Game.Storyboards.Drawables { - public interface IFlippable + public interface IFlippable : ITransformable { bool FlipH { get; set; } bool FlipV { get; set; } } + + public class TransformFlipH : Transform + { + private bool valueAt(double time) + => time < EndTime ? StartValue : EndValue; + + public override string TargetMember => nameof(IFlippable.FlipH); + + protected override void Apply(IFlippable d, double time) => d.FlipH = valueAt(time); + protected override void ReadIntoStartValue(IFlippable d) => StartValue = d.FlipH; + } + + public class TransformFlipV : Transform + { + private bool valueAt(double time) + => time < EndTime ? StartValue : EndValue; + + public override string TargetMember => nameof(IFlippable.FlipV); + + protected override void Apply(IFlippable d, double time) => d.FlipV = valueAt(time); + protected override void ReadIntoStartValue(IFlippable d) => StartValue = d.FlipV; + } + + public static class FlippableExtensions + { + /// + /// Adjusts after a delay. + /// + /// A to which further transforms can be added. + public static TransformSequence TransformFlipH(this T flippable, bool newValue, double delay = 0) + where T : IFlippable + => flippable.TransformTo(flippable.PopulateTransform(new TransformFlipH(), newValue, delay)); + + /// + /// Adjusts after a delay. + /// + /// A to which further transforms can be added. + public static TransformSequence TransformFlipV(this T flippable, bool newValue, double delay = 0) + where T : IFlippable + => flippable.TransformTo(flippable.PopulateTransform(new TransformFlipV(), newValue, delay)); + } } diff --git a/osu.Game/Storyboards/SpriteDefinition.cs b/osu.Game/Storyboards/SpriteDefinition.cs index a4697aabfb..c410fd8807 100644 --- a/osu.Game/Storyboards/SpriteDefinition.cs +++ b/osu.Game/Storyboards/SpriteDefinition.cs @@ -62,27 +62,27 @@ namespace osu.Game.Storyboards applyCommands(drawable, triggeredGroups, g => g.Rotation, (d, value) => d.Rotation = value, (d, value, duration, easing) => d.RotateTo(value, duration, easing)); applyCommands(drawable, triggeredGroups, g => g.Colour, (d, value) => d.Colour = value, (d, value, duration, easing) => d.FadeColour(value, duration, easing)); applyCommands(drawable, triggeredGroups, g => g.Alpha, (d, value) => d.Alpha = value, (d, value, duration, easing) => d.FadeTo(value, duration, easing)); - - if (getAggregatedCommands(g => g.Additive, triggeredGroups).Any()) - drawable.BlendingMode = BlendingMode.Additive; + applyCommands(drawable, triggeredGroups, g => g.BlendingMode, (d, value) => d.BlendingMode = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration), false); var flippable = drawable as IFlippable; if (flippable != null) { - flippable.FlipH = getAggregatedCommands(g => g.FlipH, triggeredGroups).Any(); - flippable.FlipV = getAggregatedCommands(g => g.FlipV, triggeredGroups).Any(); + applyCommands(drawable, triggeredGroups, g => g.FlipH, (d, value) => flippable.FlipH = value, (d, value, duration, easing) => flippable.TransformFlipH(value, duration), false); + applyCommands(drawable, triggeredGroups, g => g.FlipV, (d, value) => flippable.FlipV = value, (d, value, duration, easing) => flippable.TransformFlipV(value, duration), false); } } private void applyCommands(Drawable drawable, IEnumerable> triggeredGroups, - CommandTimelineSelector timelineSelector, DrawablePropertyInitializer initializeProperty, DrawableTransformer transform) + CommandTimelineSelector timelineSelector, DrawablePropertyInitializer initializeProperty, DrawableTransformer transform, bool alwaysInitialize = true) + where T : struct { var initialized = false; foreach (var command in getAggregatedCommands(timelineSelector, triggeredGroups).OrderBy(l => l)) { if (!initialized) { - initializeProperty(drawable, command.StartValue); + if (alwaysInitialize || command.StartTime == command.EndTime) + initializeProperty.Invoke(drawable, command.StartValue); initialized = true; } using (drawable.BeginAbsoluteSequence(command.StartTime)) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8c91a9e80a..7e068979bf 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -86,6 +86,7 @@ + From 0a9ca8a1ff89c58f39b171256239be41640ea3e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 10 Sep 2017 11:53:47 +0900 Subject: [PATCH 345/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 4e7ea6af4f..a617245a42 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 4e7ea6af4f59f21f6afc522fb063c05417e1a5fe +Subproject commit a617245a4261d7d6e138c2fddbbeaa7940d24ca7 From 59d9dc5ee74d7ab2988b7fa50cc516d08807b910 Mon Sep 17 00:00:00 2001 From: Damnae Date: Sun, 10 Sep 2017 20:08:56 +0200 Subject: [PATCH 346/483] Ignore storyboard sprites with invalid positions. --- osu.Game/Storyboards/Drawables/StoryboardAnimation.cs | 3 +++ osu.Game/Storyboards/Drawables/StoryboardSprite.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs index eb2ba59397..2051b9c4af 100644 --- a/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs @@ -49,6 +49,9 @@ namespace osu.Game.Storyboards.Drawables } } + public override bool IsPresent + => !float.IsNaN(DrawPosition.X) && !float.IsNaN(DrawPosition.Y) && base.IsPresent; + public StoryboardAnimation(AnimationDefinition definition) { Definition = definition; diff --git a/osu.Game/Storyboards/Drawables/StoryboardSprite.cs b/osu.Game/Storyboards/Drawables/StoryboardSprite.cs index 565b5a5069..ca055fe6d4 100644 --- a/osu.Game/Storyboards/Drawables/StoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/StoryboardSprite.cs @@ -49,6 +49,9 @@ namespace osu.Game.Storyboards.Drawables } } + public override bool IsPresent + => !float.IsNaN(DrawPosition.X) && !float.IsNaN(DrawPosition.Y) && base.IsPresent; + public StoryboardSprite(SpriteDefinition definition) { Definition = definition; From af07d5cc51fcf4c5e9dbe982b8c2ade551ef1e77 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 03:37:13 +0900 Subject: [PATCH 347/483] Update framework. --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 686436566e..d891fc31d8 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 686436566e057ace127e4cb6a977823459b88ebe +Subproject commit d891fc31d8dbe5ee88b798eca9d0a5a7483a144f From 4d77a81e40a2c71456f6840367751d3c492d4675 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 03:50:16 +0900 Subject: [PATCH 348/483] Make TestCaseManiaHitObjects work again. --- .../Visual/TestCaseManiaHitObjects.cs | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs b/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs index 76235bbf19..8f0e87bee6 100644 --- a/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs +++ b/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs @@ -41,8 +41,22 @@ namespace osu.Desktop.Tests.Visual RelativeChildSize = new Vector2(1, 10000), Children = new[] { - new DrawableNote(new Note { StartTime = 5000 }, ManiaAction.Key1) { AccentColour = Color4.Red }, - new DrawableNote(new Note { StartTime = 6000 }, ManiaAction.Key1) { AccentColour = Color4.Red } + new DrawableNote(new Note(), ManiaAction.Key1) + { + RelativePositionAxes = Axes.Y, + Y = 5000, + LifetimeStart = double.MinValue, + LifetimeEnd = double.MaxValue, + AccentColour = Color4.Red + }, + new DrawableNote(new Note(), ManiaAction.Key1) + { + RelativePositionAxes = Axes.Y, + Y = 6000, + LifetimeStart = double.MinValue, + LifetimeEnd = double.MaxValue, + AccentColour = Color4.Red + } } } } @@ -63,11 +77,15 @@ namespace osu.Desktop.Tests.Visual RelativeChildSize = new Vector2(1, 10000), Children = new[] { - new DrawableHoldNote(new HoldNote + new DrawableHoldNote(new HoldNote(), ManiaAction.Key1) { - StartTime = 5000, - Duration = 1000 - }, ManiaAction.Key1) { AccentColour = Color4.Red } + RelativePositionAxes = Axes.Y, + Y = 5000, + Height = 3000, + LifetimeStart = double.MinValue, + LifetimeEnd = double.MaxValue, + AccentColour = Color4.Red + } } } } From 8797382700c9264841e52043ea1f4623940f7151 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 04:21:22 +0900 Subject: [PATCH 349/483] Update body styling of hold notes --- .../Objects/Drawables/DrawableHoldNote.cs | 9 ++ .../Objects/Drawables/DrawableNote.cs | 2 +- .../Objects/Drawables/Pieces/BodyPiece.cs | 95 ++++++++++++++++++- 3 files changed, 100 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index e06f71cb64..93e26927e9 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -49,6 +49,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, }, tickContainer = new Container { @@ -104,6 +105,14 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { } + protected override void Update() + { + base.Update(); + + bodyPiece.Y = head.Height; + bodyPiece.Height = DrawHeight - head.Height; + } + public bool OnPressed(ManiaAction action) { // Make sure the action happened within the body of the hold note diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index c201ab7bd0..6d4f921020 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables : base(hitObject, action) { RelativeSizeAxes = Axes.X; - Height = 100; + AutoSizeAxes = Axes.Y; Add(headPiece = new NotePiece { diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs index 04e8df4ae2..ac7054abe8 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs @@ -1,7 +1,10 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using osu.Framework.Caching; using OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -14,22 +17,61 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces /// internal class BodyPiece : Container, IHasAccentColour { - private readonly Box box; + private readonly Container subtractionLayer; + + private readonly Drawable background; + private readonly BufferedContainer foreground; + private readonly BufferedContainer subtractionContainer; public BodyPiece() { - RelativeSizeAxes = Axes.Both; + Blending = BlendingMode.Additive; Children = new[] { - box = new Box + background = new Box { RelativeSizeAxes = Axes.Both }, + foreground = new BufferedContainer { RelativeSizeAxes = Axes.Both, - Alpha = 0.3f + CacheDrawnFrameBuffer = true, + Children = new Drawable[] + { + new Box { RelativeSizeAxes = Axes.Both }, + subtractionContainer = new BufferedContainer + { + RelativeSizeAxes = Axes.Both, + // This is needed because we're blending with another object + BackgroundColour = Color4.White.Opacity(0), + CacheDrawnFrameBuffer = true, + // The 'hole' is achieved by subtracting the result of this container with the parent + Blending = new BlendingModeParameters { AlphaEquation = BlendingEquation.ReverseSubtract }, + Child = subtractionLayer = new CircularContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + // Height computed in Update + Width = 1, + Masking = true, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + } + } + } + } } }; } + protected override void LoadComplete() + { + base.LoadComplete(); + + updateAccentColour(); + } + private Color4 accentColour; public Color4 AccentColour { @@ -40,8 +82,51 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces return; accentColour = value; - box.Colour = accentColour; + updateAccentColour(); } } + + private Cached subtractionCache = new Cached(); + + public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) + { + if ((invalidation & Invalidation.DrawSize) > 0) + subtractionCache.Invalidate(); + + return base.Invalidate(invalidation, source, shallPropagate); + } + + protected override void Update() + { + base.Update(); + + if (!subtractionCache.IsValid) + { + subtractionLayer.Width = 5; + subtractionLayer.Height = Math.Max(0, DrawHeight - DrawWidth); + subtractionLayer.EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.White, + Type = EdgeEffectType.Glow, + Radius = DrawWidth + }; + + foreground.ForceRedraw(); + subtractionContainer.ForceRedraw(); + + subtractionCache.Validate(); + } + } + + private void updateAccentColour() + { + if (!IsLoaded) + return; + + foreground.Colour = AccentColour.Opacity(0.4f); + background.Colour = AccentColour.Opacity(0.2f); + + subtractionCache.Invalidate(); + } } } From 73d77637efe4e54294779e8cc15dc220115cd447 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 04:22:05 +0900 Subject: [PATCH 350/483] Add glow to DrawableNote --- .../Objects/Drawables/DrawableNote.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 6d4f921020..707b83ef13 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -2,8 +2,10 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Extensions.Color4Extensions; using OpenTK.Graphics; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; @@ -16,6 +18,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// public class DrawableNote : DrawableManiaHitObject, IKeyBindingHandler { + /// + /// Whether the glow for this is handled by a containing it. + /// + protected bool HasOwnGlow = true; + private readonly NotePiece headPiece; public DrawableNote(Note hitObject, ManiaAction action) @@ -23,6 +30,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; + Masking = true; Add(headPiece = new NotePiece { @@ -31,6 +39,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables }); } + protected override void LoadComplete() + { + base.LoadComplete(); + + UpdateGlow(); + } + public override Color4 AccentColour { get { return base.AccentColour; } @@ -41,6 +56,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables base.AccentColour = value; headPiece.AccentColour = value; + + UpdateGlow(); } } @@ -79,6 +96,23 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } + protected virtual void UpdateGlow() + { + if (!IsLoaded) + return; + + if (!HasOwnGlow) + return; + + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = AccentColour.Opacity(0.5f), + Radius = 10, + Hollow = true + }; + } + public virtual bool OnPressed(ManiaAction action) { if (action != Action) From 590a34dc28d7b45531afc51580078cac4e0470df Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 04:22:17 +0900 Subject: [PATCH 351/483] Add glow to DrawableHoldNote --- .../Objects/Drawables/DrawableHoldNote.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 93e26927e9..3ac8f2a2ee 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Extensions.Color4Extensions; using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; @@ -9,6 +10,7 @@ using OpenTK; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Mania.Judgements; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Bindings; namespace osu.Game.Rulesets.Mania.Objects.Drawables @@ -23,6 +25,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables private readonly BodyPiece bodyPiece; private readonly Container tickContainer; + private readonly Container glowContainer; /// /// Time at which the user started holding this hold note. Null if the user is not holding this hold note. @@ -66,6 +69,17 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { Anchor = Anchor.BottomCentre, Origin = Anchor.TopCentre + }, + glowContainer = new Container + { + RelativeSizeAxes = Axes.X, + Masking = true, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + } } }); @@ -111,6 +125,15 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables bodyPiece.Y = head.Height; bodyPiece.Height = DrawHeight - head.Height; + + glowContainer.Height = DrawHeight + tail.Height; + glowContainer.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = AccentColour.Opacity(0.5f), + Radius = 10, + Hollow = true, + }; } public bool OnPressed(ManiaAction action) @@ -162,6 +185,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables RelativePositionAxes = Axes.None; Y = 0; + + HasOwnGlow = false; } public override bool OnPressed(ManiaAction action) @@ -199,6 +224,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables RelativePositionAxes = Axes.None; Y = 0; + + HasOwnGlow = false; } protected override ManiaJudgement CreateJudgement() => new HoldNoteTailJudgement(); From 3b5e847a31a2ab51b76fff5a8f29e2eb8022e16b Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 04:29:32 +0900 Subject: [PATCH 352/483] Better updateGlow methods. --- .../Objects/Drawables/DrawableHoldNote.cs | 35 +++++++++++++---- .../Objects/Drawables/DrawableNote.cs | 38 +++++++++---------- 2 files changed, 47 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 3ac8f2a2ee..671884fe17 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -70,6 +70,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Anchor = Anchor.BottomCentre, Origin = Anchor.TopCentre }, + // The hit object itself cannot be used for the glow because the tail overshoots it + // So a specialized container that is updated to contain the tail height is used glowContainer = new Container { RelativeSizeAxes = Axes.X, @@ -98,6 +100,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables AddNested(tail); } + protected override void LoadComplete() + { + base.LoadComplete(); + + updateGlow(); + } + public override Color4 AccentColour { get { return base.AccentColour; } @@ -112,9 +121,25 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables bodyPiece.AccentColour = value; head.AccentColour = value; tail.AccentColour = value; + + updateGlow(); } } + private void updateGlow() + { + if (!IsLoaded) + return; + + glowContainer.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = AccentColour.Opacity(0.5f), + Radius = 10, + Hollow = true + }; + } + protected override void UpdateState(ArmedState state) { } @@ -123,17 +148,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { base.Update(); + // Make the body piece not lie under the head note bodyPiece.Y = head.Height; bodyPiece.Height = DrawHeight - head.Height; + // Make the glowContainer "contain" the height of the tail note, keeping in mind + // that the tail note overshoots the height of this hit object glowContainer.Height = DrawHeight + tail.Height; - glowContainer.EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Colour = AccentColour.Opacity(0.5f), - Radius = 10, - Hollow = true, - }; } public bool OnPressed(ManiaAction action) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 707b83ef13..310d6ba347 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { base.LoadComplete(); - UpdateGlow(); + updateGlow(); } public override Color4 AccentColour @@ -57,10 +57,27 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables headPiece.AccentColour = value; - UpdateGlow(); + updateGlow(); } } + private void updateGlow() + { + if (!IsLoaded) + return; + + if (!HasOwnGlow) + return; + + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = AccentColour.Opacity(0.5f), + Radius = 10, + Hollow = true + }; + } + protected override void CheckJudgement(bool userTriggered) { if (!userTriggered) @@ -96,23 +113,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } - protected virtual void UpdateGlow() - { - if (!IsLoaded) - return; - - if (!HasOwnGlow) - return; - - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Colour = AccentColour.Opacity(0.5f), - Radius = 10, - Hollow = true - }; - } - public virtual bool OnPressed(ManiaAction action) { if (action != Action) From 8bb8999820d71fc2df666ed3fd0c675dd4eaa15e Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 04:34:30 +0900 Subject: [PATCH 353/483] More TestCaseManiaHitObjects fixes. --- osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs | 5 +---- .../Objects/Drawables/DrawableHoldNote.cs | 8 ++++++++ .../Objects/Drawables/DrawableManiaHitObject.cs | 2 ++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs b/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs index 8f0e87bee6..d855e86aa0 100644 --- a/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs +++ b/osu.Desktop.Tests/Visual/TestCaseManiaHitObjects.cs @@ -43,7 +43,6 @@ namespace osu.Desktop.Tests.Visual { new DrawableNote(new Note(), ManiaAction.Key1) { - RelativePositionAxes = Axes.Y, Y = 5000, LifetimeStart = double.MinValue, LifetimeEnd = double.MaxValue, @@ -51,7 +50,6 @@ namespace osu.Desktop.Tests.Visual }, new DrawableNote(new Note(), ManiaAction.Key1) { - RelativePositionAxes = Axes.Y, Y = 6000, LifetimeStart = double.MinValue, LifetimeEnd = double.MaxValue, @@ -79,9 +77,8 @@ namespace osu.Desktop.Tests.Visual { new DrawableHoldNote(new HoldNote(), ManiaAction.Key1) { - RelativePositionAxes = Axes.Y, Y = 5000, - Height = 3000, + Height = 1000, LifetimeStart = double.MinValue, LifetimeEnd = double.MaxValue, AccentColour = Color4.Red diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 671884fe17..e2ab405cf5 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -207,6 +207,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables RelativePositionAxes = Axes.None; Y = 0; + // Life time managed by the parent DrawableHoldNote + LifetimeStart = double.MinValue; + LifetimeEnd = double.MaxValue; + HasOwnGlow = false; } @@ -246,6 +250,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables RelativePositionAxes = Axes.None; Y = 0; + // Life time managed by the parent DrawableHoldNote + LifetimeStart = double.MinValue; + LifetimeEnd = double.MaxValue; + HasOwnGlow = false; } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index bfef05ea07..f6129602a8 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Graphics; using OpenTK.Graphics; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Objects.Drawables; @@ -20,6 +21,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected DrawableManiaHitObject(TObject hitObject, ManiaAction? action = null) : base(hitObject) { + RelativePositionAxes = Axes.Y; HitObject = hitObject; if (action != null) From 79a9612243eb7d28b3131068d1d9dd3d2c4ba90f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 04:37:48 +0900 Subject: [PATCH 354/483] Remove now unnecessary comment. --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index e2ab405cf5..3bfcf401d7 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -45,9 +45,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables AddRange(new Drawable[] { - // For now the body piece covers the entire height of the container - // whereas possibly in the future we don't want to extend under the head/tail. - // This will be fixed when new designs are given or the current design is finalized. bodyPiece = new BodyPiece { Anchor = Anchor.TopCentre, From 9cd3af11d5911a9efa0c37c8691f296aa85ee925 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 04:45:10 +0900 Subject: [PATCH 355/483] Fix hold note tick position + lifetime. --- .../Objects/Drawables/DrawableHoldNoteTick.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 39abbb6b3d..546afd089b 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -36,9 +36,15 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; + Y = (float)HitObject.StartTime; + RelativeSizeAxes = Axes.X; Size = new Vector2(1); + // Life time managed by the parent DrawableHoldNote + LifetimeStart = double.MinValue; + LifetimeEnd = double.MaxValue; + Children = new[] { glowContainer = new CircularContainer From 2086ed209db9c14c193afe4b4dba339eadfce727 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 04:51:44 +0900 Subject: [PATCH 356/483] Fix hold note tick input. --- .../Objects/Drawables/DrawableHoldNoteTick.cs | 8 ++------ osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 3 ++- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 546afd089b..7a397514d8 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; namespace osu.Game.Rulesets.Mania.Objects.Drawables { @@ -23,11 +24,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// public Func HoldStartTime; - /// - /// References whether the user is currently holding the hold note. - /// - public Func IsHolding; - private readonly Container glowContainer; public DrawableHoldNoteTick(HoldNoteTick hitObject) @@ -118,7 +114,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (Judgement.Result != HitResult.None) return; - if (IsHolding?.Invoke() != true) + if (HoldStartTime?.Invoke() == null) return; UpdateJudgement(true); diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 3fba168216..369ea76028 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -12,10 +12,11 @@ using osu.Game.Rulesets.Objects.Types; using OpenTK.Graphics; using osu.Game.Audio; using System.Linq; +using osu.Game.Graphics; namespace osu.Game.Rulesets.Objects.Drawables { - public abstract class DrawableHitObject : Container + public abstract class DrawableHitObject : Container, IHasAccentColour { public readonly HitObject HitObject; From f33bd700c5ae1f1ecd602b8a1dfe1f15c7739129 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 08:27:29 +0900 Subject: [PATCH 357/483] Fix individual volume controls not being adjustable via wheel They were blocking each others' input unnecessarily. --- .../Graphics/UserInterface/Volume/VolumeControl.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs index 4c108e793a..8c777f491b 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs @@ -15,11 +15,7 @@ namespace osu.Game.Graphics.UserInterface.Volume { private readonly VolumeMeter volumeMeterMaster; - private void volumeChanged(double newVolume) - { - Show(); - schedulePopOut(); - } + protected override bool BlockPassThroughMouse => false; public VolumeControl() { @@ -85,6 +81,12 @@ namespace osu.Game.Graphics.UserInterface.Volume return false; } + private void volumeChanged(double newVolume) + { + Show(); + schedulePopOut(); + } + [BackgroundDependencyLoader] private void load(AudioManager audio) { From 2f72dff779b39c6efd712936fb2967e348c67a2f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 08:59:56 +0900 Subject: [PATCH 358/483] Update with framework changes. --- osu-framework | 2 +- .../Objects/Drawables/DrawableHoldNoteTick.cs | 1 - osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu-framework b/osu-framework index d891fc31d8..c9a1998676 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit d891fc31d8dbe5ee88b798eca9d0a5a7483a144f +Subproject commit c9a1998676c57f8d5e6a9d817e75b506d40e4246 diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 7a397514d8..7f4ec8d8d2 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; namespace osu.Game.Rulesets.Mania.Objects.Drawables { diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs index ac7054abe8..fe40532e42 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces BackgroundColour = Color4.White.Opacity(0), CacheDrawnFrameBuffer = true, // The 'hole' is achieved by subtracting the result of this container with the parent - Blending = new BlendingModeParameters { AlphaEquation = BlendingEquation.ReverseSubtract }, + Blending = new BlendingParameters { AlphaEquation = BlendingEquation.ReverseSubtract }, Child = subtractionLayer = new CircularContainer { Anchor = Anchor.Centre, From 42dc4d9b1c96c83eff95948a331a7d8948fa8af5 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 10:46:54 +0900 Subject: [PATCH 359/483] Rework mania playfield to be more sane with masking/nesting. --- osu-framework | 2 +- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 39 +++++++++++--------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/osu-framework b/osu-framework index a617245a42..09f71b9383 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit a617245a4261d7d6e138c2fddbbeaa7940d24ca7 +Subproject commit 09f71b93837f072da067cc60755bdf85682d9fb4 diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index ce91fda023..57f204990f 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -50,6 +50,8 @@ namespace osu.Game.Rulesets.Mania.UI protected override Container Content => content; private readonly Container content; + private readonly Container topLevelContainer; + private List normalColumnColours = new List(); private Color4 specialColumnColour; @@ -69,17 +71,16 @@ namespace osu.Game.Rulesets.Mania.UI { new Container { + Name = "Playfield elements", Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.Both, - Masking = true, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, Children = new Drawable[] { new Container { - Name = "Masked elements", - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, + Name = "Columns mask", RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, Masking = true, @@ -87,6 +88,7 @@ namespace osu.Game.Rulesets.Mania.UI { new Box { + Name = "Background", RelativeSizeAxes = Axes.Both, Colour = Color4.Black }, @@ -98,27 +100,28 @@ namespace osu.Game.Rulesets.Mania.UI Direction = FillDirection.Horizontal, Padding = new MarginPadding { Left = 1, Right = 1 }, Spacing = new Vector2(1, 0) - } + }, } }, new Container { + Name = "Barlines mask", Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = HIT_TARGET_POSITION }, - Children = new[] + RelativeSizeAxes = Axes.Y, + Width = 1366, // Bar lines should only be masked on the vertical axis + BypassAutoSizeAxes = Axes.Both, + Masking = true, + Child = content = new Container { - content = new Container - { - Name = "Bar lines", - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.Y, - // Width is set in the Update method - } + Name = "Bar lines", + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.Y, + Padding = new MarginPadding { Top = HIT_TARGET_POSITION } } - } + }, + topLevelContainer = new Container { RelativeSizeAxes = Axes.Both } } } }; From 8d919e42c9eb04202547972893ad4261cf3ead78 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 11:18:53 +0900 Subject: [PATCH 360/483] Fix nullref when loading MusicController VisualTest after Player VisualTest --- osu.Game/Overlays/MusicController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 0a06439c3e..64d0d628f0 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -302,8 +302,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 = 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(); direction = last > next ? TransformDirection.Prev : TransformDirection.Next; } From 4f6c93aa0f711b1a9aad7e0c2479b258d4f1faf1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 11:34:40 +0900 Subject: [PATCH 361/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index a617245a42..0fe1e50b38 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit a617245a4261d7d6e138c2fddbbeaa7940d24ca7 +Subproject commit 0fe1e50b38ff9ce8aceba231eede3333cb73bb23 From eedfbdc0e8de2f3da4418a20ac42e1b84ee16404 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 11:41:09 +0900 Subject: [PATCH 362/483] Add nullref check in KeyCounterCollection's Add method --- osu.Game/Screens/Play/KeyCounterCollection.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/KeyCounterCollection.cs b/osu.Game/Screens/Play/KeyCounterCollection.cs index 0f6c5984c4..d21be71785 100644 --- a/osu.Game/Screens/Play/KeyCounterCollection.cs +++ b/osu.Game/Screens/Play/KeyCounterCollection.cs @@ -28,6 +28,8 @@ namespace osu.Game.Screens.Play public override void Add(KeyCounter key) { + if (key == null) throw new ArgumentNullException(nameof(key)); + base.Add(key); key.IsCounting = IsCounting; key.FadeTime = FadeTime; From 3cacee300ace35b41947bf374c1e15550b0b99e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 11:41:29 +0900 Subject: [PATCH 363/483] Fix a false resharper positive --- .../OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs index 72ba421344..c6ecc3a506 100644 --- a/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs +++ b/osu.Game.Rulesets.Osu/OsuDifficulty/Preprocessing/OsuDifficultyBeatmap.cs @@ -51,6 +51,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing 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 } From 7170fbd0873252304f1a49bdd933965f7c368303 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 12:35:40 +0900 Subject: [PATCH 364/483] Target .NET 4.6.1 --- osu.Desktop.Deploy/osu.Desktop.Deploy.csproj | 2 +- osu.Desktop.Tests/osu.Desktop.Tests.csproj | 2 +- osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj | 2 +- osu.Desktop/osu.Desktop.csproj | 2 +- osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj | 2 +- osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj | 2 +- osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj | 2 +- osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- osu.Game/osu.Game.csproj | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj index c6474eae5a..c090342a4b 100644 --- a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj +++ b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj @@ -9,7 +9,7 @@ Properties osu.Desktop.Deploy osu.Desktop.Deploy - v4.5.2 + v4.6.1 512 true diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj index 86268e6110..975af1a782 100644 --- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj +++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj @@ -9,7 +9,7 @@ Properties osu.Desktop.Tests osu.Desktop.Tests - v4.5 + v4.6.1 512 diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 8bba59207f..33019909c6 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -22,7 +22,7 @@ OnOutputUpdated false LocalIntranet - v4.5 + v4.6.1 true publish\ true diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index bbca4145c6..661c17699b 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -22,7 +22,7 @@ OnOutputUpdated false LocalIntranet - v4.5 + v4.6.1 true publish\ true diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 79ef5f4ba8..2ae2262ac7 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -9,7 +9,7 @@ Properties osu.Game.Rulesets.Catch osu.Game.Rulesets.Catch - v4.5 + v4.6.1 512 diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 890c9116cf..5f39054d82 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -9,7 +9,7 @@ Properties osu.Game.Rulesets.Mania osu.Game.Rulesets.Mania - v4.5 + v4.6.1 512 diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index 0c9e53cf69..857f47f9b9 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -9,7 +9,7 @@ Properties osu.Game.Rulesets.Osu osu.Game.Rulesets.Osu - v4.5 + v4.6.1 512 diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 33748a267f..e1987ec96d 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -9,7 +9,7 @@ Properties osu.Game.Rulesets.Taiko osu.Game.Rulesets.Taiko - v4.5 + v4.6.1 512 diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 8ec68b41be..220b1aac7f 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -7,7 +7,7 @@ Library osu.Game.Tests osu.Game.Tests - v4.5 + v4.6.1 true diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index defa9f8a6d..d20618a2ae 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -9,7 +9,7 @@ Properties osu.Game osu.Game - v4.5 + v4.6.1 512 From 712c6942a9f0072af9c7a4c1b6cbd7fcfc1af692 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 12:39:06 +0900 Subject: [PATCH 365/483] Update submodules --- osu-framework | 2 +- osu-resources | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu-framework b/osu-framework index 0fe1e50b38..e24d24ae70 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 0fe1e50b38ff9ce8aceba231eede3333cb73bb23 +Subproject commit e24d24ae70a78cea5a11635c37d2808d29233e96 diff --git a/osu-resources b/osu-resources index f6042e1cb3..a4418111f8 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit f6042e1cb37cfad6c879d0e1245f7880c7fcd5f5 +Subproject commit a4418111f8ed2350a6fd46fe69258884f0757745 From 10f0d1f20d515c30e71877801ba67ab16e897913 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 12:57:10 +0900 Subject: [PATCH 366/483] Pass down OnJudgement to columns. --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 57f204990f..ee50cb3f6b 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -180,6 +180,8 @@ namespace osu.Game.Rulesets.Mania.UI } } + public override void OnJudgement(DrawableHitObject judgedObject) => columns[judgedObject.HitObject.Column].OnJudgement(judgedObject); + /// /// Whether the column index is a special column for this playfield. /// From 0cadee998c7fb2c2e07a7b2dfacae32084330315 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 13:43:52 +0900 Subject: [PATCH 367/483] Set default AccentColour for hit objects --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 3fba168216..ed852b1c25 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects.Drawables /// /// The colour used for various elements of this DrawableHitObject. /// - public virtual Color4 AccentColour { get; set; } + public virtual Color4 AccentColour { get; set; } = Color4.Gray; protected DrawableHitObject(HitObject hitObject) { From 3026675f35466bbfbe89a61d090605e4530a2336 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 13:44:39 +0900 Subject: [PATCH 368/483] Add explosions. --- .../Visual/TestCaseManiaPlayfield.cs | 20 ++++++- osu.Game.Rulesets.Mania/Objects/HoldNote.cs | 11 ++++ .../Objects/ManiaHitObject.cs | 2 +- osu.Game.Rulesets.Mania/UI/Column.cs | 21 ++++++- osu.Game.Rulesets.Mania/UI/HitExplosion.cs | 55 +++++++++++++++++++ osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 6 +- .../osu.Game.Rulesets.Mania.csproj | 1 + 7 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/UI/HitExplosion.cs diff --git a/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs index fb14bdb3bf..8fa627ab6d 100644 --- a/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs @@ -13,6 +13,9 @@ using osu.Game.Rulesets.Mania.Timing; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Timing; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mania.Judgements; +using osu.Game.Rulesets.Objects.Drawables; +using OpenTK.Graphics; namespace osu.Desktop.Tests.Visual { @@ -43,6 +46,19 @@ namespace osu.Desktop.Tests.Visual AddStep("Notes with input (reversed)", () => createPlayfieldWithNotes(false, true)); AddStep("Notes with gravity", () => createPlayfieldWithNotes(true)); AddStep("Notes with gravity (reversed)", () => createPlayfieldWithNotes(true, true)); + + AddStep("Hit explosion", () => + { + var playfield = createPlayfield(4, SpecialColumnPosition.Normal); + + var note = new DrawableNote(new Note(), ManiaAction.Key1) + { + Judgement = new ManiaJudgement { Result = HitResult.Hit }, + AccentColour = Color4.Green + }; + + playfield.OnJudgement(note); + }); } [BackgroundDependencyLoader] @@ -56,7 +72,7 @@ namespace osu.Desktop.Tests.Visual TimingPoint = { BeatLength = 1000 } }, gravity ? ScrollingAlgorithm.Gravity : ScrollingAlgorithm.Basic); - private void createPlayfield(int cols, SpecialColumnPosition specialPos, bool inverted = false) + private ManiaPlayfield createPlayfield(int cols, SpecialColumnPosition specialPos, bool inverted = false) { Clear(); @@ -72,6 +88,8 @@ namespace osu.Desktop.Tests.Visual }); playfield.Inverted.Value = inverted; + + return playfield; } private void createPlayfieldWithNotes(bool gravity, bool inverted = false) diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs index c3a29b39a8..ef2e02a791 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs @@ -37,6 +37,17 @@ namespace osu.Game.Rulesets.Mania.Objects } } + public override int Column + { + get { return base.Column; } + set + { + base.Column = value; + Head.Column = value; + Tail.Column = value; + } + } + /// /// The head note of the hold. /// diff --git a/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs index 93aaa94f45..7beb21f9e3 100644 --- a/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs @@ -8,6 +8,6 @@ namespace osu.Game.Rulesets.Mania.Objects { public abstract class ManiaHitObject : HitObject, IHasColumn { - public int Column { get; set; } + public virtual int Column { get; set; } } } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index d5bc7cc659..213144c84d 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -36,6 +36,9 @@ namespace osu.Game.Rulesets.Mania.UI private readonly Container hitTargetBar; private readonly Container keyIcon; + internal readonly Container TopLevelContainer; + private readonly Container explosionContainer; + protected override Container Content => content; private readonly Container content; @@ -98,6 +101,11 @@ namespace osu.Game.Rulesets.Mania.UI { Pressed = onPressed, Released = onReleased + }, + explosionContainer = new Container + { + Name = "Hit explosions", + RelativeSizeAxes = Axes.Both } } }, @@ -136,8 +144,11 @@ namespace osu.Game.Rulesets.Mania.UI } } } - } + }, + TopLevelContainer = new Container { RelativeSizeAxes = Axes.Both } }; + + TopLevelContainer.Add(explosionContainer.CreateProxy()); } public override Axes RelativeSizeAxes => Axes.Y; @@ -194,6 +205,14 @@ namespace osu.Game.Rulesets.Mania.UI HitObjects.Add(hitObject); } + public override void OnJudgement(DrawableHitObject judgedObject) + { + if (judgedObject.Judgement.Result != HitResult.Hit) + return; + + explosionContainer.Add(new HitExplosion(judgedObject)); + } + private bool onPressed(ManiaAction action) { if (action == Action) diff --git a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs new file mode 100644 index 0000000000..ae2a09c67e --- /dev/null +++ b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs @@ -0,0 +1,55 @@ +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Mania.Judgements; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Mania.UI +{ + internal class HitExplosion : CompositeDrawable + { + private readonly Box inner; + + public HitExplosion(DrawableHitObject judgedObject) + { + Anchor = Anchor.TopCentre; + Origin = Anchor.Centre; + + RelativeSizeAxes = Axes.Both; + FillMode = FillMode.Fit; + + BlendingMode = BlendingMode.Additive; + + InternalChild = new CircularContainer + { + RelativeSizeAxes = Axes.Both, + Masking = true, + BorderThickness = 1, + BorderColour = judgedObject.AccentColour, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = judgedObject.AccentColour, + Radius = 10, + Hollow = true + }, + Child = inner = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = judgedObject.AccentColour, + Alpha = 1, + AlwaysPresent = true, + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + this.ScaleTo(2f, 600, Easing.OutQuint).FadeOut(500); + inner.FadeOut(250); + } + } +} diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index ee50cb3f6b..aceea7bea3 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -14,6 +14,7 @@ using osu.Framework.Allocation; using System.Linq; using System.Collections.Generic; using osu.Framework.Configuration; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Framework.Graphics.Shapes; @@ -50,8 +51,6 @@ namespace osu.Game.Rulesets.Mania.UI protected override Container Content => content; private readonly Container content; - private readonly Container topLevelContainer; - private List normalColumnColours = new List(); private Color4 specialColumnColour; @@ -67,6 +66,7 @@ namespace osu.Game.Rulesets.Mania.UI Inverted.Value = true; + Container topLevelContainer; InternalChildren = new Drawable[] { new Container @@ -135,6 +135,8 @@ namespace osu.Game.Rulesets.Mania.UI c.IsSpecial = isSpecialColumn(i); c.Action = c.IsSpecial ? ManiaAction.Special : currentAction++; + topLevelContainer.Add(c.TopLevelContainer.CreateProxy()); + columns.Add(c); AddNested(c); } diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 890c9116cf..1e44fb7025 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -83,6 +83,7 @@ + From 9e3206fef31ca49a4fbb0f15c63cae114a9d67d7 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 13:55:34 +0900 Subject: [PATCH 369/483] Improve test case a little bit. --- osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs index 8fa627ab6d..7b458b9224 100644 --- a/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; @@ -32,6 +33,8 @@ namespace osu.Desktop.Tests.Visual public TestCaseManiaPlayfield() { + var rng = new Random(1337); + AddStep("1 column", () => createPlayfield(1, SpecialColumnPosition.Normal)); AddStep("4 columns", () => createPlayfield(4, SpecialColumnPosition.Normal)); AddStep("Left special style", () => createPlayfield(4, SpecialColumnPosition.Left)); @@ -51,10 +54,12 @@ namespace osu.Desktop.Tests.Visual { var playfield = createPlayfield(4, SpecialColumnPosition.Normal); - var note = new DrawableNote(new Note(), ManiaAction.Key1) + int col = rng.Next(0, 4); + + var note = new DrawableNote(new Note { Column = col }, ManiaAction.Key1) { Judgement = new ManiaJudgement { Result = HitResult.Hit }, - AccentColour = Color4.Green + AccentColour = playfield.Columns.ElementAt(col).AccentColour }; playfield.OnJudgement(note); From 2c3131d391aee97a70a6437a19ca01466354bbbf Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 13:56:10 +0900 Subject: [PATCH 370/483] Remove green coloration when hit. --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index c201ab7bd0..f0b622de17 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -71,12 +71,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected override void UpdateState(ArmedState state) { - switch (State) - { - case ArmedState.Hit: - Colour = Color4.Green; - break; - } } public virtual bool OnPressed(ManiaAction action) From 512232c1c887c9e5d7f4b118e6238bf315b17cee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 14:25:01 +0900 Subject: [PATCH 371/483] Fix regression causing autoplay to fail --- osu.Game/Rulesets/UI/RulesetContainer.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index e2701faca0..34b079951d 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -77,13 +77,6 @@ namespace osu.Game.Rulesets.UI Ruleset = ruleset; } - [BackgroundDependencyLoader] - private void load() - { - KeyBindingInputManager = CreateInputManager(); - KeyBindingInputManager.RelativeSizeAxes = Axes.Both; - } - /// /// Checks whether all HitObjects have been judged, and invokes OnAllJudged. /// @@ -194,6 +187,9 @@ namespace osu.Game.Rulesets.UI // Post-process the beatmap processor.PostProcess(Beatmap); + KeyBindingInputManager = CreateInputManager(); + KeyBindingInputManager.RelativeSizeAxes = Axes.Both; + // Add mods, should always be the last thing applied to give full control to mods applyMods(Mods); } From e8efdcf188cb066cdd4b906242fb46d69464f879 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 14:35:18 +0900 Subject: [PATCH 372/483] Make tick explosions white and lower scale. --- .../Visual/TestCaseManiaPlayfield.cs | 1 - .../Objects/Drawables/DrawableHoldNoteTick.cs | 3 --- osu.Game.Rulesets.Mania/Objects/HoldNote.cs | 3 ++- osu.Game.Rulesets.Mania/UI/HitExplosion.cs | 16 ++++++++++++---- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 1 - 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs index 7b458b9224..a0f1162ecb 100644 --- a/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseManiaPlayfield.cs @@ -16,7 +16,6 @@ using osu.Game.Rulesets.Timing; using osu.Game.Rulesets; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Objects.Drawables; -using OpenTK.Graphics; namespace osu.Desktop.Tests.Visual { diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 39abbb6b3d..a074715faf 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -58,9 +58,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } }; - - // Set the default glow - AccentColour = Color4.White; } public override Color4 AccentColour diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs index ef2e02a791..fc1331551e 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs @@ -91,7 +91,8 @@ namespace osu.Game.Rulesets.Mania.Objects { ret.Add(new HoldNoteTick { - StartTime = t + StartTime = t, + Column = Column }); } diff --git a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs index ae2a09c67e..c57833c623 100644 --- a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs @@ -1,8 +1,11 @@ -using osu.Framework.Graphics; +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Mania.UI @@ -13,31 +16,36 @@ namespace osu.Game.Rulesets.Mania.UI public HitExplosion(DrawableHitObject judgedObject) { + bool isTick = judgedObject is DrawableHoldNoteTick; + Anchor = Anchor.TopCentre; Origin = Anchor.Centre; RelativeSizeAxes = Axes.Both; + Size = new Vector2(isTick ? 0.5f : 1); FillMode = FillMode.Fit; BlendingMode = BlendingMode.Additive; + Color4 accent = isTick ? Color4.White : judgedObject.AccentColour; + InternalChild = new CircularContainer { RelativeSizeAxes = Axes.Both, Masking = true, BorderThickness = 1, - BorderColour = judgedObject.AccentColour, + BorderColour = accent, EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, - Colour = judgedObject.AccentColour, + Colour = accent, Radius = 10, Hollow = true }, Child = inner = new Box { RelativeSizeAxes = Axes.Both, - Colour = judgedObject.AccentColour, + Colour = accent, Alpha = 1, AlwaysPresent = true, } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index aceea7bea3..5697da537e 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -14,7 +14,6 @@ using osu.Framework.Allocation; using System.Linq; using System.Collections.Generic; using osu.Framework.Configuration; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Framework.Graphics.Shapes; From b01233eddcb6ea2ee223d40ddd8bcf588bf6aea9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 14:48:01 +0900 Subject: [PATCH 373/483] Fix CI issues --- osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs | 3 ++- osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs index 132c49ab31..70270af6c9 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Mods; @@ -24,7 +25,7 @@ namespace osu.Game.Rulesets.Mania.Mods public void ApplyToRulesetContainer(ManiaRulesetContainer rulesetContainer, ref List[] hitObjectTimingChanges, ref List barlineTimingChanges) { // We have to generate one speed adjustment per hit object for gravity - foreach (ManiaHitObject obj in rulesetContainer.Objects) + foreach (ManiaHitObject obj in rulesetContainer.Objects.OfType()) { MultiplierControlPoint controlPoint = rulesetContainer.CreateControlPointAt(obj.StartTime); // Beat length has too large of an effect for gravity, so we'll force it to a constant value for now diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs index fb64b667e6..41b66c286b 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs @@ -19,6 +19,7 @@ namespace osu.Game.Rulesets.Taiko.UI /// /// Creates a new judgement text. /// + /// The object which is being judged. /// The judgement to visualise. public DrawableTaikoJudgement(DrawableHitObject judgedObject, Judgement judgement) : base(judgement) From 6c4f507e3947ed42c37bd7efae0cf06a31474d02 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 15:02:30 +0900 Subject: [PATCH 374/483] Update framework. --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index d891fc31d8..cb48c7bef8 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit d891fc31d8dbe5ee88b798eca9d0a5a7483a144f +Subproject commit cb48c7bef8c5909472c70e09059ee6ea5bf6fc8a From de7d50d384a9551ed523759ce51deda564ee5b88 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 15:08:51 +0900 Subject: [PATCH 375/483] Better variable + comment naming --- .../Objects/Drawables/DrawableHoldNote.cs | 4 ++-- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 3bfcf401d7..3b801cba01 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -208,7 +208,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables LifetimeStart = double.MinValue; LifetimeEnd = double.MaxValue; - HasOwnGlow = false; + ApplyGlow = false; } public override bool OnPressed(ManiaAction action) @@ -251,7 +251,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables LifetimeStart = double.MinValue; LifetimeEnd = double.MaxValue; - HasOwnGlow = false; + ApplyGlow = false; } protected override ManiaJudgement CreateJudgement() => new HoldNoteTailJudgement(); diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 310d6ba347..a58ae9b31c 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -19,9 +19,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables public class DrawableNote : DrawableManiaHitObject, IKeyBindingHandler { /// - /// Whether the glow for this is handled by a containing it. + /// Gets or sets whether this should apply glow to itself. /// - protected bool HasOwnGlow = true; + protected bool ApplyGlow = true; private readonly NotePiece headPiece; @@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (!IsLoaded) return; - if (!HasOwnGlow) + if (!ApplyGlow) return; EdgeEffect = new EdgeEffectParameters From 6ecd530d7b2acf16c958cff9c02183ebb628d222 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 11 Sep 2017 15:24:28 +0900 Subject: [PATCH 376/483] Add missing license header --- osu.Game.Rulesets.Mania/UI/HitExplosion.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs index c57833c623..168d6db20d 100644 --- a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs @@ -1,4 +1,7 @@ -using OpenTK; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; From 54aff432fee521e739c1665f42a16a094c85a390 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 15:43:23 +0900 Subject: [PATCH 377/483] Fix CI error --- osu.Game.Rulesets.Mania/UI/HitExplosion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs index 168d6db20d..962082c368 100644 --- a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Mania.UI Size = new Vector2(isTick ? 0.5f : 1); FillMode = FillMode.Fit; - BlendingMode = BlendingMode.Additive; + Blending = BlendingMode.Additive; Color4 accent = isTick ? Color4.White : judgedObject.AccentColour; From df0a31bf2aad29e74d76190ded0ffdca853803ed Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 11 Sep 2017 17:53:27 +0900 Subject: [PATCH 378/483] Add judgement text displays to osu!mania --- .../Judgements/ManiaJudgement.cs | 5 ++- .../UI/DrawableManiaJudgement.cs | 38 +++++++++++++++++++ osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 23 ++++++++++- .../osu.Game.Rulesets.Mania.csproj | 1 + 4 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs diff --git a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs index 33083ca0f5..f8602ac42a 100644 --- a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Extensions; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; @@ -33,9 +34,9 @@ namespace osu.Game.Rulesets.Mania.Judgements /// public int MaxResultValueForAccuracy => NumericResultForAccuracy(MAX_HIT_RESULT); - public override string ResultString => string.Empty; + public override string ResultString => ManiaResult.GetDescription(); - public override string MaxResultString => string.Empty; + public override string MaxResultString => MAX_HIT_RESULT.GetDescription(); /// /// The hit result. diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs new file mode 100644 index 0000000000..8efc2262e1 --- /dev/null +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs @@ -0,0 +1,38 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using osu.Framework.Graphics; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mania.Judgements; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Mania.UI +{ + internal class DrawableManiaJudgement : DrawableJudgement + { + public DrawableManiaJudgement(ManiaJudgement judgement) + : base(judgement) + { + JudgementText.TextSize = 25; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + this.FadeInFromZero(50, Easing.OutQuint); + + switch (Judgement.Result) + { + case HitResult.Hit: + this.ScaleTo(0.8f); + this.ScaleTo(1, 250, Easing.OutElastic); + + this.Delay(50).FadeOut(200).ScaleTo(0.75f, 250); + break; + } + + Expire(); + } + } +} diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 5697da537e..b333dfe1d5 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -53,6 +53,8 @@ namespace osu.Game.Rulesets.Mania.UI private List normalColumnColours = new List(); private Color4 specialColumnColour; + private readonly Container judgements; + private readonly int columnCount; public ManiaPlayfield(int columnCount) @@ -120,6 +122,14 @@ namespace osu.Game.Rulesets.Mania.UI Padding = new MarginPadding { Top = HIT_TARGET_POSITION } } }, + judgements = new Container + { + Anchor = Anchor.TopCentre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Y = HIT_TARGET_POSITION + 150, + BypassAutoSizeAxes = Axes.Both + }, topLevelContainer = new Container { RelativeSizeAxes = Axes.Both } } } @@ -147,6 +157,7 @@ namespace osu.Game.Rulesets.Mania.UI private void invertedChanged(bool newValue) { Scale = new Vector2(1, newValue ? -1 : 1); + judgements.Scale = Scale; } [BackgroundDependencyLoader] @@ -181,7 +192,17 @@ namespace osu.Game.Rulesets.Mania.UI } } - public override void OnJudgement(DrawableHitObject judgedObject) => columns[judgedObject.HitObject.Column].OnJudgement(judgedObject); + public override void OnJudgement(DrawableHitObject judgedObject) + { + columns[judgedObject.HitObject.Column].OnJudgement(judgedObject); + + judgements.Clear(); + judgements.Add(new DrawableManiaJudgement(judgedObject.Judgement) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + } /// /// Whether the column index is a special column for this playfield. diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index f9d8f6b358..ef098a023d 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -83,6 +83,7 @@ + From 262aea8b6b208bcaf99ee40a4764b98773f9dbb5 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Mon, 11 Sep 2017 19:01:36 +0930 Subject: [PATCH 379/483] Fix osu! logo triangles going super fast when the track is paused --- osu.Game/Screens/Menu/OsuLogo.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 55c25d4c54..6f4a46b10b 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -272,14 +272,22 @@ namespace osu.Game.Screens.Menu const float scale_adjust_cutoff = 0.4f; const float velocity_adjust_cutoff = 0.98f; + const float paused_velocity = 0.5f; - var maxAmplitude = lastBeatIndex >= 0 ? Beatmap.Value.Track?.CurrentAmplitudes.Maximum ?? 0 : 0; - logoAmplitudeContainer.ScaleTo(1 - Math.Max(0, maxAmplitude - scale_adjust_cutoff) * 0.04f, 75, Easing.OutQuint); + if (Beatmap.Value.Track.IsRunning) + { + var maxAmplitude = lastBeatIndex >= 0 ? Beatmap.Value.Track.CurrentAmplitudes.Maximum : 0; + logoAmplitudeContainer.ScaleTo(1 - Math.Max(0, maxAmplitude - scale_adjust_cutoff) * 0.04f, 75, Easing.OutQuint); - if (maxAmplitude > velocity_adjust_cutoff) - triangles.Velocity = 1 + Math.Max(0, maxAmplitude - velocity_adjust_cutoff) * 50; + if (maxAmplitude > velocity_adjust_cutoff) + triangles.Velocity = 1 + Math.Max(0, maxAmplitude - velocity_adjust_cutoff) * 50; + else + triangles.Velocity = (float)Interpolation.Damp(triangles.Velocity, 1, 0.995f, Time.Elapsed); + } else - triangles.Velocity = (float)Interpolation.Damp(triangles.Velocity, 1, 0.995f, Time.Elapsed); + { + triangles.Velocity = paused_velocity; + } } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) From 9eaa1cb5cdeda76fcb943905baacab808bddffa2 Mon Sep 17 00:00:00 2001 From: Damnae Date: Sun, 10 Sep 2017 21:25:23 +0200 Subject: [PATCH 380/483] Fix sprites not being visible when all their commands are inside loops. --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- osu.Game/Storyboards/SpriteDefinition.cs | 55 ++++++++++--------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index d538960a37..e436a43989 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -324,7 +324,7 @@ namespace osu.Game.Beatmaps.Formats else { if (depth < 2) - timelineGroup = spriteDefinition; + timelineGroup = spriteDefinition?.TimelineGroup; var commandType = split[0]; switch (commandType) diff --git a/osu.Game/Storyboards/SpriteDefinition.cs b/osu.Game/Storyboards/SpriteDefinition.cs index c410fd8807..1e1718a255 100644 --- a/osu.Game/Storyboards/SpriteDefinition.cs +++ b/osu.Game/Storyboards/SpriteDefinition.cs @@ -10,14 +10,26 @@ using System.Linq; namespace osu.Game.Storyboards { - public class SpriteDefinition : CommandTimelineGroup, IElementDefinition + public class SpriteDefinition : IElementDefinition { + private readonly List loops = new List(); + private readonly List triggers = new List(); + public string Path { get; set; } public Anchor Origin; public Vector2 InitialPosition; - private readonly List loops = new List(); - private readonly List triggers = new List(); + public readonly CommandTimelineGroup TimelineGroup = new CommandTimelineGroup(); + + public double StartTime => Math.Min( + TimelineGroup.HasCommands ? TimelineGroup.CommandsStartTime : double.MaxValue, + loops.Any(l => l.HasCommands) ? loops.Where(l => l.HasCommands).Min(l => l.StartTime) : double.MaxValue); + + public double EndTime => Math.Max( + TimelineGroup.HasCommands ? TimelineGroup.CommandsEndTime : double.MinValue, + loops.Any(l => l.HasCommands) ? loops.Where(l => l.HasCommands).Max(l => l.EndTime) : double.MinValue); + + public bool HasCommands => TimelineGroup.HasCommands || loops.Any(l => l.HasCommands); private delegate void DrawablePropertyInitializer(Drawable drawable, T value); private delegate void DrawableTransformer(Drawable drawable, T value, double duration, Easing easing); @@ -46,38 +58,29 @@ namespace osu.Game.Storyboards public virtual Drawable CreateDrawable() => new StoryboardSprite(this); - public override IEnumerable.TypedCommand> GetCommands(CommandTimelineSelector timelineSelector, double offset = 0) - { - var result = base.GetCommands(timelineSelector, offset); - foreach (var loop in loops) - result = result.Concat(loop.GetCommands(timelineSelector, offset)); - return result; - } - public void ApplyTransforms(Drawable drawable, IEnumerable> triggeredGroups = null) { - applyCommands(drawable, triggeredGroups, g => g.X, (d, value) => d.X = value, (d, value, duration, easing) => d.MoveToX(value, duration, easing)); - applyCommands(drawable, triggeredGroups, g => g.Y, (d, value) => d.Y = value, (d, value, duration, easing) => d.MoveToY(value, duration, easing)); - applyCommands(drawable, triggeredGroups, g => g.Scale, (d, value) => d.Scale = value, (d, value, duration, easing) => d.ScaleTo(value, duration, easing)); - applyCommands(drawable, triggeredGroups, g => g.Rotation, (d, value) => d.Rotation = value, (d, value, duration, easing) => d.RotateTo(value, duration, easing)); - applyCommands(drawable, triggeredGroups, g => g.Colour, (d, value) => d.Colour = value, (d, value, duration, easing) => d.FadeColour(value, duration, easing)); - applyCommands(drawable, triggeredGroups, g => g.Alpha, (d, value) => d.Alpha = value, (d, value, duration, easing) => d.FadeTo(value, duration, easing)); - applyCommands(drawable, triggeredGroups, g => g.BlendingMode, (d, value) => d.BlendingMode = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration), false); + applyCommands(drawable, getCommands(g => g.X, triggeredGroups), (d, value) => d.X = value, (d, value, duration, easing) => d.MoveToX(value, duration, easing)); + applyCommands(drawable, getCommands(g => g.Y, triggeredGroups), (d, value) => d.Y = value, (d, value, duration, easing) => d.MoveToY(value, duration, easing)); + applyCommands(drawable, getCommands(g => g.Scale, triggeredGroups), (d, value) => d.Scale = value, (d, value, duration, easing) => d.ScaleTo(value, duration, easing)); + applyCommands(drawable, getCommands(g => g.Rotation, triggeredGroups), (d, value) => d.Rotation = value, (d, value, duration, easing) => d.RotateTo(value, duration, easing)); + applyCommands(drawable, getCommands(g => g.Colour, triggeredGroups), (d, value) => d.Colour = value, (d, value, duration, easing) => d.FadeColour(value, duration, easing)); + applyCommands(drawable, getCommands(g => g.Alpha, triggeredGroups), (d, value) => d.Alpha = value, (d, value, duration, easing) => d.FadeTo(value, duration, easing)); + applyCommands(drawable, getCommands(g => g.BlendingMode, triggeredGroups), (d, value) => d.BlendingMode = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration), false); var flippable = drawable as IFlippable; if (flippable != null) { - applyCommands(drawable, triggeredGroups, g => g.FlipH, (d, value) => flippable.FlipH = value, (d, value, duration, easing) => flippable.TransformFlipH(value, duration), false); - applyCommands(drawable, triggeredGroups, g => g.FlipV, (d, value) => flippable.FlipV = value, (d, value, duration, easing) => flippable.TransformFlipV(value, duration), false); + applyCommands(drawable, getCommands(g => g.FlipH, triggeredGroups), (d, value) => flippable.FlipH = value, (d, value, duration, easing) => flippable.TransformFlipH(value, duration), false); + applyCommands(drawable, getCommands(g => g.FlipV, triggeredGroups), (d, value) => flippable.FlipV = value, (d, value, duration, easing) => flippable.TransformFlipV(value, duration), false); } } - private void applyCommands(Drawable drawable, IEnumerable> triggeredGroups, - CommandTimelineSelector timelineSelector, DrawablePropertyInitializer initializeProperty, DrawableTransformer transform, bool alwaysInitialize = true) + private void applyCommands(Drawable drawable, IEnumerable.TypedCommand> commands, DrawablePropertyInitializer initializeProperty, DrawableTransformer transform, bool alwaysInitialize = true) where T : struct { var initialized = false; - foreach (var command in getAggregatedCommands(timelineSelector, triggeredGroups).OrderBy(l => l)) + foreach (var command in commands.OrderBy(l => l)) { if (!initialized) { @@ -93,9 +96,11 @@ namespace osu.Game.Storyboards } } - private IEnumerable.TypedCommand> getAggregatedCommands(CommandTimelineSelector timelineSelector, IEnumerable> triggeredGroups) + private IEnumerable.TypedCommand> getCommands(CommandTimelineSelector timelineSelector, IEnumerable> triggeredGroups) { - var commands = GetCommands(timelineSelector); + var commands = TimelineGroup.GetCommands(timelineSelector); + foreach (var loop in loops) + commands = commands.Concat(loop.GetCommands(timelineSelector)); if (triggeredGroups != null) foreach (var pair in triggeredGroups) commands = commands.Concat(pair.Item1.GetCommands(timelineSelector, pair.Item2)); From cd15cfc864513228112d7209d526a97f7bbf9bd3 Mon Sep 17 00:00:00 2001 From: Damnae Date: Sun, 10 Sep 2017 22:02:55 +0200 Subject: [PATCH 381/483] Use case insensitive paths to find storyboard textures. --- osu.Game/Storyboards/Drawables/StoryboardAnimation.cs | 5 +++-- osu.Game/Storyboards/Drawables/StoryboardSprite.cs | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs index 2051b9c4af..a28287fd40 100644 --- a/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs @@ -69,11 +69,12 @@ namespace osu.Game.Storyboards.Drawables [BackgroundDependencyLoader] private void load(OsuGameBase game, TextureStore textureStore) { + var basePath = Definition.Path.ToLowerInvariant(); for (var frame = 0; frame < Definition.FrameCount; frame++) { - var framePath = Definition.Path.Replace(".", frame + "."); + var framePath = basePath.Replace(".", frame + "."); - var path = game.Beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename == framePath)?.FileInfo.StoragePath; + var path = game.Beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename.ToLowerInvariant() == framePath)?.FileInfo.StoragePath; if (path == null) continue; diff --git a/osu.Game/Storyboards/Drawables/StoryboardSprite.cs b/osu.Game/Storyboards/Drawables/StoryboardSprite.cs index ca055fe6d4..3b1a431a4a 100644 --- a/osu.Game/Storyboards/Drawables/StoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/StoryboardSprite.cs @@ -68,8 +68,8 @@ namespace osu.Game.Storyboards.Drawables [BackgroundDependencyLoader] private void load(OsuGameBase game, TextureStore textureStore) { - var spritePath = Definition.Path; - var path = game.Beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename == spritePath)?.FileInfo.StoragePath; + var spritePath = Definition.Path.ToLowerInvariant(); + var path = game.Beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename.ToLowerInvariant() == spritePath)?.FileInfo.StoragePath; if (path == null) return; From d66fb307dc0f8b0fa0cb2f546dfb96663a320174 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 19:14:37 +0900 Subject: [PATCH 382/483] Fix wrong licence header --- osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs index 8efc2262e1..55b9883918 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; From 2fb203159f8a32fbc0b487b1268bf3ceeaf9bf9f Mon Sep 17 00:00:00 2001 From: Damnae Date: Mon, 11 Sep 2017 12:33:11 +0200 Subject: [PATCH 383/483] CI fixes. --- osu.Game/Storyboards/Drawables/DrawablesExtensions.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs b/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs index 0824ca2ed9..3b21c47b96 100644 --- a/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs +++ b/osu.Game/Storyboards/Drawables/DrawablesExtensions.cs @@ -1,4 +1,7 @@ -using osu.Framework.Graphics; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; using osu.Framework.Graphics.Transforms; namespace osu.Game.Storyboards.Drawables @@ -6,7 +9,7 @@ namespace osu.Game.Storyboards.Drawables public static class DrawablesExtensions { /// - /// Adjusts after a delay. + /// Adjusts after a delay. /// /// A to which further transforms can be added. public static TransformSequence TransformBlendingMode(this T drawable, BlendingMode newValue, double delay = 0) From 7c7849f189c02855254e73ceb42e40d03150467f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 21:40:58 +0900 Subject: [PATCH 384/483] Fix icon states being updated incorrectly when being set too early --- osu.Game/Graphics/SpriteIcon.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Graphics/SpriteIcon.cs b/osu.Game/Graphics/SpriteIcon.cs index d49814952c..d4f9127d54 100644 --- a/osu.Game/Graphics/SpriteIcon.cs +++ b/osu.Game/Graphics/SpriteIcon.cs @@ -57,6 +57,12 @@ namespace osu.Game.Graphics private void load(FontStore store) { this.store = store; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + updateTexture(); } From 95dfbb4f0664cb94d4781ef99cd3e39027a82fbf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 11 Sep 2017 21:41:39 +0900 Subject: [PATCH 385/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index cb48c7bef8..1b479fb947 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit cb48c7bef8c5909472c70e09059ee6ea5bf6fc8a +Subproject commit 1b479fb947da193f099df062f696b3a6164da9e0 From 3c98bc065fe73702b308032f8d55fe15ff09851d Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 09:26:09 +0900 Subject: [PATCH 386/483] Fix osu!mania note masking resulting in miss judgements not occurring. --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 11d3f970c3..37d7566e43 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -30,12 +30,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Masking = true; Add(headPiece = new NotePiece { Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre + Origin = Anchor.TopCentre, + Masking = true }); } @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (!ApplyGlow) return; - EdgeEffect = new EdgeEffectParameters + headPiece.EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Colour = AccentColour.Opacity(0.5f), From d6bf5c38b741cff04871533f245b9a3121097ac2 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 10:01:07 +0900 Subject: [PATCH 387/483] Move Kiai bool to HitObject. --- .../Objects/TaikoHitObject.cs | 16 +--------------- osu.Game/Rulesets/Objects/HitObject.cs | 8 ++++++++ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs index f1c0afc675..a62e0260bd 100644 --- a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs @@ -29,19 +29,5 @@ namespace osu.Game.Rulesets.Taiko.Objects /// Strong hit objects give more points for hitting the hit object with both keys. /// public bool IsStrong; - - /// - /// Whether this HitObject is in Kiai time. - /// - public bool Kiai { get; protected set; } - - public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) - { - base.ApplyDefaults(controlPointInfo, difficulty); - - EffectControlPoint effectPoint = controlPointInfo.EffectPointAt(StartTime); - - Kiai |= effectPoint.KiaiMode; - } } -} \ No newline at end of file +} diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index c343cdaf33..c69979d4cf 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -30,6 +30,11 @@ namespace osu.Game.Rulesets.Objects /// public SampleInfoList Samples = new SampleInfoList(); + /// + /// Whether this is in Kiai time. + /// + public bool Kiai { get; private set; } + /// /// Applies default values to this HitObject. /// @@ -38,6 +43,9 @@ namespace osu.Game.Rulesets.Objects public virtual void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) { SoundControlPoint soundPoint = controlPointInfo.SoundPointAt(StartTime); + EffectControlPoint effectPoint = controlPointInfo.EffectPointAt(StartTime); + + Kiai |= effectPoint.KiaiMode; // Initialize first sample Samples.ForEach(s => initializeSampleInfo(s, soundPoint)); From 0765027cb551bbed8c8c053b43373b9bd3c78a4d Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 11:14:16 +0900 Subject: [PATCH 388/483] Move note glow to a separate class + make it match the design a bit more. --- .../Objects/Drawables/DrawableHoldNote.cs | 57 +++++------------ .../Objects/Drawables/DrawableNote.cs | 47 +++----------- .../Objects/Drawables/Pieces/GlowPiece.cs | 62 +++++++++++++++++++ .../osu.Game.Rulesets.Mania.csproj | 1 + 4 files changed, 87 insertions(+), 80 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 3b801cba01..b0e2f4e3da 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Extensions.Color4Extensions; using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; @@ -10,7 +9,6 @@ using OpenTK; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Mania.Judgements; using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Bindings; namespace osu.Game.Rulesets.Mania.Objects.Drawables @@ -23,9 +21,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables private readonly DrawableNote head; private readonly DrawableNote tail; + private readonly GlowPiece glowPiece; private readonly BodyPiece bodyPiece; private readonly Container tickContainer; - private readonly Container glowContainer; + private readonly Container fullHeightContainer; /// /// Time at which the user started holding this hold note. Null if the user is not holding this hold note. @@ -45,6 +44,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables AddRange(new Drawable[] { + // The hit object itself cannot be used for various elements because the tail overshoots it + // So a specialized container that is updated to contain the tail height is used + fullHeightContainer = new Container + { + RelativeSizeAxes = Axes.X, + Child = glowPiece = new GlowPiece() + }, bodyPiece = new BodyPiece { Anchor = Anchor.TopCentre, @@ -66,19 +72,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { Anchor = Anchor.BottomCentre, Origin = Anchor.TopCentre - }, - // The hit object itself cannot be used for the glow because the tail overshoots it - // So a specialized container that is updated to contain the tail height is used - glowContainer = new Container - { - RelativeSizeAxes = Axes.X, - Masking = true, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true - } } }); @@ -97,13 +90,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables AddNested(tail); } - protected override void LoadComplete() - { - base.LoadComplete(); - - updateGlow(); - } - public override Color4 AccentColour { get { return base.AccentColour; } @@ -115,28 +101,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables tickContainer.Children.ForEach(t => t.AccentColour = value); + glowPiece.AccentColour = value; bodyPiece.AccentColour = value; head.AccentColour = value; tail.AccentColour = value; - - updateGlow(); } } - private void updateGlow() - { - if (!IsLoaded) - return; - - glowContainer.EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Colour = AccentColour.Opacity(0.5f), - Radius = 10, - Hollow = true - }; - } - protected override void UpdateState(ArmedState state) { } @@ -149,9 +120,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables bodyPiece.Y = head.Height; bodyPiece.Height = DrawHeight - head.Height; - // Make the glowContainer "contain" the height of the tail note, keeping in mind + // Make the fullHeightContainer "contain" the height of the tail note, keeping in mind // that the tail note overshoots the height of this hit object - glowContainer.Height = DrawHeight + tail.Height; + fullHeightContainer.Height = DrawHeight + tail.Height; } public bool OnPressed(ManiaAction action) @@ -208,7 +179,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables LifetimeStart = double.MinValue; LifetimeEnd = double.MaxValue; - ApplyGlow = false; + GlowPiece.Alpha = 0; } public override bool OnPressed(ManiaAction action) @@ -251,7 +222,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables LifetimeStart = double.MinValue; LifetimeEnd = double.MaxValue; - ApplyGlow = false; + GlowPiece.Alpha = 0; } protected override ManiaJudgement CreateJudgement() => new HoldNoteTailJudgement(); diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 37d7566e43..7a2fb71fef 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -2,10 +2,8 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using osu.Framework.Extensions.Color4Extensions; using OpenTK.Graphics; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; @@ -18,10 +16,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// public class DrawableNote : DrawableManiaHitObject, IKeyBindingHandler { - /// - /// Gets or sets whether this should apply glow to itself. - /// - protected bool ApplyGlow = true; + protected readonly GlowPiece GlowPiece; private readonly NotePiece headPiece; @@ -31,19 +26,15 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Add(headPiece = new NotePiece + Children = new Drawable[] { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Masking = true - }); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - updateGlow(); + GlowPiece = new GlowPiece(), + headPiece = new NotePiece + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + } + }; } public override Color4 AccentColour @@ -55,29 +46,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables return; base.AccentColour = value; + GlowPiece.AccentColour = value; headPiece.AccentColour = value; - - updateGlow(); } } - private void updateGlow() - { - if (!IsLoaded) - return; - - if (!ApplyGlow) - return; - - headPiece.EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Colour = AccentColour.Opacity(0.5f), - Radius = 10, - Hollow = true - }; - } - protected override void CheckJudgement(bool userTriggered) { if (!userTriggered) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs new file mode 100644 index 0000000000..b08247b180 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs @@ -0,0 +1,62 @@ +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using OpenTK.Graphics; + +namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces +{ + public class GlowPiece : CompositeDrawable, IHasAccentColour + { + private const float glow_alpha = 0.7f; + private const float glow_radius = 5; + + public GlowPiece() + { + RelativeSizeAxes = Axes.Both; + Masking = true; + + InternalChild = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + updateGlow(); + } + + private Color4 accentColour; + public Color4 AccentColour + { + get { return accentColour; } + set + { + if (accentColour == value) + return; + accentColour = value; + + updateGlow(); + } + } + + private void updateGlow() + { + if (!IsLoaded) + return; + + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = AccentColour.Opacity(glow_alpha), + Radius = glow_radius, + Hollow = true + }; + } + } +} diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index ef098a023d..3161ae8d7f 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -70,6 +70,7 @@ + From 57ee97e27d499de49216b988be78045c5919130a Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 11:14:29 +0900 Subject: [PATCH 389/483] Add lane glows. --- .../Objects/Drawables/DrawableNote.cs | 7 ++ .../Objects/Drawables/Pieces/LaneGlowPiece.cs | 82 +++++++++++++++++++ .../osu.Game.Rulesets.Mania.csproj | 1 + 3 files changed, 90 insertions(+) create mode 100644 osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 7a2fb71fef..ff2d4e8817 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -18,6 +18,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { protected readonly GlowPiece GlowPiece; + private readonly LaneGlowPiece laneGlowPiece; private readonly NotePiece headPiece; public DrawableNote(Note hitObject, ManiaAction action) @@ -28,6 +29,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Children = new Drawable[] { + laneGlowPiece = new LaneGlowPiece + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre + }, GlowPiece = new GlowPiece(), headPiece = new NotePiece { @@ -46,6 +52,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables return; base.AccentColour = value; + laneGlowPiece.AccentColour = value; GlowPiece.AccentColour = value; headPiece.AccentColour = value; } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs new file mode 100644 index 0000000000..38652d50af --- /dev/null +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs @@ -0,0 +1,82 @@ +using OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; + +namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces +{ + public class LaneGlowPiece : CompositeDrawable, IHasAccentColour + { + private const float total_height = 100; + private const float glow_height = 50; + private const float glow_alpha = 0.4f; + private const float edge_alpha = 0.3f; + + public LaneGlowPiece() + { + BypassAutoSizeAxes = Axes.Both; + RelativeSizeAxes = Axes.X; + Height = total_height; + + InternalChildren = new[] + { + new Container + { + Name = "Left edge", + RelativeSizeAxes = Axes.Y, + Width = 1, + Children = createGradient(edge_alpha) + }, + new Container + { + Name = "Right edge", + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.Y, + Width = 1, + Children = createGradient(edge_alpha) + }, + new Container + { + Name = "Glow", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + Height = glow_height, + Children = createGradient(glow_alpha) + } + }; + } + + private Drawable[] createGradient(float alpha) => new Drawable[] + { + new Box + { + Name = "Top", + RelativeSizeAxes = Axes.Both, + Height = 0.5f, + Blending = BlendingMode.Additive, + Colour = ColourInfo.GradientVertical(Color4.Transparent, Color4.White.Opacity(alpha)) + }, + new Box + { + Name = "Bottom", + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, + Height = 0.5f, + Blending = BlendingMode.Additive, + Colour = ColourInfo.GradientVertical(Color4.White.Opacity(alpha), Color4.Transparent) + } + }; + + public Color4 AccentColour + { + get { return Colour; } + set { Colour = value; } + } + } +} diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 3161ae8d7f..8fc10b7cc4 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -71,6 +71,7 @@ + From 27e3c9e778f64367f3c4a6d584728d52fb440843 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 11:51:19 +0900 Subject: [PATCH 390/483] Remove usings. --- osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs index a62e0260bd..1be91a7d94 100644 --- a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs @@ -1,8 +1,6 @@ // Copyright (c) 2007-2017 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.Objects; namespace osu.Game.Rulesets.Taiko.Objects From 585e2399bf452b8226a5a5c5f839dc94b83c97fd Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 12:02:56 +0900 Subject: [PATCH 391/483] Add license headers. --- .../Objects/Drawables/Pieces/GlowPiece.cs | 5 ++++- .../Objects/Drawables/Pieces/LaneGlowPiece.cs | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs index b08247b180..6f022f452f 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs @@ -1,4 +1,7 @@ -using osu.Framework.Extensions.Color4Extensions; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs index 38652d50af..6d4ac2fb61 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs @@ -1,3 +1,6 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; From 4113e141a274ff73d23f1f1890985c1af96f1de1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Sep 2017 12:20:42 +0900 Subject: [PATCH 392/483] Update player testcase to be usable Includes a real .osu file with slight modifications for easier testing. --- osu.Desktop.Tests/Visual/TestCasePlayer.cs | 766 +++++++++++++++++++-- osu.Desktop.Tests/Visual/TestCaseReplay.cs | 11 +- 2 files changed, 730 insertions(+), 47 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCasePlayer.cs b/osu.Desktop.Tests/Visual/TestCasePlayer.cs index f5d02d3f2b..03ee82dc73 100644 --- a/osu.Desktop.Tests/Visual/TestCasePlayer.cs +++ b/osu.Desktop.Tests/Visual/TestCasePlayer.cs @@ -1,18 +1,18 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; using osu.Desktop.Tests.Beatmaps; using osu.Framework.Allocation; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Rulesets; -using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.UI; using osu.Game.Screens.Play; -using OpenTK; using OpenTK.Graphics; +using osu.Game.Rulesets.Mods; +using System.Linq; +using osu.Game.Beatmaps.Formats; +using System.Text; +using System.IO; namespace osu.Desktop.Tests.Visual { @@ -33,55 +33,739 @@ namespace osu.Desktop.Tests.Visual { base.LoadComplete(); - var objects = new List(); - - int time = 1500; - for (int i = 0; i < 50; i++) - { - objects.Add(new HitCircle - { - StartTime = time, - Position = new Vector2(i % 4 == 0 || i % 4 == 2 ? 0 : OsuPlayfield.BASE_SIZE.X, - i % 4 < 2 ? 0 : OsuPlayfield.BASE_SIZE.Y), - NewCombo = i % 4 == 0 - }); - - time += 500; - } - - Beatmap b = new Beatmap - { - HitObjects = objects, - BeatmapInfo = new BeatmapInfo - { - Difficulty = new BeatmapDifficulty(), - Ruleset = rulesets.Query().First(), - Metadata = new BeatmapMetadata - { - Artist = @"Unknown", - Title = @"Sample Beatmap", - Author = @"peppy", - } - } - }; - - WorkingBeatmap beatmap = new TestWorkingBeatmap(b); - Add(new Box { RelativeSizeAxes = Framework.Graphics.Axes.Both, Colour = Color4.Black, }); - Add(Player = CreatePlayer(beatmap)); + foreach (var r in rulesets.Query()) + AddStep(r.Name, () => loadPlayerFor(r)); + + loadPlayerFor(rulesets.Query().First()); } - protected virtual Player CreatePlayer(WorkingBeatmap beatmap) + private void loadPlayerFor(RulesetInfo r) + { + Beatmap beatmap; + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(test_beatmap_data))) + using (var reader = new StreamReader(stream)) + beatmap = BeatmapDecoder.GetDecoder(reader).Decode(reader); + + beatmap.BeatmapInfo.Ruleset = r; + + var instance = r.CreateInstance(); + + WorkingBeatmap working = new TestWorkingBeatmap(beatmap); + working.Mods.Value = new[] { instance.GetAllMods().First(m => m is ModNoFail) }; + + if (Player != null) + Remove(Player); + + Add(Player = CreatePlayer(working, instance)); + } + + protected virtual Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset) { return new Player { InitialBeatmap = beatmap }; } + + private const string test_beatmap_data = +@"osu file format v14 + +[General] +AudioLeadIn: 500 +PreviewTime: 53498 +Countdown: 0 +SampleSet: Soft +StackLeniency: 0.7 +Mode: 0 +LetterboxInBreaks: 0 +WidescreenStoryboard: 1 + +[Editor] +DistanceSpacing: 1.2 +BeatDivisor: 4 +GridSize: 4 +TimelineZoom: 1 + +[Metadata] +Title:My Love +TitleUnicode:My Love +Artist:Kuba Oms +ArtistUnicode:Kuba Oms +Creator:W h i t e +Version:Hard +Source:ADHD +Tags:Monthly Beatmapping Contest Electronic folk pop w_h_i_t_e +BeatmapID:397534 +BeatmapSetID:163112 + +[Difficulty] +HPDrainRate:5 +CircleSize:4 +OverallDifficulty:6 +ApproachRate:7 +SliderMultiplier:1.44 +SliderTickRate:2 + +[Events] +//Break Periods +2,69870,83770 +2,152170,158770 +//Storyboard Layer 0 (Background) +//Storyboard Layer 1 (Fail) +//Storyboard Layer 2 (Pass) +//Storyboard Layer 3 (Foreground) +//Storyboard Sound Samples + +[TimingPoints] +2170,468.75,4,2,0,40,1,0 +4045,-100,4,2,0,30,0,0 +4162,-100,4,2,0,40,0,0 +5920,-100,4,2,0,30,0,0 +6037,-100,4,2,0,40,0,0 +7795,-100,4,2,0,30,0,0 +7912,-100,4,2,0,40,0,0 +9670,-100,4,2,0,40,0,0 +9787,-100,4,2,0,50,0,0 +11545,-100,4,2,0,40,0,0 +11662,-100,4,2,0,50,0,0 +13420,-100,4,2,0,40,0,0 +13537,-100,4,2,0,50,0,0 +15295,-100,4,2,0,40,0,0 +15412,-100,4,2,0,50,0,0 +17170,-100,4,2,0,40,0,0 +17287,-100,4,2,0,50,0,0 +19045,-100,4,2,0,40,0,0 +19162,-100,4,2,0,50,0,0 +20920,-100,4,2,0,40,0,0 +21037,-100,4,2,0,50,0,0 +22795,-100,4,2,0,40,0,0 +22912,-100,4,2,0,50,0,0 +24670,-100,4,2,0,70,0,0 +37560,-200,4,2,0,30,0,0 +38263,-200,4,2,0,5,0,0 +38966,-100,4,2,0,30,0,0 +39670,-100,4,2,0,70,0,0 +53732,-100,4,2,0,40,0,0 +54670,-100,4,2,0,80,0,1 +55138,-100,4,2,0,60,0,1 +55255,-100,4,2,0,80,0,1 +56076,-100,4,2,0,60,0,1 +56193,-100,4,2,0,80,0,1 +57013,-100,4,2,0,60,0,1 +57130,-100,4,2,0,80,0,1 +57951,-100,4,2,0,60,0,1 +58068,-100,4,2,0,80,0,1 +58888,-100,4,2,0,60,0,1 +59005,-100,4,2,0,80,0,1 +59826,-100,4,2,0,60,0,1 +59943,-100,4,2,0,80,0,1 +60763,-100,4,2,0,60,0,1 +60880,-100,4,2,0,80,0,1 +61701,-100,4,2,0,60,0,1 +61818,-100,4,2,0,80,0,1 +62638,-100,4,2,0,60,0,1 +62755,-100,4,2,0,80,0,1 +63576,-100,4,2,0,60,0,1 +63693,-100,4,2,0,80,0,1 +64513,-100,4,2,0,60,0,1 +64630,-100,4,2,0,80,0,1 +65451,-100,4,2,0,60,0,1 +65568,-100,4,2,0,80,0,1 +66388,-100,4,2,0,60,0,1 +66505,-100,4,2,0,80,0,1 +67326,-100,4,2,0,60,0,1 +67443,-100,4,2,0,80,0,1 +68263,-100,4,2,0,60,0,1 +68380,-100,4,2,0,80,0,1 +69201,-100,4,2,0,60,0,1 +69318,-100,4,2,0,80,0,1 +69670,-100,4,2,0,70,0,0 +84670,-100,4,2,0,70,0,0 +97560,-200,4,2,0,70,0,0 +97795,-200,4,2,0,30,0,0 +98966,-100,4,2,0,30,0,0 +99670,-100,4,2,0,70,0,0 +113732,-100,4,2,0,40,0,0 +114670,-100,4,2,0,80,0,1 +115138,-100,4,2,0,60,0,1 +115255,-100,4,2,0,80,0,1 +116076,-100,4,2,0,60,0,1 +116193,-100,4,2,0,80,0,1 +117013,-100,4,2,0,60,0,1 +117130,-100,4,2,0,80,0,1 +117951,-100,4,2,0,60,0,1 +118068,-100,4,2,0,80,0,1 +118888,-100,4,2,0,60,0,1 +119005,-100,4,2,0,80,0,1 +119826,-100,4,2,0,60,0,1 +119943,-100,4,2,0,80,0,1 +120763,-100,4,2,0,60,0,1 +120880,-100,4,2,0,80,0,1 +121701,-100,4,2,0,60,0,1 +121818,-100,4,2,0,80,0,1 +122638,-100,4,2,0,60,0,1 +122755,-100,4,2,0,80,0,1 +123576,-100,4,2,0,60,0,1 +123693,-100,4,2,0,80,0,1 +124513,-100,4,2,0,60,0,1 +124630,-100,4,2,0,80,0,1 +125451,-100,4,2,0,60,0,1 +125568,-100,4,2,0,80,0,1 +126388,-100,4,2,0,60,0,1 +126505,-100,4,2,0,80,0,1 +127326,-100,4,2,0,60,0,1 +127443,-100,4,2,0,80,0,1 +128263,-100,4,2,0,60,0,1 +128380,-100,4,2,0,80,0,1 +129201,-100,4,2,0,60,0,1 +129318,-100,4,2,0,80,0,1 +129670,-200,4,2,0,40,0,0 +144670,-133.333333333333,4,2,0,40,0,0 +159670,-133.333333333333,4,2,0,40,0,0 +163420,-133.333333333333,4,2,0,45,0,0 +163888,-125,4,2,0,50,0,0 +164357,-117.647058823529,4,2,0,55,0,0 +164826,-111.111111111111,4,2,0,60,0,0 +165295,-105.263157894737,4,2,0,65,0,0 +165763,-100,4,2,0,70,0,0 +166232,-100,4,2,0,40,0,0 +167170,-100,4,2,0,80,0,1 +167638,-100,4,2,0,60,0,1 +167755,-100,4,2,0,80,0,1 +168576,-100,4,2,0,60,0,1 +168693,-100,4,2,0,80,0,1 +169513,-100,4,2,0,60,0,1 +169630,-100,4,2,0,80,0,1 +170451,-100,4,2,0,60,0,1 +170568,-100,4,2,0,80,0,1 +171388,-100,4,2,0,60,0,1 +171505,-100,4,2,0,80,0,1 +172326,-100,4,2,0,60,0,1 +172443,-100,4,2,0,80,0,1 +173263,-100,4,2,0,60,0,1 +173380,-100,4,2,0,80,0,1 +174201,-100,4,2,0,60,0,1 +174318,-100,4,2,0,80,0,1 +175138,-100,4,2,0,60,0,1 +175255,-100,4,2,0,80,0,1 +176076,-100,4,2,0,60,0,1 +176193,-100,4,2,0,80,0,1 +177013,-100,4,2,0,60,0,1 +177130,-100,4,2,0,80,0,1 +177951,-100,4,2,0,60,0,1 +178068,-100,4,2,0,80,0,1 +178888,-100,4,2,0,60,0,1 +179005,-100,4,2,0,80,0,1 +179826,-100,4,2,0,60,0,1 +179943,-100,4,2,0,80,0,1 +180763,-100,4,2,0,60,0,1 +180880,-100,4,2,0,80,0,1 +180998,-100,4,2,0,80,0,0 +181466,-100,4,2,0,60,0,0 +181584,-100,4,2,0,80,0,0 +181935,-100,4,2,0,80,0,0 +182170,-100,4,2,0,80,0,1 +182638,-100,4,2,0,60,0,1 +182755,-100,4,2,0,80,0,1 +183576,-100,4,2,0,60,0,1 +183693,-100,4,2,0,80,0,1 +184513,-100,4,2,0,60,0,1 +184630,-100,4,2,0,80,0,1 +185451,-100,4,2,0,60,0,1 +185568,-100,4,2,0,80,0,1 +186388,-100,4,2,0,60,0,1 +186505,-100,4,2,0,80,0,1 +187326,-100,4,2,0,60,0,1 +187443,-100,4,2,0,80,0,1 +188263,-100,4,2,0,60,0,1 +188380,-100,4,2,0,80,0,1 +189201,-100,4,2,0,60,0,1 +189318,-100,4,2,0,80,0,1 +190138,-100,4,2,0,60,0,1 +190255,-100,4,2,0,80,0,1 +191076,-100,4,2,0,60,0,1 +191193,-100,4,2,0,80,0,1 +192013,-100,4,2,0,60,0,1 +192130,-100,4,2,0,80,0,1 +192951,-100,4,2,0,60,0,1 +193068,-100,4,2,0,80,0,1 +193888,-100,4,2,0,60,0,1 +194005,-100,4,2,0,80,0,1 +194826,-100,4,2,0,60,0,1 +194943,-100,4,2,0,80,0,1 +195295,-100,4,2,0,50,0,1 +195529,-100,4,2,0,52,0,1 +195646,-100,4,2,0,54,0,1 +195763,-100,4,2,0,56,0,1 +195880,-100,4,2,0,58,0,1 +195998,-100,4,2,0,60,0,1 +196115,-100,4,2,0,62,0,1 +196232,-100,4,2,0,64,0,1 +196349,-100,4,2,0,68,0,1 +196466,-100,4,2,0,70,0,1 +196584,-100,4,2,0,72,0,1 +196701,-100,4,2,0,74,0,1 +196818,-100,4,2,0,76,0,1 +196935,-100,4,2,0,78,0,1 +197052,-100,4,2,0,80,0,1 +197170,-100,4,2,0,80,0,0 +197873,-100,4,2,0,60,0,0 +197990,-100,4,2,0,80,0,0 +198341,-100,4,2,0,60,0,0 +199045,-100,4,2,0,80,0,0 +199279,-100,4,2,0,60,0,0 +199630,-100,4,2,0,80,0,0 +200216,-100,4,2,0,60,0,0 +200334,-100,4,2,0,80,0,0 +201623,-100,4,2,0,60,0,0 +201740,-100,4,2,0,80,0,0 +202326,-100,4,2,0,60,0,0 +202443,-100,4,2,0,80,0,0 +203029,-100,4,2,0,60,0,0 +203498,-100,4,2,0,80,0,0 +203966,-100,4,2,0,60,0,0 +204201,-100,4,2,0,80,0,0 +205373,-100,4,2,0,60,0,0 +205490,-100,4,2,0,80,0,0 +205841,-100,4,2,0,60,0,0 +206076,-100,4,2,0,60,0,0 +206545,-100,4,2,0,80,0,0 +206779,-100,4,2,0,60,0,0 +207130,-100,4,2,0,80,0,0 +207716,-100,4,2,0,60,0,0 +207951,-100,4,2,0,80,0,0 +209123,-100,4,2,0,60,0,0 +209240,-100,4,2,0,80,0,0 +209826,-100,4,2,0,60,0,0 +209943,-100,4,2,0,80,0,0 +210529,-100,4,2,0,60,0,0 +210880,-100,4,2,0,80,0,0 +211232,-100,4,2,0,60,0,0 +211701,-100,4,2,0,70,0,0 +212170,-100,4,2,0,80,0,0 +212873,-100,4,2,0,60,0,0 +212990,-100,4,2,0,80,0,0 +213341,-100,4,2,0,60,0,0 +213576,-100,4,2,0,60,0,0 +214045,-100,4,2,0,80,0,0 +214279,-100,4,2,0,60,0,0 +214630,-100,4,2,0,80,0,0 +215216,-100,4,2,0,60,0,0 +215451,-100,4,2,0,80,0,0 +216623,-100,4,2,0,60,0,0 +216740,-100,4,2,0,80,0,0 +217326,-100,4,2,0,60,0,0 +217443,-100,4,2,0,80,0,0 +218029,-100,4,2,0,60,0,0 +218498,-100,4,2,0,80,0,0 +218732,-100,4,2,0,50,0,0 +219670,-100,4,2,0,70,0,0 +220138,-100,4,2,0,65,0,0 +220373,-100,4,2,0,45,0,0 +220490,-100,4,2,0,65,0,0 +220607,-100,4,2,0,60,0,0 +220841,-100,4,2,0,35,0,0 +221076,-100,4,2,0,35,0,0 +221545,-100,4,2,0,50,0,0 +221779,-100,4,2,0,30,0,0 +222013,-111.111111111111,4,2,0,25,0,0 +222130,-111.111111111111,4,2,0,40,0,0 +222482,-125,4,2,0,40,0,0 +222716,-125,4,2,0,20,0,0 +222951,-100,4,2,0,15,0,0 +223420,-100,4,2,0,30,0,0 +224357,-100,4,2,0,25,0,0 +225295,-100,4,2,0,20,0,0 +226232,-100,4,2,0,15,0,0 +226701,-100,4,2,0,10,0,0 +227170,-100,4,2,0,5,0,0 + + +[Colours] + Combo1 : 17,254,176 +Combo2 : 173,255,95 +Combo3 : 255,88,100 +Combo4 : 255,94,55 + +[HitObjects] +320,256,2170,6,0,P|256:284|192:256,1,144,4|0,0:0|0:0,0:0:0:0: +144,184,2873,1,0,0:0:0:0: +108,260,3107,2,0,P|112:296|100:336,1,72 +28,288,3576,2,0,P|24:252|36:212,1,72,0|0,0:0|0:0,0:0:0:0: +76,140,4045,6,0,L|220:136,1,144,4|0,0:0|0:0,0:0:0:0: +292,88,4748,1,0,0:0:0:0: +292,88,4982,2,0,P|304:120|300:168,1,72 +388,168,5451,2,0,P|396:133|416:103,1,72,0|0,0:0|0:0,0:0:0:0: +472,172,5920,6,0,B|470:200|457:222|457:222|488:256|476:308,1,144,4|0,0:0|0:0,0:0:0:0: +396,280,6623,1,0,0:0:0:0: +324,328,6857,2,0,P|288:332|252:324,1,72 +180,280,7326,2,0,L|108:284,1,72,0|0,0:0|0:0,0:0:0:0: +256,192,7795,12,0,9670,0:0:0:0: +428,212,10138,1,0,0:0:0:0: +292,320,10607,1,0,0:0:0:0: +184,184,11076,2,0,L|112:180,1,72,0|0,0:0|0:0,0:0:0:0: +24,172,11545,5,6,0:0:0:0: +160,280,12013,1,0,0:0:0:0: +268,144,12482,1,0,0:0:0:0: +132,36,12951,2,0,L|204:32,1,72,0|0,0:0|0:0,0:0:0:0: +284,60,13420,6,0,P|340:100|344:180,2,144,6|0|0,0:0|0:0|0:0,0:0:0:0: +268,144,14591,1,0,0:0:0:0: +284,228,14826,2,0,P|316:248|364:252,1,72,0|0,0:0|0:0,0:0:0:0: +436,248,15295,6,0,P|372:272|344:340,1,144,6|2,0:0|0:0,0:0:0:0: +168,338,16232,2,0,P|141:273|76:248,1,144,2|2,0:0|0:0,0:0:0:0: +4,296,16935,1,0,0:0:0:0: +80,336,17170,5,6,0:0:0:0: +44,168,17638,1,0,0:0:0:0: +212,128,18107,1,0,0:0:0:0: +248,296,18576,2,0,P|284:288|320:292,1,72,0|0,0:0|0:0,0:0:0:0: +400,324,19045,5,6,0:0:0:0: +280,200,19513,1,0,0:0:0:0: +368,52,19982,1,0,0:0:0:0: +488,176,20451,2,0,P|452:168|416:172,1,72,0|0,0:0|0:0,0:0:0:0: +336,200,20920,6,0,P|284:216|200:192,1,144,6|0,0:0|0:0,0:0:0:0: +200,192,21857,2,0,L|204:264,1,72,0|0,0:3|0:0,0:0:0:0: +117,244,22326,2,0,L|120:172,1,72,0|0,0:0|0:0,0:0:0:0: +40,152,22795,6,0,L|28:296,2,144,6|0|0,0:0|0:0|0:0,0:0:0:0: +152,24,24201,1,0,0:0:0:0: +220,76,24435,1,0,3:0:0:0: +304,56,24670,6,0,P|288:120|296:196,1,144,4|2,0:3|0:3,0:0:0:0: +344,268,25373,1,0,0:0:0:0: +416,316,25607,2,0,P|452:312|508:316,2,72,0|0|2,0:0|0:0|0:3,0:0:0:0: +244,344,26545,6,0,P|176:356|108:328,1,144,4|2,0:3|0:3,0:0:0:0: +60,256,27248,1,0,0:0:0:0: +36,172,27482,2,0,L|40:100,2,72,0|0|2,0:0|0:0|0:3,0:0:0:0: +188,252,28420,6,0,P|192:184|196:100,1,144,4|2,0:3|0:3,0:0:0:0: +140,40,29123,1,0,0:0:0:0: +140,40,29357,2,0,B|172:16|220:24|220:24|288:36,1,144,0|2,0:0|0:3,0:0:0:0: +364,52,30060,1,0,0:0:0:0: +308,116,30295,6,0,B|300:168|300:168|328:256,1,144,4|2,0:3|0:3,0:0:0:0: +340,340,30998,1,0,0:0:0:0: +260,308,31232,2,0,L|188:304,1,72,0|2,0:0|0:3,0:0:0:0: +100,296,31701,1,2,0:3:0:0: +136,374,31935,1,0,0:0:0:0: +152,224,32170,6,0,P|160:152|132:88,1,144,4|2,0:3|0:3,0:0:0:0: +56,48,32873,1,0,0:0:0:0: +60,136,33107,2,0,L|56:208,2,72,0|0|2,0:0|0:0|0:3,0:0:0:0: +224,76,34045,6,0,P|289:104|360:96,1,144,4|2,0:3|0:3,0:0:0:0: +432,48,34748,1,0,0:0:0:0: +440,132,34982,2,0,B|432:156|432:156|436:204,2,72,0|0|2,0:0|0:0|0:3,0:0:0:0: +448,304,35920,6,0,B|412:315|380:292|380:292|348:269|312:280,1,144,4|2,0:3|0:3,0:0:0:0: +332,364,36623,1,0,0:0:0:0: +247,339,36857,2,0,P|230:308|225:273,2,72,0|0|2,0:0|0:0|0:3,0:0:0:0: +312,280,37560,6,0,L|316:172,1,108 +134,35,38966,5,0,0:0:0:0: +72,96,39201,2,0,P|119:119|171:111,1,108,0|0,0:0|0:0,0:0:0:0: +192,100,39670,6,0,L|200:172,1,72,4|2,0:0|0:0,0:0:0:0: +147,240,40138,2,0,P|133:272|132:308,1,72,0|2,1:0|0:0,0:0:0:0: +216,292,40607,2,0,B|260:308|260:308|356:292,1,144,4|0,2:3|1:0,1:0:0:0: +356,292,41310,1,2,0:0:0:0: +436,327,41545,6,0,P|441:292|435:257,1,72,4|2,0:3|0:0,0:0:0:0: +364,204,42013,2,0,P|336:144|352:68,1,144,0|4,1:0|2:3,1:0:0:0: +404,0,42716,1,2,0:0:0:0: +440,80,42951,2,0,B|464:84|464:84|512:80,1,72,0|2,1:0|0:0,0:0:0:0: +351,71,43420,6,0,B|296:68|296:68|268:76|268:76|196:72,1,144,4|0,2:3|1:0,1:0:0:0: +120,68,44123,1,2,0:0:0:0: +160,144,44357,2,0,P|172:180|168:232,1,72,4|2,0:3|0:0,0:0:0:0: +76,264,44826,2,0,P|76:228|88:194,1,72,0|2,1:0|0:0,0:0:0:0: +160,144,45295,5,4,0:3:0:0: +244,164,45529,1,2,0:0:0:0: +268,248,45763,2,0,L|344:252,1,72,0|2,1:0|0:0,0:0:0:0: +408,156,46232,2,0,L|336:159,1,72,4|2,0:3|0:0,0:0:0:0: +212,72,46701,2,0,L|288:76,1,72,0|2,1:0|0:0,0:0:0:0: +400,72,47170,6,0,P|464:96|488:172,1,144,4|0,2:0|1:0,1:0:0:0: +476,248,47873,1,2,0:0:0:0: +436,324,48107,2,0,L|284:320,1,144,4|0,2:3|1:0,1:0:0:0: +204,316,48810,1,2,0:0:0:0: +127,355,49045,6,0,P|120:321|124:285,1,72,4|2,0:3|0:0,0:0:0:0: +192,232,49513,2,0,L|335:228,1,144,0|4,1:0|2:3,1:0:0:0: +412,188,50216,1,2,0:0:0:0: +444,108,50451,2,0,P|452:72|448:36,1,72,0|2,1:0|0:0,0:0:0:0: +368,68,50920,6,0,B|332:79|300:56|300:56|268:33|232:44,1,144,4|0,2:3|1:0,1:0:0:0: +152,76,51623,1,2,0:0:0:0: +76,116,51857,2,0,L|80:268,1,144,4|0,2:3|1:0,1:0:0:0: +80,260,52560,1,2,0:0:0:0: +8,308,52795,6,0,P|34:334|69:346,1,72,4|2,0:3|0:0,0:0:0:0: +148,312,53263,2,0,P|163:278|162:241,1,72,0|2,1:0|0:0,0:0:0:0: +156,156,53732,5,0,3:0:0:0: +156,156,53966,1,2,0:0:0:0: +236,196,54201,2,0,L|312:192,1,72,8|0,0:3|0:0,0:0:0:0: +368,256,54670,6,0,P|392:216|352:116,1,144,4|2,0:0|1:2,0:0:0:0: +288,92,55373,1,0,0:0:0:0: +360,40,55607,2,0,L|432:36,1,72,4|0,0:3|3:0,0:0:0:0: +288,92,56076,2,0,L|216:88,1,72,2|0,1:2|0:0,0:0:0:0: +132,72,56545,6,0,P|172:88|200:184,1,144,4|2,0:3|1:2,0:0:0:0: +143,241,57248,1,0,0:0:0:0: +65,202,57482,2,0,P|87:174|119:157,1,72,4|0,0:3|3:0,0:0:0:0: +132,324,57951,2,0,P|98:312|72:288,1,72,2|0,1:2|0:0,0:0:0:0: +143,241,58420,6,0,L|288:240,1,144,4|2,0:3|1:2,0:0:0:0: +372,240,59123,1,0,0:0:0:0: +330,314,59357,2,0,P|318:350|322:390,1,72,4|0,0:3|3:0,0:0:0:0: +452,264,59826,2,0,P|453:228|442:194,1,72,2|0,1:2|0:0,0:0:0:0: +384,128,60295,6,0,B|336:144|336:144|244:128,1,144,4|2,0:3|1:2,0:0:0:0: +164,160,60998,2,0,P|160:116|168:88,1,72,0|4,0:0|0:3,0:0:0:0: +244,128,61466,2,0,P|248:172|240:200,1,72,0|2,3:0|1:2,0:0:0:0: +168,248,61935,1,0,0:0:0:0: +120,320,62170,6,0,P|196:328|252:272,2,144,4|2|4,0:3|1:2|0:3,0:0:0:0: +80,244,63341,1,0,3:0:0:0: +100,160,63576,2,0,L|24:156,1,72,2|0,1:2|0:0,0:0:0:0: +180,128,64045,6,0,P|249:138|304:94,1,144,4|2,0:3|1:2,0:0:0:0: +226,57,64748,1,0,0:0:0:0: +304,94,64982,2,0,L|300:166,1,72,4|0,0:3|3:0,0:0:0:0: +377,203,65451,2,0,L|388:132,1,72,2|0,1:2|0:0,0:0:0:0: +468,180,65920,6,0,L|432:328,1,144,4|2,0:3|1:2,0:0:0:0: +276,252,66857,2,0,P|208:248|140:280,1,144,4|2,0:3|1:2,0:0:0:0: +84,344,67560,1,0,0:0:0:0: +56,260,67795,6,0,L|52:188,2,72,4|2|2,0:3|0:0|1:2,0:0:0:0: +168,128,68732,2,0,L|172:56,2,72,4|2|2,0:3|0:0|1:2,0:0:0:0: +244,168,69435,1,0,0:0:0:0: +332,164,69670,1,4,0:3:0:0: +208,328,84670,6,0,P|224:264|216:188,1,144,4|2,0:3|0:3,0:0:0:0: +168,116,85373,1,0,0:0:0:0: +96,68,85607,2,0,P|60:72|4:68,2,72,0|0|2,0:0|0:0|0:3,0:0:0:0: +268,40,86545,6,0,P|336:28|404:56,1,144,4|2,0:3|0:3,0:0:0:0: +452,128,87248,1,0,0:0:0:0: +476,212,87482,2,0,L|472:284,2,72,0|0|2,0:0|0:0|0:3,0:0:0:0: +324,132,88420,6,0,P|320:200|316:284,1,144,4|2,0:3|0:3,0:0:0:0: +372,344,89123,1,0,0:0:0:0: +372,344,89357,2,0,B|340:368|292:360|292:360|224:348,1,144,0|2,0:0|0:3,0:0:0:0: +148,332,90060,1,0,0:0:0:0: +204,268,90295,6,0,B|212:216|212:216|184:128,1,144,4|2,0:3|0:3,0:0:0:0: +172,44,90998,1,0,0:0:0:0: +252,76,91232,2,0,L|324:80,1,72,0|2,0:0|0:3,0:0:0:0: +412,88,91701,1,2,0:3:0:0: +377,9,91935,1,0,0:0:0:0: +360,160,92170,6,0,P|352:232|380:296,1,144,4|2,0:3|0:3,0:0:0:0: +456,336,92873,1,0,0:0:0:0: +452,248,93107,2,0,L|456:176,2,72,0|0|2,0:0|0:0|0:3,0:0:0:0: +288,308,94045,6,0,P|223:280|152:288,1,144,4|2,0:3|0:3,0:0:0:0: +80,336,94748,1,0,0:0:0:0: +72,252,94982,2,0,B|80:228|80:228|76:180,2,72,0|0|2,0:0|0:0|0:3,0:0:0:0: +64,80,95920,6,0,B|100:69|132:92|132:92|164:115|200:104,1,144,4|2,0:3|0:3,0:0:0:0: +180,20,96623,1,0,0:0:0:0: +265,45,96857,2,0,P|282:76|287:111,2,72,0|0|2,0:0|0:0|0:3,0:0:0:0: +200,104,97560,1,0,0:0:0:0: +200,104,97677,1,0,0:0:0:0: +200,104,97795,6,0,B|196:142|217:166|217:166|176:180|160:220,1,144,4|0,0:3|0:0,0:0:0:0: +240,248,98966,5,0,0:0:0:0: +202,325,99201,2,0,P|254:333|301:309,1,108,0|0,0:0|0:0,0:0:0:0: +315,292,99670,6,0,L|323:220,1,72,4|2,0:0|0:0,0:0:0:0: +365,144,100138,2,0,P|379:112|380:76,1,72,0|2,1:0|0:0,0:0:0:0: +296,92,100607,2,0,B|252:76|252:76|156:92,1,144,4|0,2:3|1:0,1:0:0:0: +156,92,101310,1,2,0:0:0:0: +76,57,101545,6,0,P|71:92|77:127,1,72,4|2,0:3|0:0,0:0:0:0: +148,180,102013,2,0,P|176:240|160:316,1,144,0|4,1:0|2:3,1:0:0:0: +108,384,102716,1,2,0:0:0:0: +72,304,102951,2,0,B|48:300|48:300|0:304,1,72,0|2,1:0|0:0,0:0:0:0: +161,313,103420,6,0,B|216:316|216:316|244:308|244:308|316:312,1,144,4|0,2:3|1:0,1:0:0:0: +392,316,104123,1,2,0:0:0:0: +352,240,104357,2,0,P|340:204|344:152,1,72,4|2,0:3|0:0,0:0:0:0: +436,120,104826,2,0,P|436:156|424:190,1,72,0|2,1:0|0:0,0:0:0:0: +352,240,105295,5,4,0:3:0:0: +268,220,105529,1,2,0:0:0:0: +244,136,105763,2,0,L|168:132,1,72,0|2,1:0|0:0,0:0:0:0: +104,228,106232,2,0,L|176:225,1,72,4|2,0:3|0:0,0:0:0:0: +300,312,106701,2,0,L|224:308,1,72,0|2,1:0|0:0,0:0:0:0: +112,312,107170,6,0,P|48:288|24:212,1,144,4|0,2:0|1:0,1:0:0:0: +36,136,107873,1,2,0:0:0:0: +76,60,108107,2,0,L|228:64,1,144,4|0,2:3|1:0,1:0:0:0: +308,68,108810,1,2,0:0:0:0: +385,29,109045,6,0,P|392:63|388:99,1,72,4|2,0:3|0:0,0:0:0:0: +320,152,109513,2,0,L|177:156,1,144,0|4,1:0|2:3,1:0:0:0: +100,196,110216,1,2,0:0:0:0: +68,276,110451,2,0,P|60:312|64:348,1,72,0|2,1:0|0:0,0:0:0:0: +144,316,110920,6,0,B|180:305|212:328|212:328|244:351|280:340,1,144,4|0,2:3|1:0,1:0:0:0: +360,308,111623,1,2,0:0:0:0: +436,268,111857,2,0,L|432:116,1,144,4|0,2:3|1:0,1:0:0:0: +432,124,112560,1,2,0:0:0:0: +504,76,112795,6,0,P|478:50|443:38,1,72,4|2,0:3|0:0,0:0:0:0: +364,72,113263,2,0,P|349:106|350:143,1,72,0|2,1:0|0:0,0:0:0:0: +356,228,113732,5,0,3:0:0:0: +356,228,113966,1,2,0:0:0:0: +276,188,114201,2,0,L|200:192,1,72,8|0,0:3|0:0,0:0:0:0: +144,128,114670,6,0,P|120:168|160:268,1,144,4|2,0:0|1:2,0:0:0:0: +224,292,115373,1,0,0:0:0:0: +152,344,115607,2,0,L|80:348,1,72,4|0,0:3|3:0,0:0:0:0: +224,292,116076,2,0,L|296:296,1,72,2|0,1:2|0:0,0:0:0:0: +380,312,116545,6,0,P|340:296|312:200,1,144,4|2,0:3|1:2,0:0:0:0: +369,143,117248,1,0,0:0:0:0: +447,182,117482,2,0,P|425:210|393:227,1,72,4|0,0:3|3:0,0:0:0:0: +380,60,117951,2,0,P|414:72|440:96,1,72,2|0,1:2|0:0,0:0:0:0: +369,143,118420,6,0,L|224:144,1,144,4|2,0:3|1:2,0:0:0:0: +140,144,119123,1,0,0:0:0:0: +182,70,119357,2,0,P|194:34|190:-6,1,72,4|0,0:3|3:0,0:0:0:0: +60,120,119826,2,0,P|59:156|70:190,1,72,2|0,1:2|0:0,0:0:0:0: +128,256,120295,6,0,B|176:240|176:240|268:256,1,144,4|2,0:3|1:2,0:0:0:0: +348,224,120998,2,0,P|352:268|344:296,1,72,0|4,0:0|0:3,0:0:0:0: +268,256,121466,2,0,P|264:212|272:184,1,72,0|2,3:0|1:2,0:0:0:0: +344,136,121935,1,0,0:0:0:0: +392,64,122170,6,0,P|316:56|260:112,2,144,4|2|4,0:3|1:2|0:3,0:0:0:0: +432,140,123341,1,0,3:0:0:0: +412,224,123576,2,0,L|488:228,1,72,2|0,1:2|0:0,0:0:0:0: +332,256,124045,6,0,P|263:246|208:290,1,144,4|2,0:3|1:2,0:0:0:0: +286,327,124748,1,0,0:0:0:0: +208,290,124982,2,0,L|212:218,1,72,4|0,0:3|3:0,0:0:0:0: +135,181,125451,2,0,L|124:252,1,72,2|0,1:2|0:0,0:0:0:0: +44,204,125920,6,0,L|80:56,1,144,4|2,0:3|1:2,0:0:0:0: +236,132,126857,2,0,P|304:136|372:104,1,144,4|2,0:3|1:2,0:0:0:0: +428,40,127560,1,0,0:0:0:0: +456,124,127795,6,0,L|460:196,2,72,4|2|2,0:3|0:0|1:2,0:0:0:0: +344,256,128732,2,0,L|340:328,2,72,4|2|2,0:3|0:0|1:2,0:0:0:0: +268,216,129435,1,0,0:0:0:0: +180,220,129670,5,4,2:0:0:0: +256,40,130373,1,2,0:0:0:0: +64,68,131076,1,2,0:0:0:0: +92,136,131310,1,0,0:0:0:0: +64,204,131545,6,0,L|60:288,1,72 +31,343,132248,2,0,P|86:345|127:309,1,108 +332,220,133420,5,2,0:0:0:0: +256,40,134123,1,2,0:0:0:0: +448,68,134826,1,2,0:0:0:0: +420,136,135060,1,0,0:0:0:0: +448,204,135295,6,0,L|452:288,1,72,2|0,0:0|0:0,0:0:0:0: +480,343,135998,2,0,P|426:345|385:309,1,108 +256,192,137170,5,2,0:0:0:0: +156,360,137873,1,2,0:0:0:0: +356,360,138576,2,0,L|352:308,1,36,2|0,0:0|0:0,0:0:0:0: +304,268,139045,6,0,P|336:253|372:252,1,72 +448,260,139748,2,0,L|444:152,1,108 +256,192,140920,5,2,0:0:0:0: +356,24,141623,1,2,0:0:0:0: +156,24,142326,2,0,L|160:72,1,36,2|0,0:0|0:0,0:0:0:0: +208,116,142795,6,0,P|176:131|140:132,1,72,2|0,0:0|0:0,0:0:0:0: +64,124,143498,2,0,L|68:232,1,108 +68,232,144670,5,4,0:3:0:0: +216,320,145138,1,4,0:3:0:0: +304,172,145607,1,4,0:3:0:0: +156,84,146075,1,4,0:3:0:0: +296,320,146545,5,4,0:3:0:0: +208,172,147013,1,4,0:3:0:0: +356,84,147482,1,4,0:3:0:0: +444,232,147950,1,4,0:3:0:0: +296,320,148420,6,0,P|252:328|192:296,2,108.000004119873,4|4|4,0:3|0:3|0:3,0:0:0:0: +260,248,149591,1,0,0:0:0:0: +320,196,149826,2,0,L|316:140,1,54.0000020599366,4|0,0:3|0:0,0:0:0:0: +120,236,159670,6,0,L|176:232,1,54.0000020599366,4|0,0:3|0:0,0:0:0:0: +160,152,160138,2,0,L|104:156,1,54.0000020599366,2|0,0:0|0:0,0:0:0:0: +240,180,160607,2,0,P|292:188|344:172,1,108.000004119873,4|2,0:3|0:0,3:0:0:0: +408,120,161310,1,0,3:0:0:0: +424,200,161545,6,0,L|420:256,1,54.0000020599366,4|0,0:3|0:0,0:0:0:0: +376,320,162013,2,0,P|396:328|480:304,2,108.000004119873,2|6|2,2:0|0:3|2:0,3:0:0:0: +312,268,163185,1,0,0:0:0:0: +296,348,163420,6,0,L|240:344,1,54.0000020599366,4|0,3:0|3:0,0:0:0:0: +160,320,163888,2,0,L|100:316,1,57.6,4|0,3:0|3:0,0:0:0:0: +64,232,164357,6,0,L|128:228,1,61.2000011672974,4|0,3:0|3:0,0:0:0:0: +204,200,164825,2,0,L|268:196,1,61.2000011672974,4|0,3:0|3:0,0:0:0:0: +232,108,165295,6,0,L|164:104,1,68.399998173523,4|0,3:0|3:0,0:0:0:0: +80,84,165763,2,0,L|4:80,1,72,4|0,3:0|3:0,0:0:0:0: +324,120,167170,6,0,P|388:128|456:92,1,144,4|2,0:0|1:2,0:0:0:0: +496,168,167873,1,0,0:0:0:0: +496,168,168107,2,0,P|484:204|488:256,1,72,4|0,0:3|3:0,0:0:0:0: +408,296,168576,2,0,P|398:261|378:231,1,72,2|0,1:2|0:0,0:0:0:0: +296,200,169045,6,0,B|228:228|156:204,1,144,4|2,0:3|1:2,0:0:0:0: +84,156,169748,1,0,0:0:0:0: +80,244,169982,2,0,L|76:316,1,72,4|0,0:3|3:0,0:0:0:0: +170,274,170451,2,0,L|156:204,1,72,2|0,1:2|0:0,0:0:0:0: +216,140,170920,6,0,L|284:276,1,144,4|2,0:3|1:2,0:0:0:0: +320,344,171623,1,0,0:0:0:0: +372,276,171857,2,0,P|366:240|349:207,1,72,4|0,0:3|3:0,0:0:0:0: +312,132,172326,2,0,L|276:60,1,72,2|0,1:2|0:0,0:0:0:0: +208,20,172795,6,0,P|272:36|348:12,1,144,4|2,0:3|1:2,0:0:0:0: +424,48,173498,2,0,L|412:132,1,72,0|4,0:0|0:3,0:0:0:0: +484,168,173966,2,0,L|472:252,1,72,0|2,3:0|1:2,0:0:0:0: +400,280,174435,1,0,0:0:0:0: +346,348,174670,6,0,P|414:363|472:324,2,144,4|2|4,0:3|1:2|0:3,0:0:0:0: +312,268,175841,1,0,3:0:0:0: +256,336,176076,2,0,L|184:332,1,72,2|0,1:2|0:0,0:0:0:0: +80,244,176545,6,0,B|140:248|140:248|164:244|164:244|223:247,1,144,4|2,0:3|1:2,0:0:0:0: +312,268,177248,1,0,0:0:0:0: +224,247,177482,2,0,P|240:215|272:187,1,72,4|0,0:3|3:0,0:0:0:0: +204,131,177951,2,0,P|233:111|275:103,1,72,2|0,1:2|0:0,0:0:0:0: +240,23,178420,6,0,B|280:15|316:35|316:35|376:71,1,144,4|2,0:3|1:2,0:0:0:0: +399,236,179357,2,0,B|359:244|323:224|323:224|263:188,1,144,4|2,0:3|1:2,0:0:0:0: +204,132,180060,1,0,0:0:0:0: +184,216,180295,6,0,L|188:288,2,72,4|2|2,0:3|0:0|1:2,0:0:0:0: +120,156,180998,1,0,0:0:0:0: +56,96,181232,2,0,L|60:24,2,72,4|2|0,0:3|0:0|1:0,0:0:0:0: +36,180,181935,1,0,0:0:0:0: +100,240,182170,6,0,P|144:300|116:380,2,144,4|2|4,0:0|1:2|0:3,0:0:0:0: +60,316,183341,1,0,0:0:0:0: +220,352,183576,2,0,L|308:348,1,72,2|0,1:2|0:0,0:0:0:0: +396,264,184045,6,0,B|336:268|336:268|312:264|312:264|253:267,1,144,4|2,0:3|1:2,0:0:0:0: +253,267,184748,1,0,0:0:0:0: +268,180,184982,2,0,L|339:177,1,72,4|0,0:3|0:0,0:0:0:0: +164,280,185451,2,0,L|92:282,1,72,2|0,1:2|0:0,0:0:0:0: +52,208,185920,6,0,P|8:268|32:344,2,144,4|2|4,0:3|1:2|0:3,0:0:0:0: +140,212,187091,1,0,0:0:0:0: +92,284,187326,2,0,P|104:316|100:368,1,72,2|0,1:2|0:0,0:0:0:0: +52,208,187795,6,0,P|48:136|76:72,1,144,4|2,0:3|1:2,0:0:0:0: +160,52,188498,2,0,P|188:28|220:16,1,72,0|4,0:0|0:3,0:0:0:0: +232,100,188966,2,0,P|268:93|301:98,1,72,0|2,0:0|1:2,0:0:0:0: +372,152,189435,1,0,0:0:0:0: +420,224,189670,6,0,P|428:296|400:360,2,144,4|2|4,0:3|1:2|0:3,0:0:0:0: +372,152,190841,1,0,0:0:0:0: +392,68,191076,2,0,L|465:64,1,72,2|0,1:2|0:0,0:0:0:0: +304,92,191545,6,0,P|236:104|168:76,1,144,4|2,0:3|1:2,0:0:0:0: +108,12,192248,1,0,0:0:0:0: +168,76,192482,2,0,L|172:152,1,72,4|0,0:3|0:0,0:0:0:0: +80,136,192951,2,0,L|101:204,1,72,2|0,1:2|0:0,0:0:0:0: +12,220,193420,6,0,B|50:279|50:279|80:300|120:292,1,144,4|2,0:3|1:2,0:0:0:0: +284,232,194357,2,0,B|320:221|352:244|352:244|384:267|420:256,1,144,4|2,0:3|1:2,0:0:0:0: +488,200,195060,1,0,0:0:0:0: +507,284,195295,6,0,P|492:315|464:338,1,72,4|0,0:0|0:0,0:0:0:0: +380,356,195763,2,0,L|236:352,1,144,0|4,1:0|0:3,0:0:0:0: +152,328,196466,1,0,3:0:0:0: +64,336,196701,2,0,P|29:325|4:300,1,72,0|0,1:0|0:0,0:0:0:0: +76,252,197170,6,0,P|108:188|96:116,1,144,4|0,0:0|1:0,0:0:0:0: +36,56,197873,1,2,0:0:0:0: +120,32,198107,2,0,L|192:28,2,72,4|2|2,0:3|0:0|1:2,0:0:0:0: +248,152,199045,6,0,P|280:168|304:196,1,72,4|2,0:3|0:0,0:0:0:0: +336,277,199513,2,0,P|306:296|269:303,1,72,2|0,1:2|0:0,0:0:0:0: +183,290,199982,2,0,P|180:254|193:219,2,72,4|2|0,0:3|0:0|1:0,0:0:0:0: +436,252,200920,6,0,P|404:188|416:116,1,144,4|0,0:3|1:0,0:0:0:0: +476,56,201623,1,2,0:0:0:0: +392,32,201857,2,0,L|320:28,2,72,4|0|2,0:3|0:0|1:2,0:0:0:0: +264,152,202795,6,0,P|232:168|208:196,1,72,4|2,0:3|0:0,0:0:0:0: +176,277,203263,2,0,P|205:296|242:303,1,72,2|0,1:2|0:0,0:0:0:0: +329,290,203732,2,0,P|331:254|318:219,2,72,4|2|0,0:3|0:0|1:0,0:0:0:0: +72,324,204670,6,0,B|60:272|60:272|76:180,1,144,4|0,0:0|1:0,0:0:0:0: +92,96,205373,1,2,0:0:0:0: +8,124,205607,2,0,P|5:88|14:53,2,72,4|2|2,0:3|0:0|1:2,0:0:0:0: +168,192,206545,6,0,P|200:174|237:173,1,72,4|2,0:3|0:0,0:0:0:0: +320,160,207013,2,0,P|318:196|301:229,1,72,2|0,1:2|0:0,0:0:0:0: +272,307,207482,2,0,P|240:287|221:256,2,72,4|2|0,0:3|0:0|1:0,0:0:0:0: +440,324,208420,6,0,B|452:272|452:272|436:180,1,144,4|0,0:3|1:0,0:0:0:0: +420,96,209123,1,2,0:0:0:0: +504,124,209357,2,0,P|507:88|498:53,2,72,4|0|2,0:3|0:0|1:2,0:0:0:0: +344,192,210295,6,0,P|311:174|274:173,1,72,4|2,0:3|0:0,0:0:0:0: +190,156,210763,2,0,P|191:192|208:225,1,72,2|0,1:2|0:0,0:0:0:0: +288,256,211232,1,4,0:3:0:0: +132,332,211701,1,0,1:0:0:0: +28,192,212170,6,0,P|16:120|44:56,1,144,4|0,0:0|1:0,0:0:0:0: +120,16,212873,1,2,0:0:0:0: +204,32,213107,2,0,L|304:28,2,72,4|2|2,0:3|0:0|1:2,0:0:0:0: +192,204,214045,6,0,P|196:240|216:272,1,72,4|2,0:3|0:0,0:0:0:0: +298,241,214513,2,0,P|327:219|345:186,1,72,6|0,1:2|0:0,0:0:0:0: +280,132,214982,2,0,P|246:117|209:118,2,72,4|2|0,0:3|0:0|1:0,0:0:0:0: +484,192,215920,6,0,P|496:120|468:56,1,144,4|0,0:3|1:0,0:0:0:0: +392,16,216623,1,2,0:0:0:0: +308,32,216857,2,0,L|208:28,2,72,4|0|2,0:3|0:0|1:2,0:0:0:0: +320,204,217795,6,0,P|316:240|296:272,1,72,4|2,0:3|0:0,0:0:0:0: +213,241,218263,2,0,P|184:219|166:186,1,72,2|0,1:2|0:0,0:0:0:0: +232,132,218732,2,0,B|260:112|300:116|300:116|384:128,1,144,4|0,0:3|1:0,0:0:0:0: +348,336,219670,6,0,B|320:356|280:352|280:352|196:340,1,144,4|0,0:0|1:0,0:0:0:0: +124,328,220373,1,2,0:0:0:0: +54,276,220607,2,0,P|41:308|39:345,2,72,4|2|2,0:3|0:0|1:2,0:0:0:0: +156,80,221545,6,0,L|251:94,1,72,4|2,0:3|0:0,0:0:0:0: +212,169,222013,2,0,L|148:160,1,64.799998022461,2|0,1:2|0:0,0:0:0:0: +140,240,222482,2,0,L|216:252,2,57.6,4|2|0,0:3|0:0|1:0,0:0:0:0: +256,192,223420,12,0,227170,0:0:0:0: +"; } } diff --git a/osu.Desktop.Tests/Visual/TestCaseReplay.cs b/osu.Desktop.Tests/Visual/TestCaseReplay.cs index 9b2f59e444..50aefb7af7 100644 --- a/osu.Desktop.Tests/Visual/TestCaseReplay.cs +++ b/osu.Desktop.Tests/Visual/TestCaseReplay.cs @@ -2,9 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Beatmaps; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Rulesets; using osu.Game.Screens.Play; +using System.Linq; namespace osu.Desktop.Tests.Visual { @@ -12,11 +12,10 @@ namespace osu.Desktop.Tests.Visual { public override string Description => @"Testing replay playback."; - protected override Player CreatePlayer(WorkingBeatmap beatmap) + protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset) { - beatmap.Mods.Value = new Mod[] { new OsuModAutoplay() }; - - return base.CreatePlayer(beatmap); + beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); + return base.CreatePlayer(beatmap, ruleset); } } } From 78764082dc82b2b0ad8aa68ded27c51b0d2bcf11 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 15:52:02 +0900 Subject: [PATCH 393/483] Remove taiko project reference from mania project. --- osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index ef098a023d..7392babbff 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -102,10 +102,6 @@ {C92A607B-1FDD-4954-9F92-03FF547D9080} osu.Game.Rulesets.Osu - - {F167E17A-7DE6-4AF5-B920-A5112296C695} - osu.Game.Rulesets.Taiko - {0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D} osu.Game From 8737a1b1a5506317891479b2847eab242ca07452 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 15:52:18 +0900 Subject: [PATCH 394/483] Implement osu!mania auto replay generation. --- .../Beatmaps/ManiaBeatmap.cs | 16 ++++ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- osu.Game.Rulesets.Mania/Mods/ManiaMod.cs | 27 ++++++ .../Replays/ManiaAutoGenerator.cs | 86 +++++++++++++++++++ .../Replays/ManiaFramedReplayInputHandler.cs | 35 ++++++++ .../UI/ManiaRulesetContainer.cs | 22 +++-- .../osu.Game.Rulesets.Mania.csproj | 3 + osu.Game/Rulesets/Mods/ModAutoplay.cs | 2 +- 8 files changed, 182 insertions(+), 11 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs create mode 100644 osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs create mode 100644 osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs new file mode 100644 index 0000000000..5c66df71c2 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs @@ -0,0 +1,16 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mania.Objects; + +namespace osu.Game.Rulesets.Mania.Beatmaps +{ + internal class ManiaBeatmap : Beatmap + { + public ManiaBeatmap(Beatmap original = null) + : base(original) + { + } + } +} diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index d852a54ab6..0011d2837f 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Mania { Mods = new Mod[] { - new ModAutoplay(), + new ManiaModAutoplay(), new ModCinema(), }, }, diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs index bb11a05fc8..60415632a8 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs @@ -4,6 +4,13 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using System; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mania.Replays; +using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.Scoring; +using osu.Game.Users; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mania.Mods { @@ -154,4 +161,24 @@ namespace osu.Game.Rulesets.Mania.Mods public override double ScoreMultiplier => 1; public override bool Ranked => true; } + + public class ManiaModAutoplay : ModAutoplay + { + private int availableColumns; + + public override void ApplyToRulesetContainer(RulesetContainer rulesetContainer) + { + // Todo: This shouldn't be done, we should be getting a ManiaBeatmap which should store AvailableColumns + // But this is dependent on a _lot_ of refactoring + var maniaRulesetContainer = (ManiaRulesetContainer)rulesetContainer; + availableColumns = maniaRulesetContainer.AvailableColumns; + + base.ApplyToRulesetContainer(rulesetContainer); + } + protected override Score CreateReplayScore(Beatmap beatmap) => new Score + { + User = new User { Username = "osu!topus!" }, + Replay = new ManiaAutoGenerator(beatmap, availableColumns).Generate(), + }; + } } diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs new file mode 100644 index 0000000000..f2cf2fa68a --- /dev/null +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -0,0 +1,86 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Replays; +using osu.Game.Users; + +namespace osu.Game.Rulesets.Mania.Replays +{ + internal class ManiaAutoGenerator : AutoGenerator + { + private readonly int availableColumns; + + public ManiaAutoGenerator(Beatmap beatmap, int availableColumns) + : base(beatmap) + { + this.availableColumns = availableColumns; + + Replay = new Replay { User = new User { Username = @"Autoplay" } }; + } + + protected Replay Replay; + + public override Replay Generate() + { + double[] holdEndTimes = new double[availableColumns]; + for (int i = 0; i < availableColumns; i++) + holdEndTimes[i] = double.NegativeInfinity; + + // Notes are handled row-by-row + foreach (var objGroup in Beatmap.HitObjects.GroupBy(h => h.StartTime)) + { + double groupTime = objGroup.Key; + + int activeColumns = 0; + + // Get the previously held-down active columns + for (int i = 0; i < availableColumns; i++) + { + if (holdEndTimes[i] > groupTime) + activeColumns |= 1 << i; + } + + // Add on the group columns, keeping track of the held notes for the next rows + foreach (var obj in objGroup) + { + var holdNote = obj as HoldNote; + if (holdNote != null) + holdEndTimes[obj.Column] = Math.Max(holdEndTimes[obj.Column], holdNote.EndTime); + + activeColumns |= 1 << obj.Column; + } + + Replay.Frames.Add(new ReplayFrame(groupTime, activeColumns, null, ReplayButtonState.None)); + + // Add the release frames. We can't do this with the loop above because we need activeColumns to be fully populated + foreach (var obj in objGroup.GroupBy(h => (h as IHasEndTime)?.EndTime ?? h.StartTime + 1).OrderBy(h => h.Key)) + { + var groupEndTime = obj.Key; + + int activeColumnsAtEnd = 0; + for (int i = 0; i < availableColumns; i++) + { + if (holdEndTimes[i] > groupEndTime) + activeColumnsAtEnd |= 1 << i; + } + + Replay.Frames.Add(new ReplayFrame(groupEndTime, activeColumnsAtEnd, 0, ReplayButtonState.None)); + } + } + + Replay.Frames = Replay.Frames + // Pick the maximum activeColumns for all frames at the same time + .GroupBy(f => f.Time) + .Select(g => new ReplayFrame(g.First().Time, g.Max(gf => gf.MouseX), 0, ReplayButtonState.None)) + .OrderBy(f => f.Time) + .ToList(); + + return Replay; + } + } +} diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs b/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs new file mode 100644 index 0000000000..7a70ac180e --- /dev/null +++ b/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using osu.Framework.Input; +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Replays; + +namespace osu.Game.Rulesets.Mania.Replays +{ + internal class ManiaFramedReplayInputHandler : FramedReplayInputHandler + { + public ManiaFramedReplayInputHandler(Replay replay) + : base(replay) + { + } + + public override List GetPendingStates() + { + var actions = new List(); + + int activeColumns = (int)(CurrentFrame.MouseX ?? 0); + + int counter = 0; + while (activeColumns > 0) + { + if ((activeColumns & 1) > 0) + actions.Add(ManiaAction.Key1 + counter); + counter++; + activeColumns >>= 1; + } + + return new List { new ReplayState { PressedActions = actions } }; + } + } +} diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 5a3da6d074..d69fa8b6ff 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -18,10 +18,12 @@ using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; +using osu.Game.Rulesets.Mania.Replays; using osu.Game.Rulesets.Mania.Scoring; using osu.Game.Rulesets.Mania.Timing; 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.Timing; using osu.Game.Rulesets.UI; @@ -34,7 +36,7 @@ namespace osu.Game.Rulesets.Mania.UI /// The number of columns which the should display, and which /// the beatmap converter will attempt to convert beatmaps to use. /// - private int availableColumns; + public int AvailableColumns { get; private set; } public IEnumerable BarLines; @@ -75,7 +77,7 @@ namespace osu.Game.Rulesets.Mania.UI BarLines.ForEach(Playfield.Add); } - protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(availableColumns) + protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(AvailableColumns) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -83,26 +85,26 @@ namespace osu.Game.Rulesets.Mania.UI public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this); - public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, availableColumns); + public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, AvailableColumns); protected override BeatmapConverter CreateBeatmapConverter() { if (IsForCurrentRuleset) - availableColumns = (int)Math.Max(1, Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.CircleSize)); + AvailableColumns = (int)Math.Max(1, Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.CircleSize)); else { float percentSliderOrSpinner = (float)WorkingBeatmap.Beatmap.HitObjects.Count(h => h is IHasEndTime) / WorkingBeatmap.Beatmap.HitObjects.Count; if (percentSliderOrSpinner < 0.2) - availableColumns = 7; + AvailableColumns = 7; else if (percentSliderOrSpinner < 0.3 || Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.CircleSize) >= 5) - availableColumns = Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty) > 5 ? 7 : 6; + AvailableColumns = Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty) > 5 ? 7 : 6; else if (percentSliderOrSpinner > 0.6) - availableColumns = Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty) > 4 ? 5 : 4; + AvailableColumns = Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty) > 4 ? 5 : 4; else - availableColumns = Math.Max(4, Math.Min((int)Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty) + 1, 7)); + AvailableColumns = Math.Max(4, Math.Min((int)Math.Round(WorkingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty) + 1, 7)); } - return new ManiaBeatmapConverter(IsForCurrentRuleset, availableColumns); + return new ManiaBeatmapConverter(IsForCurrentRuleset, AvailableColumns); } protected override DrawableHitObject GetVisualRepresentation(ManiaHitObject h) @@ -123,5 +125,7 @@ namespace osu.Game.Rulesets.Mania.UI protected override Vector2 GetPlayfieldAspectAdjust() => new Vector2(1, 0.8f); protected override SpeedAdjustmentContainer CreateSpeedAdjustmentContainer(MultiplierControlPoint controlPoint) => new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Basic); + + protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay); } } diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 7392babbff..ac68859607 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -48,6 +48,7 @@ + @@ -72,6 +73,8 @@ + + diff --git a/osu.Game/Rulesets/Mods/ModAutoplay.cs b/osu.Game/Rulesets/Mods/ModAutoplay.cs index 2b10d098f3..ece0deba84 100644 --- a/osu.Game/Rulesets/Mods/ModAutoplay.cs +++ b/osu.Game/Rulesets/Mods/ModAutoplay.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mods { protected abstract Score CreateReplayScore(Beatmap beatmap); - public void ApplyToRulesetContainer(RulesetContainer rulesetContainer) + public virtual void ApplyToRulesetContainer(RulesetContainer rulesetContainer) { rulesetContainer.SetReplay(CreateReplayScore(rulesetContainer.Beatmap)?.Replay); } From a1baefe20eada145eb2ad31c2a8ded866a64f44c Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 16:09:28 +0900 Subject: [PATCH 395/483] Add 20ms delay to release frames. --- osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index f2cf2fa68a..8be33a8dfc 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -13,6 +13,8 @@ namespace osu.Game.Rulesets.Mania.Replays { internal class ManiaAutoGenerator : AutoGenerator { + private const double release_delay = 20; + private readonly int availableColumns; public ManiaAutoGenerator(Beatmap beatmap, int availableColumns) @@ -58,7 +60,7 @@ namespace osu.Game.Rulesets.Mania.Replays Replay.Frames.Add(new ReplayFrame(groupTime, activeColumns, null, ReplayButtonState.None)); // Add the release frames. We can't do this with the loop above because we need activeColumns to be fully populated - foreach (var obj in objGroup.GroupBy(h => (h as IHasEndTime)?.EndTime ?? h.StartTime + 1).OrderBy(h => h.Key)) + foreach (var obj in objGroup.GroupBy(h => (h as IHasEndTime)?.EndTime ?? h.StartTime + release_delay).OrderBy(h => h.Key)) { var groupEndTime = obj.Key; From a7b93822d73e29d042066be2090e0267b1331293 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 16:10:31 +0900 Subject: [PATCH 396/483] Add initial frame --- .../Replays/ManiaAutoGenerator.cs | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs index 8be33a8dfc..64982532a7 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs @@ -29,6 +29,9 @@ namespace osu.Game.Rulesets.Mania.Replays public override Replay Generate() { + // Todo: Realistically this shouldn't be needed, but the first frame is skipped with the way replays are currently handled + Replay.Frames.Add(new ReplayFrame(-100000, null, null, ReplayButtonState.None)); + double[] holdEndTimes = new double[availableColumns]; for (int i = 0; i < availableColumns; i++) holdEndTimes[i] = double.NegativeInfinity; @@ -78,11 +81,53 @@ namespace osu.Game.Rulesets.Mania.Replays Replay.Frames = Replay.Frames // Pick the maximum activeColumns for all frames at the same time .GroupBy(f => f.Time) - .Select(g => new ReplayFrame(g.First().Time, g.Max(gf => gf.MouseX), 0, ReplayButtonState.None)) + .Select(g => new ReplayFrame(g.First().Time, maxMouseX(g), 0, ReplayButtonState.None)) + // The addition of release frames above maybe result in unordered frames, but we need them ordered .OrderBy(f => f.Time) .ToList(); return Replay; } + + /// + /// Finds the maximum by count of bits from a grouping of s. + /// + /// The grouping to search. + /// The maximum by count of bits. + private float maxMouseX(IGrouping group) + { + int currentCount = -1; + int currentMax = 0; + + foreach (var val in group) + { + int newCount = countBits((int)(val.MouseX ?? 0)); + if (newCount > currentCount) + { + currentCount = newCount; + currentMax = (int)(val.MouseX ?? 0); + } + } + + return currentMax; + } + + /// + /// Counts the number of bits set in a value. + /// + /// The value to count. + /// The number of set bits. + private int countBits(int value) + { + int count = 0; + while (value > 0) + { + if ((value & 1) > 0) + count++; + value >>= 1; + } + + return count; + } } } From af4cc7aada250d4091abcb85abb0da5d240ce109 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 16:15:04 +0900 Subject: [PATCH 397/483] Accuracy starts at 100% for mania. --- osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 63b443319f..596eadd00c 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -285,6 +285,7 @@ namespace osu.Game.Rulesets.Mania.Scoring base.Reset(); Health.Value = 1; + Accuracy.Value = 1; bonusScore = 0; comboPortion = 0; From a22dd80b23104f6e464cf1f030ff7527cfd7f87d Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 16:20:15 +0900 Subject: [PATCH 398/483] Expire HitExplosions. --- osu.Game.Rulesets.Mania/UI/HitExplosion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs index 962082c368..6adad771aa 100644 --- a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs @@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Mania.UI { base.LoadComplete(); - this.ScaleTo(2f, 600, Easing.OutQuint).FadeOut(500); + this.ScaleTo(2f, 600, Easing.OutQuint).FadeOut(500).Expire(); inner.FadeOut(250); } } From 7ad982b540e013902af7fcb906cc7945cba399b7 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 16:21:32 +0900 Subject: [PATCH 399/483] Fix ordering of license header. --- .../Replays/ManiaFramedReplayInputHandler.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs b/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs index 7a70ac180e..e352997f2c 100644 --- a/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs +++ b/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs @@ -1,8 +1,8 @@ -using System.Collections.Generic; -using osu.Framework.Input; -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; +using osu.Framework.Input; using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Mania.Replays From 5b9d906ad510137956e6e29c69e5fa2d976714a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Sep 2017 16:55:48 +0900 Subject: [PATCH 400/483] Improve beatmap track disposal logic - [ ] Depends on https://github.com/ppy/osu-framework/pull/1035 --- osu.Game/Beatmaps/WorkingBeatmap.cs | 11 +++++++++-- osu.Game/OsuGameBase.cs | 13 +++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index e6a26baa66..df8e7f5e3b 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -109,10 +109,17 @@ namespace osu.Game.Beatmaps public virtual void Dispose() { - track?.Dispose(); - track = null; background?.Dispose(); background = null; } + + public void DisposeTrack() + { + lock (trackLock) + { + track?.Dispose(); + track = null; + } + } } } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 76eb7d5101..d81c7cdf73 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -152,10 +152,19 @@ namespace osu.Game Beatmap.ValueChanged += b => { + var trackLoaded = lastBeatmap?.TrackLoaded ?? false; + // compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) - if (lastBeatmap?.Track != b.Track) + if (!trackLoaded || lastBeatmap?.Track != b.Track) { - lastBeatmap?.Track?.Dispose(); + if (trackLoaded) + { + Debug.Assert(lastBeatmap != null); + Debug.Assert(lastBeatmap.Track != null); + + lastBeatmap.DisposeTrack(); + } + Audio.Track.AddItem(b.Track); } From 6a815d343c2c50d98d27c2cfd347a250266c2a2e Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 16:57:51 +0900 Subject: [PATCH 401/483] Remove unneeded class. --- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs | 16 ---------------- .../osu.Game.Rulesets.Mania.csproj | 1 - 2 files changed, 17 deletions(-) delete mode 100644 osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs deleted file mode 100644 index 5c66df71c2..0000000000 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Mania.Objects; - -namespace osu.Game.Rulesets.Mania.Beatmaps -{ - internal class ManiaBeatmap : Beatmap - { - public ManiaBeatmap(Beatmap original = null) - : base(original) - { - } - } -} diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index dd6146d8ae..7ae6e8bdcd 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -48,7 +48,6 @@ - From 160ad1924f25ca2f15a86e7d68d28d590e287f6f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Sep 2017 17:01:40 +0900 Subject: [PATCH 402/483] Remove unneeded reference --- osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 7ae6e8bdcd..ac759e2ab8 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -102,10 +102,6 @@ {C76BF5B3-985E-4D39-95FE-97C9C879B83A} osu.Framework - - {C92A607B-1FDD-4954-9F92-03FF547D9080} - osu.Game.Rulesets.Osu - {0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D} osu.Game From 58e65397b06b43973c52babef2e520520fc2e94e Mon Sep 17 00:00:00 2001 From: Damnae Date: Tue, 12 Sep 2017 10:13:55 +0200 Subject: [PATCH 403/483] Add support for storyboards using numerical values. --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 53 +++++++++++++++++-- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index e436a43989..adf366cdea 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -287,8 +287,8 @@ namespace osu.Game.Beatmaps.Formats break; case EventType.Sprite: { - var layer = split[1]; - var origin = (Anchor)Enum.Parse(typeof(Anchor), split[2]); + var layer = parseLayer(split[1]); + var origin = parseOrigin(split[2]); var path = cleanFilename(split[3]); var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo); var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo); @@ -298,8 +298,8 @@ namespace osu.Game.Beatmaps.Formats break; case EventType.Animation: { - var layer = split[1]; - var origin = (Anchor)Enum.Parse(typeof(Anchor), split[2]); + var layer = parseLayer(split[1]); + var origin = parseOrigin(split[2]); var path = cleanFilename(split[3]); var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo); var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo); @@ -313,7 +313,7 @@ namespace osu.Game.Beatmaps.Formats case EventType.Sample: { var time = double.Parse(split[1], CultureInfo.InvariantCulture); - var layer = split[2]; + var layer = parseLayer(split[2]); var path = cleanFilename(split[3]); var volume = split.Length > 4 ? float.Parse(split[4], CultureInfo.InvariantCulture) : 100; beatmap.Storyboard.GetLayer(layer).Add(new SampleDefinition(path, time, volume)); @@ -446,6 +446,27 @@ namespace osu.Game.Beatmaps.Formats private static string cleanFilename(string path) => FileSafety.PathStandardise(path.Trim('\"')); + private static Anchor parseOrigin(string value) + { + var origin = (LegacyOrigins)Enum.Parse(typeof(LegacyOrigins), value); + switch (origin) + { + case LegacyOrigins.TopLeft: return Anchor.TopLeft; + case LegacyOrigins.TopCentre: return Anchor.TopCentre; + case LegacyOrigins.TopRight: return Anchor.TopRight; + case LegacyOrigins.CentreLeft: return Anchor.CentreLeft; + case LegacyOrigins.Centre: return Anchor.Centre; + case LegacyOrigins.CentreRight: return Anchor.CentreRight; + case LegacyOrigins.BottomLeft: return Anchor.BottomLeft; + case LegacyOrigins.BottomCentre: return Anchor.BottomCentre; + case LegacyOrigins.BottomRight: return Anchor.BottomRight; + } + throw new InvalidDataException($@"Unknown origin: {value}"); + } + + private static string parseLayer(string value) + => Enum.Parse(typeof(StoryLayer), value).ToString(); + private void handleTimingPoints(Beatmap beatmap, string line) { string[] split = line.Split(','); @@ -683,5 +704,27 @@ namespace osu.Game.Beatmaps.Formats Sample = 5, Animation = 6 } + + internal enum LegacyOrigins + { + TopLeft, + Centre, + CentreLeft, + TopRight, + BottomCentre, + TopCentre, + Custom, + CentreRight, + BottomLeft, + BottomRight + }; + + internal enum StoryLayer + { + Background = 0, + Fail = 1, + Pass = 2, + Foreground = 3 + } } } From 20dae5ee116c43456427f38034abcad695af9cf5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Sep 2017 17:36:46 +0900 Subject: [PATCH 404/483] Minor refactors --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 2 +- osu.Game/Rulesets/Judgements/Judgement.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 83d22454cb..13eb49698b 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.UI private void Fruit_OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { - if (judgement.Result > HitResult.Miss) + if (judgement.IsHit) { Vector2 screenPosition = judgedObject.ScreenSpaceDrawQuad.Centre; Remove(judgedObject); diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index 2732c5e778..5ee2421f4f 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -21,6 +21,7 @@ namespace osu.Game.Rulesets.Judgements /// /// The offset at which this judgement occurred. + /// Populated when added via . /// public double TimeOffset { get; internal set; } From d7ac02d09076451832cd0a21e1de68cd99d3d656 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Sep 2017 18:00:41 +0900 Subject: [PATCH 405/483] Ensure judgements aren't updated when ArmedState is not idle --- .../Objects/Drawables/DrawableOsuHitObject.cs | 4 +++- osu.Game/Rulesets/Judgements/Judgement.cs | 2 +- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index d18b3dd65e..60586327ab 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -5,6 +5,7 @@ using System.ComponentModel; using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Types; +using System.Linq; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -31,7 +32,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables UpdatePreemptState(); - var offset = !AllJudged ? 0 : Time.Current - ((HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime); + var judgement = Judgements.FirstOrDefault(); + var offset = judgement != null ? judgement.TimeOffset : 0; using (BeginDelayedSequence(TIME_PREEMPT + offset, true)) UpdateCurrentState(state); } diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index 5ee2421f4f..29cd3ff384 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Judgements public bool IsHit => Result > HitResult.Miss; /// - /// The offset at which this judgement occurred. + /// The offset from a perfect hit at which this judgement occurred. /// Populated when added via . /// public double TimeOffset { get; internal set; } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index dfea9527e1..e72d0dd142 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -138,7 +138,7 @@ namespace osu.Game.Rulesets.Objects.Drawables { judgementOccurred = false; - if (AllJudged) + if (AllJudged || State != ArmedState.Idle) return false; if (NestedHitObjects != null) From f32d444d6827f8f7ed0c9e2a57932ba67311584e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Sep 2017 18:19:28 +0900 Subject: [PATCH 406/483] Remove generics from Playfield (fixes catch) --- .../Visual/TestCaseScrollingPlayfield.cs | 6 +++--- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 4 ++-- .../UI/CatchRulesetContainer.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 1 - osu.Game.Rulesets.Mania/UI/Column.cs | 4 ++-- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 5 +++-- .../UI/ManiaRulesetContainer.cs | 2 +- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 6 ++---- osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs | 2 +- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 6 ++---- .../UI/TaikoRulesetContainer.cs | 2 +- .../Objects/Drawables/DrawableHitObject.cs | 2 ++ osu.Game/Rulesets/UI/Playfield.cs | 9 ++++----- osu.Game/Rulesets/UI/RulesetContainer.cs | 6 +++--- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 17 ++++++++--------- .../Rulesets/UI/ScrollingRulesetContainer.cs | 4 ++-- 16 files changed, 37 insertions(+), 41 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs index a431531427..fc8f70b7ce 100644 --- a/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs +++ b/osu.Desktop.Tests/Visual/TestCaseScrollingPlayfield.cs @@ -72,7 +72,7 @@ namespace osu.Desktop.Tests.Visual [Test] public void TestSpeedAdjustmentOrdering() { - var hitObjectContainer = new ScrollingPlayfield.ScrollingHitObjectContainer(Axes.X); + var hitObjectContainer = new ScrollingPlayfield.ScrollingHitObjectContainer(Axes.X); var speedAdjustments = new[] { @@ -147,7 +147,7 @@ namespace osu.Desktop.Tests.Visual protected override BeatmapConverter CreateBeatmapConverter() => new TestBeatmapConverter(); - protected override Playfield CreatePlayfield() => new TestPlayfield(scrollingAxes); + protected override Playfield CreatePlayfield() => new TestPlayfield(scrollingAxes); protected override DrawableHitObject GetVisualRepresentation(TestHitObject h) => new DrawableTestHitObject(scrollingAxes, h); } @@ -190,7 +190,7 @@ namespace osu.Desktop.Tests.Visual } } - private class TestPlayfield : ScrollingPlayfield + private class TestPlayfield : ScrollingPlayfield { protected override Container Content => content; private readonly Container content; diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 13eb49698b..d653bc92e6 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.UI { - public class CatchPlayfield : ScrollingPlayfield + public class CatchPlayfield : ScrollingPlayfield { protected override Container Content => content; private readonly Container content; @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Catch.UI }; } - public override void Add(DrawableHitObject h) + public override void Add(DrawableHitObject h) { base.Add(h); diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index eb7abf9248..8f332bdcbf 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI protected override BeatmapConverter CreateBeatmapConverter() => new CatchBeatmapConverter(); - protected override Playfield CreatePlayfield() => new CatchPlayfield(); + protected override Playfield CreatePlayfield() => new CatchPlayfield(); public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo); diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index ac1f45a2ab..64dbe04ba4 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -160,7 +160,6 @@ namespace osu.Game.Rulesets.Catch.UI fruit.Origin = Anchor.BottomCentre; fruit.Scale *= 0.7f; fruit.LifetimeEnd = double.MaxValue; - fruit.Depth = (float)Time.Current; float distance = fruit.DrawSize.X / 2 * fruit.Scale.X; diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index bbd4dea471..6a240081c8 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -18,7 +18,7 @@ using osu.Game.Rulesets.Judgements; namespace osu.Game.Rulesets.Mania.UI { - public class Column : ScrollingPlayfield, IHasAccentColour + public class Column : ScrollingPlayfield, IHasAccentColour { private const float key_icon_size = 10; private const float key_icon_corner_radius = 3; @@ -199,7 +199,7 @@ namespace osu.Game.Rulesets.Mania.UI /// Adds a DrawableHitObject to this Playfield. /// /// The DrawableHitObject to add. - public override void Add(DrawableHitObject hitObject) + public override void Add(DrawableHitObject hitObject) { hitObject.AccentColour = AccentColour; HitObjects.Add(hitObject); diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 3c37f334bd..6c164a34f0 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -20,7 +20,7 @@ using osu.Game.Rulesets.Judgements; namespace osu.Game.Rulesets.Mania.UI { - public class ManiaPlayfield : ScrollingPlayfield + public class ManiaPlayfield : ScrollingPlayfield { public const float HIT_TARGET_POSITION = 50; @@ -224,7 +224,8 @@ namespace osu.Game.Rulesets.Mania.UI } } - public override void Add(DrawableHitObject h) => Columns.ElementAt(h.HitObject.Column).Add(h); + public override void Add(DrawableHitObject h) => Columns.ElementAt(((ManiaHitObject)h.HitObject).Column).Add(h); + public void Add(DrawableBarLine barline) => HitObjects.Add(barline); protected override void Update() diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 49e53a07c9..985d9fbfe2 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Mania.UI BarLines.ForEach(Playfield.Add); } - protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(availableColumns) + protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(availableColumns) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index e9d9e0e3de..17f4f9f541 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -16,7 +16,7 @@ using osu.Game.Rulesets.Osu.UI.Cursor; namespace osu.Game.Rulesets.Osu.UI { - public class OsuPlayfield : Playfield + public class OsuPlayfield : Playfield { private readonly Container approachCircles; private readonly Container judgementLayer; @@ -68,10 +68,8 @@ namespace osu.Game.Rulesets.Osu.UI AddInternal(new GameplayCursor()); } - public override void Add(DrawableHitObject h) + public override void Add(DrawableHitObject h) { - h.Depth = (float)h.HitObject.StartTime; - var c = h as IDrawableHitObjectWithProxiedApproach; if (c != null) approachCircles.Add(c.ProxiedLayer.CreateProxy()); diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs index edf7e014a3..668a440c4a 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.UI protected override BeatmapProcessor CreateBeatmapProcessor() => new OsuBeatmapProcessor(); - protected override Playfield CreatePlayfield() => new OsuPlayfield(); + protected override Playfield CreatePlayfield() => new OsuPlayfield(); public override PassThroughInputManager CreateInputManager() => new OsuInputManager(Ruleset.RulesetInfo); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 373f9f9b7f..52b3301bc7 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -19,7 +19,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.UI { - public class TaikoPlayfield : ScrollingPlayfield + public class TaikoPlayfield : ScrollingPlayfield { /// /// Default height of a when inside a . @@ -203,10 +203,8 @@ namespace osu.Game.Rulesets.Taiko.UI background.Colour = colours.Gray0; } - public override void Add(DrawableHitObject h) + public override void Add(DrawableHitObject h) { - h.Depth = (float)h.HitObject.StartTime; - base.Add(h); var barline = h as DrawableBarLine; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index ccb6531b00..4e7b676fbc 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -94,7 +94,7 @@ namespace osu.Game.Rulesets.Taiko.UI public override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo); - protected override Playfield CreatePlayfield() => new TaikoPlayfield + protected override Playfield CreatePlayfield() => new TaikoPlayfield { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index e72d0dd142..c008d25083 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -55,6 +55,8 @@ namespace osu.Game.Rulesets.Objects.Drawables : base(hitObject) { HitObject = hitObject; + + Depth = (float)hitObject.StartTime; } private ArmedState state; diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index ce800b76b1..d8cfe3007d 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -14,8 +14,7 @@ using System.Linq; namespace osu.Game.Rulesets.UI { - public abstract class Playfield : Container - where TObject : HitObject + public abstract class Playfield : Container { /// /// The HitObjects contained in this Playfield. @@ -69,7 +68,7 @@ namespace osu.Game.Rulesets.UI public override Axes RelativeSizeAxes { get { return Axes.Both; } - set { throw new InvalidOperationException($@"{nameof(Playfield)}'s {nameof(RelativeSizeAxes)} should never be changed from {Axes.Both}"); } + set { throw new InvalidOperationException($@"{nameof(Playfield)}'s {nameof(RelativeSizeAxes)} should never be changed from {Axes.Both}"); } } /// @@ -81,13 +80,13 @@ namespace osu.Game.Rulesets.UI /// Adds a DrawableHitObject to this Playfield. /// /// The DrawableHitObject to add. - public virtual void Add(DrawableHitObject h) => HitObjects.Add(h); + public virtual void Add(DrawableHitObject h) => HitObjects.Add(h); /// /// Remove a DrawableHitObject from this Playfield. /// /// The DrawableHitObject to remove. - public virtual void Remove(DrawableHitObject h) => HitObjects.Remove(h); + public virtual void Remove(DrawableHitObject h) => HitObjects.Remove(h); /// /// Triggered when a new occurs on a . diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index cae211fb9c..9377d64028 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -157,7 +157,7 @@ namespace osu.Game.Rulesets.UI /// /// The playfield. /// - public Playfield Playfield { get; private set; } + public Playfield Playfield { get; private set; } protected override Container Content => content; private Container content; @@ -310,7 +310,7 @@ namespace osu.Game.Rulesets.UI /// Creates a Playfield. /// /// The Playfield. - protected abstract Playfield CreatePlayfield(); + protected abstract Playfield CreatePlayfield(); } /// @@ -320,7 +320,7 @@ namespace osu.Game.Rulesets.UI /// The type of HitObject contained by this RulesetContainer. public abstract class RulesetContainer : RulesetContainer where TObject : HitObject - where TPlayfield : Playfield + where TPlayfield : Playfield { /// /// The playfield. diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 2162d650db..748b26291b 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -20,8 +20,7 @@ namespace osu.Game.Rulesets.UI /// /// A type of specialized towards scrolling s. /// - public class ScrollingPlayfield : Playfield - where TObject : HitObject + public class ScrollingPlayfield : Playfield { /// /// The default span of time visible by the length of the scrolling axes. @@ -75,21 +74,21 @@ namespace osu.Game.Rulesets.UI HitObjects.Reversed.BindTo(Reversed); } - private List> nestedPlayfields; + private List nestedPlayfields; /// /// All the s nested inside this playfield. /// - public IEnumerable> NestedPlayfields => nestedPlayfields; + public IEnumerable NestedPlayfields => nestedPlayfields; /// /// Adds a to this playfield. The nested /// will be given all of the same speed adjustments as this playfield. /// /// The to add. - protected void AddNested(ScrollingPlayfield otherPlayfield) + protected void AddNested(ScrollingPlayfield otherPlayfield) { if (nestedPlayfields == null) - nestedPlayfields = new List>(); + nestedPlayfields = new List(); nestedPlayfields.Add(otherPlayfield); } @@ -117,7 +116,7 @@ namespace osu.Game.Rulesets.UI this.TransformTo(this.PopulateTransform(new TransformVisibleTimeRange(), newTimeRange, duration, easing)); } - private class TransformVisibleTimeRange : Transform> + private class TransformVisibleTimeRange : Transform { private double valueAt(double time) { @@ -129,8 +128,8 @@ namespace osu.Game.Rulesets.UI 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; + protected override void Apply(ScrollingPlayfield d, double time) => d.VisibleTimeRange.Value = valueAt(time); + protected override void ReadIntoStartValue(ScrollingPlayfield d) => StartValue = d.VisibleTimeRange.Value; } /// diff --git a/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs b/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs index c199c90f4a..2fd75d62cb 100644 --- a/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs +++ b/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.UI /// public abstract class ScrollingRulesetContainer : RulesetContainer where TObject : HitObject - where TPlayfield : ScrollingPlayfield + where TPlayfield : ScrollingPlayfield { /// /// Provides the default s that adjust the scrolling rate of s @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.UI DefaultControlPoints.ForEach(c => applySpeedAdjustment(c, Playfield)); } - private void applySpeedAdjustment(MultiplierControlPoint controlPoint, ScrollingPlayfield playfield) + private void applySpeedAdjustment(MultiplierControlPoint controlPoint, ScrollingPlayfield playfield) { playfield.HitObjects.AddSpeedAdjustment(CreateSpeedAdjustmentContainer(controlPoint)); playfield.NestedPlayfields.ForEach(p => applySpeedAdjustment(controlPoint, p)); From b21c080121250afef49aceea832e3670b43e6b85 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Sep 2017 18:22:02 +0900 Subject: [PATCH 407/483] Make mania readable again --- osu.Game.Rulesets.Mania/UI/Column.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 6a240081c8..3f42b71c5d 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -42,6 +42,9 @@ namespace osu.Game.Rulesets.Mania.UI protected override Container Content => content; private readonly Container content; + private const float opacity_released = 0.1f; + private const float opacity_pressed = 0.25f; + public Column() : base(Axes.Y) { @@ -51,9 +54,9 @@ namespace osu.Game.Rulesets.Mania.UI { background = new Box { - Name = "Foreground", + Name = "Background", RelativeSizeAxes = Axes.Both, - Alpha = 0.2f + Alpha = opacity_released }, new Container { @@ -217,7 +220,7 @@ namespace osu.Game.Rulesets.Mania.UI { if (action == Action) { - background.FadeTo(0.6f, 50, Easing.OutQuint); + background.FadeTo(opacity_pressed, 50, Easing.OutQuint); keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint); } @@ -228,7 +231,7 @@ namespace osu.Game.Rulesets.Mania.UI { if (action == Action) { - background.FadeTo(0.2f, 800, Easing.OutQuart); + background.FadeTo(opacity_released, 800, Easing.OutQuart); keyIcon.ScaleTo(1f, 400, Easing.OutQuart); } From 3e3411dc9d490ebcb895ce6787bfa2bb1c77f91b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Sep 2017 18:34:15 +0900 Subject: [PATCH 408/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 1b479fb947..1a259925b8 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 1b479fb947da193f099df062f696b3a6164da9e0 +Subproject commit 1a259925b82c31ddcebf7b330a6ef9d3a9daf089 From 86de4fa2e277bc1eaffbce0d1fa594fc3fd0e01b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Sep 2017 18:26:56 +0900 Subject: [PATCH 409/483] Apply CI fixes --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 1 - osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs | 1 - osu.Game.Rulesets.Mania/UI/Column.cs | 1 - osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs | 2 -- osu.Game.Rulesets.Mania/UI/HitExplosion.cs | 2 -- .../Objects/Drawables/DrawableOsuHitObject.cs | 5 +---- osu.Game/Rulesets/UI/Playfield.cs | 1 - osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 1 - 8 files changed, 1 insertion(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index d653bc92e6..0dac3ec41c 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; -using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.UI; using OpenTK; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs index c78df52227..e36146aa71 100644 --- a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Extensions; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 3f42b71c5d..1133c9f2ee 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -13,7 +13,6 @@ using osu.Game.Rulesets.Objects.Drawables; using System; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.UI; -using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Judgements; namespace osu.Game.Rulesets.Mania.UI diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs index 8887ca2fe0..08478cef33 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs @@ -3,8 +3,6 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Mania.Judgements; -using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Mania.UI { diff --git a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs index 7f7b567603..ead6b49273 100644 --- a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs @@ -6,8 +6,6 @@ using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Rulesets.Mania.Judgements; -using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 60586327ab..9205f43a6d 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -4,7 +4,6 @@ using System.ComponentModel; using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics; -using osu.Game.Rulesets.Objects.Types; using System.Linq; namespace osu.Game.Rulesets.Osu.Objects.Drawables @@ -32,9 +31,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables UpdatePreemptState(); - var judgement = Judgements.FirstOrDefault(); - var offset = judgement != null ? judgement.TimeOffset : 0; - using (BeginDelayedSequence(TIME_PREEMPT + offset, true)) + using (BeginDelayedSequence(TIME_PREEMPT + (Judgements.FirstOrDefault()?.TimeOffset ?? 0), true)) UpdateCurrentState(state); } } diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index d8cfe3007d..0270751946 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -4,7 +4,6 @@ using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using OpenTK; using osu.Game.Rulesets.Judgements; diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 748b26291b..b66a26de91 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Transforms; using osu.Framework.Input; using osu.Framework.MathUtils; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; From fb05552ac4b76f78c4335b717331cd5802ec2b0c Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 18:36:31 +0900 Subject: [PATCH 410/483] Fix one more case of incorrect offset. --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index badb6693c9..738902846b 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -172,9 +172,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables const float preempt = 100; const float out_transition_time = 300; - var offset = !AllJudged ? 0 : Time.Current - HitObject.EndTime; double untilStartTime = HitObject.StartTime - Time.Current; - double untilJudgement = untilStartTime + offset + HitObject.Duration; + double untilJudgement = untilStartTime + (Judgements.FirstOrDefault()?.TimeOffset ?? 0) + HitObject.Duration; targetRing.Delay(untilStartTime - preempt).ScaleTo(target_ring_scale, preempt * 4, Easing.OutQuint); this.Delay(untilJudgement).FadeOut(out_transition_time, Easing.Out); From 3ef65a1e5db43d53c9441c1345278b019219c938 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 18:43:28 +0900 Subject: [PATCH 411/483] Cleanup TaikoPlayfield a bit --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 52b3301bc7..2dd06f7179 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -219,27 +219,25 @@ namespace osu.Game.Rulesets.Taiko.UI public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { - bool wasHit = judgement.Result > HitResult.Miss; - bool secondHit = judgement is TaikoStrongHitJudgement; - var taikoObject = (TaikoHitObject)judgedObject.HitObject; - if (judgementContainer.FirstOrDefault(j => j.JudgedObject == judgedObject) == null) { judgementContainer.Add(new DrawableTaikoJudgement(judgedObject, judgement) { - Anchor = wasHit ? Anchor.TopLeft : Anchor.CentreLeft, - Origin = wasHit ? Anchor.BottomCentre : Anchor.Centre, + Anchor = judgement.IsHit ? Anchor.TopLeft : Anchor.CentreLeft, + Origin = judgement.IsHit ? Anchor.BottomCentre : Anchor.Centre, RelativePositionAxes = Axes.X, - X = wasHit ? judgedObject.Position.X : 0, + X = judgement.IsHit ? judgedObject.Position.X : 0, }); } - if (!wasHit) + if (!judgement.IsHit) return; bool isRim = judgedObject.HitObject is RimHit; - if (!secondHit) + if (judgement is TaikoStrongHitJudgement) + hitExplosionContainer.Children.FirstOrDefault(e => e.JudgedObject == judgedObject)?.VisualiseSecondHit(); + else { if (judgedObject.X >= -0.05f && judgedObject is DrawableHit) { @@ -249,11 +247,9 @@ namespace osu.Game.Rulesets.Taiko.UI hitExplosionContainer.Add(new HitExplosion(judgedObject, isRim)); - if (taikoObject.Kiai) + if (judgedObject.HitObject.Kiai) kiaiExplosionContainer.Add(new KiaiHitExplosion(judgedObject, isRim)); } - else - hitExplosionContainer.Children.FirstOrDefault(e => e.JudgedObject == judgedObject)?.VisualiseSecondHit(); } } } From a38e0062a4091f2eec75d507ebf4a09da5819497 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 18:49:50 +0900 Subject: [PATCH 412/483] Fix checking judgements even if we don't provide a judgement, if we have a result, or if a nested hit object handled a judgement. --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index c008d25083..434fbc80f9 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -157,6 +157,9 @@ namespace osu.Game.Rulesets.Objects.Drawables } } + if (!ProvidesJudgement || hasJudgementResult || judgementOccurred) + return judgementOccurred; + var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; CheckForJudgements(userTriggered, Time.Current - endTime); From 92b3e203e8b13e657b1414d8e6d044f42389b935 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 18:50:30 +0900 Subject: [PATCH 413/483] judgementOccurred should be passed upwards So only one hit object is ever judged in a single frame. --- .../Rulesets/Objects/Drawables/DrawableHitObject.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 434fbc80f9..7cf098c3fa 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -146,15 +146,7 @@ namespace osu.Game.Rulesets.Objects.Drawables if (NestedHitObjects != null) { foreach (var d in NestedHitObjects) - { - if (d.AllJudged) - continue; - - d.UpdateJudgement(userTriggered); - - if (d.AllJudged) - return true; - } + judgementOccurred |= d.UpdateJudgement(userTriggered); } if (!ProvidesJudgement || hasJudgementResult || judgementOccurred) From d5bd005c01bf0f7df3d675775d87fda7f78c784d Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 18:52:15 +0900 Subject: [PATCH 414/483] Remove unused code for now I don't think we'll ever be using this anyway. --- osu.Game/Rulesets/Objects/HitObject.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 984ecec2b5..c69979d4cf 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -1,11 +1,9 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Objects @@ -32,10 +30,6 @@ namespace osu.Game.Rulesets.Objects /// public SampleInfoList Samples = new SampleInfoList(); - public virtual IEnumerable CreateJudgements() => new[] { new Judgement() }; - - public readonly List Children = new List(); - /// /// Whether this is in Kiai time. /// From 112429051ea3ab5cc6c9fd9915de087bc911e040 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 19:05:37 +0900 Subject: [PATCH 415/483] Fix XMLDoc CI errors --- osu.Game/Rulesets/UI/RulesetContainer.cs | 4 ++-- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 10 +++++----- osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 9377d64028..f7ece531c3 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.UI public event Action OnAllJudged; /// - /// Whether to apply adjustments to the child based on our own size. + /// Whether to apply adjustments to the child based on our own size. /// public bool AspectAdjust = true; @@ -288,7 +288,7 @@ namespace osu.Game.Rulesets.UI protected virtual BeatmapProcessor CreateBeatmapProcessor() => new BeatmapProcessor(); /// - /// In some cases we want to apply changes to the relative size of our contained based on custom conditions. + /// In some cases we want to apply changes to the relative size of our contained based on custom conditions. /// /// protected virtual Vector2 GetPlayfieldAspectAdjust() => new Vector2(0.75f); //a sane default diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index b66a26de91..395248b2fd 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -17,7 +17,7 @@ using osu.Game.Rulesets.Timing; namespace osu.Game.Rulesets.UI { /// - /// A type of specialized towards scrolling s. + /// A type of specialized towards scrolling s. /// public class ScrollingPlayfield : Playfield { @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.UI public new readonly ScrollingHitObjectContainer HitObjects; /// - /// Creates a new . + /// Creates a new . /// /// The axes on which s in this container should scroll. /// Whether we want our internal coordinate system to be scaled to a specified width @@ -75,15 +75,15 @@ namespace osu.Game.Rulesets.UI private List nestedPlayfields; /// - /// All the s nested inside this playfield. + /// All the s nested inside this playfield. /// public IEnumerable NestedPlayfields => nestedPlayfields; /// - /// Adds a to this playfield. The nested + /// Adds a to this playfield. The nested /// will be given all of the same speed adjustments as this playfield. /// - /// The to add. + /// The to add. protected void AddNested(ScrollingPlayfield otherPlayfield) { if (nestedPlayfields == null) diff --git a/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs b/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs index 2fd75d62cb..f1b8838fa9 100644 --- a/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs +++ b/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs @@ -16,7 +16,7 @@ using osu.Game.Rulesets.Timing; namespace osu.Game.Rulesets.UI { /// - /// A type of that supports a . + /// A type of that supports a . /// s inside this will scroll within the playfield. /// public abstract class ScrollingRulesetContainer : RulesetContainer From 3af8345068f79d36910ea7c5a2a31f4d2b686c53 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 19:39:22 +0900 Subject: [PATCH 416/483] Add AffectsAccuracy to Judgement --- osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs | 1 + .../Judgements/TaikoDrumRollTickJudgement.cs | 1 + osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs | 3 +++ osu.Game/Rulesets/Judgements/Judgement.cs | 2 ++ 4 files changed, 7 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs index c00572edff..132856713a 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs @@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mania.Judgements public class HoldNoteTickJudgement : ManiaJudgement { public override bool AffectsCombo => false; + public override bool AffectsAccuracy => false; protected override int NumericResultFor(HitResult result) => 20; protected override int NumericResultForAccuracy(HitResult result) => 0; // Don't count ticks into accuracy diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs index 0d61494add..0eb5370840 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs @@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Taiko.Judgements public class TaikoDrumRollTickJudgement : TaikoJudgement { public override bool AffectsCombo => false; + public override bool AffectsAccuracy => false; protected override int NumericResultFor(HitResult result) { diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs index bb67784ab1..2cc4c922e2 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs @@ -7,6 +7,9 @@ namespace osu.Game.Rulesets.Taiko.Judgements { public class TaikoStrongHitJudgement : TaikoJudgement { + public override bool AffectsCombo => false; + public override bool AffectsAccuracy => false; + public TaikoStrongHitJudgement() { base.Result = HitResult.Perfect; diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index 29cd3ff384..40cc643f60 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Judgements /// public double TimeOffset { get; internal set; } + public virtual bool AffectsAccuracy => true; + public virtual bool AffectsCombo => true; /// From c07e831b1739ff0ebad70b6abc086419cd83c0cd Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 19:39:54 +0900 Subject: [PATCH 417/483] Move HasFailed override to base ScoreProcessor --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 2ca733d82a..c64737c875 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Scoring /// /// Whether the score is in a failed state. /// - public virtual bool HasFailed => false; + public virtual bool HasFailed => Health.Value == Health.MinValue; /// /// Whether this ScoreProcessor has already triggered the failed state. @@ -143,8 +143,6 @@ namespace osu.Game.Rulesets.Scoring /// protected readonly List Judgements = new List(); - public override bool HasFailed => Health.Value == Health.MinValue; - protected ScoreProcessor() { } @@ -156,7 +154,6 @@ namespace osu.Game.Rulesets.Scoring rulesetContainer.OnJudgement += AddJudgement; ComputeTargets(rulesetContainer.Beatmap); - Reset(); } From cba642f781d37bb1de3e097b6544fbd15c3b5f2f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 19:45:07 +0900 Subject: [PATCH 418/483] Reduce nesting, because we don't have partial judgements any more --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 35 +++++++++------------ 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index c64737c875..54466315d6 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -169,31 +169,26 @@ namespace osu.Game.Rulesets.Scoring /// The judgement to add. protected void AddJudgement(Judgement judgement) { - bool exists = Judgements.Contains(judgement); - - if (!exists) + if (judgement.AffectsCombo) { - if (judgement.AffectsCombo) + switch (judgement.Result) { - switch (judgement.Result) - { - case HitResult.None: - break; - case HitResult.Miss: - Combo.Value = 0; - break; - default: - Combo.Value++; - break; - } + case HitResult.None: + break; + case HitResult.Miss: + Combo.Value = 0; + break; + default: + Combo.Value++; + break; } - - Judgements.Add(judgement); - OnNewJudgement(judgement); - - NotifyNewJudgement(judgement); } + Judgements.Add(judgement); + OnNewJudgement(judgement); + + NotifyNewJudgement(judgement); + UpdateFailed(); } From c7677d896a0432a11c3810c09e18761f2b98b843 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 19:47:44 +0900 Subject: [PATCH 419/483] Remove SliderTickJudgement --- osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs b/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs index 3d19d19546..3ccf1cd60c 100644 --- a/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs +++ b/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs @@ -8,10 +8,6 @@ using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Judgements { - public class SliderTickJudgement : OsuJudgement - { - } - public class OsuJudgement : Judgement { /// From 195c2d7a31ffcab7f397ccc63deeb2a5ec519a07 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 19:48:17 +0900 Subject: [PATCH 420/483] Keep track of maximum hits + combo at base ScoreProcessor level --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 54466315d6..7760c6f489 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -143,6 +143,11 @@ namespace osu.Game.Rulesets.Scoring /// protected readonly List Judgements = new List(); + private int maxHits; + private int maxCombo; + + private int hits; + protected ScoreProcessor() { } @@ -154,6 +159,10 @@ namespace osu.Game.Rulesets.Scoring rulesetContainer.OnJudgement += AddJudgement; ComputeTargets(rulesetContainer.Beatmap); + + maxCombo = HighestCombo; + maxHits = hits; + Reset(); } @@ -173,8 +182,6 @@ namespace osu.Game.Rulesets.Scoring { switch (judgement.Result) { - case HitResult.None: - break; case HitResult.Miss: Combo.Value = 0; break; @@ -184,6 +191,9 @@ namespace osu.Game.Rulesets.Scoring } } + if (judgement.AffectsCombo && judgement.IsHit) + hits++; + Judgements.Add(judgement); OnNewJudgement(judgement); From d070fb80639f57ab1ba22ea231935d1b6c976620 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 19:48:35 +0900 Subject: [PATCH 421/483] Actually make DrawableSliderTick return an OsuJudgement now --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index 0938f78843..b088359fbf 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (timeOffset >= 0) - AddJudgement(new SliderTickJudgement { Result = Tracking ? HitResult.Perfect : HitResult.Miss }); + AddJudgement(new OsuJudgement { Result = Tracking ? HitResult.Perfect : HitResult.Miss }); } protected override void UpdatePreemptState() From 0b949394741a647c6379075cb7a43a2dc79799d8 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 20:53:26 +0900 Subject: [PATCH 422/483] Make Accuracy = 1, Health = 1 the default for ScoreProcessor --- osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs | 8 -------- osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs | 5 ----- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 3 --- osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs | 1 - osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 6 +++--- 5 files changed, 3 insertions(+), 20 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 2637a98fe2..7608be5762 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -19,14 +19,6 @@ namespace osu.Game.Rulesets.Catch.Scoring { } - protected override void Reset() - { - base.Reset(); - - Health.Value = 1; - Accuracy.Value = 1; - } - protected override void OnNewJudgement(Judgement judgement) { } diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 946caf71cf..e256e9bd72 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -265,13 +265,8 @@ namespace osu.Game.Rulesets.Mania.Scoring TotalScore.Value = comboScore + accuracyScore + bonusScore; } - protected override void Reset() - { base.Reset(); - Health.Value = 1; - Accuracy.Value = 1; - bonusScore = 0; comboPortion = 0; totalHits = 0; diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 59d4492480..362038baba 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -54,9 +54,6 @@ namespace osu.Game.Rulesets.Osu.Scoring { base.Reset(); - Health.Value = 1; - Accuracy.Value = 1; - scoreResultCounts.Clear(); comboResultCounts.Clear(); } diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index 6b99b23a12..21d790169c 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -242,7 +242,6 @@ namespace osu.Game.Rulesets.Taiko.Scoring base.Reset(); Health.Value = 0; - Accuracy.Value = 1; bonusScore = 0; comboPortion = 0; diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 7760c6f489..2e76f9a135 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Scoring /// /// The current accuracy. /// - public readonly BindableDouble Accuracy = new BindableDouble { MinValue = 0, MaxValue = 1 }; + public readonly BindableDouble Accuracy = new BindableDouble(1) { MinValue = 0, MaxValue = 1 }; /// /// The current health. @@ -88,8 +88,8 @@ namespace osu.Game.Rulesets.Scoring protected virtual void Reset() { TotalScore.Value = 0; - Accuracy.Value = 0; - Health.Value = 0; + Accuracy.Value = 1; + Health.Value = 1; Combo.Value = 0; HighestCombo.Value = 0; From abab2a4878654917f4cf11970e1a3e63e834daed Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 21:05:50 +0900 Subject: [PATCH 423/483] Revamp score processing to once more unify scoring methods --- .../Scoring/CatchScoreProcessor.cs | 1 + .../Scoring/ManiaScoreProcessor.cs | 101 +--------------- .../Scoring/OsuScoreProcessor.cs | 51 +------- .../Judgements/TaikoDrumRollTickJudgement.cs | 5 - .../Judgements/TaikoJudgement.cs | 30 ----- .../Scoring/TaikoScoreProcessor.cs | 112 +----------------- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 61 +++++++--- 7 files changed, 61 insertions(+), 300 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index 7608be5762..cd2a81038a 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -21,6 +21,7 @@ namespace osu.Game.Rulesets.Catch.Scoring protected override void OnNewJudgement(Judgement judgement) { + base.OnNewJudgement(judgement); } } } diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index e256e9bd72..06ba82205d 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -15,32 +15,6 @@ namespace osu.Game.Rulesets.Mania.Scoring { internal class ManiaScoreProcessor : ScoreProcessor { - /// - /// The maximum score achievable. - /// Does _not_ include bonus score - for bonus score see . - /// - private const int max_score = 1000000; - - /// - /// The amount of the score attributed to combo. - /// - private const double combo_portion_max = max_score * 0.2; - - /// - /// The amount of the score attributed to accuracy. - /// - private const double accuracy_portion_max = max_score * 0.8; - - /// - /// The factor used to determine relevance of combos. - /// - private const double combo_base = 4; - - /// - /// The combo value at which hit objects result in the max score possible. - /// - private const int combo_relevance_cap = 400; - /// /// The hit HP multiplier at OD = 0. /// @@ -116,41 +90,8 @@ namespace osu.Game.Rulesets.Mania.Scoring /// private double hpMultiplier = 1; - /// - /// The cumulative combo portion of the score. - /// - private double comboScore => combo_portion_max * comboPortion / maxComboPortion; - - /// - /// The cumulative accuracy portion of the score. - /// - private double accuracyScore => accuracy_portion_max * Math.Pow(Accuracy, 4) * totalHits / maxTotalHits; - - /// - /// The cumulative bonus score. - /// This is added on top of , thus the total score can exceed . - /// - private double bonusScore; - - /// - /// The achieved by a perfect playthrough. - /// - private double maxComboPortion; - - /// - /// The portion of the score dedicated to combo. - /// - private double comboPortion; - - /// - /// The achieved by a perfect playthrough. - /// - private int maxTotalHits; - - /// - /// The total hits. - /// - private int totalHits; + protected override double ComboPortion => 0.2f; + protected override double AccuracyPortion => 0.8f; public ManiaScoreProcessor() { @@ -199,27 +140,21 @@ namespace osu.Game.Rulesets.Mania.Scoring Reset(); } - - maxTotalHits = totalHits; - maxComboPortion = comboPortion; } protected override void OnNewJudgement(Judgement judgement) { + base.OnNewJudgement(judgement); + bool isTick = judgement is HoldNoteTickJudgement; if (isTick) { if (judgement.IsHit) - { Health.Value += hpMultiplier * hp_increase_tick; - bonusScore += judgement.NumericResult; - } } else { - totalHits++; - switch (judgement.Result) { case HitResult.Miss: @@ -241,35 +176,7 @@ namespace osu.Game.Rulesets.Mania.Scoring Health.Value += hpMultiplier * hp_increase_perfect; break; } - - if (judgement.IsHit) - { - // A factor that is applied to make higher combos more relevant - double comboRelevance = Math.Min(Math.Max(0.5, Math.Log(Combo.Value, combo_base)), Math.Log(combo_relevance_cap, combo_base)); - comboPortion += judgement.NumericResult * comboRelevance; - } } - - int scoreForAccuracy = 0; - int maxScoreForAccuracy = 0; - - foreach (var j in Judgements) - { - var maniaJudgement = (ManiaJudgement)j; - - scoreForAccuracy += maniaJudgement.NumericAccuracyResult; - maxScoreForAccuracy += maniaJudgement.MaxNumericAccuracyResult; - } - - Accuracy.Value = (double)scoreForAccuracy / maxScoreForAccuracy; - TotalScore.Value = comboScore + accuracyScore + bonusScore; - } - - base.Reset(); - - bonusScore = 0; - comboPortion = 0; - totalHits = 0; } } } diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 362038baba..dcfa0aa28e 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 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.Configuration; using osu.Framework.Extensions; @@ -20,6 +19,9 @@ namespace osu.Game.Rulesets.Osu.Scoring { public readonly Bindable Mode = new Bindable(ScoringMode.Exponential); + protected override double ComboPortion => 0.7; + protected override double AccuracyPortion => 0.3; + public OsuScoreProcessor() { } @@ -31,17 +33,12 @@ namespace osu.Game.Rulesets.Osu.Scoring private float hpDrainRate; - private int totalAccurateJudgements; - private readonly Dictionary scoreResultCounts = new Dictionary(); private readonly Dictionary comboResultCounts = new Dictionary(); - private double comboMaxScore; - protected override void ComputeTargets(Beatmap beatmap) { hpDrainRate = beatmap.BeatmapInfo.Difficulty.DrainRate; - totalAccurateJudgements = beatmap.HitObjects.Count; foreach (var unused in beatmap.HitObjects) { @@ -70,6 +67,8 @@ namespace osu.Game.Rulesets.Osu.Scoring protected override void OnNewJudgement(Judgement judgement) { + base.OnNewJudgement(judgement); + var osuJudgement = (OsuJudgement)judgement; if (judgement.Result != HitResult.None) @@ -100,46 +99,6 @@ namespace osu.Game.Rulesets.Osu.Scoring Health.Value -= hpDrainRate * 0.04; break; } - - calculateScore(); - } - - private void calculateScore() - { - int baseScore = 0; - double comboScore = 0; - - int baseMaxScore = 0; - - foreach (var j in Judgements) - { - baseScore += j.NumericResult; - baseMaxScore += j.MaxNumericResult; - - comboScore += j.NumericResult * (1 + Combo.Value / 10d); - } - - Accuracy.Value = (double)baseScore / baseMaxScore; - - if (comboScore > comboMaxScore) - comboMaxScore = comboScore; - - if (baseScore == 0) - TotalScore.Value = 0; - else - { - // temporary to make scoring feel more like score v1 without being score v1. - float exponentialFactor = Mode.Value == ScoringMode.Exponential ? (float)Judgements.Count / 100 : 1; - - TotalScore.Value = - (int) - ( - exponentialFactor * - 700000 * comboScore / comboMaxScore + - 300000 * Math.Pow(Accuracy.Value, 10) * ((double)Judgements.Count / totalAccurateJudgements) + - 0 /* bonusScore */ - ); - } } public enum ScoringMode diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs index 0eb5370840..bd021a1560 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs @@ -20,10 +20,5 @@ namespace osu.Game.Rulesets.Taiko.Judgements return 200; } } - - protected override int NumericResultForAccuracy(HitResult result) - { - return 0; - } } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs index 9d6b5ca535..a3cc228c20 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs @@ -8,19 +8,8 @@ namespace osu.Game.Rulesets.Taiko.Judgements { public class TaikoJudgement : Judgement { - /// - /// The result value for the accuracy portion of the score. - /// - public int ResultNumericForAccuracy => Result == HitResult.Miss ? 0 : NumericResultForAccuracy(Result); - - /// - /// The maximum result value for the accuracy portion of the score. - /// - public int MaxResultValueForAccuracy => NumericResultForAccuracy(HitResult.Great); - /// /// Computes the numeric result value for the combo portion of the score. - /// For the accuracy portion of the score (including accuracy percentage), see . /// /// The result to compute the value for. /// The numeric result value. @@ -36,24 +25,5 @@ namespace osu.Game.Rulesets.Taiko.Judgements return 300; } } - - /// - /// Computes the numeric result value for the accuracy portion of the score. - /// For the combo portion of the score, see . - /// - /// The result to compute the value for. - /// The numeric result value. - protected virtual int NumericResultForAccuracy(HitResult result) - { - switch (result) - { - default: - return 0; - case HitResult.Good: - return 150; - case HitResult.Great: - return 300; - } - } } } diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index 21d790169c..18625df508 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -15,27 +15,6 @@ namespace osu.Game.Rulesets.Taiko.Scoring { internal class TaikoScoreProcessor : ScoreProcessor { - /// - /// The maximum score achievable. - /// Does _not_ include bonus score - for bonus score see . - /// - private const int max_score = 1000000; - - /// - /// The amount of the score attributed to combo. - /// - private const double combo_portion_max = max_score * 0.2; - - /// - /// The amount of the score attributed to accuracy. - /// - private const double accuracy_portion_max = max_score * 0.8; - - /// - /// The factor used to determine relevance of combos. - /// - private const double combo_base = 4; - /// /// The HP awarded by a hit. /// @@ -76,40 +55,16 @@ namespace osu.Game.Rulesets.Taiko.Scoring /// /// Taiko fails at the end of the map if the player has not half-filled their HP bar. /// - public override bool HasFailed => totalHits == maxTotalHits && Health.Value <= 0.5; + public override bool HasFailed => Hits == MaxHits && Health.Value <= 0.5; - /// - /// The cumulative combo portion of the score. - /// - private double comboScore => combo_portion_max * comboPortion / maxComboPortion; - - /// - /// The cumulative accuracy portion of the score. - /// - private double accuracyScore => accuracy_portion_max * Math.Pow(Accuracy, 3.6) * totalHits / maxTotalHits; - - /// - /// The cumulative bonus score. - /// This is added on top of , thus the total score can exceed . - /// - private double bonusScore; - - /// - /// The multiple of the original score added to the combo portion of the score - /// for correctly hitting a strong hit object with both keys. - /// - private double strongHitScale; + protected override double ComboPortion => 0.2; + protected override double AccuracyPortion => 0.8; private double hpIncreaseTick; private double hpIncreaseGreat; private double hpIncreaseGood; private double hpIncreaseMiss; - private double maxComboPortion; - private double comboPortion; - private int maxTotalHits; - private int totalHits; - public TaikoScoreProcessor() { } @@ -128,13 +83,6 @@ namespace osu.Game.Rulesets.Taiko.Scoring hpIncreaseGood = hpMultiplierNormal * hp_hit_good; hpIncreaseMiss = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.Difficulty.DrainRate, hp_miss_min, hp_miss_mid, hp_miss_max); - var strongHits = beatmap.HitObjects.FindAll(o => o is Hit && o.IsStrong); - - // This is a linear function that awards: - // 10 times bonus points for hitting a strong hit object with both keys with 30 strong hit objects in the map - // 3 times bonus points for hitting a strong hit object with both keys with 120 strong hit objects in the map - strongHitScale = -7d / 90d * MathHelper.Clamp(strongHits.Count, 30, 120) + 111d / 9d; - foreach (var obj in beatmap.HitObjects) { if (obj is Hit) @@ -163,46 +111,14 @@ namespace osu.Game.Rulesets.Taiko.Scoring AddJudgement(new TaikoJudgement { Result = HitResult.Great }); } } - - maxTotalHits = totalHits; - maxComboPortion = comboPortion; } protected override void OnNewJudgement(Judgement judgement) { - bool isStrong = judgement is TaikoStrongHitJudgement; + base.OnNewJudgement(judgement); + bool isTick = judgement is TaikoDrumRollTickJudgement; - // Don't consider ticks and strong hits as a type of hit that counts towards map completion - if (!isTick && !isStrong) - totalHits++; - - // Apply score changes - if (judgement.IsHit) - { - double baseValue = judgement.NumericResult; - - if (isStrong) - { - // Add increased score for the previous judgement by hitting a strong hit object with the second key - var prevJudgement = Judgements[Judgements.Count - 1]; - baseValue = prevJudgement.NumericResult * strongHitScale; - - } - - // Add score to portions - if (judgement is TaikoDrumRollTickJudgement) - bonusScore += baseValue; - else - { - // A relevance factor that needs to be applied to make higher combos more relevant - // Value is capped at 400 combo - double comboRelevance = Math.Min(Math.Log(400, combo_base), Math.Max(0.5, Math.Log(Combo.Value, combo_base))); - - comboPortion += baseValue * comboRelevance; - } - } - // Apply HP changes switch (judgement.Result) { @@ -221,20 +137,6 @@ namespace osu.Game.Rulesets.Taiko.Scoring Health.Value += hpIncreaseGreat; break; } - - int scoreForAccuracy = 0; - int maxScoreForAccuracy = 0; - - foreach (var j in Judgements) - { - var taikoJudgement = (TaikoJudgement)j; - - scoreForAccuracy += taikoJudgement.ResultNumericForAccuracy; - maxScoreForAccuracy += taikoJudgement.MaxResultValueForAccuracy; - } - - Accuracy.Value = (double)scoreForAccuracy / maxScoreForAccuracy; - TotalScore.Value = comboScore + accuracyScore + bonusScore; } protected override void Reset() @@ -242,10 +144,6 @@ namespace osu.Game.Rulesets.Taiko.Scoring base.Reset(); Health.Value = 0; - - bonusScore = 0; - comboPortion = 0; - totalHits = 0; } } } diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 2e76f9a135..213b92486a 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -138,15 +138,21 @@ namespace osu.Game.Rulesets.Scoring public abstract class ScoreProcessor : ScoreProcessor where TObject : HitObject { + private const double max_score = 1000000; + /// /// All judgements held by this ScoreProcessor. /// protected readonly List Judgements = new List(); - private int maxHits; - private int maxCombo; + protected virtual double ComboPortion => 0.5f; + protected virtual double AccuracyPortion => 0.5f; - private int hits; + protected int MaxHits { get; private set; } + protected int Hits { get; private set; } + + private double maxComboScore; + private double comboScore; protected ScoreProcessor() { @@ -160,8 +166,8 @@ namespace osu.Game.Rulesets.Scoring ComputeTargets(rulesetContainer.Beatmap); - maxCombo = HighestCombo; - maxHits = hits; + maxComboScore = comboScore; + MaxHits = Hits; Reset(); } @@ -191,28 +197,53 @@ namespace osu.Game.Rulesets.Scoring } } - if (judgement.AffectsCombo && judgement.IsHit) - hits++; - Judgements.Add(judgement); OnNewJudgement(judgement); - NotifyNewJudgement(judgement); UpdateFailed(); } + protected virtual void OnNewJudgement(Judgement judgement) + { + double bonusScore = 0; + + if (judgement.AffectsCombo) + { + switch (judgement.Result) + { + case HitResult.None: + break; + case HitResult.Miss: + Combo.Value = 0; + break; + default: + Combo.Value++; + break; + } + + comboScore += judgement.NumericResult; + } + else if (judgement.IsHit) + bonusScore += judgement.NumericResult; + + if (judgement.AffectsAccuracy && judgement.IsHit) + Hits++; + + TotalScore.Value = + max_score * (ComboPortion * comboScore / maxComboScore + + AccuracyPortion * Hits / MaxHits) + + bonusScore; + } + protected override void Reset() { base.Reset(); Judgements.Clear(); - } - /// - /// Updates any values that need post-processing. Invoked when a new judgement has occurred. - /// - /// The judgement that triggered this calculation. - protected abstract void OnNewJudgement(Judgement judgement); + Hits = 0; + comboScore = 0; + } } } From 3e3618d7242a4f7f859efe8a1242d593332e067f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 21:12:57 +0900 Subject: [PATCH 424/483] More cleanups --- .../Scoring/CatchScoreProcessor.cs | 6 ------ .../Scoring/ManiaScoreProcessor.cs | 1 - .../Scoring/TaikoScoreProcessor.cs | 2 -- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 15 ++------------- 4 files changed, 2 insertions(+), 22 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index cd2a81038a..11e95622ca 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Rulesets.Catch.Objects; -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; @@ -18,10 +17,5 @@ namespace osu.Game.Rulesets.Catch.Scoring : base(rulesetContainer) { } - - protected override void OnNewJudgement(Judgement judgement) - { - base.OnNewJudgement(judgement); - } } } diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 06ba82205d..92e661203d 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using System.Linq; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index 18625df508..a629dae9fa 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; @@ -9,7 +8,6 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.UI; -using OpenTK; namespace osu.Game.Rulesets.Taiko.Scoring { diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 213b92486a..43fdd99fa5 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; using osu.Framework.Configuration; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; @@ -140,18 +139,13 @@ namespace osu.Game.Rulesets.Scoring { private const double max_score = 1000000; - /// - /// All judgements held by this ScoreProcessor. - /// - protected readonly List Judgements = new List(); - protected virtual double ComboPortion => 0.5f; protected virtual double AccuracyPortion => 0.5f; - protected int MaxHits { get; private set; } + protected readonly int MaxHits; protected int Hits { get; private set; } - private double maxComboScore; + private readonly double maxComboScore; private double comboScore; protected ScoreProcessor() @@ -160,8 +154,6 @@ namespace osu.Game.Rulesets.Scoring protected ScoreProcessor(RulesetContainer rulesetContainer) { - Judgements.Capacity = rulesetContainer.Beatmap.HitObjects.Count; - rulesetContainer.OnJudgement += AddJudgement; ComputeTargets(rulesetContainer.Beatmap); @@ -197,7 +189,6 @@ namespace osu.Game.Rulesets.Scoring } } - Judgements.Add(judgement); OnNewJudgement(judgement); NotifyNewJudgement(judgement); @@ -240,8 +231,6 @@ namespace osu.Game.Rulesets.Scoring { base.Reset(); - Judgements.Clear(); - Hits = 0; comboScore = 0; } From d0774c7bc657090fa60b142680b43dd7478efbac Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 21:16:47 +0900 Subject: [PATCH 425/483] ComputeTargets -> SimulateAutoplay + improve xmldoc --- osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs | 2 +- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 2 +- osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs | 2 +- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 9 +++++---- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 92e661203d..41e2de5f39 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -101,7 +101,7 @@ namespace osu.Game.Rulesets.Mania.Scoring { } - protected override void ComputeTargets(Beatmap beatmap) + protected override void SimulateAutoplay(Beatmap beatmap) { BeatmapDifficulty difficulty = beatmap.BeatmapInfo.Difficulty; hpMultiplier = BeatmapDifficulty.DifficultyRange(difficulty.DrainRate, hp_multiplier_min, hp_multiplier_mid, hp_multiplier_max); diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index dcfa0aa28e..84c8c50dd4 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Scoring private readonly Dictionary scoreResultCounts = new Dictionary(); private readonly Dictionary comboResultCounts = new Dictionary(); - protected override void ComputeTargets(Beatmap beatmap) + protected override void SimulateAutoplay(Beatmap beatmap) { hpDrainRate = beatmap.BeatmapInfo.Difficulty.DrainRate; diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index a629dae9fa..7b0bdeea13 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring { } - protected override void ComputeTargets(Beatmap beatmap) + protected override void SimulateAutoplay(Beatmap beatmap) { double hpMultiplierNormal = 1 / (hp_hit_great * beatmap.HitObjects.FindAll(o => o is Hit).Count * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.Difficulty.DrainRate, 0.5, 0.75, 0.98)); diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 43fdd99fa5..b1859195ef 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -156,7 +156,7 @@ namespace osu.Game.Rulesets.Scoring { rulesetContainer.OnJudgement += AddJudgement; - ComputeTargets(rulesetContainer.Beatmap); + SimulateAutoplay(rulesetContainer.Beatmap); maxComboScore = comboScore; MaxHits = Hits; @@ -165,10 +165,11 @@ namespace osu.Game.Rulesets.Scoring } /// - /// Computes target scoring values for this ScoreProcessor. This is equivalent to performing an auto-play of the score to find the values. + /// Simulates an autoplay of s that will be judged by this + /// by adding s for each in the . /// - /// The Beatmap containing the objects that will be judged by this ScoreProcessor. - protected virtual void ComputeTargets(Beatmap beatmap) { } + /// The containing the s that will be judged by this . + protected virtual void SimulateAutoplay(Beatmap beatmap) { } /// /// Adds a judgement to this ScoreProcessor. From cc6bb81a73dee2bcfa448a634897635694ab10c7 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 21:46:54 +0900 Subject: [PATCH 426/483] Reimplement Exponential scoring with a simpler and more intuitive calculation Default for all rulesets for now. --- .../Scoring/OsuScoreProcessor.cs | 8 ------- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 22 +++++++++++++++---- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 84c8c50dd4..2c941bf13a 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -17,8 +17,6 @@ namespace osu.Game.Rulesets.Osu.Scoring { internal class OsuScoreProcessor : ScoreProcessor { - public readonly Bindable Mode = new Bindable(ScoringMode.Exponential); - protected override double ComboPortion => 0.7; protected override double AccuracyPortion => 0.3; @@ -100,11 +98,5 @@ namespace osu.Game.Rulesets.Osu.Scoring break; } } - - public enum ScoringMode - { - Standardised, - Exponential - } } } diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index b1859195ef..b12f730511 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -139,6 +139,8 @@ namespace osu.Game.Rulesets.Scoring { private const double max_score = 1000000; + public readonly Bindable Mode = new Bindable(ScoringMode.Exponential); + protected virtual double ComboPortion => 0.5f; protected virtual double AccuracyPortion => 0.5f; @@ -222,10 +224,16 @@ namespace osu.Game.Rulesets.Scoring if (judgement.AffectsAccuracy && judgement.IsHit) Hits++; - TotalScore.Value = - max_score * (ComboPortion * comboScore / maxComboScore - + AccuracyPortion * Hits / MaxHits) - + bonusScore; + switch (Mode.Value) + { + case ScoringMode.Standardised: + TotalScore.Value = + max_score * (ComboPortion * comboScore / maxComboScore + AccuracyPortion * Hits / MaxHits) + bonusScore; + break; + case ScoringMode.Exponential: + TotalScore.Value = (comboScore + bonusScore) * Math.Log(HighestCombo + 1, 2); + break; + } } protected override void Reset() @@ -236,4 +244,10 @@ namespace osu.Game.Rulesets.Scoring comboScore = 0; } } + + public enum ScoringMode + { + Standardised, + Exponential + } } From 2e0218f388c14f9083a9afbc6bdb8bee218f9921 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 22:01:08 +0900 Subject: [PATCH 427/483] Move AllObjectsJudged into ScoreProcessor as AllJudged Changes to OsuScoreProcessor were required to make sure that ticks and slider heads weren't ignored. --- .../Scoring/OsuScoreProcessor.cs | 15 ++++++++++++--- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 18 +++++++++++++++++- osu.Game/Rulesets/UI/RulesetContainer.cs | 15 --------------- osu.Game/Screens/Play/Player.cs | 6 ++---- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 2c941bf13a..32cd53f3a2 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using osu.Framework.Configuration; using osu.Framework.Extensions; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; @@ -38,9 +37,19 @@ namespace osu.Game.Rulesets.Osu.Scoring { hpDrainRate = beatmap.BeatmapInfo.Difficulty.DrainRate; - foreach (var unused in beatmap.HitObjects) + foreach (var obj in beatmap.HitObjects) { - // TODO: add support for other object types. + var slider = obj as Slider; + if (slider != null) + { + // Head + AddJudgement(new OsuJudgement { Result = HitResult.Great }); + + // Ticks + foreach (var tick in slider.Ticks) + AddJudgement(new OsuJudgement { Result = HitResult.Great }); + } + AddJudgement(new OsuJudgement { Result = HitResult.Great }); } } diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index b12f730511..be468f84b4 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -14,11 +14,17 @@ namespace osu.Game.Rulesets.Scoring public abstract class ScoreProcessor { /// - /// Invoked when the ScoreProcessor is in a failed state. + /// Invoked when the is in a failed state. + /// This may occur regardless of whether an event is invoked. /// Return true if the fail was permitted. /// public event Func Failed; + /// + /// Invoked when all s have been judged. + /// + public event Action AllJudged; + /// /// Invoked when a new judgement has occurred. This occurs after the judgement has been processed by the . /// @@ -49,6 +55,11 @@ namespace osu.Game.Rulesets.Scoring /// public readonly BindableInt HighestCombo = new BindableInt(); + /// + /// Whether all s have been processed. + /// + protected virtual bool HasCompleted => false; + /// /// Whether the score is in a failed state. /// @@ -117,6 +128,9 @@ namespace osu.Game.Rulesets.Scoring protected void NotifyNewJudgement(Judgement judgement) { NewJudgement?.Invoke(judgement); + + if (HasCompleted) + AllJudged?.Invoke(); } /// @@ -141,6 +155,8 @@ namespace osu.Game.Rulesets.Scoring public readonly Bindable Mode = new Bindable(ScoringMode.Exponential); + protected sealed override bool HasCompleted => Hits == MaxHits; + protected virtual double ComboPortion => 0.5f; protected virtual double AccuracyPortion => 0.5f; diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index f7ece531c3..767bb94f8d 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -29,11 +29,6 @@ namespace osu.Game.Rulesets.UI /// public abstract class RulesetContainer : Container { - /// - /// Invoked when all the judgeable HitObjects have been judged. - /// - public event Action OnAllJudged; - /// /// Whether to apply adjustments to the child based on our own size. /// @@ -77,15 +72,6 @@ namespace osu.Game.Rulesets.UI Ruleset = ruleset; } - /// - /// Checks whether all HitObjects have been judged, and invokes OnAllJudged. - /// - protected void CheckAllJudged() - { - if (AllObjectsJudged) - OnAllJudged?.Invoke(); - } - public abstract ScoreProcessor CreateScoreProcessor(); /// @@ -263,7 +249,6 @@ namespace osu.Game.Rulesets.UI { Playfield.OnJudgement(d, j); OnJudgement?.Invoke(j); - CheckAllJudged(); }; drawableObjects.Add(drawableObject); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 615e04d6c2..593abb7d26 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -206,10 +206,8 @@ namespace osu.Game.Screens.Play hudOverlay.ModDisplay.Current.BindTo(working.Mods); - //bind RulesetContainer to ScoreProcessor and ourselves (for a pass situation) - RulesetContainer.OnAllJudged += onCompletion; - - //bind ScoreProcessor to ourselves (for a fail situation) + // Bind ScoreProcessor to ourselves + scoreProcessor.AllJudged += onCompletion; scoreProcessor.Failed += onFail; } From b5f48c2368091420df894168b68af1311fbef8e0 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 22:27:27 +0900 Subject: [PATCH 428/483] Add storeResults as a parameter to Reset Whether to store the current state of the ScoreProcessor for future use. --- .../Scoring/ManiaScoreProcessor.cs | 12 +++------ .../Scoring/OsuScoreProcessor.cs | 6 ++--- .../Scoring/TaikoScoreProcessor.cs | 4 +-- osu.Game/Rulesets/Judgements/Judgement.cs | 7 +++++ osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 27 ++++++++++--------- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 41e2de5f39..ff9dcdc682 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -113,11 +113,7 @@ namespace osu.Game.Rulesets.Mania.Scoring { var holdNote = obj as HoldNote; - if (obj is Note) - { - AddJudgement(new ManiaJudgement { Result = HitResult.Perfect }); - } - else if (holdNote != null) + if (holdNote != null) { // Head AddJudgement(new ManiaJudgement { Result = HitResult.Perfect }); @@ -126,9 +122,9 @@ namespace osu.Game.Rulesets.Mania.Scoring int tickCount = holdNote.Ticks.Count(); for (int i = 0; i < tickCount; i++) AddJudgement(new HoldNoteTickJudgement { Result = HitResult.Perfect }); - - AddJudgement(new HoldNoteTailJudgement { Result = HitResult.Perfect }); } + + AddJudgement(new ManiaJudgement { Result = HitResult.Perfect }); } if (!HasFailed) @@ -137,7 +133,7 @@ namespace osu.Game.Rulesets.Mania.Scoring hpMultiplier *= 1.01; hpMissMultiplier *= 0.98; - Reset(); + Reset(false); } } diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 32cd53f3a2..da474dac65 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Scoring AddJudgement(new OsuJudgement { Result = HitResult.Great }); // Ticks - foreach (var tick in slider.Ticks) + foreach (var unused in slider.Ticks) AddJudgement(new OsuJudgement { Result = HitResult.Great }); } @@ -54,9 +54,9 @@ namespace osu.Game.Rulesets.Osu.Scoring } } - protected override void Reset() + protected override void Reset(bool storeResults) { - base.Reset(); + base.Reset(storeResults); scoreResultCounts.Clear(); comboResultCounts.Clear(); diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index 7b0bdeea13..f31cd2d634 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -137,9 +137,9 @@ namespace osu.Game.Rulesets.Taiko.Scoring } } - protected override void Reset() + protected override void Reset(bool storeResults) { - base.Reset(); + base.Reset(storeResults); Health.Value = 0; } diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index 40cc643f60..71743b9988 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -25,8 +25,15 @@ namespace osu.Game.Rulesets.Judgements /// public double TimeOffset { get; internal set; } + /// + /// Whether the should be considered as a factor in the accuracy percentage and portion. + /// public virtual bool AffectsAccuracy => true; + /// + /// Whether the should affect the combo portion of the score. + /// If false, the will be considered for the bonus portion of the score. + /// public virtual bool AffectsCombo => true; /// diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index be468f84b4..9f46d7da8f 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -73,8 +73,6 @@ namespace osu.Game.Rulesets.Scoring protected ScoreProcessor() { Combo.ValueChanged += delegate { HighestCombo.Value = Math.Max(HighestCombo.Value, Combo.Value); }; - - Reset(); } private ScoreRank rankFrom(double acc) @@ -95,7 +93,8 @@ namespace osu.Game.Rulesets.Scoring /// /// Resets this ScoreProcessor to a default state. /// - protected virtual void Reset() + /// Whether to store the current state of the for future use. + protected virtual void Reset(bool storeResults) { TotalScore.Value = 0; Accuracy.Value = 1; @@ -160,10 +159,11 @@ namespace osu.Game.Rulesets.Scoring protected virtual double ComboPortion => 0.5f; protected virtual double AccuracyPortion => 0.5f; - protected readonly int MaxHits; + protected int MaxHits { get; private set; } protected int Hits { get; private set; } - private readonly double maxComboScore; + private double maxHighestCombo; + private double maxComboScore; private double comboScore; protected ScoreProcessor() @@ -175,11 +175,7 @@ namespace osu.Game.Rulesets.Scoring rulesetContainer.OnJudgement += AddJudgement; SimulateAutoplay(rulesetContainer.Beatmap); - - maxComboScore = comboScore; - MaxHits = Hits; - - Reset(); + Reset(true); } /// @@ -252,9 +248,16 @@ namespace osu.Game.Rulesets.Scoring } } - protected override void Reset() + protected override void Reset(bool storeResults) { - base.Reset(); + if (storeResults) + { + maxHighestCombo = HighestCombo; + maxComboScore = comboScore; + MaxHits = Hits; + } + + base.Reset(storeResults); Hits = 0; comboScore = 0; From dc9b47559af46d5480fcf1a069da5978a51209c0 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 22:28:10 +0900 Subject: [PATCH 429/483] Multiply standardised combos by the HighestCombo to make higher combos matter more --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 9f46d7da8f..4b11435e23 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -240,7 +240,10 @@ namespace osu.Game.Rulesets.Scoring { case ScoringMode.Standardised: TotalScore.Value = - max_score * (ComboPortion * comboScore / maxComboScore + AccuracyPortion * Hits / MaxHits) + bonusScore; + max_score * + (ComboPortion * (comboScore * Math.Log(HighestCombo + 1, 2)) / (maxComboScore * Math.Log(maxHighestCombo + 1, 2)) + + AccuracyPortion * Hits / MaxHits) + + bonusScore; break; case ScoringMode.Exponential: TotalScore.Value = (comboScore + bonusScore) * Math.Log(HighestCombo + 1, 2); From 89cb38386c6414478f08522411f6bf4bb03d6d7f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 22:28:16 +0900 Subject: [PATCH 430/483] Set accuracy --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 4b11435e23..412f778f7b 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -249,6 +249,8 @@ namespace osu.Game.Rulesets.Scoring TotalScore.Value = (comboScore + bonusScore) * Math.Log(HighestCombo + 1, 2); break; } + + Accuracy.Value = (double)Hits / MaxHits; } protected override void Reset(bool storeResults) From 4269533babfe1384f1a08da28d938a8c01029bbb Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 22:29:44 +0900 Subject: [PATCH 431/483] Remove remaining AllObjectsJudged in RulesetContainer --- osu.Game/Rulesets/UI/RulesetContainer.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 767bb94f8d..207ae647b9 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -56,11 +56,6 @@ namespace osu.Game.Rulesets.UI public abstract IEnumerable Objects { get; } - /// - /// Whether all the HitObjects have been judged. - /// - protected abstract bool AllObjectsJudged { get; } - protected readonly Ruleset Ruleset; /// @@ -138,8 +133,6 @@ namespace osu.Game.Rulesets.UI public sealed override bool ProvidingUserCursor => !HasReplayLoaded && Playfield.ProvidingUserCursor; - protected override bool AllObjectsJudged => drawableObjects.All(h => h.AllJudged); - /// /// The playfield. /// @@ -148,8 +141,6 @@ namespace osu.Game.Rulesets.UI protected override Container Content => content; private Container content; - private readonly List> drawableObjects = new List>(); - /// /// Whether to assume the beatmap passed into this is for the current ruleset. /// Creates a hit renderer for a beatmap. @@ -236,8 +227,6 @@ namespace osu.Game.Rulesets.UI /// private void loadObjects() { - drawableObjects.Capacity = Beatmap.HitObjects.Count; - foreach (TObject h in Beatmap.HitObjects) { var drawableObject = GetVisualRepresentation(h); @@ -251,8 +240,6 @@ namespace osu.Game.Rulesets.UI OnJudgement?.Invoke(j); }; - drawableObjects.Add(drawableObject); - Playfield.Add(drawableObject); } Playfield.PostProcess(); From 756d7527dafbf41b350b45934e298d8c890421da Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 22:33:39 +0900 Subject: [PATCH 432/483] Remove NumericAccuracyResult from ManiaJudgement --- .../Judgements/HoldNoteTailJudgement.cs | 12 -------- .../Judgements/HoldNoteTickJudgement.cs | 1 - .../Judgements/ManiaJudgement.cs | 29 ------------------- 3 files changed, 42 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTailJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTailJudgement.cs index cc7aa63f7e..a8d1b079eb 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTailJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTailJudgement.cs @@ -23,17 +23,5 @@ namespace osu.Game.Rulesets.Mania.Judgements return base.NumericResultFor(HasBroken ? HitResult.Good : result); } } - - protected override int NumericResultForAccuracy(HitResult result) - { - switch (result) - { - default: - return base.NumericResultForAccuracy(result); - case HitResult.Great: - case HitResult.Perfect: - return base.NumericResultForAccuracy(HasBroken ? HitResult.Good : result); - } - } } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs index 132856713a..46e6f0feec 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs @@ -11,6 +11,5 @@ namespace osu.Game.Rulesets.Mania.Judgements public override bool AffectsAccuracy => false; protected override int NumericResultFor(HitResult result) => 20; - protected override int NumericResultForAccuracy(HitResult result) => 0; // Don't count ticks into accuracy } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs index e36146aa71..1f3b352da4 100644 --- a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs @@ -8,11 +8,6 @@ namespace osu.Game.Rulesets.Mania.Judgements { public class ManiaJudgement : Judgement { - /// - /// The maximum result value for the accuracy portion of the score. - /// - public int MaxNumericAccuracyResult => NumericResultForAccuracy(HitResult.Perfect); - protected override int NumericResultFor(HitResult result) { switch (result) @@ -30,29 +25,5 @@ namespace osu.Game.Rulesets.Mania.Judgements return 300; } } - - public int NumericAccuracyResult => NumericResultForAccuracy(Result); - - /// - /// The result value for the accuracy portion of the score. - /// - protected virtual int NumericResultForAccuracy(HitResult result) - { - switch (result) - { - default: - return 0; - case HitResult.Meh: - return 50; - case HitResult.Ok: - return 100; - case HitResult.Good: - return 200; - case HitResult.Great: - return 300; - case HitResult.Perfect: - return 305; - } - } } } From ba4f81d022ebff3836f5594d97b2715dfaa6175d Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 23:30:15 +0900 Subject: [PATCH 433/483] Woops, fix incorrectly deleted line --- osu.Game/Rulesets/UI/RulesetContainer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 207ae647b9..cff3365788 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -240,6 +240,7 @@ namespace osu.Game.Rulesets.UI OnJudgement?.Invoke(j); }; + Playfield.Add(drawableObject); } Playfield.PostProcess(); From 12641edb4dbbfa0cbb4b6aa6a3808f472a68f751 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 23:36:51 +0900 Subject: [PATCH 434/483] Fix incorrect mania hold note tick judgements --- .../Objects/Drawables/DrawableHoldNoteTick.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 49bca6d1d7..324f4e4e99 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -78,8 +78,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables } } - protected ManiaJudgement CreateJudgement() => new HoldNoteTickJudgement(); - protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (!userTriggered) @@ -91,7 +89,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (HoldStartTime?.Invoke() > HitObject.StartTime) return; - AddJudgement(new ManiaJudgement { Result = HitResult.Perfect }); + AddJudgement(new HoldNoteTickJudgement { Result = HitResult.Perfect }); } protected override void UpdateState(ArmedState state) From 7dd79f5a0beebd0995f53ebc8fc35618bc131977 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 12 Sep 2017 23:42:58 +0900 Subject: [PATCH 435/483] Fix incorrect accuracy calculation --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 412f778f7b..ed0b0bfdd0 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -162,6 +162,9 @@ namespace osu.Game.Rulesets.Scoring protected int MaxHits { get; private set; } protected int Hits { get; private set; } + private int maxAccurateHits; + private int accurateHits; + private double maxHighestCombo; private double maxComboScore; private double comboScore; @@ -233,8 +236,12 @@ namespace osu.Game.Rulesets.Scoring else if (judgement.IsHit) bonusScore += judgement.NumericResult; - if (judgement.AffectsAccuracy && judgement.IsHit) + if (judgement.AffectsAccuracy) + { Hits++; + if (judgement.IsHit) + accurateHits++; + } switch (Mode.Value) { @@ -242,7 +249,7 @@ namespace osu.Game.Rulesets.Scoring TotalScore.Value = max_score * (ComboPortion * (comboScore * Math.Log(HighestCombo + 1, 2)) / (maxComboScore * Math.Log(maxHighestCombo + 1, 2)) - + AccuracyPortion * Hits / MaxHits) + + AccuracyPortion * accurateHits / maxAccurateHits) + bonusScore; break; case ScoringMode.Exponential: @@ -250,21 +257,23 @@ namespace osu.Game.Rulesets.Scoring break; } - Accuracy.Value = (double)Hits / MaxHits; + Accuracy.Value = (double)accurateHits / Hits; } protected override void Reset(bool storeResults) { if (storeResults) { + MaxHits = Hits; + maxAccurateHits = accurateHits; maxHighestCombo = HighestCombo; maxComboScore = comboScore; - MaxHits = Hits; } base.Reset(storeResults); Hits = 0; + accurateHits = 0; comboScore = 0; } } From 2a45451308b67be0c44d1b470b5b5971aced8433 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 00:19:17 +0900 Subject: [PATCH 436/483] Fix combo duplication. --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index ed0b0bfdd0..2f8459b527 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -194,19 +194,6 @@ namespace osu.Game.Rulesets.Scoring /// The judgement to add. protected void AddJudgement(Judgement judgement) { - if (judgement.AffectsCombo) - { - switch (judgement.Result) - { - case HitResult.Miss: - Combo.Value = 0; - break; - default: - Combo.Value++; - break; - } - } - OnNewJudgement(judgement); NotifyNewJudgement(judgement); From 7b44ad300fc7d34500b26330d508eb019e8f9166 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 00:33:01 +0900 Subject: [PATCH 437/483] Remove accurateHits, make Accuracy once again tied to comboScore --- .../Judgements/OsuJudgement.cs | 2 ++ .../Judgements/TaikoJudgement.cs | 2 ++ osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 18 ++++++------------ 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs b/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs index 3ccf1cd60c..28b6a04376 100644 --- a/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs +++ b/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs @@ -10,6 +10,8 @@ namespace osu.Game.Rulesets.Osu.Judgements { public class OsuJudgement : Judgement { + public override HitResult MaxResult => HitResult.Great; + /// /// The positional hit offset. /// diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs index a3cc228c20..3cd134f3f7 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs @@ -8,6 +8,8 @@ namespace osu.Game.Rulesets.Taiko.Judgements { public class TaikoJudgement : Judgement { + public override HitResult MaxResult => HitResult.Great; + /// /// Computes the numeric result value for the combo portion of the score. /// diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 2f8459b527..5d31ee9729 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -162,11 +162,9 @@ namespace osu.Game.Rulesets.Scoring protected int MaxHits { get; private set; } protected int Hits { get; private set; } - private int maxAccurateHits; - private int accurateHits; - private double maxHighestCombo; private double maxComboScore; + private double rollingMaxComboScore; private double comboScore; protected ScoreProcessor() @@ -219,16 +217,15 @@ namespace osu.Game.Rulesets.Scoring } comboScore += judgement.NumericResult; + rollingMaxComboScore += judgement.MaxNumericResult; } else if (judgement.IsHit) bonusScore += judgement.NumericResult; if (judgement.AffectsAccuracy) - { Hits++; - if (judgement.IsHit) - accurateHits++; - } + + Accuracy.Value = comboScore / rollingMaxComboScore; switch (Mode.Value) { @@ -236,15 +233,13 @@ namespace osu.Game.Rulesets.Scoring TotalScore.Value = max_score * (ComboPortion * (comboScore * Math.Log(HighestCombo + 1, 2)) / (maxComboScore * Math.Log(maxHighestCombo + 1, 2)) - + AccuracyPortion * accurateHits / maxAccurateHits) + + AccuracyPortion * Accuracy) + bonusScore; break; case ScoringMode.Exponential: TotalScore.Value = (comboScore + bonusScore) * Math.Log(HighestCombo + 1, 2); break; } - - Accuracy.Value = (double)accurateHits / Hits; } protected override void Reset(bool storeResults) @@ -252,7 +247,6 @@ namespace osu.Game.Rulesets.Scoring if (storeResults) { MaxHits = Hits; - maxAccurateHits = accurateHits; maxHighestCombo = HighestCombo; maxComboScore = comboScore; } @@ -260,8 +254,8 @@ namespace osu.Game.Rulesets.Scoring base.Reset(storeResults); Hits = 0; - accurateHits = 0; comboScore = 0; + rollingMaxComboScore = 0; } } From 3386dbb243425e1ee02bf42acf6bf6e03f5495b5 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 00:37:18 +0900 Subject: [PATCH 438/483] Fix incorrect HitResult for slider ticks. --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index b088359fbf..53b3427fc4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void CheckForJudgements(bool userTriggered, double timeOffset) { if (timeOffset >= 0) - AddJudgement(new OsuJudgement { Result = Tracking ? HitResult.Perfect : HitResult.Miss }); + AddJudgement(new OsuJudgement { Result = Tracking ? HitResult.Great : HitResult.Miss }); } protected override void UpdatePreemptState() From 3619f7c1ebc926f9b59fc79607aa46cb2c980106 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 00:38:52 +0900 Subject: [PATCH 439/483] Fix possible NaN accuracy --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 5d31ee9729..448cb56e0c 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -225,7 +225,8 @@ namespace osu.Game.Rulesets.Scoring if (judgement.AffectsAccuracy) Hits++; - Accuracy.Value = comboScore / rollingMaxComboScore; + if (rollingMaxComboScore != 0) + Accuracy.Value = comboScore / rollingMaxComboScore; switch (Mode.Value) { From 7b30fc8a09470611d7d60f17873ae4eae1f5b940 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 00:43:30 +0900 Subject: [PATCH 440/483] Fix osu! slider initial circles being placed at the wrong depth. --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 7cb06df679..8cef7de948 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Scale = s.Scale, ComboColour = s.ComboColour, Samples = s.Samples, - }), + }) { Depth = 0 }, }; components.Add(body); From c78695cfe099eeba646df22f9b22eb6440238f86 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Tue, 12 Sep 2017 18:26:52 +0200 Subject: [PATCH 441/483] Removed redundant call --- osu.Game/Overlays/ChatOverlay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index af5c6d9916..c682724d35 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -181,7 +181,6 @@ namespace osu.Game.Overlays { chatContainer.ResizeHeightTo(1f - channel_selection_min_height, 800, Easing.OutQuint); channelSelectionContainer.ResizeHeightTo(channel_selection_min_height, 800, Easing.OutQuint); - channelSelection.Show(); chatHeight.Value = 1f - channel_selection_min_height; } } From 9839a3b937e17dbe041b5acc878b0f84d8713eeb Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Tue, 12 Sep 2017 18:47:21 +0200 Subject: [PATCH 442/483] Smoothly transform the chat height when opening the channel selection --- osu.Game/Overlays/ChatOverlay.cs | 45 ++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index c682724d35..7c28bdea4d 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -12,8 +12,10 @@ 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; @@ -56,7 +58,7 @@ namespace osu.Game.Overlays private readonly Box chatBackground; private readonly Box tabBackground; - private Bindable chatHeight; + public Bindable ChatHeight { get; internal set; } private readonly Container channelSelectionContainer; private readonly ChannelSelectionOverlay channelSelection; @@ -177,17 +179,11 @@ namespace osu.Game.Overlays if (state == Visibility.Visible) { textbox.HoldFocus = false; - if (1f - chatHeight.Value < channel_selection_min_height) - { - chatContainer.ResizeHeightTo(1f - channel_selection_min_height, 800, Easing.OutQuint); - channelSelectionContainer.ResizeHeightTo(channel_selection_min_height, 800, Easing.OutQuint); - chatHeight.Value = 1f - channel_selection_min_height; - } + if (1f - ChatHeight.Value < channel_selection_min_height) + transformChatHeightTo(1f - channel_selection_min_height, 800, Easing.OutQuint); } else - { textbox.HoldFocus = true; - } }; } @@ -201,7 +197,7 @@ namespace osu.Game.Overlays if (!isDragging) return base.OnDragStart(state); - startDragChatHeight = chatHeight.Value; + startDragChatHeight = ChatHeight.Value; return true; } @@ -217,7 +213,7 @@ namespace osu.Game.Overlays if (channelSelection.State == Visibility.Visible && targetChatHeight > 1f - channel_selection_min_height) targetChatHeight = 1f - channel_selection_min_height; - chatHeight.Value = targetChatHeight; + ChatHeight.Value = targetChatHeight; } return true; @@ -277,14 +273,14 @@ namespace osu.Game.Overlays this.api = api; api.Register(this); - chatHeight = config.GetBindable(OsuSetting.ChatDisplayHeight); - chatHeight.ValueChanged += h => + ChatHeight = config.GetBindable(OsuSetting.ChatDisplayHeight); + ChatHeight.ValueChanged += h => { chatContainer.Height = (float)h; channelSelectionContainer.Height = 1f - (float)h; tabBackground.FadeTo(h == 1 ? 1 : 0.8f, 200); }; - chatHeight.TriggerChange(); + ChatHeight.TriggerChange(); chatBackground.Colour = colours.ChatBlue; } @@ -506,5 +502,26 @@ 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; + } } } From 1de1b882e30653438c155add1222860ec2134a20 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Sep 2017 10:29:09 +0900 Subject: [PATCH 443/483] Fix BeatmapInfo's comparator when not being sourced from database --- osu.Game/Beatmaps/BeatmapInfo.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index c962201fe3..0776669811 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -100,6 +100,11 @@ namespace osu.Game.Beatmaps public bool Equals(BeatmapInfo other) { + if (ID == 0 || other?.ID == 0) + // one of the two BeatmapInfos we are comparing isn't sourced from a database. + // fall back to reference equality. + return ReferenceEquals(this, other); + return ID == other?.ID; } From ba3e44cd71f6e6a7d1f5600537ed8b74299ccf90 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 15:17:32 +0900 Subject: [PATCH 444/483] Simplify standardized scoring to BasePortion (raw scoring) + ComboPortion (highest combo) --- .../Scoring/ManiaScoreProcessor.cs | 4 +-- .../Scoring/OsuScoreProcessor.cs | 2 +- .../Scoring/TaikoScoreProcessor.cs | 2 +- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 31 +++++++++---------- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index ff9dcdc682..857616ad9a 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -89,8 +89,8 @@ namespace osu.Game.Rulesets.Mania.Scoring /// private double hpMultiplier = 1; - protected override double ComboPortion => 0.2f; - protected override double AccuracyPortion => 0.8f; + protected override double BasePortion => 0.8; + protected override double ComboPortion => 0.2; public ManiaScoreProcessor() { diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index da474dac65..3d30293d4b 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -16,8 +16,8 @@ namespace osu.Game.Rulesets.Osu.Scoring { internal class OsuScoreProcessor : ScoreProcessor { + protected override double BasePortion => 0.3; protected override double ComboPortion => 0.7; - protected override double AccuracyPortion => 0.3; public OsuScoreProcessor() { diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index f31cd2d634..31e3c435b4 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -55,8 +55,8 @@ namespace osu.Game.Rulesets.Taiko.Scoring /// public override bool HasFailed => Hits == MaxHits && Health.Value <= 0.5; + protected override double BasePortion => 0.8; protected override double ComboPortion => 0.2; - protected override double AccuracyPortion => 0.8; private double hpIncreaseTick; private double hpIncreaseGreat; diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 448cb56e0c..a0b24c52df 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -156,16 +156,17 @@ namespace osu.Game.Rulesets.Scoring protected sealed override bool HasCompleted => Hits == MaxHits; + protected virtual double BasePortion => 0.5f; protected virtual double ComboPortion => 0.5f; - protected virtual double AccuracyPortion => 0.5f; protected int MaxHits { get; private set; } protected int Hits { get; private set; } private double maxHighestCombo; - private double maxComboScore; - private double rollingMaxComboScore; - private double comboScore; + + private double maxBaseScore; + private double rollingMaxBaseScore; + private double baseScore; protected ScoreProcessor() { @@ -216,8 +217,8 @@ namespace osu.Game.Rulesets.Scoring break; } - comboScore += judgement.NumericResult; - rollingMaxComboScore += judgement.MaxNumericResult; + baseScore += judgement.NumericResult; + rollingMaxBaseScore += judgement.MaxNumericResult; } else if (judgement.IsHit) bonusScore += judgement.NumericResult; @@ -225,20 +226,16 @@ namespace osu.Game.Rulesets.Scoring if (judgement.AffectsAccuracy) Hits++; - if (rollingMaxComboScore != 0) - Accuracy.Value = comboScore / rollingMaxComboScore; + if (rollingMaxBaseScore != 0) + Accuracy.Value = baseScore / rollingMaxBaseScore; switch (Mode.Value) { case ScoringMode.Standardised: - TotalScore.Value = - max_score * - (ComboPortion * (comboScore * Math.Log(HighestCombo + 1, 2)) / (maxComboScore * Math.Log(maxHighestCombo + 1, 2)) - + AccuracyPortion * Accuracy) - + bonusScore; + TotalScore.Value = max_score * (BasePortion * baseScore / maxBaseScore + ComboPortion * HighestCombo / maxHighestCombo) + bonusScore; break; case ScoringMode.Exponential: - TotalScore.Value = (comboScore + bonusScore) * Math.Log(HighestCombo + 1, 2); + TotalScore.Value = (baseScore + bonusScore) * Math.Log(HighestCombo + 1, 2); break; } } @@ -249,14 +246,14 @@ namespace osu.Game.Rulesets.Scoring { MaxHits = Hits; maxHighestCombo = HighestCombo; - maxComboScore = comboScore; + maxBaseScore = baseScore; } base.Reset(storeResults); Hits = 0; - comboScore = 0; - rollingMaxComboScore = 0; + baseScore = 0; + rollingMaxBaseScore = 0; } } From 7681d97f1002506b39722404d4bb880da9533661 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Sep 2017 15:20:49 +0900 Subject: [PATCH 445/483] Fix typo in user profile header Replays watched, not replay watched. --- osu.Game/Overlays/Profile/ProfileHeader.cs | 4 ++-- osu.Game/Users/UserStatistics.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 77a3449b9c..d6a86fe714 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -414,8 +414,8 @@ namespace osu.Game.Overlays.Profile scoreNumberText.Add(createScoreNumberText(user.Statistics.TotalHits.ToString(@"#,0"))); scoreText.Add(createScoreText("Max Combo")); scoreNumberText.Add(createScoreNumberText(user.Statistics.MaxCombo.ToString(@"#,0"))); - scoreText.Add(createScoreText("Replay Watched by Others")); - scoreNumberText.Add(createScoreNumberText(user.Statistics.ReplayWatched.ToString(@"#,0"))); + scoreText.Add(createScoreText("Replays Watched by Others")); + scoreNumberText.Add(createScoreNumberText(user.Statistics.ReplaysWatched.ToString(@"#,0"))); gradeSS.DisplayCount = user.Statistics.GradesCount.SS; gradeSS.Show(); diff --git a/osu.Game/Users/UserStatistics.cs b/osu.Game/Users/UserStatistics.cs index 05f3d65f30..15b57553a6 100644 --- a/osu.Game/Users/UserStatistics.cs +++ b/osu.Game/Users/UserStatistics.cs @@ -44,7 +44,7 @@ namespace osu.Game.Users public int MaxCombo; [JsonProperty(@"replays_watched_by_others")] - public int ReplayWatched; + public int ReplaysWatched; [JsonProperty(@"grade_counts")] public Grades GradesCount; From 05ac23f99a880f034949f88aecb5060cc16b8ccc Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 15:42:47 +0900 Subject: [PATCH 446/483] Remove AffectsAccuracy for now --- .../Judgements/HoldNoteTickJudgement.cs | 1 - .../Judgements/TaikoDrumRollTickJudgement.cs | 1 - .../Judgements/TaikoStrongHitJudgement.cs | 1 - osu.Game/Rulesets/Judgements/Judgement.cs | 5 ----- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 7 +++---- 5 files changed, 3 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs index 46e6f0feec..d326c6fc0a 100644 --- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs +++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs @@ -8,7 +8,6 @@ namespace osu.Game.Rulesets.Mania.Judgements public class HoldNoteTickJudgement : ManiaJudgement { public override bool AffectsCombo => false; - public override bool AffectsAccuracy => false; protected override int NumericResultFor(HitResult result) => 20; } diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs index bd021a1560..c9daef8c99 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs @@ -8,7 +8,6 @@ namespace osu.Game.Rulesets.Taiko.Judgements public class TaikoDrumRollTickJudgement : TaikoJudgement { public override bool AffectsCombo => false; - public override bool AffectsAccuracy => false; protected override int NumericResultFor(HitResult result) { diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs index 2cc4c922e2..f0b57e5c09 100644 --- a/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs +++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs @@ -8,7 +8,6 @@ namespace osu.Game.Rulesets.Taiko.Judgements public class TaikoStrongHitJudgement : TaikoJudgement { public override bool AffectsCombo => false; - public override bool AffectsAccuracy => false; public TaikoStrongHitJudgement() { diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index 71743b9988..0ae33272a7 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -25,11 +25,6 @@ namespace osu.Game.Rulesets.Judgements /// public double TimeOffset { get; internal set; } - /// - /// Whether the should be considered as a factor in the accuracy percentage and portion. - /// - public virtual bool AffectsAccuracy => true; - /// /// Whether the should affect the combo portion of the score. /// If false, the will be considered for the bonus portion of the score. diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index a0b24c52df..7f3d5e2501 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -152,7 +152,7 @@ namespace osu.Game.Rulesets.Scoring { private const double max_score = 1000000; - public readonly Bindable Mode = new Bindable(ScoringMode.Exponential); + public readonly Bindable Mode = new Bindable(ScoringMode.Standardised); protected sealed override bool HasCompleted => Hits == MaxHits; @@ -219,13 +219,12 @@ namespace osu.Game.Rulesets.Scoring baseScore += judgement.NumericResult; rollingMaxBaseScore += judgement.MaxNumericResult; + + Hits++; } else if (judgement.IsHit) bonusScore += judgement.NumericResult; - if (judgement.AffectsAccuracy) - Hits++; - if (rollingMaxBaseScore != 0) Accuracy.Value = baseScore / rollingMaxBaseScore; From d83a2d4dc6e7084bff7a337af6d0adc3836fc1db Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 15:56:49 +0900 Subject: [PATCH 447/483] Disable masking optimisations for scrolling hit objects Lifetime is very tightly controlled here, so all should be okay. --- .../Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs | 1 + osu.Game/Rulesets/Timing/ScrollingContainer.cs | 1 + osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs | 1 + 3 files changed, 3 insertions(+) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs index 5ba9c2ff4d..538bb826ad 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs @@ -31,6 +31,7 @@ namespace osu.Game.Rulesets.Objects.Drawables } public override bool RemoveWhenNotAlive => false; + protected override bool RequiresChildrenUpdate => true; protected DrawableScrollingHitObject(TObject hitObject) : base(hitObject) diff --git a/osu.Game/Rulesets/Timing/ScrollingContainer.cs b/osu.Game/Rulesets/Timing/ScrollingContainer.cs index 6e77c49e3d..eac596297a 100644 --- a/osu.Game/Rulesets/Timing/ScrollingContainer.cs +++ b/osu.Game/Rulesets/Timing/ScrollingContainer.cs @@ -29,6 +29,7 @@ namespace osu.Game.Rulesets.Timing internal Axes ScrollingAxes; public override bool RemoveWhenNotAlive => false; + protected override bool RequiresChildrenUpdate => true; /// /// The control point that defines the speed adjustments for this container. This is set by the . diff --git a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs index d3bd7685da..81e3a5c70e 100644 --- a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs +++ b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs @@ -38,6 +38,7 @@ namespace osu.Game.Rulesets.Timing } public override bool RemoveWhenNotAlive => false; + protected override bool RequiresChildrenUpdate => true; /// /// The that defines the speed adjustments. From e472518e4f9892c26f1335e2c95b14c30869ef65 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 15:58:50 +0900 Subject: [PATCH 448/483] Standardized is default for now --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 7f3d5e2501..ced1a5d06b 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -152,7 +152,7 @@ namespace osu.Game.Rulesets.Scoring { private const double max_score = 1000000; - public readonly Bindable Mode = new Bindable(ScoringMode.Standardised); + public readonly Bindable Mode = new Bindable(); protected sealed override bool HasCompleted => Hits == MaxHits; From e146bcacf1119534c23a63bf941bae72fc2be33f Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 16:13:27 +0900 Subject: [PATCH 449/483] Make BasePortion and ComboPortion constants --- osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs | 3 --- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 3 --- osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs | 3 --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 10 ++++++---- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index 857616ad9a..a200ba31e2 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -89,9 +89,6 @@ namespace osu.Game.Rulesets.Mania.Scoring /// private double hpMultiplier = 1; - protected override double BasePortion => 0.8; - protected override double ComboPortion => 0.2; - public ManiaScoreProcessor() { } diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 3d30293d4b..d299faaae2 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -16,9 +16,6 @@ namespace osu.Game.Rulesets.Osu.Scoring { internal class OsuScoreProcessor : ScoreProcessor { - protected override double BasePortion => 0.3; - protected override double ComboPortion => 0.7; - public OsuScoreProcessor() { } diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index 31e3c435b4..abdda9676f 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -55,9 +55,6 @@ namespace osu.Game.Rulesets.Taiko.Scoring /// public override bool HasFailed => Hits == MaxHits && Health.Value <= 0.5; - protected override double BasePortion => 0.8; - protected override double ComboPortion => 0.2; - private double hpIncreaseTick; private double hpIncreaseGreat; private double hpIncreaseGood; diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index ced1a5d06b..a40a7c2849 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Diagnostics; using osu.Framework.Configuration; using osu.Game.Beatmaps; using osu.Game.Rulesets.Judgements; @@ -150,15 +151,14 @@ namespace osu.Game.Rulesets.Scoring public abstract class ScoreProcessor : ScoreProcessor where TObject : HitObject { + private const double base_portion = 0.3; + private const double combo_portion = 0.7; private const double max_score = 1000000; public readonly Bindable Mode = new Bindable(); protected sealed override bool HasCompleted => Hits == MaxHits; - protected virtual double BasePortion => 0.5f; - protected virtual double ComboPortion => 0.5f; - protected int MaxHits { get; private set; } protected int Hits { get; private set; } @@ -174,6 +174,8 @@ namespace osu.Game.Rulesets.Scoring protected ScoreProcessor(RulesetContainer rulesetContainer) { + Debug.Assert(base_portion + combo_portion == 1.0); + rulesetContainer.OnJudgement += AddJudgement; SimulateAutoplay(rulesetContainer.Beatmap); @@ -231,7 +233,7 @@ namespace osu.Game.Rulesets.Scoring switch (Mode.Value) { case ScoringMode.Standardised: - TotalScore.Value = max_score * (BasePortion * baseScore / maxBaseScore + ComboPortion * HighestCombo / maxHighestCombo) + bonusScore; + TotalScore.Value = max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore; break; case ScoringMode.Exponential: TotalScore.Value = (baseScore + bonusScore) * Math.Log(HighestCombo + 1, 2); From 6682c3a73696300925b50296eb68acb39ad79ca8 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 16:15:11 +0900 Subject: [PATCH 450/483] Override instead of re-binding event --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 0dac3ec41c..d946b45372 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -49,10 +49,9 @@ namespace osu.Game.Rulesets.Catch.UI var fruit = (DrawableFruit)h; fruit.CheckPosition = catcherArea.CheckIfWeCanCatch; - fruit.OnJudgement += Fruit_OnJudgement; } - private void Fruit_OnJudgement(DrawableHitObject judgedObject, Judgement judgement) + public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { if (judgement.IsHit) { From 093d82ac45c245da6ab6b0b39eed292eb9d4a027 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 16:17:01 +0900 Subject: [PATCH 451/483] Set depths from playfield add methods instead of DrawableHitObject --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 2 ++ osu.Game.Rulesets.Mania/UI/Column.cs | 2 ++ osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs | 2 +- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 2 ++ osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 2 ++ osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 -- 6 files changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index d946b45372..2b6f9bbf5a 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -45,6 +45,8 @@ namespace osu.Game.Rulesets.Catch.UI public override void Add(DrawableHitObject h) { + h.Depth = (float)h.HitObject.StartTime; + base.Add(h); var fruit = (DrawableFruit)h; diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 1133c9f2ee..2d553f8639 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -203,6 +203,8 @@ namespace osu.Game.Rulesets.Mania.UI /// The DrawableHitObject to add. public override void Add(DrawableHitObject hitObject) { + hitObject.Depth = (float)hitObject.HitObject.StartTime; + hitObject.AccentColour = AccentColour; HitObjects.Add(hitObject); } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 8cef7de948..c5155d1e10 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Scale = s.Scale, ComboColour = s.ComboColour, Samples = s.Samples, - }) { Depth = 0 }, + }) }; components.Add(body); diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 17f4f9f541..1bb4e8493b 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -70,6 +70,8 @@ namespace osu.Game.Rulesets.Osu.UI public override void Add(DrawableHitObject h) { + h.Depth = (float)h.HitObject.StartTime; + var c = h as IDrawableHitObjectWithProxiedApproach; if (c != null) approachCircles.Add(c.ProxiedLayer.CreateProxy()); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 2dd06f7179..d9a216bbfc 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -205,6 +205,8 @@ namespace osu.Game.Rulesets.Taiko.UI public override void Add(DrawableHitObject h) { + h.Depth = (float)h.HitObject.StartTime; + base.Add(h); var barline = h as DrawableBarLine; diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 7cf098c3fa..7a26a53c2a 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -55,8 +55,6 @@ namespace osu.Game.Rulesets.Objects.Drawables : base(hitObject) { HitObject = hitObject; - - Depth = (float)hitObject.StartTime; } private ArmedState state; From f1130eb899dda8d1d8e15f680aed9773485501dd Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 16:35:13 +0900 Subject: [PATCH 452/483] Add default implementation for ScoreProcessor using Exponential scoring --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 13 +++++++++++-- osu.Game/Rulesets/UI/RulesetContainer.cs | 2 ++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index a40a7c2849..deb87e92d8 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Scoring } } - public abstract class ScoreProcessor : ScoreProcessor + public class ScoreProcessor : ScoreProcessor where TObject : HitObject { private const double base_portion = 0.3; @@ -172,7 +172,7 @@ namespace osu.Game.Rulesets.Scoring { } - protected ScoreProcessor(RulesetContainer rulesetContainer) + public ScoreProcessor(RulesetContainer rulesetContainer) { Debug.Assert(base_portion + combo_portion == 1.0); @@ -180,11 +180,20 @@ namespace osu.Game.Rulesets.Scoring SimulateAutoplay(rulesetContainer.Beatmap); Reset(true); + + if (maxBaseScore == 0 || maxHighestCombo == 0) + { + Mode.Value = ScoringMode.Exponential; + Mode.Disabled = true; + } } /// /// Simulates an autoplay of s that will be judged by this /// by adding s for each in the . + /// + /// This is required for to work, otherwise will be used. + /// /// /// The containing the s that will be judged by this . protected virtual void SimulateAutoplay(Beatmap beatmap) { } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index cff3365788..86ab9a0199 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -133,6 +133,8 @@ namespace osu.Game.Rulesets.UI public sealed override bool ProvidingUserCursor => !HasReplayLoaded && Playfield.ProvidingUserCursor; + public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(this); + /// /// The playfield. /// From 5e32d95ad2dbebaed81841593ec7d9384b9efd42 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Wed, 13 Sep 2017 16:37:05 +0900 Subject: [PATCH 453/483] Remove Ruleset's CreateScoreProcessor method --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 4 ---- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 4 ---- osu.Game.Rulesets.Osu/OsuRuleset.cs | 4 ---- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 4 ---- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 6 ------ osu.Game/Rulesets/Ruleset.cs | 3 --- 6 files changed, 25 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 214cbc7f50..1a9b034cf2 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -9,8 +9,6 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; using System.Collections.Generic; using osu.Framework.Graphics; -using osu.Game.Rulesets.Catch.Scoring; -using osu.Game.Rulesets.Scoring; using osu.Framework.Input.Bindings; namespace osu.Game.Rulesets.Catch @@ -99,8 +97,6 @@ namespace osu.Game.Rulesets.Catch public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new CatchDifficultyCalculator(beatmap); - public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(); - public override int LegacyID => 2; public CatchRuleset(RulesetInfo rulesetInfo) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 0011d2837f..c0996cadf9 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -10,8 +10,6 @@ using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; using osu.Game.Graphics; -using osu.Game.Rulesets.Mania.Scoring; -using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania { @@ -111,8 +109,6 @@ namespace osu.Game.Rulesets.Mania public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new ManiaDifficultyCalculator(beatmap); - public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(); - public override int LegacyID => 3; public ManiaRuleset(RulesetInfo rulesetInfo) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index c943518b0b..7650a91d7a 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -12,8 +12,6 @@ using osu.Game.Rulesets.UI; using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; -using osu.Game.Rulesets.Osu.Scoring; -using osu.Game.Rulesets.Scoring; using osu.Game.Overlays.Settings; using osu.Framework.Input.Bindings; @@ -118,8 +116,6 @@ namespace osu.Game.Rulesets.Osu public override string Description => "osu!"; - public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor(); - public override SettingsSubsection CreateSettings() => new OsuSettings(); public override int LegacyID => 0; diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 7b1452766e..ea0f0eae1a 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -9,8 +9,6 @@ using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.UI; using System.Collections.Generic; using osu.Framework.Graphics; -using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Taiko.Scoring; using osu.Framework.Input.Bindings; namespace osu.Game.Rulesets.Taiko @@ -101,8 +99,6 @@ namespace osu.Game.Rulesets.Taiko public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new TaikoDifficultyCalculator(beatmap); - public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(); - public override int LegacyID => 1; public TaikoRuleset(RulesetInfo rulesetInfo) diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index ad0b110e48..d8cd58d939 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -7,7 +7,6 @@ using osu.Framework.Audio.Track; using osu.Framework.Graphics.Textures; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; namespace osu.Game.Beatmaps @@ -62,11 +61,6 @@ namespace osu.Game.Beatmaps public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => null; - public override ScoreProcessor CreateScoreProcessor() - { - throw new NotImplementedException(); - } - public override string Description => "dummy"; public DummyRuleset(RulesetInfo rulesetInfo) diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 33621662af..587c2fc659 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -10,7 +10,6 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets @@ -50,8 +49,6 @@ namespace osu.Game.Rulesets public abstract DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap); - public abstract ScoreProcessor CreateScoreProcessor(); - public virtual Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_question_circle }; public abstract string Description { get; } From bab3ef0669de179351956504e7096d85e5a18900 Mon Sep 17 00:00:00 2001 From: Damnae Date: Wed, 13 Sep 2017 11:22:24 +0200 Subject: [PATCH 454/483] Rename storyboard classes. --- .../Visual/TestCaseStoryboard.cs | 6 ++-- osu.Game/Beatmaps/Beatmap.cs | 2 +- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 24 ++++++------- .../{Storyboard.cs => DrawableStoryboard.cs} | 14 ++++---- ...tion.cs => DrawableStoryboardAnimation.cs} | 32 ++++++++--------- ...ardLayer.cs => DrawableStoryboardLayer.cs} | 12 +++---- ...dSprite.cs => DrawableStoryboardSprite.cs} | 26 +++++++------- ...entDefinition.cs => IStoryboardElement.cs} | 2 +- osu.Game/Storyboards/Storyboard.cs | 35 +++++++++++++++++++ ...onDefinition.cs => StoryboardAnimation.cs} | 6 ++-- osu.Game/Storyboards/StoryboardDefinition.cs | 35 ------------------- ...{LayerDefinition.cs => StoryboardLayer.cs} | 14 ++++---- ...ampleDefinition.cs => StoryboardSample.cs} | 4 +-- ...priteDefinition.cs => StoryboardSprite.cs} | 6 ++-- osu.Game/osu.Game.csproj | 20 +++++------ 15 files changed, 119 insertions(+), 119 deletions(-) rename osu.Game/Storyboards/Drawables/{Storyboard.cs => DrawableStoryboard.cs} (74%) rename osu.Game/Storyboards/Drawables/{StoryboardAnimation.cs => DrawableStoryboardAnimation.cs} (67%) rename osu.Game/Storyboards/Drawables/{StoryboardLayer.cs => DrawableStoryboardLayer.cs} (69%) rename osu.Game/Storyboards/Drawables/{StoryboardSprite.cs => DrawableStoryboardSprite.cs} (71%) rename osu.Game/Storyboards/{IElementDefinition.cs => IStoryboardElement.cs} (84%) create mode 100644 osu.Game/Storyboards/Storyboard.cs rename osu.Game/Storyboards/{AnimationDefinition.cs => StoryboardAnimation.cs} (79%) delete mode 100644 osu.Game/Storyboards/StoryboardDefinition.cs rename osu.Game/Storyboards/{LayerDefinition.cs => StoryboardLayer.cs} (55%) rename osu.Game/Storyboards/{SampleDefinition.cs => StoryboardSample.cs} (77%) rename osu.Game/Storyboards/{SpriteDefinition.cs => StoryboardSprite.cs} (95%) diff --git a/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs b/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs index 10dd706f62..878198e8d2 100644 --- a/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs +++ b/osu.Desktop.Tests/Visual/TestCaseStoryboard.cs @@ -21,8 +21,8 @@ namespace osu.Desktop.Tests.Visual private readonly Bindable beatmapBacking = new Bindable(); - private readonly Container storyboardContainer; - private Storyboard storyboard; + private readonly Container storyboardContainer; + private DrawableStoryboard storyboard; public TestCaseStoryboard() { @@ -38,7 +38,7 @@ namespace osu.Desktop.Tests.Visual RelativeSizeAxes = Axes.Both, Colour = Color4.Black, }, - storyboardContainer = new Container + storyboardContainer = new Container { RelativeSizeAxes = Axes.Both, }, diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index a28f7832b7..458c2304f2 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps /// /// The Beatmap's Storyboard. /// - public StoryboardDefinition Storyboard = new StoryboardDefinition(); + public Storyboard Storyboard = new Storyboard(); /// /// Constructs a new beatmap. diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index adf366cdea..21fee0f465 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -242,7 +242,7 @@ namespace osu.Game.Beatmaps.Formats } } - private void handleEvents(Beatmap beatmap, string line, ref SpriteDefinition spriteDefinition, ref CommandTimelineGroup timelineGroup) + private void handleEvents(Beatmap beatmap, string line, ref StoryboardSprite storyboardSprite, ref CommandTimelineGroup timelineGroup) { var depth = 0; while (line.StartsWith(" ") || line.StartsWith("_")) @@ -257,7 +257,7 @@ namespace osu.Game.Beatmaps.Formats if (depth == 0) { - spriteDefinition = null; + storyboardSprite = null; EventType type; if (!Enum.TryParse(split[0], out type)) @@ -292,8 +292,8 @@ namespace osu.Game.Beatmaps.Formats var path = cleanFilename(split[3]); var x = float.Parse(split[4], NumberFormatInfo.InvariantInfo); var y = float.Parse(split[5], NumberFormatInfo.InvariantInfo); - spriteDefinition = new SpriteDefinition(path, origin, new Vector2(x, y)); - beatmap.Storyboard.GetLayer(layer).Add(spriteDefinition); + storyboardSprite = new StoryboardSprite(path, origin, new Vector2(x, y)); + beatmap.Storyboard.GetLayer(layer).Add(storyboardSprite); } break; case EventType.Animation: @@ -306,8 +306,8 @@ namespace osu.Game.Beatmaps.Formats var frameCount = int.Parse(split[6]); var frameDelay = double.Parse(split[7], NumberFormatInfo.InvariantInfo); var loopType = split.Length > 8 ? (AnimationLoopType)Enum.Parse(typeof(AnimationLoopType), split[8]) : AnimationLoopType.LoopForever; - spriteDefinition = new AnimationDefinition(path, origin, new Vector2(x, y), frameCount, frameDelay, loopType); - beatmap.Storyboard.GetLayer(layer).Add(spriteDefinition); + storyboardSprite = new StoryboardAnimation(path, origin, new Vector2(x, y), frameCount, frameDelay, loopType); + beatmap.Storyboard.GetLayer(layer).Add(storyboardSprite); } break; case EventType.Sample: @@ -316,7 +316,7 @@ namespace osu.Game.Beatmaps.Formats var layer = parseLayer(split[2]); var path = cleanFilename(split[3]); var volume = split.Length > 4 ? float.Parse(split[4], CultureInfo.InvariantCulture) : 100; - beatmap.Storyboard.GetLayer(layer).Add(new SampleDefinition(path, time, volume)); + beatmap.Storyboard.GetLayer(layer).Add(new StoryboardSample(path, time, volume)); } break; } @@ -324,7 +324,7 @@ namespace osu.Game.Beatmaps.Formats else { if (depth < 2) - timelineGroup = spriteDefinition?.TimelineGroup; + timelineGroup = storyboardSprite?.TimelineGroup; var commandType = split[0]; switch (commandType) @@ -335,14 +335,14 @@ namespace osu.Game.Beatmaps.Formats var startTime = split.Length > 2 ? double.Parse(split[2], CultureInfo.InvariantCulture) : double.MinValue; var endTime = split.Length > 3 ? double.Parse(split[3], CultureInfo.InvariantCulture) : double.MaxValue; var groupNumber = split.Length > 4 ? int.Parse(split[4]) : 0; - timelineGroup = spriteDefinition?.AddTrigger(triggerName, startTime, endTime, groupNumber); + timelineGroup = storyboardSprite?.AddTrigger(triggerName, startTime, endTime, groupNumber); } break; case "L": { var startTime = double.Parse(split[1], CultureInfo.InvariantCulture); var loopCount = int.Parse(split[2]); - timelineGroup = spriteDefinition?.AddLoop(startTime, loopCount); + timelineGroup = storyboardSprite?.AddLoop(startTime, loopCount); } break; default: @@ -607,7 +607,7 @@ namespace osu.Game.Beatmaps.Formats Section section = Section.None; bool hasCustomColours = false; - SpriteDefinition spriteDefinition = null; + StoryboardSprite storyboardSprite = null; CommandTimelineGroup timelineGroup = null; string line; @@ -647,7 +647,7 @@ namespace osu.Game.Beatmaps.Formats handleDifficulty(beatmap, line); break; case Section.Events: - handleEvents(beatmap, line, ref spriteDefinition, ref timelineGroup); + handleEvents(beatmap, line, ref storyboardSprite, ref timelineGroup); break; case Section.TimingPoints: handleTimingPoints(beatmap, line); diff --git a/osu.Game/Storyboards/Drawables/Storyboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs similarity index 74% rename from osu.Game/Storyboards/Drawables/Storyboard.cs rename to osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index 45aa063f79..f88e5d118f 100644 --- a/osu.Game/Storyboards/Drawables/Storyboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs @@ -10,9 +10,9 @@ using osu.Game.IO; namespace osu.Game.Storyboards.Drawables { - public class Storyboard : Container + public class DrawableStoryboard : Container { - public StoryboardDefinition Definition { get; private set; } + public Storyboard Storyboard { get; private set; } protected override Vector2 DrawScale => new Vector2(Parent.DrawHeight / 480); public override bool HandleInput => false; @@ -33,9 +33,9 @@ namespace osu.Game.Storyboards.Drawables protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - public Storyboard(StoryboardDefinition definition) + public DrawableStoryboard(Storyboard storyboard) { - Definition = definition; + Storyboard = storyboard; Size = new Vector2(640, 480); Anchor = Anchor.Centre; Origin = Anchor.Centre; @@ -46,14 +46,14 @@ namespace osu.Game.Storyboards.Drawables { dependencies.Cache(new TextureStore(new RawTextureLoaderStore(fileStore.Store), false) { ScaleAdjust = 1, }); - foreach (var layerDefinition in Definition.Layers) - Add(layerDefinition.CreateDrawable()); + foreach (var layer in Storyboard.Layers) + Add(layer.CreateDrawable()); } private void updateLayerVisibility() { foreach (var layer in Children) - layer.Enabled = passing ? layer.Definition.EnabledWhenPassing : layer.Definition.EnabledWhenFailing; + layer.Enabled = passing ? layer.Layer.EnabledWhenPassing : layer.Layer.EnabledWhenFailing; } } } diff --git a/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs similarity index 67% rename from osu.Game/Storyboards/Drawables/StoryboardAnimation.cs rename to osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs index a28287fd40..d8b7d05ee9 100644 --- a/osu.Game/Storyboards/Drawables/StoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs @@ -10,12 +10,12 @@ using System.Linq; namespace osu.Game.Storyboards.Drawables { - public class StoryboardAnimation : TextureAnimation, IFlippable + public class DrawableStoryboardAnimation : TextureAnimation, IFlippable { - public AnimationDefinition Definition { get; private set; } + public StoryboardAnimation Animation { get; private set; } - protected override bool ShouldBeAlive => Definition.HasCommands && base.ShouldBeAlive; - public override bool RemoveWhenNotAlive => !Definition.HasCommands || base.RemoveWhenNotAlive; + protected override bool ShouldBeAlive => Animation.HasCommands && base.ShouldBeAlive; + public override bool RemoveWhenNotAlive => !Animation.HasCommands || base.RemoveWhenNotAlive; public bool FlipH { get; set; } public bool FlipV { get; set; } @@ -52,25 +52,25 @@ namespace osu.Game.Storyboards.Drawables public override bool IsPresent => !float.IsNaN(DrawPosition.X) && !float.IsNaN(DrawPosition.Y) && base.IsPresent; - public StoryboardAnimation(AnimationDefinition definition) + public DrawableStoryboardAnimation(StoryboardAnimation animation) { - Definition = definition; - Origin = definition.Origin; - Position = definition.InitialPosition; - Repeat = definition.LoopType == AnimationLoopType.LoopForever; + Animation = animation; + Origin = animation.Origin; + Position = animation.InitialPosition; + Repeat = animation.LoopType == AnimationLoopType.LoopForever; - if (definition.HasCommands) + if (animation.HasCommands) { - LifetimeStart = definition.StartTime; - LifetimeEnd = definition.EndTime; + LifetimeStart = animation.StartTime; + LifetimeEnd = animation.EndTime; } } [BackgroundDependencyLoader] private void load(OsuGameBase game, TextureStore textureStore) { - var basePath = Definition.Path.ToLowerInvariant(); - for (var frame = 0; frame < Definition.FrameCount; frame++) + var basePath = Animation.Path.ToLowerInvariant(); + for (var frame = 0; frame < Animation.FrameCount; frame++) { var framePath = basePath.Replace(".", frame + "."); @@ -79,9 +79,9 @@ namespace osu.Game.Storyboards.Drawables continue; var texture = textureStore.Get(path); - AddFrame(texture, Definition.FrameDelay); + AddFrame(texture, Animation.FrameDelay); } - Definition.ApplyTransforms(this); + Animation.ApplyTransforms(this); } } } diff --git a/osu.Game/Storyboards/Drawables/StoryboardLayer.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs similarity index 69% rename from osu.Game/Storyboards/Drawables/StoryboardLayer.cs rename to osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs index 48532e0418..2b5db5b6fa 100644 --- a/osu.Game/Storyboards/Drawables/StoryboardLayer.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs @@ -7,26 +7,26 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Storyboards.Drawables { - public class StoryboardLayer : Container + public class DrawableStoryboardLayer : Container { - public LayerDefinition Definition { get; private set; } + public StoryboardLayer Layer { get; private set; } public bool Enabled; public override bool IsPresent => Enabled && base.IsPresent; - public StoryboardLayer(LayerDefinition definition) + public DrawableStoryboardLayer(StoryboardLayer layer) { - Definition = definition; + Layer = layer; RelativeSizeAxes = Axes.Both; Anchor = Anchor.Centre; Origin = Anchor.Centre; - Enabled = definition.EnabledWhenPassing; + Enabled = layer.EnabledWhenPassing; } [BackgroundDependencyLoader] private void load() { - foreach (var element in Definition.Elements) + foreach (var element in Layer.Elements) { var drawable = element.CreateDrawable(); if (drawable != null) diff --git a/osu.Game/Storyboards/Drawables/StoryboardSprite.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs similarity index 71% rename from osu.Game/Storyboards/Drawables/StoryboardSprite.cs rename to osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs index 3b1a431a4a..4b491fa008 100644 --- a/osu.Game/Storyboards/Drawables/StoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs @@ -10,12 +10,12 @@ using System.Linq; namespace osu.Game.Storyboards.Drawables { - public class StoryboardSprite : Sprite, IFlippable + public class DrawableStoryboardSprite : Sprite, IFlippable { - public SpriteDefinition Definition { get; private set; } + public StoryboardSprite Sprite { get; private set; } - protected override bool ShouldBeAlive => Definition.HasCommands && base.ShouldBeAlive; - public override bool RemoveWhenNotAlive => !Definition.HasCommands || base.RemoveWhenNotAlive; + protected override bool ShouldBeAlive => Sprite.HasCommands && base.ShouldBeAlive; + public override bool RemoveWhenNotAlive => !Sprite.HasCommands || base.RemoveWhenNotAlive; public bool FlipH { get; set; } public bool FlipV { get; set; } @@ -52,29 +52,29 @@ namespace osu.Game.Storyboards.Drawables public override bool IsPresent => !float.IsNaN(DrawPosition.X) && !float.IsNaN(DrawPosition.Y) && base.IsPresent; - public StoryboardSprite(SpriteDefinition definition) + public DrawableStoryboardSprite(StoryboardSprite sprite) { - Definition = definition; - Origin = definition.Origin; - Position = definition.InitialPosition; + Sprite = sprite; + Origin = sprite.Origin; + Position = sprite.InitialPosition; - if (definition.HasCommands) + if (sprite.HasCommands) { - LifetimeStart = definition.StartTime; - LifetimeEnd = definition.EndTime; + LifetimeStart = sprite.StartTime; + LifetimeEnd = sprite.EndTime; } } [BackgroundDependencyLoader] private void load(OsuGameBase game, TextureStore textureStore) { - var spritePath = Definition.Path.ToLowerInvariant(); + var spritePath = Sprite.Path.ToLowerInvariant(); var path = game.Beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename.ToLowerInvariant() == spritePath)?.FileInfo.StoragePath; if (path == null) return; Texture = textureStore.Get(path); - Definition.ApplyTransforms(this); + Sprite.ApplyTransforms(this); } } } diff --git a/osu.Game/Storyboards/IElementDefinition.cs b/osu.Game/Storyboards/IStoryboardElement.cs similarity index 84% rename from osu.Game/Storyboards/IElementDefinition.cs rename to osu.Game/Storyboards/IStoryboardElement.cs index 93c9a473f7..d5fc86b0f7 100644 --- a/osu.Game/Storyboards/IElementDefinition.cs +++ b/osu.Game/Storyboards/IStoryboardElement.cs @@ -5,7 +5,7 @@ using osu.Framework.Graphics; namespace osu.Game.Storyboards { - public interface IElementDefinition + public interface IStoryboardElement { string Path { get; } Drawable CreateDrawable(); diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs new file mode 100644 index 0000000000..111cdd5d41 --- /dev/null +++ b/osu.Game/Storyboards/Storyboard.cs @@ -0,0 +1,35 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Storyboards.Drawables; +using System.Collections.Generic; +using System.Linq; + +namespace osu.Game.Storyboards +{ + public class Storyboard + { + private readonly Dictionary layers = new Dictionary(); + public IEnumerable Layers => layers.Values; + + public Storyboard() + { + layers.Add("Background", new StoryboardLayer("Background", 3)); + layers.Add("Fail", new StoryboardLayer("Fail", 2) { EnabledWhenPassing = false, }); + layers.Add("Pass", new StoryboardLayer("Pass", 1) { EnabledWhenFailing = false, }); + layers.Add("Foreground", new StoryboardLayer("Foreground", 0)); + } + + public StoryboardLayer GetLayer(string name) + { + StoryboardLayer layer; + if (!layers.TryGetValue(name, out layer)) + layers[name] = layer = new StoryboardLayer(name, layers.Values.Min(l => l.Depth) - 1); + + return layer; + } + + public DrawableStoryboard CreateDrawable() + => new DrawableStoryboard(this); + } +} diff --git a/osu.Game/Storyboards/AnimationDefinition.cs b/osu.Game/Storyboards/StoryboardAnimation.cs similarity index 79% rename from osu.Game/Storyboards/AnimationDefinition.cs rename to osu.Game/Storyboards/StoryboardAnimation.cs index 3ac9cbfe0e..98936df9e5 100644 --- a/osu.Game/Storyboards/AnimationDefinition.cs +++ b/osu.Game/Storyboards/StoryboardAnimation.cs @@ -7,13 +7,13 @@ using osu.Game.Storyboards.Drawables; namespace osu.Game.Storyboards { - public class AnimationDefinition : SpriteDefinition + public class StoryboardAnimation : StoryboardSprite { public int FrameCount; public double FrameDelay; public AnimationLoopType LoopType; - public AnimationDefinition(string path, Anchor origin, Vector2 initialPosition, int frameCount, double frameDelay, AnimationLoopType loopType) + public StoryboardAnimation(string path, Anchor origin, Vector2 initialPosition, int frameCount, double frameDelay, AnimationLoopType loopType) : base(path, origin, initialPosition) { FrameCount = frameCount; @@ -22,7 +22,7 @@ namespace osu.Game.Storyboards } public override Drawable CreateDrawable() - => new StoryboardAnimation(this); + => new DrawableStoryboardAnimation(this); } public enum AnimationLoopType diff --git a/osu.Game/Storyboards/StoryboardDefinition.cs b/osu.Game/Storyboards/StoryboardDefinition.cs deleted file mode 100644 index 4ef24cda91..0000000000 --- a/osu.Game/Storyboards/StoryboardDefinition.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Storyboards.Drawables; -using System.Collections.Generic; -using System.Linq; - -namespace osu.Game.Storyboards -{ - public class StoryboardDefinition - { - private readonly Dictionary layers = new Dictionary(); - public IEnumerable Layers => layers.Values; - - public StoryboardDefinition() - { - layers.Add("Background", new LayerDefinition("Background", 3)); - layers.Add("Fail", new LayerDefinition("Fail", 2) { EnabledWhenPassing = false, }); - layers.Add("Pass", new LayerDefinition("Pass", 1) { EnabledWhenFailing = false, }); - layers.Add("Foreground", new LayerDefinition("Foreground", 0)); - } - - public LayerDefinition GetLayer(string name) - { - LayerDefinition layer; - if (!layers.TryGetValue(name, out layer)) - layers[name] = layer = new LayerDefinition(name, layers.Values.Min(l => l.Depth) - 1); - - return layer; - } - - public Storyboard CreateDrawable() - => new Storyboard(this); - } -} diff --git a/osu.Game/Storyboards/LayerDefinition.cs b/osu.Game/Storyboards/StoryboardLayer.cs similarity index 55% rename from osu.Game/Storyboards/LayerDefinition.cs rename to osu.Game/Storyboards/StoryboardLayer.cs index baefe1626a..f565b13eb5 100644 --- a/osu.Game/Storyboards/LayerDefinition.cs +++ b/osu.Game/Storyboards/StoryboardLayer.cs @@ -6,28 +6,28 @@ using System.Collections.Generic; namespace osu.Game.Storyboards { - public class LayerDefinition + public class StoryboardLayer { public string Name; public int Depth; public bool EnabledWhenPassing = true; public bool EnabledWhenFailing = true; - private readonly List elements = new List(); - public IEnumerable Elements => elements; + private readonly List elements = new List(); + public IEnumerable Elements => elements; - public LayerDefinition(string name, int depth) + public StoryboardLayer(string name, int depth) { Name = name; Depth = depth; } - public void Add(IElementDefinition element) + public void Add(IStoryboardElement element) { elements.Add(element); } - public StoryboardLayer CreateDrawable() - => new StoryboardLayer(this) { Depth = Depth, }; + public DrawableStoryboardLayer CreateDrawable() + => new DrawableStoryboardLayer(this) { Depth = Depth, }; } } diff --git a/osu.Game/Storyboards/SampleDefinition.cs b/osu.Game/Storyboards/StoryboardSample.cs similarity index 77% rename from osu.Game/Storyboards/SampleDefinition.cs rename to osu.Game/Storyboards/StoryboardSample.cs index 5d5e8ef1e9..bcf6a4329d 100644 --- a/osu.Game/Storyboards/SampleDefinition.cs +++ b/osu.Game/Storyboards/StoryboardSample.cs @@ -5,13 +5,13 @@ using osu.Framework.Graphics; namespace osu.Game.Storyboards { - public class SampleDefinition : IElementDefinition + public class StoryboardSample : IStoryboardElement { public string Path { get; set; } public double Time; public float Volume; - public SampleDefinition(string path, double time, float volume) + public StoryboardSample(string path, double time, float volume) { Path = path; Time = time; diff --git a/osu.Game/Storyboards/SpriteDefinition.cs b/osu.Game/Storyboards/StoryboardSprite.cs similarity index 95% rename from osu.Game/Storyboards/SpriteDefinition.cs rename to osu.Game/Storyboards/StoryboardSprite.cs index 4e5c8f8903..598167d720 100644 --- a/osu.Game/Storyboards/SpriteDefinition.cs +++ b/osu.Game/Storyboards/StoryboardSprite.cs @@ -10,7 +10,7 @@ using System.Linq; namespace osu.Game.Storyboards { - public class SpriteDefinition : IElementDefinition + public class StoryboardSprite : IStoryboardElement { private readonly List loops = new List(); private readonly List triggers = new List(); @@ -34,7 +34,7 @@ namespace osu.Game.Storyboards private delegate void DrawablePropertyInitializer(Drawable drawable, T value); private delegate void DrawableTransformer(Drawable drawable, T value, double duration, Easing easing); - public SpriteDefinition(string path, Anchor origin, Vector2 initialPosition) + public StoryboardSprite(string path, Anchor origin, Vector2 initialPosition) { Path = path; Origin = origin; @@ -56,7 +56,7 @@ namespace osu.Game.Storyboards } public virtual Drawable CreateDrawable() - => new StoryboardSprite(this); + => new DrawableStoryboardSprite(this); public void ApplyTransforms(Drawable drawable, IEnumerable> triggeredGroups = null) { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f9980b0b58..737d0cc334 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -81,21 +81,21 @@ - - - - - + + + + + - + - - - - + + + + From fb7740a3ab7abeccf02c1ff574cf4c1a60a2ce1a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Sep 2017 20:25:40 +0900 Subject: [PATCH 455/483] Update all dependencies in line with framework --- NuGet.config | 6 +++++ osu-framework | 2 +- osu.Desktop.Deploy/App.config | 2 +- osu.Desktop.Deploy/osu.Desktop.Deploy.csproj | 17 +++++++------ osu.Desktop.Deploy/packages.config | 8 +++--- osu.Desktop.Tests/OpenTK.dll.config | 25 +++++++++++++++++++ osu.Desktop.Tests/osu.Desktop.Tests.csproj | 10 +++++--- osu.Desktop.Tests/packages.config | 6 ++--- osu.Desktop/OpenTK.dll.config | 4 --- osu.Desktop/app.config | 15 +++++++++++ osu.Desktop/osu.Desktop.csproj | 13 +++++----- osu.Desktop/packages.config | 6 ++--- osu.Game.Rulesets.Catch/OpenTK.dll.config | 4 --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 2 +- osu.Game.Rulesets.Catch/app.config | 11 ++++++++ .../osu.Game.Rulesets.Catch.csproj | 3 ++- osu.Game.Rulesets.Catch/packages.config | 7 +----- osu.Game.Rulesets.Mania/OpenTK.dll.config | 4 --- osu.Game.Rulesets.Mania/app.config | 11 ++++++++ .../osu.Game.Rulesets.Mania.csproj | 3 ++- osu.Game.Rulesets.Mania/packages.config | 6 +---- .../Beatmaps/OsuBeatmapProcessor.cs | 13 +++++----- osu.Game.Rulesets.Osu/OpenTK.dll.config | 4 --- osu.Game.Rulesets.Osu/app.config | 11 ++++++++ .../osu.Game.Rulesets.Osu.csproj | 3 ++- osu.Game.Rulesets.Osu/packages.config | 7 +----- osu.Game.Rulesets.Taiko/OpenTK.dll.config | 4 --- osu.Game.Rulesets.Taiko/app.config | 11 ++++++++ .../osu.Game.Rulesets.Taiko.csproj | 3 ++- osu.Game.Rulesets.Taiko/packages.config | 6 +---- osu.Game.Tests/OpenTK.dll.config | 4 --- osu.Game.Tests/app.config | 11 ++++++++ osu.Game.Tests/osu.Game.Tests.csproj | 7 +++--- osu.Game.Tests/packages.config | 4 +-- osu.Game/Graphics/Backgrounds/Triangles.cs | 6 ++--- osu.Game/Graphics/Cursor/MenuCursor.cs | 2 +- osu.Game/OpenTK.dll.config | 25 +++++++++++++++++++ osu.Game/Screens/Menu/LogoVisualisation.cs | 8 +++--- osu.Game/app.config | 11 ++++++++ osu.Game/osu.Game.csproj | 11 +++++--- osu.Game/packages.config | 6 ++--- 41 files changed, 215 insertions(+), 107 deletions(-) create mode 100644 NuGet.config create mode 100644 osu.Desktop.Tests/OpenTK.dll.config create mode 100644 osu.Desktop/app.config create mode 100644 osu.Game.Rulesets.Catch/app.config create mode 100644 osu.Game.Rulesets.Mania/app.config create mode 100644 osu.Game.Rulesets.Osu/app.config create mode 100644 osu.Game.Rulesets.Taiko/app.config create mode 100644 osu.Game.Tests/app.config create mode 100644 osu.Game/OpenTK.dll.config create mode 100644 osu.Game/app.config diff --git a/NuGet.config b/NuGet.config new file mode 100644 index 0000000000..95f993e510 --- /dev/null +++ b/NuGet.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/osu-framework b/osu-framework index 1a259925b8..f039a8cb70 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 1a259925b82c31ddcebf7b330a6ef9d3a9daf089 +Subproject commit f039a8cb707296238d22b6c382af862725c05928 diff --git a/osu.Desktop.Deploy/App.config b/osu.Desktop.Deploy/App.config index 6711f9c54e..2fae7a5e1c 100644 --- a/osu.Desktop.Deploy/App.config +++ b/osu.Desktop.Deploy/App.config @@ -33,7 +33,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste - + diff --git a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj index c090342a4b..a66c9c8993 100644 --- a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj +++ b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj @@ -66,22 +66,23 @@ True - $(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll - - - $(SolutionDir)\packages\squirrel.windows.1.7.5\lib\Net45\NuGet.Squirrel.dll + $(SolutionDir)\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll True - - $(SolutionDir)\packages\SharpCompress.0.17.1\lib\net45\SharpCompress.dll + + $(SolutionDir)\packages\squirrel.windows.1.7.8\lib\Net45\NuGet.Squirrel.dll + True + + + $(SolutionDir)\packages\SharpCompress.0.18.1\lib\net45\SharpCompress.dll True $(SolutionDir)\packages\Splat.2.0.0\lib\Net45\Splat.dll True - - $(SolutionDir)\packages\squirrel.windows.1.7.5\lib\Net45\Squirrel.dll + + $(SolutionDir)\packages\squirrel.windows.1.7.8\lib\Net45\Squirrel.dll True diff --git a/osu.Desktop.Deploy/packages.config b/osu.Desktop.Deploy/packages.config index 3c5ca9f9a3..7725be5f5e 100644 --- a/osu.Desktop.Deploy/packages.config +++ b/osu.Desktop.Deploy/packages.config @@ -6,9 +6,9 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste - - - + + + - + \ No newline at end of file diff --git a/osu.Desktop.Tests/OpenTK.dll.config b/osu.Desktop.Tests/OpenTK.dll.config new file mode 100644 index 0000000000..5620e3d9e2 --- /dev/null +++ b/osu.Desktop.Tests/OpenTK.dll.config @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/osu.Desktop.Tests/osu.Desktop.Tests.csproj b/osu.Desktop.Tests/osu.Desktop.Tests.csproj index 975af1a782..e40ee5b049 100644 --- a/osu.Desktop.Tests/osu.Desktop.Tests.csproj +++ b/osu.Desktop.Tests/osu.Desktop.Tests.csproj @@ -35,14 +35,15 @@ - $(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll + $(SolutionDir)\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + True - - $(SolutionDir)\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll + + $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True - $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll True @@ -156,6 +157,7 @@ osu.licenseheader + diff --git a/osu.Desktop.Tests/packages.config b/osu.Desktop.Tests/packages.config index ed487e5cd5..ea33822638 100644 --- a/osu.Desktop.Tests/packages.config +++ b/osu.Desktop.Tests/packages.config @@ -4,9 +4,9 @@ Copyright (c) 2007-2017 ppy Pty Ltd . Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE --> - - - + + + diff --git a/osu.Desktop/OpenTK.dll.config b/osu.Desktop/OpenTK.dll.config index 627e9f6009..5620e3d9e2 100644 --- a/osu.Desktop/OpenTK.dll.config +++ b/osu.Desktop/OpenTK.dll.config @@ -1,7 +1,3 @@ - diff --git a/osu.Desktop/app.config b/osu.Desktop/app.config new file mode 100644 index 0000000000..a704cc3750 --- /dev/null +++ b/osu.Desktop/app.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 661c17699b..5eebad47ef 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -136,23 +136,23 @@ - $(SolutionDir)\packages\squirrel.windows.1.7.5\lib\Net45\NuGet.Squirrel.dll + $(SolutionDir)\packages\squirrel.windows.1.7.8\lib\Net45\NuGet.Squirrel.dll True - $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll True - - $(SolutionDir)\packages\SharpCompress.0.17.1\lib\net45\SharpCompress.dll + + $(SolutionDir)\packages\SharpCompress.0.18.1\lib\net45\SharpCompress.dll True $(SolutionDir)\packages\Splat.2.0.0\lib\Net45\Splat.dll True - - $(SolutionDir)\packages\squirrel.windows.1.7.5\lib\Net45\Squirrel.dll + + $(SolutionDir)\packages\squirrel.windows.1.7.8\lib\Net45\Squirrel.dll True @@ -173,6 +173,7 @@ osu.licenseheader + diff --git a/osu.Desktop/packages.config b/osu.Desktop/packages.config index 3ad2106d2b..269b901a97 100644 --- a/osu.Desktop/packages.config +++ b/osu.Desktop/packages.config @@ -7,8 +7,8 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste - - + + - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/OpenTK.dll.config b/osu.Game.Rulesets.Catch/OpenTK.dll.config index 627e9f6009..5620e3d9e2 100644 --- a/osu.Game.Rulesets.Catch/OpenTK.dll.config +++ b/osu.Game.Rulesets.Catch/OpenTK.dll.config @@ -1,7 +1,3 @@ - diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 64dbe04ba4..5fc2cf9ef7 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -163,7 +163,7 @@ namespace osu.Game.Rulesets.Catch.UI float distance = fruit.DrawSize.X / 2 * fruit.Scale.X; - while (Children.OfType().Any(f => Vector2.DistanceSquared(f.Position, fruit.Position) < distance * distance)) + while (Children.OfType().Any(f => Vector2Extensions.DistanceSquared(f.Position, fruit.Position) < distance * distance)) { fruit.X += RNG.Next(-5, 5); fruit.Y -= RNG.Next(0, 5); diff --git a/osu.Game.Rulesets.Catch/app.config b/osu.Game.Rulesets.Catch/app.config new file mode 100644 index 0000000000..faeaf001de --- /dev/null +++ b/osu.Game.Rulesets.Catch/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 2ae2262ac7..18e1ee29ca 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -34,7 +34,7 @@ - $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll True @@ -69,6 +69,7 @@ osu.licenseheader + diff --git a/osu.Game.Rulesets.Catch/packages.config b/osu.Game.Rulesets.Catch/packages.config index fa6edb9c8f..0b1838ceee 100644 --- a/osu.Game.Rulesets.Catch/packages.config +++ b/osu.Game.Rulesets.Catch/packages.config @@ -1,9 +1,4 @@  - - - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/OpenTK.dll.config b/osu.Game.Rulesets.Mania/OpenTK.dll.config index 627e9f6009..5620e3d9e2 100644 --- a/osu.Game.Rulesets.Mania/OpenTK.dll.config +++ b/osu.Game.Rulesets.Mania/OpenTK.dll.config @@ -1,7 +1,3 @@ - diff --git a/osu.Game.Rulesets.Mania/app.config b/osu.Game.Rulesets.Mania/app.config new file mode 100644 index 0000000000..faeaf001de --- /dev/null +++ b/osu.Game.Rulesets.Mania/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index bd540f72c0..739f1cf48c 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -34,7 +34,7 @@ - $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll True @@ -110,6 +110,7 @@ osu.licenseheader + diff --git a/osu.Game.Rulesets.Mania/packages.config b/osu.Game.Rulesets.Mania/packages.config index 8add43d5d5..0b1838ceee 100644 --- a/osu.Game.Rulesets.Mania/packages.config +++ b/osu.Game.Rulesets.Mania/packages.config @@ -1,8 +1,4 @@  - - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index fce0188cda..9379ec22c8 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; +using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Beatmaps; using osu.Game.Rulesets.Objects.Types; @@ -64,8 +65,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps //We are no longer within stacking range of the next object. break; - if (Vector2.Distance(stackBaseObject.Position, objectN.Position) < stack_distance || - stackBaseObject is Slider && Vector2.Distance(stackBaseObject.EndPosition, objectN.Position) < stack_distance) + if (Vector2Extensions.Distance(stackBaseObject.Position, objectN.Position) < stack_distance || + stackBaseObject is Slider && Vector2Extensions.Distance(stackBaseObject.EndPosition, objectN.Position) < stack_distance) { stackBaseIndex = n; @@ -130,14 +131,14 @@ namespace osu.Game.Rulesets.Osu.Beatmaps * o <- hitCircle has stack of -1 * o <- hitCircle has stack of -2 */ - if (objectN is Slider && Vector2.Distance(objectN.EndPosition, objectI.Position) < stack_distance) + if (objectN is Slider && Vector2Extensions.Distance(objectN.EndPosition, objectI.Position) < stack_distance) { int offset = objectI.StackHeight - objectN.StackHeight + 1; for (int j = n + 1; j <= i; j++) { //For each object which was declared under this slider, we will offset it to appear *below* the slider end (rather than above). OsuHitObject objectJ = beatmap.HitObjects[j]; - if (Vector2.Distance(objectN.EndPosition, objectJ.Position) < stack_distance) + if (Vector2Extensions.Distance(objectN.EndPosition, objectJ.Position) < stack_distance) objectJ.StackHeight -= offset; } @@ -146,7 +147,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps break; } - if (Vector2.Distance(objectN.Position, objectI.Position) < stack_distance) + if (Vector2Extensions.Distance(objectN.Position, objectI.Position) < stack_distance) { //Keep processing as if there are no sliders. If we come across a slider, this gets cancelled out. //NOTE: Sliders with start positions stacking are a special case that is also handled here. @@ -170,7 +171,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps //We are no longer within stacking range of the previous object. break; - if (Vector2.Distance(objectN.EndPosition, objectI.Position) < stack_distance) + if (Vector2Extensions.Distance(objectN.EndPosition, objectI.Position) < stack_distance) { objectN.StackHeight = objectI.StackHeight + 1; objectI = objectN; diff --git a/osu.Game.Rulesets.Osu/OpenTK.dll.config b/osu.Game.Rulesets.Osu/OpenTK.dll.config index 627e9f6009..5620e3d9e2 100644 --- a/osu.Game.Rulesets.Osu/OpenTK.dll.config +++ b/osu.Game.Rulesets.Osu/OpenTK.dll.config @@ -1,7 +1,3 @@ - diff --git a/osu.Game.Rulesets.Osu/app.config b/osu.Game.Rulesets.Osu/app.config new file mode 100644 index 0000000000..faeaf001de --- /dev/null +++ b/osu.Game.Rulesets.Osu/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index 857f47f9b9..0963b0ad1b 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -35,7 +35,7 @@ - $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll True @@ -110,6 +110,7 @@ osu.licenseheader + diff --git a/osu.Game.Rulesets.Osu/packages.config b/osu.Game.Rulesets.Osu/packages.config index fa6edb9c8f..0b1838ceee 100644 --- a/osu.Game.Rulesets.Osu/packages.config +++ b/osu.Game.Rulesets.Osu/packages.config @@ -1,9 +1,4 @@  - - - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/OpenTK.dll.config b/osu.Game.Rulesets.Taiko/OpenTK.dll.config index 627e9f6009..5620e3d9e2 100644 --- a/osu.Game.Rulesets.Taiko/OpenTK.dll.config +++ b/osu.Game.Rulesets.Taiko/OpenTK.dll.config @@ -1,7 +1,3 @@ - diff --git a/osu.Game.Rulesets.Taiko/app.config b/osu.Game.Rulesets.Taiko/app.config new file mode 100644 index 0000000000..faeaf001de --- /dev/null +++ b/osu.Game.Rulesets.Taiko/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index a840997214..c8915d233e 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -34,7 +34,7 @@ - $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll True @@ -100,6 +100,7 @@ osu.licenseheader + diff --git a/osu.Game.Rulesets.Taiko/packages.config b/osu.Game.Rulesets.Taiko/packages.config index 8add43d5d5..0b1838ceee 100644 --- a/osu.Game.Rulesets.Taiko/packages.config +++ b/osu.Game.Rulesets.Taiko/packages.config @@ -1,8 +1,4 @@  - - + \ No newline at end of file diff --git a/osu.Game.Tests/OpenTK.dll.config b/osu.Game.Tests/OpenTK.dll.config index 627e9f6009..5620e3d9e2 100644 --- a/osu.Game.Tests/OpenTK.dll.config +++ b/osu.Game.Tests/OpenTK.dll.config @@ -1,7 +1,3 @@ - diff --git a/osu.Game.Tests/app.config b/osu.Game.Tests/app.config new file mode 100644 index 0000000000..faeaf001de --- /dev/null +++ b/osu.Game.Tests/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 220b1aac7f..07190bedb0 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -30,12 +30,12 @@ false - - $(SolutionDir)\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll + + $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True - $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll True @@ -53,6 +53,7 @@ osu.licenseheader + diff --git a/osu.Game.Tests/packages.config b/osu.Game.Tests/packages.config index 9ad76308d7..af47f642e3 100644 --- a/osu.Game.Tests/packages.config +++ b/osu.Game.Tests/packages.config @@ -4,8 +4,8 @@ Copyright (c) 2007-2017 ppy Pty Ltd . Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE --> - - + + \ No newline at end of file diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 08745ce6ba..6312db3ad6 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -228,9 +228,9 @@ namespace osu.Game.Graphics.Backgrounds var size = new Vector2(2 * offset.X, offset.Y); var triangle = new Triangle( - particle.Position * Size * DrawInfo.Matrix, - (particle.Position * Size + offset) * DrawInfo.Matrix, - (particle.Position * Size + new Vector2(-offset.X, offset.Y)) * DrawInfo.Matrix + Vector2Extensions.Transform(particle.Position * Size, DrawInfo.Matrix), + Vector2Extensions.Transform(particle.Position * Size + offset, DrawInfo.Matrix), + Vector2Extensions.Transform(particle.Position * Size + new Vector2(-offset.X, offset.Y), DrawInfo.Matrix) ); ColourInfo colourInfo = DrawInfo.Colour; diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 053ed9c191..36f23d1ae9 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -32,7 +32,7 @@ namespace osu.Game.Graphics.Cursor // don't start rotating until we're moved a minimum distance away from the mouse down location, // else it can have an annoying effect. - startRotation |= Vector2.Distance(state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30; + startRotation |= Vector2Extensions.Distance(state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30; if (startRotation) { diff --git a/osu.Game/OpenTK.dll.config b/osu.Game/OpenTK.dll.config new file mode 100644 index 0000000000..5620e3d9e2 --- /dev/null +++ b/osu.Game/OpenTK.dll.config @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index bc94f88866..4b8942349d 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -201,10 +201,10 @@ namespace osu.Game.Screens.Menu var amplitudeOffset = new Vector2(rotationCos * barSize.Y, rotationSin * barSize.Y); var rectangle = new Quad( - (barPosition - bottomOffset) * DrawInfo.Matrix, - (barPosition - bottomOffset + amplitudeOffset) * DrawInfo.Matrix, - (barPosition + bottomOffset) * DrawInfo.Matrix, - (barPosition + bottomOffset + amplitudeOffset) * DrawInfo.Matrix + Vector2Extensions.Transform(barPosition - bottomOffset, DrawInfo.Matrix), + Vector2Extensions.Transform(barPosition - bottomOffset + amplitudeOffset, DrawInfo.Matrix), + Vector2Extensions.Transform(barPosition + bottomOffset, DrawInfo.Matrix), + Vector2Extensions.Transform(barPosition + bottomOffset + amplitudeOffset, DrawInfo.Matrix) ); Texture.DrawQuad( diff --git a/osu.Game/app.config b/osu.Game/app.config new file mode 100644 index 0000000000..faeaf001de --- /dev/null +++ b/osu.Game/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index e0eafe8422..65ec7d31b3 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -37,15 +37,16 @@ - $(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll + $(SolutionDir)\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + True - $(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll + $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll True - + + $(SolutionDir)\packages\SharpCompress.0.18.1\lib\net45\SharpCompress.dll True - $(SolutionDir)\packages\SharpCompress.0.17.1\lib\net45\SharpCompress.dll $(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll @@ -556,6 +557,8 @@ osu.licenseheader + + diff --git a/osu.Game/packages.config b/osu.Game/packages.config index 434f9328ea..292ba22c06 100644 --- a/osu.Game/packages.config +++ b/osu.Game/packages.config @@ -5,9 +5,9 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste --> - - - + + + From 25f2a102f467966655d6c824afd2c810537b2694 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Sep 2017 20:35:44 +0900 Subject: [PATCH 456/483] Fix CI issue --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index 9379ec22c8..621584ce05 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Beatmaps; From 14efee7ed8568d60953bd6dab3a6a2f20a2d86c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Sep 2017 21:02:07 +0900 Subject: [PATCH 457/483] Update deploy dependency paths Forgot about these. Should probably make them automatically handle version changes at some point... --- osu.Desktop.Deploy/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Desktop.Deploy/Program.cs b/osu.Desktop.Deploy/Program.cs index 644987ce5a..929483b428 100644 --- a/osu.Desktop.Deploy/Program.cs +++ b/osu.Desktop.Deploy/Program.cs @@ -17,8 +17,8 @@ namespace osu.Desktop.Deploy { internal static class Program { - private const string nuget_path = @"packages\NuGet.CommandLine.4.1.0\tools\NuGet.exe"; - private const string squirrel_path = @"packages\squirrel.windows.1.7.5\tools\Squirrel.exe"; + private const string nuget_path = @"packages\NuGet.CommandLine.4.3.0\tools\NuGet.exe"; + private const string squirrel_path = @"packages\squirrel.windows.1.7.8\tools\Squirrel.exe"; private const string msbuild_path = @"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe"; public static string StagingFolder = ConfigurationManager.AppSettings["StagingFolder"]; From 89b5a6670eb535e8b7fcc96e7d092a15ba053c95 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Wed, 13 Sep 2017 16:18:02 +0200 Subject: [PATCH 458/483] Changed type of IHasFilterTerms.FilterTerms according to framework update --- osu.Game/Graphics/UserInterface/OsuButton.cs | 3 ++- osu.Game/Overlays/Chat/ChannelListItem.cs | 3 ++- osu.Game/Overlays/Chat/ChannelSection.cs | 2 +- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 4 ++-- osu.Game/Overlays/Music/PlaylistItem.cs | 2 +- osu.Game/Overlays/Music/PlaylistList.cs | 2 +- osu.Game/Overlays/Settings/SettingsItem.cs | 3 ++- osu.Game/Overlays/Settings/SettingsSection.cs | 2 +- osu.Game/Overlays/Settings/SettingsSubsection.cs | 2 +- 9 files changed, 13 insertions(+), 10 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 32a37a4910..ccc23e3ff6 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -112,7 +113,7 @@ namespace osu.Game.Graphics.UserInterface return base.OnMouseUp(state, args); } - public string[] FilterTerms => new[] { Text }; + public IEnumerable FilterTerms => new[] { Text }; public bool MatchingFilter { diff --git a/osu.Game/Overlays/Chat/ChannelListItem.cs b/osu.Game/Overlays/Chat/ChannelListItem.cs index 8360e793d8..f4cf806044 100644 --- a/osu.Game/Overlays/Chat/ChannelListItem.cs +++ b/osu.Game/Overlays/Chat/ChannelListItem.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 OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; @@ -34,7 +35,7 @@ namespace osu.Game.Overlays.Chat private Color4 topicColour; private Color4 hoverColour; - public string[] FilterTerms => new[] { channel.Name }; + public IEnumerable FilterTerms => new[] { channel.Name }; public bool MatchingFilter { set diff --git a/osu.Game/Overlays/Chat/ChannelSection.cs b/osu.Game/Overlays/Chat/ChannelSection.cs index 1f046aff2a..5068b415bc 100644 --- a/osu.Game/Overlays/Chat/ChannelSection.cs +++ b/osu.Game/Overlays/Chat/ChannelSection.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Chat public readonly FillFlowContainer ChannelFlow; public IEnumerable FilterableChildren => ChannelFlow.Children; - public string[] FilterTerms => new[] { Header }; + public IEnumerable FilterTerms => new[] { Header }; public bool MatchingFilter { set diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 046e56573f..fb84853a0d 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays.KeyBinding private FillFlowContainer buttons; - public string[] FilterTerms => new[] { text.Text }.Concat(bindings.Select(b => b.KeyCombination.ReadableString())).ToArray(); + public IEnumerable FilterTerms => new[] { text.Text }.Concat(bindings.Select(b => b.KeyCombination.ReadableString())).ToArray(); public KeyBindingRow(object action, IEnumerable bindings) { @@ -371,4 +371,4 @@ namespace osu.Game.Overlays.KeyBinding } } } -} \ No newline at end of file +} diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 2aaa182685..723b3f4e96 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -129,7 +129,7 @@ namespace osu.Game.Overlays.Music return true; } - public string[] FilterTerms { get; private set; } + public IEnumerable FilterTerms { get; private set; } private bool matching = true; diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 360e2ad843..6f1eaded7f 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -229,7 +229,7 @@ namespace osu.Game.Overlays.Music private class ItemSearchContainer : FillFlowContainer, IHasFilterableChildren { - public string[] FilterTerms => new string[] { }; + public IEnumerable FilterTerms => new string[] { }; public bool MatchingFilter { set diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index c74f4070e7..f2044f178b 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Collections.Generic; using OpenTK.Graphics; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -53,7 +54,7 @@ namespace osu.Game.Overlays.Settings } } - public string[] FilterTerms => new[] { LabelText }; + public IEnumerable FilterTerms => new[] { LabelText }; public bool MatchingFilter { diff --git a/osu.Game/Overlays/Settings/SettingsSection.cs b/osu.Game/Overlays/Settings/SettingsSection.cs index f091192d27..eb6e398477 100644 --- a/osu.Game/Overlays/Settings/SettingsSection.cs +++ b/osu.Game/Overlays/Settings/SettingsSection.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Settings public abstract string Header { get; } public IEnumerable FilterableChildren => Children.OfType(); - public string[] FilterTerms => new[] { Header }; + public IEnumerable FilterTerms => new[] { Header }; private const int header_size = 26; private const int header_margin = 25; diff --git a/osu.Game/Overlays/Settings/SettingsSubsection.cs b/osu.Game/Overlays/Settings/SettingsSubsection.cs index 0fbb5b92f7..4164ceee21 100644 --- a/osu.Game/Overlays/Settings/SettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/SettingsSubsection.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Settings protected abstract string Header { get; } public IEnumerable FilterableChildren => Children.OfType(); - public string[] FilterTerms => new[] { Header }; + public IEnumerable FilterTerms => new[] { Header }; public bool MatchingFilter { set From 886ad7496d6fc471efbd71f6b3b706e1676eed43 Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 13 Sep 2017 17:35:05 +0200 Subject: [PATCH 459/483] Implement random mod for osu!mania --- osu.Game.Rulesets.Mania/Mods/ManiaMod.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs index 60415632a8..7c01af3b15 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs @@ -4,6 +4,9 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using System; +using System.Linq; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Replays; @@ -83,12 +86,20 @@ namespace osu.Game.Rulesets.Mania.Mods public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) }; } - public class ManiaModRandom : Mod + public class ManiaModRandom : Mod, IApplicableMod { public override string Name => "Random"; public override string ShortenedName => "RD"; public override string Description => @"Shuffle around the notes!"; public override double ScoreMultiplier => 1; + public void ApplyToRulesetContainer(RulesetContainer rulesetContainer) + { + int availableColumns = ((ManiaRulesetContainer)rulesetContainer).AvailableColumns; + + var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList(); + + rulesetContainer.Objects.OfType().ForEach(h => h.Column = shuffledColumns[h.Column]); + } } public abstract class ManiaKeyMod : Mod From 4a232bbc046cf19ce5607c4c38048eb5ea053375 Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Wed, 13 Sep 2017 18:44:44 +0200 Subject: [PATCH 460/483] updated framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index f039a8cb70..b060218232 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit f039a8cb707296238d22b6c382af862725c05928 +Subproject commit b060218232fcd6f24d4922d05160616db0195bd4 From ae3e118584786add6bb5850761873b1755c75506 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Thu, 14 Sep 2017 09:32:10 +0900 Subject: [PATCH 461/483] Dummy commit to test CI --- osu.Game.Rulesets.Mania/Mods/ManiaMod.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs index 7c01af3b15..56a41d32e8 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs @@ -92,10 +92,10 @@ namespace osu.Game.Rulesets.Mania.Mods public override string ShortenedName => "RD"; public override string Description => @"Shuffle around the notes!"; public override double ScoreMultiplier => 1; + public void ApplyToRulesetContainer(RulesetContainer rulesetContainer) { int availableColumns = ((ManiaRulesetContainer)rulesetContainer).AvailableColumns; - var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList(); rulesetContainer.Objects.OfType().ForEach(h => h.Column = shuffledColumns[h.Column]); From b1145272d1c7cc3d7dc51ef178cd2df700102e5c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Sep 2017 12:58:32 +0900 Subject: [PATCH 462/483] Update code to support new inspectcode analysis rules --- appveyor.yml | 1 + osu-framework | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 7 +++++-- osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs | 2 +- .../Overlays/Settings/Sections/General/UpdateSettings.cs | 2 +- .../Overlays/Settings/Sections/Input/KeyboardSettings.cs | 2 +- osu.Game/Screens/Menu/MainMenu.cs | 2 +- osu.Game/Screens/Play/SongProgressGraph.cs | 8 ++++++-- osu.Game/Screens/Select/SongSelect.cs | 2 +- osu.Game/Screens/Tournament/Drawings.cs | 2 +- osu.Game/Users/Avatar.cs | 2 +- osu.sln.DotSettings | 3 +++ 12 files changed, 23 insertions(+), 12 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b26a895788..21c15724e6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,3 +1,4 @@ +# 2017-09-14 clone_depth: 1 version: '{branch}-{build}' configuration: Debug diff --git a/osu-framework b/osu-framework index b060218232..7347c386dc 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit b060218232fcd6f24d4922d05160616db0195bd4 +Subproject commit 7347c386dcd10eb799b1ce1512536879328109f9 diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index df8e7f5e3b..bb3122489e 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -100,8 +100,11 @@ namespace osu.Game.Beatmaps public void TransferTo(WorkingBeatmap other) { - if (track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo)) - other.track = track; + lock (trackLock) + { + if (track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo)) + other.track = track; + } if (background != null && BeatmapInfo.BackgroundEquals(other.BeatmapInfo)) other.background = background; diff --git a/osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs b/osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs index 0a32b50809..495a2543d1 100644 --- a/osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Debug/GCSettings.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Settings.Sections.Debug { RelativeSizeAxes = Axes.X, Text = "Force garbage collection", - Action = () => GC.Collect() + Action = GC.Collect }, }; } diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs index 01e32b5a1b..833a5ff966 100644 --- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Settings.Sections.General { RelativeSizeAxes = Axes.X, Text = "Open osu! folder", - Action = () => storage.OpenInNativeExplorer(), + Action = storage.OpenInNativeExplorer, } }; } diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyboardSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyboardSettings.cs index 01e73d0168..b68fd4bc04 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyboardSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyboardSettings.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input { RelativeSizeAxes = Axes.X, Text = "Key Configuration", - Action = () => keyConfig.ToggleVisibility() + Action = keyConfig.ToggleVisibility }, }; } diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 2544cc2837..1c82d15f50 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Menu OnEdit = delegate { Push(new Editor()); }, OnSolo = delegate { Push(consumeSongSelect()); }, OnMulti = delegate { Push(new Lobby()); }, - OnExit = delegate { Exit(); }, + OnExit = Exit, } } }, diff --git a/osu.Game/Screens/Play/SongProgressGraph.cs b/osu.Game/Screens/Play/SongProgressGraph.cs index 541065e532..dc4deaaefc 100644 --- a/osu.Game/Screens/Play/SongProgressGraph.cs +++ b/osu.Game/Screens/Play/SongProgressGraph.cs @@ -1,8 +1,10 @@ // Copyright (c) 2007-2017 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 System.Diagnostics; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects; @@ -34,10 +36,12 @@ namespace osu.Game.Screens.Play foreach (var h in objects) { - IHasEndTime end = h as IHasEndTime; + var endTime = Math.Max((h as IHasEndTime)?.EndTime ?? h.StartTime, h.StartTime); + + Debug.Assert(endTime > h.StartTime); int startRange = (int)((h.StartTime - firstHit) / interval); - int endRange = (int)(((end?.EndTime > 0 ? end.EndTime : h.StartTime) - firstHit) / interval); + int endRange = (int)((endTime - firstHit) / interval); for (int i = startRange; i <= endRange; i++) Values[i]++; } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index f97c4fe420..84457b77a7 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -106,7 +106,7 @@ namespace osu.Game.Screens.Select Origin = Anchor.CentreRight, SelectionChanged = carouselSelectionChanged, BeatmapsChanged = carouselBeatmapsLoaded, - DeleteRequested = b => promptDelete(b), + DeleteRequested = promptDelete, RestoreRequested = s => { foreach (var b in s.Beatmaps) manager.Restore(b); }, HideDifficultyRequested = b => manager.Hide(b), StartRequested = () => carouselRaisedStart(), diff --git a/osu.Game/Screens/Tournament/Drawings.cs b/osu.Game/Screens/Tournament/Drawings.cs index 7cd81a924d..3d27552212 100644 --- a/osu.Game/Screens/Tournament/Drawings.cs +++ b/osu.Game/Screens/Tournament/Drawings.cs @@ -237,7 +237,7 @@ namespace osu.Game.Screens.Tournament RelativeSizeAxes = Axes.X, Text = "Reset", - Action = () => reset(false) + Action = () => reset() } } } diff --git a/osu.Game/Users/Avatar.cs b/osu.Game/Users/Avatar.cs index 5d518f1780..111c901ca0 100644 --- a/osu.Game/Users/Avatar.cs +++ b/osu.Game/Users/Avatar.cs @@ -26,7 +26,7 @@ namespace osu.Game.Users private void load(TextureStore textures) { Texture texture = null; - if (user?.Id > 1) texture = textures.Get($@"https://a.ppy.sh/{user.Id}"); + if (user != null && user.Id > 1) texture = textures.Get($@"https://a.ppy.sh/{user.Id}"); if (texture == null) texture = textures.Get(@"Online/avatar-guest"); Add(new Sprite diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 0b8c196ec8..8988908ee2 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -56,6 +56,8 @@ WARNING HINT HINT + HINT + HINT HINT WARNING WARNING @@ -617,6 +619,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-frame <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> + <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> From fe90570d0ffab34ea977060d3612cf12ec3ee021 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Sep 2017 13:10:24 +0900 Subject: [PATCH 463/483] Lower inheritdoc code suggestions to hint level --- osu.sln.DotSettings | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 8988908ee2..4011e3991f 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -42,6 +42,7 @@ WARNING WARNING ERROR + HINT HINT WARNING WARNING From 4f09f30b7a501d478173aad5091dd38932ef1526 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Sep 2017 13:13:54 +0900 Subject: [PATCH 464/483] Fix incorrect exception --- osu.Game/Screens/Play/SongProgressGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/SongProgressGraph.cs b/osu.Game/Screens/Play/SongProgressGraph.cs index dc4deaaefc..4455b97a7e 100644 --- a/osu.Game/Screens/Play/SongProgressGraph.cs +++ b/osu.Game/Screens/Play/SongProgressGraph.cs @@ -38,7 +38,7 @@ namespace osu.Game.Screens.Play { var endTime = Math.Max((h as IHasEndTime)?.EndTime ?? h.StartTime, h.StartTime); - Debug.Assert(endTime > h.StartTime); + Debug.Assert(endTime >= h.StartTime); int startRange = (int)((h.StartTime - firstHit) / interval); int endRange = (int)((endTime - firstHit) / interval); From d330b39db492a8b85b79a93e5ed1d6018db0b1bb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Sep 2017 13:42:58 +0900 Subject: [PATCH 465/483] Remove max --- osu.Game/Screens/Play/SongProgressGraph.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/SongProgressGraph.cs b/osu.Game/Screens/Play/SongProgressGraph.cs index 4455b97a7e..38c680902a 100644 --- a/osu.Game/Screens/Play/SongProgressGraph.cs +++ b/osu.Game/Screens/Play/SongProgressGraph.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 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 System.Diagnostics; @@ -36,7 +35,7 @@ namespace osu.Game.Screens.Play foreach (var h in objects) { - var endTime = Math.Max((h as IHasEndTime)?.EndTime ?? h.StartTime, h.StartTime); + var endTime = (h as IHasEndTime)?.EndTime ?? h.StartTime; Debug.Assert(endTime >= h.StartTime); From bdf62870d10ca8b818b8da7504945b1d44fe826a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Sep 2017 15:40:36 +0900 Subject: [PATCH 466/483] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 7347c386dc..3f4545aae8 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 7347c386dcd10eb799b1ce1512536879328109f9 +Subproject commit 3f4545aae82650dc87cac7dd5df64e6e47918da1 From 396a56ddf4febbaffd9a934934e281ebfd133eaf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Sep 2017 15:41:32 +0900 Subject: [PATCH 467/483] Remove global OsuContextMenuContainer --- osu.Game/OsuGameBase.cs | 3 +-- osu.Game/Screens/Select/BeatmapCarousel.cs | 8 +++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index d81c7cdf73..79e03a8141 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -200,10 +200,9 @@ namespace osu.Game globalBinding = new GlobalKeyBindingInputManager(this) { RelativeSizeAxes = Axes.Both, - Child = new OsuTooltipContainer(Cursor) + Child = content = new OsuTooltipContainer(Cursor) { RelativeSizeAxes = Axes.Both, - Child = content = new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both }, } } } diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 94ae740c74..abd288baf2 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -19,6 +19,7 @@ using osu.Framework.Threading; using osu.Framework.Configuration; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Cursor; namespace osu.Game.Screens.Select { @@ -86,9 +87,14 @@ namespace osu.Game.Screens.Select public BeatmapCarousel() { - Add(scrollableContent = new Container + Add(new OsuContextMenuContainer { RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = scrollableContent = new Container + { + RelativeSizeAxes = Axes.X, + } }); } From b7c981968091ede7cbc38b19934abba2ee4d09dd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Sep 2017 15:43:47 +0900 Subject: [PATCH 468/483] Add context menus to chat names and user panels --- osu.Game/Overlays/Chat/ChatLine.cs | 33 ++++++++++++++---- osu.Game/Overlays/Chat/DrawableChannel.cs | 34 +++++++++++-------- osu.Game/Overlays/LoginOverlay.cs | 4 +-- .../Sections/General/LoginSettings.cs | 4 --- osu.Game/Overlays/SocialOverlay.cs | 12 +++++-- osu.Game/Users/UserPanel.cs | 14 ++++++-- 6 files changed, 69 insertions(+), 32 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index afc6589f57..cac0ce01ae 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; @@ -13,6 +12,9 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Online.Chat; using osu.Game.Users; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Chat { @@ -63,8 +65,6 @@ namespace osu.Game.Overlays.Chat private const float message_padding = 200; private const float text_size = 20; - private Action loadProfile; - private Color4 customUsernameColour; private OsuSpriteText timestamp; @@ -100,10 +100,9 @@ namespace osu.Game.Overlays.Chat } [BackgroundDependencyLoader(true)] - private void load(OsuColour colours, UserProfileOverlay profile) + private void load(OsuColour colours) { customUsernameColour = colours.ChatBlue; - loadProfile = u => profile?.ShowUser(u); } private bool senderHasBackground => !string.IsNullOrEmpty(message.Sender.Colour); @@ -171,13 +170,12 @@ namespace osu.Game.Overlays.Chat FixedWidth = true, TextSize = text_size * 0.75f, }, - new ClickableContainer + new MessageSender(message.Sender) { AutoSizeAxes = Axes.Both, Origin = Anchor.TopRight, Anchor = Anchor.TopRight, Child = effectedUsername, - Action = () => loadProfile(message.Sender), }, } }, @@ -210,5 +208,26 @@ namespace osu.Game.Overlays.Chat username.Text = $@"{message.Sender.Username}" + (senderHasBackground ? "" : ":"); contentFlow.Text = message.Content; } + + private class MessageSender : ClickableContainer, IHasContextMenu + { + private readonly User sender; + + public MessageSender(User sender) + { + this.sender = sender; + } + + [BackgroundDependencyLoader(true)] + private void load(UserProfileOverlay profile) + { + Action = () => profile?.ShowUser(sender); + } + + public MenuItem[] ContextMenuItems => new MenuItem[] + { + new OsuMenuItem("View Profile", MenuItemType.Highlighted, Action), + }; + } } } diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 840edaece2..7179d8ed90 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -10,23 +10,13 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Cursor; using osu.Game.Online.Chat; namespace osu.Game.Overlays.Chat { public class DrawableChannel : Container { - private class ChatLineContainer : FillFlowContainer - { - protected override int Compare(Drawable x, Drawable y) - { - var xC = (ChatLine)x; - var yC = (ChatLine)y; - - return xC.Message.CompareTo(yC.Message); - } - } - public readonly Channel Channel; private readonly ChatLineContainer flow; private readonly ScrollContainer scroll; @@ -45,12 +35,17 @@ namespace osu.Game.Overlays.Chat // Some chat lines have effects that slightly protrude to the bottom, // which we do not want to mask away, hence the padding. Padding = new MarginPadding { Bottom = 5 }, - Child = flow = new ChatLineContainer + Child = new OsuContextMenuContainer { - Padding = new MarginPadding { Left = 20, Right = 20 }, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, + Child = flow = new ChatLineContainer + { + Padding = new MarginPadding { Left = 20, Right = 20 }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + } }, } }; @@ -124,5 +119,16 @@ namespace osu.Game.Overlays.Chat } private void scrollToEnd() => ScheduleAfterChildren(() => scroll.ScrollToEnd()); + + private class ChatLineContainer : FillFlowContainer + { + protected override int Compare(Drawable x, Drawable y) + { + var xC = (ChatLine)x; + var yC = (ChatLine)y; + + return xC.Message.CompareTo(yC.Message); + } + } } } diff --git a/osu.Game/Overlays/LoginOverlay.cs b/osu.Game/Overlays/LoginOverlay.cs index 1bce31c789..58b259fcbb 100644 --- a/osu.Game/Overlays/LoginOverlay.cs +++ b/osu.Game/Overlays/LoginOverlay.cs @@ -3,12 +3,12 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Overlays.Settings.Sections.General; using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Cursor; namespace osu.Game.Overlays { @@ -34,7 +34,7 @@ namespace osu.Game.Overlays Colour = Color4.Black, Alpha = 0.6f, }, - new Container + new OsuContextMenuContainer { Width = 360, AutoSizeAxes = Axes.Y, diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index e62050fae1..8b7d7b0d69 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -366,10 +366,6 @@ namespace osu.Game.Overlays.Settings.Sections.General BackgroundColour = colours.Gray3; } } - - - - } private enum UserAction diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 1cd2343848..954a838461 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -9,6 +9,7 @@ using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; +using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; @@ -63,12 +64,17 @@ namespace osu.Game.Overlays ScrollFlow.Children = new[] { - panelFlow = new FillFlowContainer + new OsuContextMenuContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 20 }, - Spacing = new Vector2(10f), + Child = panelFlow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 20 }, + Spacing = new Vector2(10f), + } }, }; diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 89bd4b68d2..e5518b5845 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -13,10 +13,13 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics.UserInterface; +using osu.Framework.Graphics.Cursor; namespace osu.Game.Users { - public class UserPanel : ClickableContainer + public class UserPanel : ClickableContainer, IHasContextMenu { private readonly User user; private const float height = 100; @@ -31,6 +34,8 @@ namespace osu.Game.Users public new Action Action; + protected Action ViewProfile; + public UserPanel(User user) { this.user = user; @@ -171,7 +176,7 @@ namespace osu.Game.Users Status.ValueChanged += displayStatus; Status.ValueChanged += status => statusBg.FadeColour(status?.GetAppropriateColour(colours) ?? colours.Gray5, 500, Easing.OutQuint); - base.Action = () => + base.Action = ViewProfile = () => { Action?.Invoke(); profile?.ShowUser(user); @@ -203,5 +208,10 @@ namespace osu.Game.Users statusMessage.Text = status.Message; } } + + public MenuItem[] ContextMenuItems => new MenuItem[] + { + new OsuMenuItem("View Profile", MenuItemType.Highlighted, ViewProfile), + }; } } From 160f48bf8587f0a38b15d92fb5187edb84bbb11d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Sep 2017 17:50:50 +0900 Subject: [PATCH 469/483] Make VisualTests target 64 bit where possible --- osu.Desktop/osu.Desktop.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 5eebad47ef..bb9852681c 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -104,6 +104,7 @@ prompt AllRules.ruleset --tests + false From db6437eea9fc1a79e7655cd7cc098cd8383f2b07 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Sep 2017 17:58:42 +0900 Subject: [PATCH 470/483] Remove very old defined constants --- osu.Desktop/osu.Desktop.csproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index bb9852681c..ef57265a06 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -69,7 +69,8 @@ none true bin\Release\ - CuttingEdge NoUpdate + + prompt 4 true From 7cd6caacaa2e0b1be559a1660ef63cc0a349abdd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Sep 2017 18:08:12 +0900 Subject: [PATCH 471/483] Update to support newer return structure from osu-web API --- .../Visual/TestCaseUserProfile.cs | 9 +++----- osu.Game/Overlays/Profile/RankChart.cs | 2 +- osu.Game/Users/User.cs | 23 ++++--------------- 3 files changed, 8 insertions(+), 26 deletions(-) diff --git a/osu.Desktop.Tests/Visual/TestCaseUserProfile.cs b/osu.Desktop.Tests/Visual/TestCaseUserProfile.cs index e5955441dc..a94177c1b6 100644 --- a/osu.Desktop.Tests/Visual/TestCaseUserProfile.cs +++ b/osu.Desktop.Tests/Visual/TestCaseUserProfile.cs @@ -33,13 +33,10 @@ namespace osu.Desktop.Tests.Visual Rank = 2148, PP = 4567.89m }, - AllRankHistories = new User.RankHistories + RankHistory = new User.RankHistoryData { - Osu = new User.RankHistory - { - Mode = @"osu", - Data = Enumerable.Range(2345,45).Concat(Enumerable.Range(2109,40)).ToArray() - } + Mode = @"osu", + Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() } }, false)); AddStep("Show ppy", () => profile.ShowUser(new User diff --git a/osu.Game/Overlays/Profile/RankChart.cs b/osu.Game/Overlays/Profile/RankChart.cs index 416bcedfea..2e2286098a 100644 --- a/osu.Game/Overlays/Profile/RankChart.cs +++ b/osu.Game/Overlays/Profile/RankChart.cs @@ -70,7 +70,7 @@ namespace osu.Game.Overlays.Profile } }; - ranks = user.AllRankHistories?.Osu?.Data ?? new[] { user.Statistics.Rank }; + ranks = user.RankHistory?.Data ?? new[] { user.Statistics.Rank }; } private void updateRankTexts() diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index 37b426ac2c..2adb809334 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -122,25 +122,10 @@ namespace osu.Game.Users public int Available; } - [JsonProperty(@"defaultStatistics")] + [JsonProperty(@"statistics")] public UserStatistics Statistics; - public class RankHistories - { - [JsonProperty(@"osu")] - public RankHistory Osu; - - [JsonProperty(@"taiko")] - public RankHistory Taiko; - - [JsonProperty(@"fruits")] - public RankHistory Fruits; - - [JsonProperty(@"mania")] - public RankHistory Mania; - } - - public class RankHistory + public class RankHistoryData { [JsonProperty(@"mode")] public string Mode; @@ -149,7 +134,7 @@ namespace osu.Game.Users public int[] Data; } - [JsonProperty(@"allRankHistories")] - public RankHistories AllRankHistories; + [JsonProperty(@"rankHistory")] + public RankHistoryData RankHistory; } } From a42fb4af2aa716dbe5ec3aebc29b96da1bc6e614 Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 14 Sep 2017 12:04:05 +0200 Subject: [PATCH 472/483] Add icon for random mod --- osu.Game.Rulesets.Mania/Mods/ManiaMod.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs index 56a41d32e8..037c3bd567 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs @@ -90,12 +90,14 @@ namespace osu.Game.Rulesets.Mania.Mods { public override string Name => "Random"; public override string ShortenedName => "RD"; + public override FontAwesome Icon => FontAwesome.fa_osu_dice; public override string Description => @"Shuffle around the notes!"; public override double ScoreMultiplier => 1; public void ApplyToRulesetContainer(RulesetContainer rulesetContainer) { int availableColumns = ((ManiaRulesetContainer)rulesetContainer).AvailableColumns; + var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList(); rulesetContainer.Objects.OfType().ForEach(h => h.Column = shuffledColumns[h.Column]); From 1e0ce6dabd70f4ce5bd28eeaded542460674485a Mon Sep 17 00:00:00 2001 From: MrTheMake Date: Thu, 14 Sep 2017 13:18:50 +0200 Subject: [PATCH 473/483] Removed unnecessary casting of KeyBindingRow.FilterTerms --- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index fb84853a0d..4141a502a0 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays.KeyBinding private FillFlowContainer buttons; - public IEnumerable FilterTerms => new[] { text.Text }.Concat(bindings.Select(b => b.KeyCombination.ReadableString())).ToArray(); + public IEnumerable FilterTerms => new[] { text.Text }.Concat(bindings.Select(b => b.KeyCombination.ReadableString())); public KeyBindingRow(object action, IEnumerable bindings) { From 9e059a2ef041c323767fb33dd95e1db96eeb27a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Sep 2017 00:25:38 +0900 Subject: [PATCH 474/483] Force clean before deploying Ensures app.config is up-to-date before deploying, rather than using a potentially old version --- 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 929483b428..a181a6fa5e 100644 --- a/osu.Desktop.Deploy/Program.cs +++ b/osu.Desktop.Deploy/Program.cs @@ -100,7 +100,7 @@ namespace osu.Desktop.Deploy updateAssemblyInfo(version); write("Running build process..."); - runCommand(msbuild_path, $"/v:quiet /m /t:{TargetName.Replace('.', '_')} /p:OutputPath={stagingPath};Configuration=Release {SolutionName}.sln"); + runCommand(msbuild_path, $"/v:quiet /m /t:{TargetName.Replace('.', '_')} /p:OutputPath={stagingPath};Targets=\"Clean;Build\";Configuration=Release {SolutionName}.sln"); write("Creating NuGet deployment package..."); runCommand(nuget_path, $"pack {NuSpecName} -Version {version} -Properties Configuration=Deploy -OutputDirectory {stagingPath} -BasePath {stagingPath}"); From 6ea22cc6c7c677f266b86e51079f9ee72bee24dc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Sep 2017 08:15:23 +0900 Subject: [PATCH 475/483] Add missing return to PlayerLoader was being a bit too eager previously --- osu.Game/Screens/Play/PlayerLoader.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 1cac1bd2ad..58aee0380f 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -109,7 +109,10 @@ namespace osu.Game.Screens.Play private void pushWhenLoaded() { if (!player.IsLoaded) + { Schedule(pushWhenLoaded); + return; + } contentOut(); From b72921b30ee888c73d38b3f2f49303f3a3cb71b8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Sep 2017 12:44:48 +0900 Subject: [PATCH 476/483] Ensure an OnlineBeatmapID is present before attempting API requests --- osu.Game/Online/API/Requests/GetScoresRequest.cs | 12 +++--------- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index ef9ee85d25..13bd8d288d 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; -using osu.Framework.IO.Network; using osu.Game.Beatmaps; using osu.Game.Users; using osu.Game.Rulesets.Replays; @@ -19,6 +18,9 @@ namespace osu.Game.Online.API.Requests public GetScoresRequest(BeatmapInfo beatmap) { + if (!beatmap.OnlineBeatmapID.HasValue) + throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(BeatmapInfo.OnlineBeatmapID)}."); + this.beatmap = beatmap; Success += onSuccess; @@ -30,14 +32,6 @@ namespace osu.Game.Online.API.Requests score.ApplyBeatmap(beatmap); } - protected override WebRequest CreateWebRequest() - { - var req = base.CreateWebRequest(); - //req.AddParameter(@"c", beatmap.Hash); - //req.AddParameter(@"f", beatmap.Path); - return req; - } - protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores"; } diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 0506784614..7d65b8b648 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -130,7 +130,7 @@ namespace osu.Game.Screens.Select.Leaderboards Scores = null; getScoresRequest?.Cancel(); - if (api == null || Beatmap == null) return; + if (api == null || Beatmap?.OnlineBeatmapID == null) return; loading.Show(); From 010a6ec252d0d3e41b64469271ed165d82e145c4 Mon Sep 17 00:00:00 2001 From: Damnae Date: Fri, 15 Sep 2017 09:06:27 +0200 Subject: [PATCH 477/483] Fix player loading. --- osu.Game/Screens/Play/PlayerLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 58aee0380f..9366797f47 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -108,7 +108,7 @@ namespace osu.Game.Screens.Play private void pushWhenLoaded() { - if (!player.IsLoaded) + if (player.LoadState != LoadState.Ready) { Schedule(pushWhenLoaded); return; From 47b62803d866c6101486dd65d3e4f0f116f03707 Mon Sep 17 00:00:00 2001 From: ColdVolcano Date: Fri, 15 Sep 2017 15:47:56 -0500 Subject: [PATCH 478/483] Account for all files instead of just the main directory ones --- osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs b/osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs index dc38181717..8857a4ad42 100644 --- a/osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs +++ b/osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs @@ -26,7 +26,7 @@ namespace osu.Game.Beatmaps.IO // no-op } - public override IEnumerable Filenames => Directory.GetFiles(path).Select(Path.GetFileName).ToArray(); + public override IEnumerable Filenames => Directory.GetDirectories(path).Select(Path.GetFileName).ToArray(); public override Stream GetUnderlyingStream() => null; } From 51a5e963bb80aff199e34df8ed5f1e96150746e2 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Sat, 16 Sep 2017 15:10:24 +0300 Subject: [PATCH 479/483] Dispose IDisposable object before method returns --- osu.Game/Online/API/OAuth.cs | 37 +++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/osu.Game/Online/API/OAuth.cs b/osu.Game/Online/API/OAuth.cs index c96b21a855..5410bcc55d 100644 --- a/osu.Game/Online/API/OAuth.cs +++ b/osu.Game/Online/API/OAuth.cs @@ -27,42 +27,45 @@ namespace osu.Game.Online.API internal bool AuthenticateWithLogin(string username, string password) { - var req = new AccessTokenRequestPassword(username, password) + using (var req = new AccessTokenRequestPassword(username, password) { Url = $@"{endpoint}/oauth/token", Method = HttpMethod.POST, ClientId = clientId, ClientSecret = clientSecret - }; - - try + }) { - req.BlockingPerform(); - } - catch - { - return false; - } + try + { + req.BlockingPerform(); + } + catch + { + return false; + } - Token = req.ResponseObject; - return true; + Token = req.ResponseObject; + return true; + } } internal bool AuthenticateWithRefresh(string refresh) { try { - var req = new AccessTokenRequestRefresh(refresh) + using (var req = new AccessTokenRequestRefresh(refresh) { Url = $@"{endpoint}/oauth/token", Method = HttpMethod.POST, ClientId = clientId, ClientSecret = clientSecret - }; - req.BlockingPerform(); + }) + { + req.BlockingPerform(); - Token = req.ResponseObject; - return true; + Token = req.ResponseObject; + return true; + } } catch { From 8944d0f705c6a1e4ac3b1a8b0fb9269f2f3e00b2 Mon Sep 17 00:00:00 2001 From: ColdVolcano Date: Sat, 16 Sep 2017 18:44:32 -0500 Subject: [PATCH 480/483] make it only look for files instead of directories --- osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs b/osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs index 8857a4ad42..21042ad8bd 100644 --- a/osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs +++ b/osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs @@ -26,7 +26,7 @@ namespace osu.Game.Beatmaps.IO // no-op } - public override IEnumerable Filenames => Directory.GetDirectories(path).Select(Path.GetFileName).ToArray(); + public override IEnumerable Filenames => Directory.GetFiles(path, "*", SearchOption.AllDirectories).Select(Path.GetFileName).ToArray(); public override Stream GetUnderlyingStream() => null; } From 15d3a998fac91862752f3586546d8a7fe74afbb8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 17 Sep 2017 21:57:40 +0900 Subject: [PATCH 481/483] Don't unlimit FPS for visual tests --- osu.Desktop/OsuTestBrowser.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Desktop/OsuTestBrowser.cs b/osu.Desktop/OsuTestBrowser.cs index 50af9bd317..23617de1c0 100644 --- a/osu.Desktop/OsuTestBrowser.cs +++ b/osu.Desktop/OsuTestBrowser.cs @@ -24,11 +24,6 @@ namespace osu.Desktop public override void SetHost(GameHost host) { base.SetHost(host); - - host.UpdateThread.InactiveHz = host.UpdateThread.ActiveHz; - host.DrawThread.InactiveHz = host.DrawThread.ActiveHz; - host.InputThread.InactiveHz = host.InputThread.ActiveHz; - host.Window.CursorState |= CursorState.Hidden; } } From d62ad89150d751879460b8e3cd30319cc7594f6e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Sep 2017 14:09:44 +0900 Subject: [PATCH 482/483] Remove unnecessary Microsoft.Net.Http include --- osu.Desktop/osu.Desktop.csproj | 8 -------- osu.Desktop/packages.config | 1 - 2 files changed, 9 deletions(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index ef57265a06..87d9ce8eec 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -160,14 +160,6 @@ - - $(SolutionDir)\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll - True - - - $(SolutionDir)\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll - True - diff --git a/osu.Desktop/packages.config b/osu.Desktop/packages.config index 269b901a97..58f9102aa1 100644 --- a/osu.Desktop/packages.config +++ b/osu.Desktop/packages.config @@ -5,7 +5,6 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste --> - From 5a76ed4000075aecd01fa0c3583709d6d34f811c Mon Sep 17 00:00:00 2001 From: Damnae Date: Mon, 18 Sep 2017 10:14:29 +0200 Subject: [PATCH 483/483] Fix LegacyFilesystemReader Filenames property. --- osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs b/osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs index 21042ad8bd..79a47c8724 100644 --- a/osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs +++ b/osu.Game/Beatmaps/IO/LegacyFilesystemReader.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.IO.File; using System.Collections.Generic; using System.IO; using System.Linq; @@ -26,7 +27,7 @@ namespace osu.Game.Beatmaps.IO // no-op } - public override IEnumerable Filenames => Directory.GetFiles(path, "*", SearchOption.AllDirectories).Select(Path.GetFileName).ToArray(); + public override IEnumerable Filenames => Directory.GetFiles(path, "*", SearchOption.AllDirectories).Select(f => FileSafety.GetRelativePath(f, path)).ToArray(); public override Stream GetUnderlyingStream() => null; }