From bc53642cab6380c1a917f89e01a48540a4922e8c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2016 15:40:05 +0900 Subject: [PATCH 01/28] Fix some warnings. --- osu.Game/Beatmaps/Timing/TimingChange.cs | 5 +++++ osu.Game/Graphics/Background/Background.cs | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Timing/TimingChange.cs b/osu.Game/Beatmaps/Timing/TimingChange.cs index dd2b9cdc7c..da552881a1 100644 --- a/osu.Game/Beatmaps/Timing/TimingChange.cs +++ b/osu.Game/Beatmaps/Timing/TimingChange.cs @@ -13,6 +13,11 @@ namespace osu.Game.Beatmaps.Timing { public double BeatLength; + public TimingChange(double beatLength) + { + BeatLength = beatLength; + } + public double BPM => 60000 / BeatLength; } } diff --git a/osu.Game/Graphics/Background/Background.cs b/osu.Game/Graphics/Background/Background.cs index bb5b229f8b..1b36feb761 100644 --- a/osu.Game/Graphics/Background/Background.cs +++ b/osu.Game/Graphics/Background/Background.cs @@ -27,8 +27,6 @@ namespace osu.Game.Graphics.Background Depth = float.MinValue; } - Texture texture; - protected override void Load(BaseGame game) { base.Load(game); From 7e6d5a28b1bd2bb93a1a629f0988d7ecef60cc48 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 12:22:22 +0900 Subject: [PATCH 02/28] Scale up TestCaseHitObjects so detail is a bit more visible. --- osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs index cf66829ceb..8f0bfad535 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs @@ -8,6 +8,7 @@ using osu.Framework.Timing; using osu.Game.Beatmaps.Objects; using osu.Game.Beatmaps.Objects.Osu; using osu.Game.Beatmaps.Objects.Osu.Drawable; +using OpenTK; namespace osu.Desktop.VisualTests.Tests { @@ -38,13 +39,14 @@ namespace osu.Desktop.VisualTests.Tests var h = new Circle { StartTime = ourClock.CurrentTime + 1000 + i * 80, - Position = new OpenTK.Vector2(i * 14), + Position = new Vector2(i * 14), }; Add(new DrawableCircle(h) { Anchor = Anchor.Centre, Origin = Anchor.Centre, + Scale = new Vector2(1.2f), Depth = -i, State = ArmedState.Armed, }); From 8d4e7038b3a0c7c25edc30f6150a776732495248 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 12:22:29 +0900 Subject: [PATCH 03/28] Part -> Layer. --- .../Objects/Osu/Drawable/DrawableCircle.cs | 77 +++++++++---------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index 0f1538953a..5449c645e8 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -8,22 +8,21 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Transformations; -using OpenTK; -using OpenTK.Graphics; using osu.Framework.Input; using osu.Framework.MathUtils; +using OpenTK; namespace osu.Game.Beatmaps.Objects.Osu.Drawable { public class DrawableCircle : DrawableHitObject { private Sprite approachCircle; - private CirclePart circle; - private RingPart ring; - private FlashPart flash; - private ExplodePart explode; - private NumberPart number; - private GlowPart glow; + private CircleLayer circle; + private RingLayer ring; + private FlashLayer flash; + private ExplodeLayer explode; + private NumberLayer number; + private GlowLayer glow; private OsuBaseHit h; public DrawableCircle(Circle h) : base(h) @@ -37,19 +36,19 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable Children = new Framework.Graphics.Drawable[] { - glow = new GlowPart() + glow = new GlowLayer { - Colour = h.Colour, + Colour = h.Colour }, - circle = new CirclePart() + circle = new CircleLayer { Colour = h.Colour, Hit = delegate { State = ArmedState.Armed; } }, - number = new NumberPart(), - ring = new RingPart(), - flash = new FlashPart(), - explode = new ExplodePart() + number = new NumberLayer(), + ring = new RingLayer(), + flash = new FlashLayer(), + explode = new ExplodeLayer { Colour = h.Colour }, @@ -111,11 +110,11 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } } - class NumberPart : Container + class NumberLayer : Container { private Sprite number; - public NumberPart() + public NumberLayer() { Anchor = Anchor.Centre; Origin = Anchor.Centre; @@ -126,7 +125,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Alpha = 1, + Alpha = 1 } }; } @@ -138,11 +137,11 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } } - class GlowPart : Container + class GlowLayer : Container { private Sprite layer3; - public GlowPart() + public GlowLayer() { Anchor = Anchor.Centre; Origin = Anchor.Centre; @@ -154,7 +153,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable Anchor = Anchor.Centre, Origin = Anchor.Centre, Additive = true, - Alpha = 0.5f, + Alpha = 0.5f } }; } @@ -166,11 +165,11 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } } - class RingPart : Container + class RingLayer : Container { private Sprite ring; - public RingPart() + public RingLayer() { Anchor = Anchor.Centre; Origin = Anchor.Centre; @@ -180,8 +179,8 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable ring = new Sprite { Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }, + Origin = Anchor.Centre + } }; } @@ -192,9 +191,9 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } } - class FlashPart : Container + class FlashLayer : Container { - public FlashPart() + public FlashLayer() { Size = new Vector2(144); Masking = true; @@ -210,15 +209,15 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable { new Box { - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.Both } }; } } - class ExplodePart : Container + class ExplodeLayer : Container { - public ExplodePart() + public ExplodeLayer() { Size = new Vector2(144); @@ -232,8 +231,8 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable { new Triangles { - RelativeSizeAxes = Axes.Both, - }, + RelativeSizeAxes = Axes.Both + } }; } @@ -255,7 +254,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable Origin = Anchor.Centre, Position = new Vector2(RNG.NextSingle() * DrawSize.X, RNG.NextSingle() * DrawSize.Y), Scale = new Vector2(RNG.NextSingle() * 0.4f + 0.2f), - Alpha = RNG.NextSingle() * 0.3f, + Alpha = RNG.NextSingle() * 0.3f }); } } @@ -270,7 +269,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } } - class CirclePart : Container + class CircleLayer : Container { private Sprite disc; @@ -278,7 +277,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable public Action Hit; - public CirclePart() + public CircleLayer() { Size = new Vector2(144); Masking = true; @@ -292,13 +291,13 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable disc = new Sprite { Anchor = Anchor.Centre, - Origin = Anchor.Centre, + Origin = Anchor.Centre }, triangles = new Triangles { Additive = true, - RelativeSizeAxes = Axes.Both, - }, + RelativeSizeAxes = Axes.Both + } }; } @@ -332,7 +331,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable Origin = Anchor.Centre, Position = new Vector2(RNG.NextSingle() * DrawSize.X, RNG.NextSingle() * DrawSize.Y), Scale = new Vector2(RNG.NextSingle() * 0.4f + 0.2f), - Alpha = RNG.NextSingle() * 0.3f, + Alpha = RNG.NextSingle() * 0.3f }); } } From fbaae94ba44959d0f22e018429ca04e28a7c2862 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 12:31:51 +0900 Subject: [PATCH 04/28] Limit state changes to apply only once. --- osu.Game/Beatmaps/Objects/DrawableHitObject.cs | 1 + osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/osu.Game/Beatmaps/Objects/DrawableHitObject.cs b/osu.Game/Beatmaps/Objects/DrawableHitObject.cs index d6b459b0d1..27826008cf 100644 --- a/osu.Game/Beatmaps/Objects/DrawableHitObject.cs +++ b/osu.Game/Beatmaps/Objects/DrawableHitObject.cs @@ -31,6 +31,7 @@ namespace osu.Game.Beatmaps.Objects set { + if (state == value) return; state = value; UpdateState(state); diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index 5449c645e8..335f4d6103 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -70,6 +70,14 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable approachCircle.Texture = game.Textures.Get(@"Play/osu/approachcircle@2x"); } + protected override void LoadComplete() + { + base.LoadComplete(); + + //force application of the state that was set before we loaded. + UpdateState(State); + } + protected override void UpdateState(ArmedState state) { if (!IsLoaded) return; From 185416032172d6fd3f4070f1c3e1e636658cd502 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 12:57:43 +0900 Subject: [PATCH 05/28] Add hit time and the ability for an external operator to block hits. --- .../Beatmaps/Objects/DrawableHitObject.cs | 19 +++++++++++ .../Objects/Osu/Drawable/DrawableCircle.cs | 34 +++++++++---------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/osu.Game/Beatmaps/Objects/DrawableHitObject.cs b/osu.Game/Beatmaps/Objects/DrawableHitObject.cs index 27826008cf..713f44e939 100644 --- a/osu.Game/Beatmaps/Objects/DrawableHitObject.cs +++ b/osu.Game/Beatmaps/Objects/DrawableHitObject.cs @@ -14,9 +14,12 @@ namespace osu.Game.Beatmaps.Objects { public abstract class DrawableHitObject : Container, IStateful { + //todo: move to a more central implementation. this logic should not be at a drawable level. public Action OnHit; public Action OnMiss; + public Func AllowHit; + public HitObject HitObject; public DrawableHitObject(HitObject hitObject) @@ -38,6 +41,22 @@ namespace osu.Game.Beatmaps.Objects } } + protected double? HitTime; + + protected virtual bool Hit() + { + if (State != ArmedState.Disarmed) + return false; + + if (AllowHit?.Invoke(this) == false) + return false; + + HitTime = Time; + + State = ArmedState.Armed; + return true; + } + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index 335f4d6103..7838728bf4 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -43,7 +43,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable circle = new CircleLayer { Colour = h.Colour, - Hit = delegate { State = ArmedState.Armed; } + Hit = Hit, }, number = new NumberLayer(), ring = new RingLayer(), @@ -84,36 +84,36 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable Flush(); //move to DrawableHitObject - Transforms.Add(new TransformAlpha { StartTime = h.StartTime - 1000, EndTime = h.StartTime - 800, StartValue = 0, EndValue = 1 }); + double armTime = HitTime ?? h.StartTime; - approachCircle.Transforms.Add(new TransformScale { StartTime = h.StartTime - 1000, EndTime = h.StartTime, StartValue = new Vector2(2f), EndValue = new Vector2(0.6f) }); - approachCircle.Transforms.Add(new TransformAlpha { StartTime = h.StartTime, EndTime = h.StartTime, StartValue = 1, EndValue = 0 }); + Transforms.Add(new TransformAlpha { StartTime = armTime - 1000, EndTime = armTime - 800, StartValue = 0, EndValue = 1 }); - glow.Transforms.Add(new TransformAlpha { StartTime = h.StartTime, EndTime = h.StartTime + 400, StartValue = glow.Alpha, EndValue = 0 }); + approachCircle.Transforms.Add(new TransformScale { StartTime = armTime - 1000, EndTime = armTime, StartValue = new Vector2(2f), EndValue = new Vector2(0.6f) }); + approachCircle.Transforms.Add(new TransformAlpha { StartTime = armTime, EndTime = armTime, StartValue = 1, EndValue = 0 }); + + glow.Transforms.Add(new TransformAlpha { StartTime = armTime, EndTime = armTime + 400, StartValue = glow.Alpha, EndValue = 0 }); switch (state) { case ArmedState.Disarmed: - Transforms.Add(new TransformAlpha { StartTime = h.StartTime + h.Duration + 200, EndTime = h.StartTime + h.Duration + 400, StartValue = 1, EndValue = 0 }); + Transforms.Add(new TransformAlpha { StartTime = armTime + h.Duration + 200, EndTime = armTime + h.Duration + 400, StartValue = 1, EndValue = 0 }); break; case ArmedState.Armed: const float flashIn = 30; const float fadeOut = 800; - //Transforms.Add(new TransformScale() { StartTime = h.StartTime, EndTime = h.StartTime + 400, StartValue = Scale, EndValue = Scale * 1.1f }); + ring.Transforms.Add(new TransformAlpha { StartTime = armTime + flashIn, EndTime = armTime + flashIn, StartValue = 0, EndValue = 0 }); + circle.Transforms.Add(new TransformAlpha { StartTime = armTime + flashIn, EndTime = armTime + flashIn, StartValue = 0, EndValue = 0 }); + number.Transforms.Add(new TransformAlpha { StartTime = armTime + flashIn, EndTime = armTime + flashIn, StartValue = 0, EndValue = 0 }); - ring.Transforms.Add(new TransformAlpha { StartTime = h.StartTime + flashIn, EndTime = h.StartTime + flashIn, StartValue = 0, EndValue = 0 }); - circle.Transforms.Add(new TransformAlpha { StartTime = h.StartTime + flashIn, EndTime = h.StartTime + flashIn, StartValue = 0, EndValue = 0 }); - number.Transforms.Add(new TransformAlpha { StartTime = h.StartTime + flashIn, EndTime = h.StartTime + flashIn, StartValue = 0, EndValue = 0 }); + flash.Transforms.Add(new TransformAlpha { StartTime = armTime, EndTime = armTime + flashIn, StartValue = 0, EndValue = 0.8f }); + flash.Transforms.Add(new TransformAlpha { StartTime = armTime + flashIn, EndTime = armTime + flashIn + 100, StartValue = 0.8f, EndValue = 0 }); - flash.Transforms.Add(new TransformAlpha { StartTime = h.StartTime, EndTime = h.StartTime + flashIn, StartValue = 0, EndValue = 0.8f }); - flash.Transforms.Add(new TransformAlpha { StartTime = h.StartTime + flashIn, EndTime = h.StartTime + flashIn + 100, StartValue = 0.8f, EndValue = 0 }); + explode.Transforms.Add(new TransformAlpha { StartTime = armTime, EndTime = armTime + flashIn, StartValue = 0, EndValue = 1 }); - explode.Transforms.Add(new TransformAlpha { StartTime = h.StartTime, EndTime = h.StartTime + flashIn, StartValue = 0, EndValue = 1 }); + Transforms.Add(new TransformAlpha { StartTime = armTime + flashIn, EndTime = armTime + flashIn + fadeOut, StartValue = 1, EndValue = 0 }); - Transforms.Add(new TransformAlpha { StartTime = h.StartTime + flashIn, EndTime = h.StartTime + flashIn + fadeOut, StartValue = 1, EndValue = 0 }); - - Transforms.Add(new TransformScale { StartTime = h.StartTime + h.Duration, EndTime = h.StartTime + h.Duration + 400, StartValue = Scale, EndValue = Scale * 1.5f, Easing = EasingTypes.OutQuad }); + Transforms.Add(new TransformScale { StartTime = armTime + h.Duration, EndTime = armTime + h.Duration + 400, StartValue = Scale, EndValue = Scale * 1.5f, Easing = EasingTypes.OutQuad }); break; } } @@ -283,7 +283,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable private Sprite disc; private Triangles triangles; - public Action Hit; + public Func Hit; public CircleLayer() { From a4e2f25065b35eb86ae7124e8ba3dff8ab35b51a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 13:22:23 +0900 Subject: [PATCH 06/28] Flush recursively, more transform tidying. --- .../Objects/Osu/Drawable/DrawableCircle.cs | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index 7838728bf4..09b7df8023 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -82,38 +82,47 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable { if (!IsLoaded) return; - Flush(); //move to DrawableHitObject + Flush(true); //move to DrawableHitObject - double armTime = HitTime ?? h.StartTime; + double t = HitTime ?? h.StartTime; - Transforms.Add(new TransformAlpha { StartTime = armTime - 1000, EndTime = armTime - 800, StartValue = 0, EndValue = 1 }); + //sane defaults + ring.Alpha = circle.Alpha = number.Alpha = approachCircle.Alpha = glow.Alpha = 1; - approachCircle.Transforms.Add(new TransformScale { StartTime = armTime - 1000, EndTime = armTime, StartValue = new Vector2(2f), EndValue = new Vector2(0.6f) }); - approachCircle.Transforms.Add(new TransformAlpha { StartTime = armTime, EndTime = armTime, StartValue = 1, EndValue = 0 }); + //always-present transforms + Transforms.Add(new TransformAlpha { StartTime = t - 1000, EndTime = t - 800, StartValue = 0, EndValue = 1 }); + approachCircle.Transforms.Add(new TransformScale { StartTime = t - 1000, EndTime = t, StartValue = new Vector2(2f), EndValue = new Vector2(0.6f) }); - glow.Transforms.Add(new TransformAlpha { StartTime = armTime, EndTime = armTime + 400, StartValue = glow.Alpha, EndValue = 0 }); + //set transform delay to t==hitTime + Delay(t - Time, true); + + approachCircle.FadeOut(); + glow.FadeOut(400); switch (state) { case ArmedState.Disarmed: - Transforms.Add(new TransformAlpha { StartTime = armTime + h.Duration + 200, EndTime = armTime + h.Duration + 400, StartValue = 1, EndValue = 0 }); + Delay(h.Duration + 200); + FadeOut(200); break; case ArmedState.Armed: - const float flashIn = 30; - const float fadeOut = 800; + const double flash_in = 30; - ring.Transforms.Add(new TransformAlpha { StartTime = armTime + flashIn, EndTime = armTime + flashIn, StartValue = 0, EndValue = 0 }); - circle.Transforms.Add(new TransformAlpha { StartTime = armTime + flashIn, EndTime = armTime + flashIn, StartValue = 0, EndValue = 0 }); - number.Transforms.Add(new TransformAlpha { StartTime = armTime + flashIn, EndTime = armTime + flashIn, StartValue = 0, EndValue = 0 }); + flash.FadeTo(0.8f, flash_in); + flash.Delay(flash_in); + flash.FadeOut(100); - flash.Transforms.Add(new TransformAlpha { StartTime = armTime, EndTime = armTime + flashIn, StartValue = 0, EndValue = 0.8f }); - flash.Transforms.Add(new TransformAlpha { StartTime = armTime + flashIn, EndTime = armTime + flashIn + 100, StartValue = 0.8f, EndValue = 0 }); + explode.FadeIn(flash_in); - explode.Transforms.Add(new TransformAlpha { StartTime = armTime, EndTime = armTime + flashIn, StartValue = 0, EndValue = 1 }); + Delay(flash_in, true); - Transforms.Add(new TransformAlpha { StartTime = armTime + flashIn, EndTime = armTime + flashIn + fadeOut, StartValue = 1, EndValue = 0 }); + //after the flash, we can hide some elements that were behind it + ring.FadeOut(); + circle.FadeOut(); + number.FadeOut(); - Transforms.Add(new TransformScale { StartTime = armTime + h.Duration, EndTime = armTime + h.Duration + 400, StartValue = Scale, EndValue = Scale * 1.5f, Easing = EasingTypes.OutQuad }); + FadeOut(800); + ScaleTo(Scale * 1.5f, 400, EasingTypes.OutQuad); break; } } From f5f5aa9eacdb8dfdabdba6099d160e679fb4c049 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 14:03:03 +0900 Subject: [PATCH 07/28] Fix some incorrect default values. --- osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index 09b7df8023..4b7c81ad13 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -30,9 +30,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable this.h = h; Origin = Anchor.Centre; - Alpha = 0; Position = h.Position; - Scale = new Vector2(0.4f); Children = new Framework.Graphics.Drawable[] { @@ -50,7 +48,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable flash = new FlashLayer(), explode = new ExplodeLayer { - Colour = h.Colour + Colour = h.Colour, }, approachCircle = new Sprite { @@ -88,6 +86,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable //sane defaults ring.Alpha = circle.Alpha = number.Alpha = approachCircle.Alpha = glow.Alpha = 1; + explode.Alpha = 0; //always-present transforms Transforms.Add(new TransformAlpha { StartTime = t - 1000, EndTime = t - 800, StartValue = 0, EndValue = 1 }); From 788cba6f4de85d5855ab1c5a527f7f34600adfbe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 14:07:20 +0900 Subject: [PATCH 08/28] Add autoplay toggle (const). --- osu.Game/GameModes/Play/HitRenderer.cs | 11 +++++++---- osu.Game/GameModes/Play/Osu/OsuPlayfield.cs | 19 +++++++++++-------- osu.Game/GameModes/Play/Player.cs | 8 ++++++-- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/osu.Game/GameModes/Play/HitRenderer.cs b/osu.Game/GameModes/Play/HitRenderer.cs index d77aaab50f..e693da527d 100644 --- a/osu.Game/GameModes/Play/HitRenderer.cs +++ b/osu.Game/GameModes/Play/HitRenderer.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps.Objects; using osu.Framework; using System; +using System.Linq; namespace osu.Game.GameModes.Play { @@ -14,6 +15,10 @@ namespace osu.Game.GameModes.Play { public Action OnHit; public Action OnMiss; + + protected Playfield Playfield; + + public IEnumerable DrawableObjects => Playfield.Children.Cast(); } public abstract class HitRenderer : HitRenderer @@ -31,8 +36,6 @@ namespace osu.Game.GameModes.Play } } - private Playfield playfield; - protected abstract Playfield CreatePlayfield(); protected abstract HitObjectConverter Converter { get; } @@ -47,7 +50,7 @@ namespace osu.Game.GameModes.Play Children = new Drawable[] { - playfield = CreatePlayfield() + Playfield = CreatePlayfield() }; loadObjects(); @@ -65,7 +68,7 @@ namespace osu.Game.GameModes.Play drawableObject.OnHit = onHit; drawableObject.OnMiss = onMiss; - playfield.Add(drawableObject); + Playfield.Add(drawableObject); } } diff --git a/osu.Game/GameModes/Play/Osu/OsuPlayfield.cs b/osu.Game/GameModes/Play/Osu/OsuPlayfield.cs index 111dd608c1..59ce1699e4 100644 --- a/osu.Game/GameModes/Play/Osu/OsuPlayfield.cs +++ b/osu.Game/GameModes/Play/Osu/OsuPlayfield.cs @@ -12,19 +12,17 @@ namespace osu.Game.GameModes.Play.Osu { public class OsuPlayfield : Playfield { + protected override Container Content => hitObjectContainer; + + private Container hitObjectContainer; + public OsuPlayfield() { - Size = new Vector2(512, 384); - Scale = new Vector2(1.6f); Anchor = Anchor.Centre; Origin = Anchor.Centre; - } + Size = new Vector2(512, 384); - protected override void Load(BaseGame game) - { - base.Load(game); - - Add(new Box() + AddInternal(new Box { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -32,6 +30,11 @@ namespace osu.Game.GameModes.Play.Osu Colour = Color4.Black, Alpha = 0.5f }); + + AddInternal(hitObjectContainer = new Container + { + RelativeSizeAxes = Axes.Both + }); } } } \ No newline at end of file diff --git a/osu.Game/GameModes/Play/Player.cs b/osu.Game/GameModes/Play/Player.cs index 860e077588..d48e252fa5 100644 --- a/osu.Game/GameModes/Play/Player.cs +++ b/osu.Game/GameModes/Play/Player.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.Beatmaps; using osu.Game.Beatmaps.Objects; using osu.Game.GameModes.Backgrounds; using osu.Game.GameModes.Play.Catch; @@ -12,13 +11,15 @@ using osu.Game.GameModes.Play.Taiko; using osu.Framework; using osu.Game.Database; using osu.Framework.Timing; -using osu.Framework.GameModes; using osu.Framework.Audio.Track; +using osu.Framework.Extensions.IEnumerableExtensions; namespace osu.Game.GameModes.Play { public class Player : OsuGameMode { + const bool autoplay = false; + protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4"); public BeatmapInfo BeatmapInfo; @@ -124,6 +125,9 @@ namespace osu.Game.GameModes.Play hitRenderer.OnHit += delegate (HitObject h) { scoreOverlay.OnHit(h); }; hitRenderer.OnMiss += delegate (HitObject h) { scoreOverlay.OnMiss(h); }; + if (autoplay) + hitRenderer.Schedule(() => hitRenderer.DrawableObjects.ForEach(h => h.State = ArmedState.Armed)); + Children = new Drawable[] { hitRenderer, From e9397461593be7a3fe8e45d9dfda6e20859f1d18 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 15:37:45 +0900 Subject: [PATCH 09/28] Fix scale ratio of gamefield. --- .../Tests/TestCaseHitObjects.cs | 7 +++--- .../Objects/Osu/Drawable/DrawableCircle.cs | 5 ++-- osu.Game/GameModes/Play/Osu/OsuPlayfield.cs | 23 +++++++++++++++---- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs index 8f0bfad535..54d8bbd2e7 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs @@ -34,19 +34,20 @@ namespace osu.Desktop.VisualTests.Tests ourClock.ProcessFrame(); - for (int i = 0; i < 20; i++) + const int count = 10; + + for (int i = 0; i < count; i++) { var h = new Circle { StartTime = ourClock.CurrentTime + 1000 + i * 80, - Position = new Vector2(i * 14), + Position = new Vector2((i - count / 2) * 14), }; Add(new DrawableCircle(h) { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Scale = new Vector2(1.2f), Depth = -i, State = ArmedState.Armed, }); diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index 4b7c81ad13..f25e06aa31 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -30,7 +30,8 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable this.h = h; Origin = Anchor.Centre; - Position = h.Position; + RelativePositionAxes = Axes.Both; + Position = new Vector2(h.Position.X / 512, h.Position.Y / 384); Children = new Framework.Graphics.Drawable[] { @@ -57,8 +58,6 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable Colour = h.Colour } }; - - Size = new Vector2(100); } protected override void Load(BaseGame game) diff --git a/osu.Game/GameModes/Play/Osu/OsuPlayfield.cs b/osu.Game/GameModes/Play/Osu/OsuPlayfield.cs index 59ce1699e4..f2f3068dc8 100644 --- a/osu.Game/GameModes/Play/Osu/OsuPlayfield.cs +++ b/osu.Game/GameModes/Play/Osu/OsuPlayfield.cs @@ -16,24 +16,39 @@ namespace osu.Game.GameModes.Play.Osu private Container hitObjectContainer; + public override Vector2 Size + { + get + { + var parentSize = Parent.DrawSize; + var aspectSize = parentSize.X * 0.75f < parentSize.Y ? new Vector2(parentSize.X, parentSize.X * 0.75f) : new Vector2(parentSize.Y * 4f / 3f, parentSize.Y); + + return new Vector2(aspectSize.X / parentSize.X, aspectSize.Y / parentSize.Y) * base.Size; + } + } + public OsuPlayfield() { Anchor = Anchor.Centre; Origin = Anchor.Centre; - Size = new Vector2(512, 384); + RelativeSizeAxes = Axes.Both; + Size = new Vector2(0.86f); AddInternal(new Box { + RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, Colour = Color4.Black, - Alpha = 0.5f + Alpha = 0.5f, }); AddInternal(hitObjectContainer = new Container { - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(0.4f), }); } } From 92b85b251ebbc7bbc83ca403e54ee9c61d8d4e6d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 17:08:34 +0900 Subject: [PATCH 10/28] Fix scale more. --- .../Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs | 1 + osu.Game/GameModes/Play/Osu/OsuPlayfield.cs | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index f25e06aa31..88ed547017 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -86,6 +86,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable //sane defaults ring.Alpha = circle.Alpha = number.Alpha = approachCircle.Alpha = glow.Alpha = 1; explode.Alpha = 0; + Scale = Vector2.One; //always-present transforms Transforms.Add(new TransformAlpha { StartTime = t - 1000, EndTime = t - 800, StartValue = 0, EndValue = 1 }); diff --git a/osu.Game/GameModes/Play/Osu/OsuPlayfield.cs b/osu.Game/GameModes/Play/Osu/OsuPlayfield.cs index f2f3068dc8..a6c4112321 100644 --- a/osu.Game/GameModes/Play/Osu/OsuPlayfield.cs +++ b/osu.Game/GameModes/Play/Osu/OsuPlayfield.cs @@ -32,7 +32,7 @@ namespace osu.Game.GameModes.Play.Osu Anchor = Anchor.Centre; Origin = Anchor.Centre; RelativeSizeAxes = Axes.Both; - Size = new Vector2(0.86f); + Size = new Vector2(0.75f); AddInternal(new Box { @@ -43,13 +43,17 @@ namespace osu.Game.GameModes.Play.Osu Alpha = 0.5f, }); - AddInternal(hitObjectContainer = new Container + AddInternal(hitObjectContainer = new HitObjectContainer { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, - Scale = new Vector2(0.4f), }); } + + class HitObjectContainer : Container + { + protected override Vector2 ChildScale => new Vector2(0.625f); + } } } \ No newline at end of file From b40ccccbe4fb2cc6074170dd1ef58be98c0b53c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 18:08:08 +0900 Subject: [PATCH 11/28] Add HitObject colours back in the mix. --- .../Tests/TestCasePlayer.cs | 18 ++++++--- osu.Game/Beatmaps/Formats/BeatmapDecoder.cs | 40 +++++++++++++++++-- .../Formats/ConstructableBeatmapDecoder.cs | 20 ++++++++++ osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- osu.Game/Beatmaps/Objects/HitObject.cs | 5 +++ osu.Game/Beatmaps/Objects/Osu/Circle.cs | 1 - osu.Game/Beatmaps/Objects/Osu/OsuBaseHit.cs | 1 - osu.Game/osu.Game.csproj | 1 + 8 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 osu.Game/Beatmaps/Formats/ConstructableBeatmapDecoder.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs index a3ae103f28..b5e31bc5f5 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs @@ -6,6 +6,7 @@ using osu.Framework.GameModes.Testing; using osu.Framework.MathUtils; using osu.Framework.Timing; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Objects; using osu.Game.Beatmaps.Objects.Osu; using osu.Game.GameModes.Play; @@ -38,20 +39,27 @@ namespace osu.Desktop.VisualTests.Tests objects.Add(new Circle() { StartTime = time, - Position = new Vector2(RNG.Next(100, 400), RNG.Next(100, 200)) + Position = new Vector2(RNG.Next(0, 512), RNG.Next(0, 384)), + NewCombo = (i + 1) % 4 == 0 }); time += 500; } + var decoder = new ConstructableBeatmapDecoder(); + + Beatmap b = new Beatmap + { + HitObjects = objects + }; + + decoder.Process(b); + Add(new Player { Beatmap = new WorkingBeatmap { - Beatmap = new Beatmap - { - HitObjects = objects - } + Beatmap = b } }); } diff --git a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs index f376d831cf..047d599784 100644 --- a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs @@ -1,13 +1,15 @@ using System; using System.Collections.Generic; using System.IO; +using osu.Game.Beatmaps.Objects; +using OpenTK.Graphics; namespace osu.Game.Beatmaps.Formats { public abstract class BeatmapDecoder { private static Dictionary decoders { get; } = new Dictionary(); - + public static BeatmapDecoder GetDecoder(TextReader stream) { var line = stream.ReadLine().Trim(); @@ -20,7 +22,39 @@ namespace osu.Game.Beatmaps.Formats { decoders[magic] = typeof(T); } - - public abstract Beatmap Decode(TextReader stream); + + public virtual Beatmap Decode(TextReader stream) + { + Beatmap b = ParseFile(stream); + Process(b); + return b; + } + + public virtual Beatmap Process(Beatmap beatmap) + { + ApplyColours(beatmap); + + return beatmap; + } + + protected abstract Beatmap ParseFile(TextReader stream); + + public virtual void ApplyColours(Beatmap b) + { + List colours = b.ComboColors ?? new List() { + new Color4(17, 136, 170, 255), + new Color4(102,136,0, 255), + new Color4(204,102,0, 255), + new Color4(121,9,13, 255), + }; + + int i = 0; + + foreach (HitObject h in b.HitObjects) + { + h.Colour = colours[i]; + if (h.NewCombo) i = (i + 1) % colours.Count; + } + } } } diff --git a/osu.Game/Beatmaps/Formats/ConstructableBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/ConstructableBeatmapDecoder.cs new file mode 100644 index 0000000000..e1dae7b193 --- /dev/null +++ b/osu.Game/Beatmaps/Formats/ConstructableBeatmapDecoder.cs @@ -0,0 +1,20 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace osu.Game.Beatmaps.Formats +{ + public class ConstructableBeatmapDecoder : BeatmapDecoder + { + protected override Beatmap ParseFile(TextReader stream) + { + throw new NotImplementedException(); + } + } +} diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 7d3b918961..7dce625a8e 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -207,7 +207,7 @@ namespace osu.Game.Beatmaps.Formats }); } - public override Beatmap Decode(TextReader stream) + protected override Beatmap ParseFile(TextReader stream) { var beatmap = new Beatmap { diff --git a/osu.Game/Beatmaps/Objects/HitObject.cs b/osu.Game/Beatmaps/Objects/HitObject.cs index 44cab54fa3..ef6659224f 100644 --- a/osu.Game/Beatmaps/Objects/HitObject.cs +++ b/osu.Game/Beatmaps/Objects/HitObject.cs @@ -4,6 +4,7 @@ using osu.Game.Beatmaps.Objects.Osu; using osu.Game.Beatmaps.Samples; using osu.Game.GameModes.Play; +using OpenTK.Graphics; namespace osu.Game.Beatmaps.Objects { @@ -15,6 +16,10 @@ namespace osu.Game.Beatmaps.Objects public double StartTime; public virtual double EndTime => StartTime; + public bool NewCombo { get; set; } + + public Color4 Colour = new Color4(17, 136, 170, 255); + public double Duration => EndTime - StartTime; public HitSampleInfo Sample; diff --git a/osu.Game/Beatmaps/Objects/Osu/Circle.cs b/osu.Game/Beatmaps/Objects/Osu/Circle.cs index e276132ebc..9b7f92f29e 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Circle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Circle.cs @@ -7,6 +7,5 @@ namespace osu.Game.Beatmaps.Objects.Osu { public class Circle : OsuBaseHit { - public Color4 Colour = new Color4(17, 136, 170, 255); } } diff --git a/osu.Game/Beatmaps/Objects/Osu/OsuBaseHit.cs b/osu.Game/Beatmaps/Objects/Osu/OsuBaseHit.cs index 2f94c70a0e..e4bb272404 100644 --- a/osu.Game/Beatmaps/Objects/Osu/OsuBaseHit.cs +++ b/osu.Game/Beatmaps/Objects/Osu/OsuBaseHit.cs @@ -10,7 +10,6 @@ namespace osu.Game.Beatmaps.Objects.Osu public abstract class OsuBaseHit : HitObject { public Vector2 Position { get; set; } - public bool NewCombo { get; set; } [Flags] private enum HitObjectType diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b2a8cee6a5..92679b7d58 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -64,6 +64,7 @@ + From 74c655ebfc6269af0388bd213ea880b9b126fc62 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 18:12:12 +0900 Subject: [PATCH 12/28] Fix input not working. --- osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index 88ed547017..d935762e4b 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -58,6 +58,9 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable Colour = h.Colour } }; + + //may not be so correct + Size = circle.DrawSize; } protected override void Load(BaseGame game) From b72e9221fdf7f645a3ddfc77925591946a24efa7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 18:24:57 +0900 Subject: [PATCH 13/28] Only add valid hitobjects. --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 7dce625a8e..e988498093 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -270,7 +270,9 @@ namespace osu.Game.Beatmaps.Formats handleColours(beatmap, key, val); break; case Section.HitObjects: - beatmap.HitObjects.Add(HitObject.Parse(beatmap.BeatmapInfo.Mode, val)); + var h = HitObject.Parse(beatmap.BeatmapInfo.Mode, val); + if (h != null) + beatmap.HitObjects.Add(h); break; } } From da18e2d4f64977e1187623c23592473aea91e6bd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 18:38:17 +0900 Subject: [PATCH 14/28] Fix off-by-one colour retrieval. --- osu.Desktop.VisualTests/Tests/TestCasePlayer.cs | 2 +- osu.Game/Beatmaps/Formats/BeatmapDecoder.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs index b5e31bc5f5..5d66888916 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs @@ -40,7 +40,7 @@ namespace osu.Desktop.VisualTests.Tests { StartTime = time, Position = new Vector2(RNG.Next(0, 512), RNG.Next(0, 384)), - NewCombo = (i + 1) % 4 == 0 + NewCombo = i % 4 == 0 }); time += 500; diff --git a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs index 047d599784..e3d89ac6fc 100644 --- a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs @@ -48,12 +48,12 @@ namespace osu.Game.Beatmaps.Formats new Color4(121,9,13, 255), }; - int i = 0; + int i = -1; foreach (HitObject h in b.HitObjects) { - h.Colour = colours[i]; if (h.NewCombo) i = (i + 1) % colours.Count; + h.Colour = colours[i]; } } } From 9df43c6d330195aae6e6d544f91137beb47e641b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2016 19:42:07 +0900 Subject: [PATCH 15/28] Fix draw order of hitobjects. --- osu.Game/Beatmaps/Objects/DrawableHitObject.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/Objects/DrawableHitObject.cs b/osu.Game/Beatmaps/Objects/DrawableHitObject.cs index 713f44e939..126f66be19 100644 --- a/osu.Game/Beatmaps/Objects/DrawableHitObject.cs +++ b/osu.Game/Beatmaps/Objects/DrawableHitObject.cs @@ -25,6 +25,7 @@ namespace osu.Game.Beatmaps.Objects public DrawableHitObject(HitObject hitObject) { HitObject = hitObject; + Depth = -(float)hitObject.StartTime; } private ArmedState state; From 108b7092c987c4843a714638b1225cc865402ac9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2016 16:08:04 +0900 Subject: [PATCH 16/28] Fix regression in hitcircle appearance. --- .../Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index d935762e4b..2082566581 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -215,6 +215,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable public FlashLayer() { Size = new Vector2(144); + Masking = true; CornerRadius = Size.X / 2; @@ -271,7 +272,8 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable { Texture = tex, Origin = Anchor.Centre, - Position = new Vector2(RNG.NextSingle() * DrawSize.X, RNG.NextSingle() * DrawSize.Y), + Position = new Vector2(RNG.NextSingle(), RNG.NextSingle()), + RelativePositionAxes = Axes.Both, Scale = new Vector2(RNG.NextSingle() * 0.4f + 0.2f), Alpha = RNG.NextSingle() * 0.3f }); @@ -283,7 +285,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable base.Update(); foreach (Framework.Graphics.Drawable d in Children) - d.Position -= new Vector2(0, (float)(d.Scale.X * (Clock.ElapsedFrameTime / 20))); + d.Position -= new Vector2(0, (float)(d.Scale.X * (Clock.ElapsedFrameTime / 2880))); } } } @@ -348,7 +350,8 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable { Texture = tex, Origin = Anchor.Centre, - Position = new Vector2(RNG.NextSingle() * DrawSize.X, RNG.NextSingle() * DrawSize.Y), + RelativePositionAxes = Axes.Both, + Position = new Vector2(RNG.NextSingle(), RNG.NextSingle()), Scale = new Vector2(RNG.NextSingle() * 0.4f + 0.2f), Alpha = RNG.NextSingle() * 0.3f }); @@ -360,7 +363,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable base.Update(); foreach (Framework.Graphics.Drawable d in Children) - d.Position -= new Vector2(0, (float)(d.Scale.X * (Clock.ElapsedFrameTime / 20))); + d.Position -= new Vector2(0, (float)(d.Scale.X * (Clock.ElapsedFrameTime / 2880))); } } } From b17d219acea8ab1fe950b493a2a42ddd7672e283 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2016 16:11:22 +0900 Subject: [PATCH 17/28] Share Triangles logic. --- .../Objects/Osu/Drawable/DrawableCircle.cs | 81 ++++++------------- 1 file changed, 24 insertions(+), 57 deletions(-) diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index 2082566581..6e0b7c5b05 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -255,39 +255,6 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } }; } - - class Triangles : Container - { - private Texture tex; - - protected override void Load(BaseGame game) - { - base.Load(game); - - tex = game.Textures.Get(@"Play/osu/triangle@2x"); - - for (int i = 0; i < 10; i++) - { - Add(new Sprite - { - Texture = tex, - Origin = Anchor.Centre, - Position = new Vector2(RNG.NextSingle(), RNG.NextSingle()), - RelativePositionAxes = Axes.Both, - Scale = new Vector2(RNG.NextSingle() * 0.4f + 0.2f), - Alpha = RNG.NextSingle() * 0.3f - }); - } - } - - protected override void Update() - { - base.Update(); - - foreach (Framework.Graphics.Drawable d in Children) - d.Position -= new Vector2(0, (float)(d.Scale.X * (Clock.ElapsedFrameTime / 2880))); - } - } } class CircleLayer : Container @@ -333,38 +300,38 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable Hit?.Invoke(); return true; } + } - class Triangles : Container + class Triangles : Container + { + private Texture tex; + + protected override void Load(BaseGame game) { - private Texture tex; + base.Load(game); - protected override void Load(BaseGame game) + tex = game.Textures.Get(@"Play/osu/triangle@2x"); + + for (int i = 0; i < 10; i++) { - base.Load(game); - - tex = game.Textures.Get(@"Play/osu/triangle@2x"); - - for (int i = 0; i < 10; i++) + Add(new Sprite { - Add(new Sprite - { - Texture = tex, - Origin = Anchor.Centre, - RelativePositionAxes = Axes.Both, - Position = new Vector2(RNG.NextSingle(), RNG.NextSingle()), - Scale = new Vector2(RNG.NextSingle() * 0.4f + 0.2f), - Alpha = RNG.NextSingle() * 0.3f - }); - } + Texture = tex, + Origin = Anchor.Centre, + RelativePositionAxes = Axes.Both, + Position = new Vector2(RNG.NextSingle(), RNG.NextSingle()), + Scale = new Vector2(RNG.NextSingle() * 0.4f + 0.2f), + Alpha = RNG.NextSingle() * 0.3f + }); } + } - protected override void Update() - { - base.Update(); + protected override void Update() + { + base.Update(); - foreach (Framework.Graphics.Drawable d in Children) - d.Position -= new Vector2(0, (float)(d.Scale.X * (Clock.ElapsedFrameTime / 2880))); - } + foreach (Framework.Graphics.Drawable d in Children) + d.Position -= new Vector2(0, (float)(d.Scale.X * (Clock.ElapsedFrameTime / 2880))); } } } From 10f2ed4387e4f6d5d2621cfc5a722244357d55a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2016 16:12:35 +0900 Subject: [PATCH 18/28] Add explicit privates. --- .../Objects/Osu/Drawable/DrawableCircle.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index 6e0b7c5b05..4626f554f7 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -129,7 +129,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } } - class NumberLayer : Container + private class NumberLayer : Container { private Sprite number; @@ -156,7 +156,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } } - class GlowLayer : Container + private class GlowLayer : Container { private Sprite layer3; @@ -184,7 +184,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } } - class RingLayer : Container + private class RingLayer : Container { private Sprite ring; @@ -210,7 +210,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } } - class FlashLayer : Container + private class FlashLayer : Container { public FlashLayer() { @@ -235,7 +235,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } } - class ExplodeLayer : Container + private class ExplodeLayer : Container { public ExplodeLayer() { @@ -257,7 +257,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } } - class CircleLayer : Container + private class CircleLayer : Container { private Sprite disc; @@ -302,7 +302,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable } } - class Triangles : Container + private class Triangles : Container { private Texture tex; From 2ee5e2efb730597a43645fb736c52189c6d163b0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 5 Nov 2016 18:15:37 +0900 Subject: [PATCH 19/28] Bring framework up-to-date. # Conflicts: # osu-framework --- osu-framework | 2 +- osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs | 8 ++++---- osu.Game/GameModes/GameModeWhiteBox.cs | 2 +- osu.Game/GameModes/Menu/Intro.cs | 2 +- osu.Game/GameModes/Menu/OsuLogo.cs | 4 ++-- osu.Game/Graphics/Background/Background.cs | 1 - osu.Game/Overlays/OptionsOverlay.cs | 2 +- osu.Game/Overlays/ToolbarButton.cs | 2 +- 8 files changed, 11 insertions(+), 12 deletions(-) diff --git a/osu-framework b/osu-framework index 2b9a56e8b3..6650f7fbbc 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 2b9a56e8b3bb6c99bf4c75307639e6726fe8d3ec +Subproject commit 6650f7fbbcbfb29489e378e73cb4f3b1042384bd diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index 0f1538953a..2b52657f1e 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -153,7 +153,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Additive = true, + BlendingMode = BlendingMode.Additive, Alpha = 0.5f, } }; @@ -203,7 +203,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable Anchor = Anchor.Centre; Origin = Anchor.Centre; - Additive = true; + BlendingMode = BlendingMode.Additive; Alpha = 0; Children = new Framework.Graphics.Drawable[] @@ -225,7 +225,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable Anchor = Anchor.Centre; Origin = Anchor.Centre; - Additive = true; + BlendingMode = BlendingMode.Additive; Alpha = 0; Children = new Framework.Graphics.Drawable[] @@ -296,7 +296,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable }, triangles = new Triangles { - Additive = true, + BlendingMode = BlendingMode.Additive, RelativeSizeAxes = Axes.Both, }, }; diff --git a/osu.Game/GameModes/GameModeWhiteBox.cs b/osu.Game/GameModes/GameModeWhiteBox.cs index d4a0893cba..3bb8dd4566 100644 --- a/osu.Game/GameModes/GameModeWhiteBox.cs +++ b/osu.Game/GameModes/GameModeWhiteBox.cs @@ -91,7 +91,7 @@ namespace osu.Game.GameModes Origin = Anchor.Centre, Colour = getColourFor(GetType()), Alpha = 1, - Additive = false + BlendingMode = BlendingMode.Additive, }, textContainer = new Container { diff --git a/osu.Game/GameModes/Menu/Intro.cs b/osu.Game/GameModes/Menu/Intro.cs index 308eb157d3..c107fd0c92 100644 --- a/osu.Game/GameModes/Menu/Intro.cs +++ b/osu.Game/GameModes/Menu/Intro.cs @@ -35,7 +35,7 @@ namespace osu.Game.GameModes.Menu logo = new OsuLogo() { Alpha = 0, - Additive = true, + BlendingMode = BlendingMode.Additive, Interactive = false, Colour = Color4.DarkGray, Ripple = false diff --git a/osu.Game/GameModes/Menu/OsuLogo.cs b/osu.Game/GameModes/Menu/OsuLogo.cs index 889b7ccb32..106df1a1be 100644 --- a/osu.Game/GameModes/Menu/OsuLogo.cs +++ b/osu.Game/GameModes/Menu/OsuLogo.cs @@ -83,7 +83,7 @@ namespace osu.Game.GameModes.Menu { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Additive = true, + BlendingMode = BlendingMode.Additive, Alpha = 0.05f } } @@ -93,7 +93,7 @@ namespace osu.Game.GameModes.Menu Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = logo.Size, - Additive = true, + BlendingMode = BlendingMode.Additive, Alpha = 0.2f, } } diff --git a/osu.Game/Graphics/Background/Background.cs b/osu.Game/Graphics/Background/Background.cs index 1b36feb761..8d004dcf86 100644 --- a/osu.Game/Graphics/Background/Background.cs +++ b/osu.Game/Graphics/Background/Background.cs @@ -10,7 +10,6 @@ using OpenTK.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework; using System.Threading.Tasks; -using osu.Framework.Graphics.Textures; namespace osu.Game.Graphics.Background { diff --git a/osu.Game/Overlays/OptionsOverlay.cs b/osu.Game/Overlays/OptionsOverlay.cs index 5f6e3ba3e3..cdf7628953 100644 --- a/osu.Game/Overlays/OptionsOverlay.cs +++ b/osu.Game/Overlays/OptionsOverlay.cs @@ -44,7 +44,7 @@ namespace osu.Game.Overlays new ScrollContainer { RelativeSizeAxes = Axes.Both, - ScrollDraggerOnLeft = true, + ScrollDraggerAnchor = Anchor.TopLeft, Children = new[] { new FlowContainer diff --git a/osu.Game/Overlays/ToolbarButton.cs b/osu.Game/Overlays/ToolbarButton.cs index adc436a3b4..65004a78da 100644 --- a/osu.Game/Overlays/ToolbarButton.cs +++ b/osu.Game/Overlays/ToolbarButton.cs @@ -66,7 +66,7 @@ namespace osu.Game.Overlays HoverBackground = new Box { RelativeSizeAxes = Axes.Both, - Additive = true, + BlendingMode = BlendingMode.Additive, Colour = new Color4(60, 60, 60, 255), Alpha = 0, }, From 8fe63689a420010c3498ff235edf3cfd99a78b0a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 5 Nov 2016 18:16:15 +0900 Subject: [PATCH 20/28] Fix thread safety issue when accessing files in beatmap (zip) files. --- .../Tests/TestCasePlayer.cs | 9 +++----- osu.Game/Beatmaps/WorkingBeatmap.cs | 23 +++++++++++++------ osu.Game/Database/BeatmapDatabase.cs | 4 +--- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs index a3ae103f28..1d292442e6 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs @@ -46,13 +46,10 @@ namespace osu.Desktop.VisualTests.Tests Add(new Player { - Beatmap = new WorkingBeatmap + Beatmap = new WorkingBeatmap(new Beatmap { - Beatmap = new Beatmap - { - HitObjects = objects - } - } + HitObjects = objects + }) }); } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 4deed53465..a2a0a27e02 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -12,9 +12,12 @@ namespace osu.Game.Beatmaps { public class WorkingBeatmap : IDisposable { - public BeatmapInfo BeatmapInfo; + public readonly BeatmapInfo BeatmapInfo; - public readonly ArchiveReader Reader; + public readonly BeatmapSetInfo BeatmapSetInfo; + private readonly BeatmapDatabase database; + + private ArchiveReader reader => database.GetReader(BeatmapSetInfo); private Beatmap beatmap; public Beatmap Beatmap @@ -25,7 +28,7 @@ namespace osu.Game.Beatmaps try { - using (var stream = new StreamReader(Reader.ReadFile(BeatmapInfo.Path))) + using (var stream = new StreamReader(reader.ReadFile(BeatmapInfo.Path))) beatmap = BeatmapDecoder.GetDecoder(stream)?.Decode(stream); } catch { } @@ -44,7 +47,7 @@ namespace osu.Game.Beatmaps try { - var trackData = Reader.ReadFile(BeatmapInfo.Metadata.AudioFile); + var trackData = reader.ReadFile(BeatmapInfo.Metadata.AudioFile); if (trackData != null) track = new AudioTrackBass(trackData); } @@ -55,10 +58,16 @@ namespace osu.Game.Beatmaps set { track = value; } } - public WorkingBeatmap(BeatmapInfo beatmapInfo = null, ArchiveReader reader = null) + public WorkingBeatmap(Beatmap beatmap) + { + this.beatmap = beatmap; + } + + public WorkingBeatmap(BeatmapInfo beatmapInfo, BeatmapSetInfo beatmapSetInfo, BeatmapDatabase database) { this.BeatmapInfo = beatmapInfo; - Reader = reader; + this.BeatmapSetInfo = beatmapSetInfo; + this.database = database; } private bool isDisposed; @@ -68,7 +77,7 @@ namespace osu.Game.Beatmaps if (!isDisposed) { track?.Dispose(); - Reader?.Dispose(); + reader?.Dispose(); isDisposed = true; } } diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index bb98daf6bc..06007dba9c 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -149,12 +149,10 @@ namespace osu.Game.Database if (beatmapSetInfo == null) throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetID} is not in the local database."); - var reader = GetReader(beatmapSetInfo); - if (beatmapInfo.Metadata == null) beatmapInfo.Metadata = beatmapSetInfo.Metadata; - var working = new WorkingBeatmap(beatmapInfo, reader); + var working = new WorkingBeatmap(beatmapInfo, beatmapSetInfo, this); previous?.TransferTo(working); From 7cc19d74c68894d15e3d5aa17fbd92637be8fbf8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2016 18:08:43 +0900 Subject: [PATCH 21/28] Add full Exo font set and bring song select panels closer to final design. --- osu-resources | 2 +- osu.Game/Beatmaps/Drawable/BeatmapPanel.cs | 31 ++++++++++++++++--- .../Beatmaps/Drawable/BeatmapSetHeader.cs | 5 +-- osu.Game/OsuGameBase.cs | 14 ++++++++- 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/osu-resources b/osu-resources index c0781d1d55..5ce2639887 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit c0781d1d557c3e5a00f6cf1780049e382f92c0c8 +Subproject commit 5ce263988735b3f15c1195568b65fef40756198c diff --git a/osu.Game/Beatmaps/Drawable/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawable/BeatmapPanel.cs index cd28e909a8..35a7f95037 100644 --- a/osu.Game/Beatmaps/Drawable/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawable/BeatmapPanel.cs @@ -29,7 +29,7 @@ namespace osu.Game.Beatmaps.Drawable public BeatmapPanel(BeatmapInfo beatmap) { Beatmap = beatmap; - Height *= 0.75f; + Height *= 0.60f; Children = new Framework.Graphics.Drawable[] { @@ -44,12 +44,20 @@ namespace osu.Game.Beatmaps.Drawable Padding = new MarginPadding(5), Direction = FlowDirection.HorizontalOnly, AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, Children = new Framework.Graphics.Drawable[] { - new DifficultyIcon(FontAwesome.dot_circle_o, new Color4(159, 198, 0, 255)), + new DifficultyIcon(FontAwesome.dot_circle_o, new Color4(159, 198, 0, 255)) + { + Scale = new Vector2(1.8f), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + }, new FlowContainer { - Padding = new MarginPadding { Left = 10 }, + Padding = new MarginPadding { Left = 5 }, + Spacing = new Vector2(0, 5), Direction = FlowDirection.VerticalOnly, AutoSizeAxes = Axes.Both, Children = new Framework.Graphics.Drawable[] @@ -58,17 +66,32 @@ namespace osu.Game.Beatmaps.Drawable { Direction = FlowDirection.HorizontalOnly, AutoSizeAxes = Axes.Both, + Spacing = new Vector2(4, 0), Children = new[] { new SpriteText { + Font = @"Exo2.0-Medium", Text = beatmap.Version, TextSize = 20, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft }, new SpriteText { - Text = $" mapped by {(beatmap.Metadata ?? beatmap.BeatmapSet.Metadata).Author}", + Font = @"Exo2.0-Medium", + Text = "mapped by", TextSize = 16, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft + }, + new SpriteText + { + Font = @"Exo2.0-MediumItalic", + Text = $"{(beatmap.Metadata ?? beatmap.BeatmapSet.Metadata).Author}", + TextSize = 16, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft }, } }, diff --git a/osu.Game/Beatmaps/Drawable/BeatmapSetHeader.cs b/osu.Game/Beatmaps/Drawable/BeatmapSetHeader.cs index a15198cc8c..9ce0bafdf4 100644 --- a/osu.Game/Beatmaps/Drawable/BeatmapSetHeader.cs +++ b/osu.Game/Beatmaps/Drawable/BeatmapSetHeader.cs @@ -60,14 +60,15 @@ namespace osu.Game.Beatmaps.Drawable AutoSizeAxes = Axes.Both, Children = new[] { - // TODO: Make these italic new SpriteText { + Font = @"Exo2.0-SemiBoldItalic", Text = beatmapSet.Metadata.Title ?? beatmapSet.Metadata.TitleUnicode, - TextSize = 20 + TextSize = 22 }, new SpriteText { + Font = @"Exo2.0-MediumItalic", Text = beatmapSet.Metadata.Artist ?? beatmapSet.Metadata.ArtistUnicode, TextSize = 16 }, diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index a506044bee..ae13b20f4a 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -65,9 +65,21 @@ namespace osu.Game //this completely overrides the framework default. will need to change once we make a proper FontStore. Fonts = new TextureStore() { ScaleAdjust = 0.01f }; - Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Regular")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/FontAwesome")); Fonts.AddStore(new GlyphStore(Resources, @"Fonts/osuFont")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Regular")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-RegularItalic")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-SemiBold")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-SemiBoldItalic")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Bold")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-BoldItalic")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Light")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-LightItalic")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Medium")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-MediumItalic")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-Black")); + Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Exo2.0-BlackItalic")); API = new APIAccess() { From a11d53406752fbf4aea67b99934d5c6c9c7c98a8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 5 Nov 2016 20:00:14 +0900 Subject: [PATCH 22/28] Add beatmap backgrounds. --- .../Beatmaps/IO/LegacyFilesystemReader.cs | 4 +-- .../Beatmaps/IO/OszArchiveReaderTest.cs | 2 +- osu.Game/Beatmaps/Drawable/BeatmapGroup.cs | 6 ++--- .../Beatmaps/Drawable/BeatmapSetHeader.cs | 25 ++++++------------- osu.Game/Beatmaps/Drawable/Panel.cs | 9 ++++++- osu.Game/Beatmaps/IO/ArchiveReader.cs | 20 +++++++++++++-- osu.Game/Beatmaps/IO/OszArchiveReader.cs | 4 +-- osu.Game/Beatmaps/WorkingBeatmap.cs | 23 +++++++++++++++-- osu.Game/Database/BeatmapDatabase.cs | 2 +- osu.Game/GameModes/Play/PlaySongSelect.cs | 5 +++- 10 files changed, 68 insertions(+), 32 deletions(-) diff --git a/osu.Desktop/Beatmaps/IO/LegacyFilesystemReader.cs b/osu.Desktop/Beatmaps/IO/LegacyFilesystemReader.cs index c57498f5dd..471f48c750 100644 --- a/osu.Desktop/Beatmaps/IO/LegacyFilesystemReader.cs +++ b/osu.Desktop/Beatmaps/IO/LegacyFilesystemReader.cs @@ -29,7 +29,7 @@ namespace osu.Desktop.Beatmaps.IO beatmaps = Directory.GetFiles(basePath, @"*.osu").Select(f => Path.GetFileName(f)).ToArray(); if (beatmaps.Length == 0) throw new FileNotFoundException(@"This directory contains no beatmaps"); - using (var stream = new StreamReader(ReadFile(beatmaps[0]))) + using (var stream = new StreamReader(GetStream(beatmaps[0]))) { var decoder = BeatmapDecoder.GetDecoder(stream); firstMap = decoder.Decode(stream); @@ -41,7 +41,7 @@ namespace osu.Desktop.Beatmaps.IO return beatmaps; } - public override Stream ReadFile(string name) + public override Stream GetStream(string name) { return File.OpenRead(Path.Combine(basePath, name)); } diff --git a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs index 568c08cfc6..ea26cce467 100644 --- a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs @@ -70,7 +70,7 @@ namespace osu.Game.Tests.Beatmaps.IO { var reader = new OszArchiveReader(osz); using (var stream = new StreamReader( - reader.ReadFile("Soleily - Renatus (Deif) [Platter].osu"))) + reader.GetStream("Soleily - Renatus (Deif) [Platter].osu"))) { Assert.AreEqual("osu file format v13", stream.ReadLine().Trim()); } diff --git a/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs index 673394553e..5e10402206 100644 --- a/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs @@ -52,7 +52,7 @@ namespace osu.Game.Beatmaps.Drawable header.State = PanelSelectedState.Selected; break; case BeatmapGroupState.Collapsed: - FadeTo(0.5f, 250); + FadeTo(0.8f, 250); header.State = PanelSelectedState.NotSelected; difficulties.Hide(); @@ -61,7 +61,7 @@ namespace osu.Game.Beatmaps.Drawable } } - public BeatmapGroup(BeatmapSetInfo beatmapSet) + public BeatmapGroup(BeatmapSetInfo beatmapSet, WorkingBeatmap working) { this.beatmapSet = beatmapSet; @@ -78,7 +78,7 @@ namespace osu.Game.Beatmaps.Drawable Direction = FlowDirection.VerticalOnly, Children = new Framework.Graphics.Drawable[] { - header = new BeatmapSetHeader(beatmapSet) + header = new BeatmapSetHeader(beatmapSet, working) { GainedSelection = headerGainedSelection, RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Beatmaps/Drawable/BeatmapSetHeader.cs b/osu.Game/Beatmaps/Drawable/BeatmapSetHeader.cs index 9ce0bafdf4..7c6fd5a963 100644 --- a/osu.Game/Beatmaps/Drawable/BeatmapSetHeader.cs +++ b/osu.Game/Beatmaps/Drawable/BeatmapSetHeader.cs @@ -31,27 +31,18 @@ namespace osu.Game.Beatmaps.Drawable Width = 0.8f; } - public BeatmapSetHeader(BeatmapSetInfo beatmapSet) + public BeatmapSetHeader(BeatmapSetInfo beatmapSet, WorkingBeatmap working) { Children = new Framework.Graphics.Drawable[] { - new Box + working.Background == null ? new Box{ RelativeSizeAxes = Axes.Both, Colour = new Color4(20, 20, 20, 255) } : new Sprite { - Colour = new Color4(85, 85, 85, 255), - RelativeSizeAxes = Axes.Both, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Framework.Graphics.Drawable[] - { - new Box // TODO: Gradient - { - Colour = new Color4(0, 0, 0, 100), - RelativeSizeAxes = Axes.Both, - } - } - }, + Texture = working.Background, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(0.5f), + Colour = new Color4(200, 200, 200, 255), + }, new FlowContainer { Direction = FlowDirection.VerticalOnly, diff --git a/osu.Game/Beatmaps/Drawable/Panel.cs b/osu.Game/Beatmaps/Drawable/Panel.cs index 98b7cc4e97..c9da9e9ac2 100644 --- a/osu.Game/Beatmaps/Drawable/Panel.cs +++ b/osu.Game/Beatmaps/Drawable/Panel.cs @@ -10,6 +10,7 @@ using osu.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; +using OpenTK; using OpenTK.Graphics; namespace osu.Game.Beatmaps.Drawable @@ -69,7 +70,13 @@ namespace osu.Game.Beatmaps.Drawable BorderColour = new Color4(BorderColour.R, BorderColour.G, BorderColour.B, 0); BorderThickness = 0; - EdgeEffect = new EdgeEffect { Type = EdgeEffectType.None }; + EdgeEffect = new EdgeEffect + { + Type = EdgeEffectType.Shadow, + Offset = new Vector2(1), + Radius = 10, + Colour = new Color4(0, 0, 0, 100), + }; } protected override bool OnClick(InputState state) diff --git a/osu.Game/Beatmaps/IO/ArchiveReader.cs b/osu.Game/Beatmaps/IO/ArchiveReader.cs index 5f1afe3a00..bde6bb8b35 100644 --- a/osu.Game/Beatmaps/IO/ArchiveReader.cs +++ b/osu.Game/Beatmaps/IO/ArchiveReader.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; using System.IO; +using osu.Framework.IO.Stores; using osu.Framework.Platform; using osu.Game.Database; namespace osu.Game.Beatmaps.IO { - public abstract class ArchiveReader : IDisposable + public abstract class ArchiveReader : IDisposable, IResourceStore { private class Reader { @@ -42,8 +43,23 @@ namespace osu.Game.Beatmaps.IO /// /// Opens a stream for reading a specific file from this archive. /// - public abstract Stream ReadFile(string name); + public abstract Stream GetStream(string name); public abstract void Dispose(); + + public virtual byte[] Get(string name) + { + using (Stream input = GetStream(name)) + { + if (input == null) + return null; + + using (MemoryStream ms = new MemoryStream()) + { + input.CopyTo(ms); + return ms.ToArray(); + } + } + } } } \ No newline at end of file diff --git a/osu.Game/Beatmaps/IO/OszArchiveReader.cs b/osu.Game/Beatmaps/IO/OszArchiveReader.cs index edfaca7708..85ee2d19b9 100644 --- a/osu.Game/Beatmaps/IO/OszArchiveReader.cs +++ b/osu.Game/Beatmaps/IO/OszArchiveReader.cs @@ -33,7 +33,7 @@ namespace osu.Game.Beatmaps.IO .Select(e => e.FileName).ToArray(); if (beatmaps.Length == 0) throw new FileNotFoundException(@"This directory contains no beatmaps"); - using (var stream = new StreamReader(ReadFile(beatmaps[0]))) + using (var stream = new StreamReader(GetStream(beatmaps[0]))) { var decoder = BeatmapDecoder.GetDecoder(stream); firstMap = decoder.Decode(stream); @@ -45,7 +45,7 @@ namespace osu.Game.Beatmaps.IO return beatmaps; } - public override Stream ReadFile(string name) + public override Stream GetStream(string name) { ZipEntry entry = archive.Entries.SingleOrDefault(e => e.FileName == name); if (entry == null) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index a2a0a27e02..07e88af517 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -4,6 +4,7 @@ using System; using System.IO; using osu.Framework.Audio.Track; +using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.IO; using osu.Game.Database; @@ -19,6 +20,24 @@ namespace osu.Game.Beatmaps private ArchiveReader reader => database.GetReader(BeatmapSetInfo); + private Texture background; + public Texture Background + { + get + { + if (background != null) return background; + + try + { + background = new TextureStore(new RawTextureLoaderStore(reader)).Get(BeatmapInfo.Metadata.BackgroundFile); + } + catch { } + + return background; + } + set { background = value; } + } + private Beatmap beatmap; public Beatmap Beatmap { @@ -28,7 +47,7 @@ namespace osu.Game.Beatmaps try { - using (var stream = new StreamReader(reader.ReadFile(BeatmapInfo.Path))) + using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path))) beatmap = BeatmapDecoder.GetDecoder(stream)?.Decode(stream); } catch { } @@ -47,7 +66,7 @@ namespace osu.Game.Beatmaps try { - var trackData = reader.ReadFile(BeatmapInfo.Metadata.AudioFile); + var trackData = reader.GetStream(BeatmapInfo.Metadata.AudioFile); if (trackData != null) track = new AudioTrackBass(trackData); } diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index 06007dba9c..aa68a3be15 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -95,7 +95,7 @@ namespace osu.Game.Database string[] mapNames = reader.ReadBeatmaps(); foreach (var name in mapNames) { - using (var stream = new StreamReader(reader.ReadFile(name))) + using (var stream = new StreamReader(reader.GetStream(name))) { var decoder = BeatmapDecoder.GetDecoder(stream); Beatmap beatmap = decoder.Decode(stream); diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index d7136e52d0..a2855d55b5 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -240,7 +240,10 @@ namespace osu.Game.GameModes.Play beatmapSet = database.GetWithChildren(beatmapSet.BeatmapSetID); beatmapSet.Beatmaps.ForEach(b => database.GetChildren(b)); beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList(); - var group = new BeatmapGroup(beatmapSet) { SelectionChanged = selectionChanged }; + + var working = database.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()); + + var group = new BeatmapGroup(beatmapSet, working) { SelectionChanged = selectionChanged }; group.Preload(Game, g => { From 76e6931a59a787a4ff6d301d5d673e39ef129877 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 5 Nov 2016 20:06:04 +0900 Subject: [PATCH 23/28] Update framework. --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 6650f7fbbc..ed33cc4899 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 6650f7fbbcbfb29489e378e73cb4f3b1042384bd +Subproject commit ed33cc48996e9b57093c4d057aa0560319495dee From ba39a9df8ec61c364ca8c62813d3138025a95783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Sat, 5 Nov 2016 12:24:15 +0100 Subject: [PATCH 24/28] Fix wrong initial state of beatmap panels. --- osu.Game/Beatmaps/Drawable/Panel.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Drawable/Panel.cs b/osu.Game/Beatmaps/Drawable/Panel.cs index c9da9e9ac2..5e77e152ff 100644 --- a/osu.Game/Beatmaps/Drawable/Panel.cs +++ b/osu.Game/Beatmaps/Drawable/Panel.cs @@ -23,12 +23,14 @@ namespace osu.Game.Beatmaps.Drawable Masking = true; CornerRadius = 10; - BorderColour = new Color4(221, 255, 255, 0); + BorderColour = new Color4(221, 255, 255, 255); RelativeSizeAxes = Axes.X; + + Deselected(); } - private PanelSelectedState state; + private PanelSelectedState state = PanelSelectedState.NotSelected; public PanelSelectedState State { @@ -53,7 +55,6 @@ namespace osu.Game.Beatmaps.Drawable protected virtual void Selected() { - BorderColour = new Color4(BorderColour.R, BorderColour.G, BorderColour.B, 1f); BorderThickness = 2.5f; EdgeEffect = new EdgeEffect @@ -67,7 +68,6 @@ namespace osu.Game.Beatmaps.Drawable protected virtual void Deselected() { - BorderColour = new Color4(BorderColour.R, BorderColour.G, BorderColour.B, 0); BorderThickness = 0; EdgeEffect = new EdgeEffect From f2b37e1fe725ea3e6c1a2cae2011ac3145007766 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 5 Nov 2016 20:01:46 +0800 Subject: [PATCH 25/28] Add lock on each property of WorkingBeatmap. --- osu.Game/Beatmaps/WorkingBeatmap.cs | 66 +++++++++++++++++------------ 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 07e88af517..a94511ca2e 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -21,60 +21,72 @@ namespace osu.Game.Beatmaps private ArchiveReader reader => database.GetReader(BeatmapSetInfo); private Texture background; + private object backgroundLock = new object(); public Texture Background { get { - if (background != null) return background; - - try + lock (backgroundLock) { - background = new TextureStore(new RawTextureLoaderStore(reader)).Get(BeatmapInfo.Metadata.BackgroundFile); - } - catch { } + if (background != null) return background; - return background; + try + { + background = new TextureStore(new RawTextureLoaderStore(reader)).Get(BeatmapInfo.Metadata.BackgroundFile); + } + catch { } + + return background; + } } - set { background = value; } + set { lock (backgroundLock) background = value; } } private Beatmap beatmap; + private object beatmapLock; public Beatmap Beatmap { get { - if (beatmap != null) return beatmap; - - try + lock (beatmapLock) { - using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path))) - beatmap = BeatmapDecoder.GetDecoder(stream)?.Decode(stream); - } - catch { } + if (beatmap != null) return beatmap; - return beatmap; + try + { + using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path))) + beatmap = BeatmapDecoder.GetDecoder(stream)?.Decode(stream); + } + catch { } + + return beatmap; + } } - set { beatmap = value; } + set { lock (beatmapLock) beatmap = value; } } private AudioTrack track; + private object trackLock = new object(); public AudioTrack Track { get { - if (track != null) return track; - - try + lock (trackLock) { - var trackData = reader.GetStream(BeatmapInfo.Metadata.AudioFile); - if (trackData != null) - track = new AudioTrackBass(trackData); - } - catch { } + if (track != null) return track; - return track; + try + { + var trackData = reader.GetStream(BeatmapInfo.Metadata.AudioFile); + if (trackData != null) + track = new AudioTrackBass(trackData); + } + catch { } + + return track; + } } - set { track = value; } + set { lock (trackLock) track = value; } } public WorkingBeatmap(Beatmap beatmap) From e69dac774519e57a12dd25c6e82b14e51d5fc29d Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sat, 5 Nov 2016 20:21:08 +0800 Subject: [PATCH 26/28] Fix lock object. --- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index a94511ca2e..417e289b65 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -43,7 +43,7 @@ namespace osu.Game.Beatmaps } private Beatmap beatmap; - private object beatmapLock; + private object beatmapLock = new object(); public Beatmap Beatmap { get From 619d97c642680767d9511defde6d8eb9d686e13f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Sat, 5 Nov 2016 13:51:52 +0100 Subject: [PATCH 27/28] Fix indentation and typo. --- .../Objects/Osu/Drawable/DrawableCircle.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs index 595584f099..26d7375852 100644 --- a/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs +++ b/osu.Game/Beatmaps/Objects/Osu/Drawable/DrawableCircle.cs @@ -140,12 +140,12 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable Children = new[] { - number = new Sprite - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Alpha = 1 - } + number = new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Alpha = 1 + } }; } @@ -158,7 +158,7 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable private class GlowLayer : Container { - private Sprite layer3; + private Sprite layer; public GlowLayer() { @@ -167,20 +167,20 @@ namespace osu.Game.Beatmaps.Objects.Osu.Drawable Children = new[] { - layer3 = new Sprite - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - BlendingMode = BlendingMode.Additive, - Alpha = 0.5f - } + layer = new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + BlendingMode = BlendingMode.Additive, + Alpha = 0.5f + } }; } protected override void Load(BaseGame game) { base.Load(game); - layer3.Texture = game.Textures.Get(@"Play/osu/ring-glow@2x"); + layer.Texture = game.Textures.Get(@"Play/osu/ring-glow@2x"); } } From cc140c963413a37de0bfceb18aa875fa0cfde23a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 5 Nov 2016 22:48:32 +0900 Subject: [PATCH 28/28] Fix broken tests. --- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index eb8e9260df..bbd441d25a 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -8,6 +8,7 @@ using osu.Framework.Desktop.Platform; using osu.Framework.Platform; using osu.Game.Database; using osu.Game.IPC; +using osu.Game.GameModes.Play; namespace osu.Game.Tests.Beatmaps.IO { @@ -45,7 +46,7 @@ namespace osu.Game.Tests.Beatmaps.IO var importer = new BeatmapImporter(client); if (!importer.Import(osz_path).Wait(1000)) - Assert.Fail(@"IPC took too long to send"); + Assert.Fail(@"IPC took too long to send"); ensureLoaded(osu, 10000); } @@ -78,7 +79,7 @@ namespace osu.Game.Tests.Beatmaps.IO @"BeatmapSet did not import to the database"); //ensure we were stored to beatmap database backing... - + Assert.IsTrue(resultSets.Count() == 1); IEnumerable resultBeatmaps = null; @@ -103,7 +104,7 @@ namespace osu.Game.Tests.Beatmaps.IO Assert.IsTrue(set.Beatmaps.Count > 0); - var beatmap = osu.Beatmaps.GetBeatmap(set.Beatmaps[0]); + var beatmap = osu.Beatmaps.GetBeatmap(set.Beatmaps.First(b => b.Mode == PlayMode.Osu)); Assert.IsTrue(beatmap.HitObjects.Count > 0); }