From 7141bc86d3ef1ad6acc8ca4e44cc493aa9e9c47b Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Tue, 14 Mar 2017 17:01:21 +0900 Subject: [PATCH] Rework beatmap post-processing into HitRenderer. --- .../Tests/TestCasePlayer.cs | 2 -- .../Beatmaps/CatchBeatmapProcessor.cs | 16 +++++++++ osu.Game.Modes.Catch/UI/CatchHitRenderer.cs | 2 ++ .../osu.Game.Modes.Catch.csproj | 1 + .../Beatmaps/ManiaBeatmapProcessor.cs | 16 +++++++++ osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs | 2 ++ .../osu.Game.Modes.Mania.csproj | 1 + .../Beatmaps/OsuBeatmapConverter.cs | 15 +------- .../Beatmaps/OsuBeatmapProcessor.cs | 33 +++++++++++++++++ osu.Game.Modes.Osu/Objects/Spinner.cs | 1 - osu.Game.Modes.Osu/UI/OsuHitRenderer.cs | 2 ++ osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj | 1 + .../Beatmaps/TaikoBeatmapProcessor.cs | 16 +++++++++ osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs | 2 ++ .../osu.Game.Modes.Taiko.csproj | 1 + osu.Game/Beatmaps/Beatmap.cs | 14 +++++--- osu.Game/Beatmaps/Formats/BeatmapDecoder.cs | 36 +------------------ osu.Game/Beatmaps/IBeatmapProcessor.cs | 27 ++++++++++++++ osu.Game/Modes/Objects/Hit.cs | 4 ++- osu.Game/Modes/Objects/HitObjectWithCombo.cs | 15 -------- osu.Game/Modes/Objects/Slider.cs | 4 ++- osu.Game/Modes/Objects/Types/IHasCombo.cs | 12 ------- osu.Game/Modes/UI/HitRenderer.cs | 6 +++- osu.Game/osu.Game.csproj | 2 +- 24 files changed, 144 insertions(+), 87 deletions(-) create mode 100644 osu.Game.Modes.Catch/Beatmaps/CatchBeatmapProcessor.cs create mode 100644 osu.Game.Modes.Mania/Beatmaps/ManiaBeatmapProcessor.cs create mode 100644 osu.Game.Modes.Osu/Beatmaps/OsuBeatmapProcessor.cs create mode 100644 osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapProcessor.cs create mode 100644 osu.Game/Beatmaps/IBeatmapProcessor.cs delete mode 100644 osu.Game/Modes/Objects/HitObjectWithCombo.cs diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs index ee58d934a4..7d770031a4 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs @@ -77,8 +77,6 @@ namespace osu.Desktop.VisualTests.Tests } }; - decoder.Process(b); - beatmap = new TestWorkingBeatmap(b); } diff --git a/osu.Game.Modes.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Modes.Catch/Beatmaps/CatchBeatmapProcessor.cs new file mode 100644 index 0000000000..59cd5d4092 --- /dev/null +++ b/osu.Game.Modes.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -0,0 +1,16 @@ +using osu.Game.Beatmaps; +using osu.Game.Modes.Catch.Objects; + +namespace osu.Game.Modes.Catch.Beatmaps +{ + internal class CatchBeatmapProcessor : IBeatmapProcessor + { + public void PostProcess(Beatmap beatmap) + { + } + + public void SetDefaults(CatchBaseHit hitObject) + { + } + } +} diff --git a/osu.Game.Modes.Catch/UI/CatchHitRenderer.cs b/osu.Game.Modes.Catch/UI/CatchHitRenderer.cs index a8b2d48760..7a7a8ac222 100644 --- a/osu.Game.Modes.Catch/UI/CatchHitRenderer.cs +++ b/osu.Game.Modes.Catch/UI/CatchHitRenderer.cs @@ -18,6 +18,8 @@ namespace osu.Game.Modes.Catch.UI protected override IBeatmapConverter CreateBeatmapConverter() => new CatchBeatmapConverter(); + protected override IBeatmapProcessor CreateBeatmapProcessor() => new CatchBeatmapProcessor(); + protected override Playfield CreatePlayfield() => new CatchPlayfield(); protected override DrawableHitObject GetVisualRepresentation(CatchBaseHit h) => null;// new DrawableFruit(h); diff --git a/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj b/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj index 4908bcd0d0..ca6d7ed081 100644 --- a/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj +++ b/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj @@ -48,6 +48,7 @@ + diff --git a/osu.Game.Modes.Mania/Beatmaps/ManiaBeatmapProcessor.cs b/osu.Game.Modes.Mania/Beatmaps/ManiaBeatmapProcessor.cs new file mode 100644 index 0000000000..55a1807601 --- /dev/null +++ b/osu.Game.Modes.Mania/Beatmaps/ManiaBeatmapProcessor.cs @@ -0,0 +1,16 @@ +using osu.Game.Beatmaps; +using osu.Game.Modes.Mania.Objects; + +namespace osu.Game.Modes.Mania.Beatmaps +{ + internal class ManiaBeatmapProcessor : IBeatmapProcessor + { + public void PostProcess(Beatmap beatmap) + { + } + + public void SetDefaults(ManiaBaseHit hitObject) + { + } + } +} diff --git a/osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs b/osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs index d29a088225..11671a34d2 100644 --- a/osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs +++ b/osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs @@ -21,6 +21,8 @@ namespace osu.Game.Modes.Mania.UI protected override IBeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter(); + protected override IBeatmapProcessor CreateBeatmapProcessor() => new ManiaBeatmapProcessor(); + protected override Playfield CreatePlayfield() => new ManiaPlayfield(columns); protected override DrawableHitObject GetVisualRepresentation(ManiaBaseHit h) diff --git a/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj b/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj index 48f8d23a07..43b6401fdb 100644 --- a/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj +++ b/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj @@ -48,6 +48,7 @@ + diff --git a/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs index d60a22652d..61e97f1f4d 100644 --- a/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs +++ b/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs @@ -8,7 +8,6 @@ using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.Objects.Drawables; using System.Collections.Generic; using osu.Game.Modes.Objects.Types; -using OpenTK.Graphics; using System.Linq; namespace osu.Game.Modes.Osu.Beatmaps @@ -17,13 +16,9 @@ namespace osu.Game.Modes.Osu.Beatmaps { public Beatmap Convert(Beatmap original) { - List converted = convertHitObjects(original.HitObjects, original.BeatmapInfo?.StackLeniency ?? 0.7f); - - converted.ForEach(c => c.SetDefaultsFromBeatmap(original)); - return new Beatmap(original) { - HitObjects = converted + HitObjects = convertHitObjects(original.HitObjects, original.BeatmapInfo?.StackLeniency ?? 0.7f) }; } @@ -57,8 +52,6 @@ namespace osu.Game.Modes.Osu.Beatmaps Position = positionData?.Position ?? Vector2.Zero, - ComboColour = comboData?.ComboColour ?? Color4.White, - ComboIndex = comboData?.ComboIndex ?? 0, NewCombo = comboData?.NewCombo ?? false, Length = distanceData?.Distance ?? 0, @@ -76,10 +69,6 @@ namespace osu.Game.Modes.Osu.Beatmaps Position = new Vector2(512, 384) / 2, EndTime = endTimeData.EndTime, - - ComboColour = comboData?.ComboColour ?? Color4.White, - ComboIndex = comboData?.ComboIndex ?? 0, - NewCombo = comboData?.NewCombo ?? false, }; } @@ -90,8 +79,6 @@ namespace osu.Game.Modes.Osu.Beatmaps Position = positionData?.Position ?? Vector2.Zero, - ComboColour = comboData?.ComboColour ?? Color4.White, - ComboIndex = comboData?.ComboIndex ?? 0, NewCombo = comboData?.NewCombo ?? false }; } diff --git a/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapProcessor.cs new file mode 100644 index 0000000000..6f1a380243 --- /dev/null +++ b/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -0,0 +1,33 @@ +using osu.Game.Beatmaps; +using osu.Game.Modes.Osu.Objects; + +namespace osu.Game.Modes.Osu.Beatmaps +{ + internal class OsuBeatmapProcessor : IBeatmapProcessor + { + public void SetDefaults(OsuHitObject hitObject) + { + } + + public void PostProcess(Beatmap beatmap) + { + if ((beatmap.ComboColors?.Count ?? 0) == 0) + return; + + int comboIndex = 0; + int colourIndex = 0; + + foreach (var obj in beatmap.HitObjects) + { + if (obj.NewCombo) + { + comboIndex = 0; + colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count; + } + + obj.ComboIndex = comboIndex++; + obj.ComboColour = beatmap.ComboColors[colourIndex]; + } + } + } +} diff --git a/osu.Game.Modes.Osu/Objects/Spinner.cs b/osu.Game.Modes.Osu/Objects/Spinner.cs index 9bc13c47d8..65e39f30ed 100644 --- a/osu.Game.Modes.Osu/Objects/Spinner.cs +++ b/osu.Game.Modes.Osu/Objects/Spinner.cs @@ -13,6 +13,5 @@ namespace osu.Game.Modes.Osu.Objects public override HitObjectType Type => HitObjectType.Spinner; public override bool NewCombo => true; - } } diff --git a/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs b/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs index 414bfd2afa..a3b05fe009 100644 --- a/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs +++ b/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs @@ -19,6 +19,8 @@ namespace osu.Game.Modes.Osu.UI protected override IBeatmapConverter CreateBeatmapConverter() => new OsuBeatmapConverter(); + protected override IBeatmapProcessor CreateBeatmapProcessor() => new OsuBeatmapProcessor(); + protected override Playfield CreatePlayfield() => new OsuPlayfield(); protected override DrawableHitObject GetVisualRepresentation(OsuHitObject h) diff --git a/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj b/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj index ec43a3379a..e2c1a71cb9 100644 --- a/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj +++ b/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj @@ -44,6 +44,7 @@ + diff --git a/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapProcessor.cs b/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapProcessor.cs new file mode 100644 index 0000000000..a3dcbd6749 --- /dev/null +++ b/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapProcessor.cs @@ -0,0 +1,16 @@ +using osu.Game.Beatmaps; +using osu.Game.Modes.Taiko.Objects; + +namespace osu.Game.Modes.Taiko.Beatmaps +{ + internal class TaikoBeatmapProcessor : IBeatmapProcessor + { + public void PostProcess(Beatmap beatmap) + { + } + + public void SetDefaults(TaikoBaseHit hitObject) + { + } + } +} diff --git a/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs b/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs index fb5e38d4dc..328ff5c425 100644 --- a/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs +++ b/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs @@ -18,6 +18,8 @@ namespace osu.Game.Modes.Taiko.UI protected override IBeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter(); + protected override IBeatmapProcessor CreateBeatmapProcessor() => new TaikoBeatmapProcessor(); + protected override Playfield CreatePlayfield() => new TaikoPlayfield(); protected override DrawableHitObject GetVisualRepresentation(TaikoBaseHit h) => null;// new DrawableTaikoHit(h); diff --git a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj b/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj index 7d6bcf4853..f6902bdf67 100644 --- a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj +++ b/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj @@ -48,6 +48,7 @@ + diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index de869192b9..05334b2cd2 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -19,7 +19,13 @@ namespace osu.Game.Beatmaps { public BeatmapInfo BeatmapInfo; public List ControlPoints; - public List ComboColors; + public List 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) + }; public BeatmapMetadata Metadata => BeatmapInfo?.Metadata ?? BeatmapInfo?.BeatmapSet?.Metadata; @@ -34,9 +40,9 @@ namespace osu.Game.Beatmaps /// The original beatmap to use the parameters of. public Beatmap(Beatmap original = null) { - BeatmapInfo = original?.BeatmapInfo; - ControlPoints = original?.ControlPoints; - ComboColors = original?.ComboColors; + BeatmapInfo = original?.BeatmapInfo ?? BeatmapInfo; + ControlPoints = original?.ControlPoints ?? ControlPoints; + ComboColors = original?.ComboColors ?? ComboColors; } public double BPMMaximum => 60000 / (ControlPoints?.Where(c => c.BeatLength != 0).OrderBy(c => c.BeatLength).FirstOrDefault() ?? ControlPoint.Default).BeatLength; diff --git a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs index e8d9a6a96f..ba608fb08d 100644 --- a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.IO; using osu.Game.Modes.Objects; -using OpenTK.Graphics; using osu.Game.Beatmaps.Timing; using osu.Game.Database; @@ -31,9 +30,7 @@ namespace osu.Game.Beatmaps.Formats public virtual Beatmap Decode(TextReader stream) { - Beatmap b = ParseFile(stream); - Process(b); - return b; + return ParseFile(stream); } public virtual void Decode(TextReader stream, Beatmap beatmap) @@ -41,43 +38,12 @@ namespace osu.Game.Beatmaps.Formats ParseFile(stream, beatmap); } - public virtual Beatmap Process(Beatmap beatmap) - { - int comboIndex = 0; - int colourIndex = 0; - - foreach (var obj in beatmap.HitObjects) - { - HitObjectWithCombo comboObject = obj as HitObjectWithCombo; - - if (comboObject == null || comboObject.NewCombo) - { - comboIndex = 0; - colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count; - } - - if (comboObject != null) - { - comboObject.ComboIndex = comboIndex++; - comboObject.ComboColour = beatmap.ComboColors[colourIndex]; - } - } - - return beatmap; - } - protected virtual Beatmap ParseFile(TextReader stream) { var beatmap = new Beatmap { HitObjects = new List(), ControlPoints = new List(), - 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), - }, BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata(), diff --git a/osu.Game/Beatmaps/IBeatmapProcessor.cs b/osu.Game/Beatmaps/IBeatmapProcessor.cs new file mode 100644 index 0000000000..5e23044cbf --- /dev/null +++ b/osu.Game/Beatmaps/IBeatmapProcessor.cs @@ -0,0 +1,27 @@ +using osu.Game.Modes.Objects; + +namespace osu.Game.Beatmaps +{ + /// + /// Processes a post-converted Beatmap. + /// + /// The type of HitObject contained in the Beatmap. + public interface IBeatmapProcessor + where T : HitObject + { + /// + /// Sets default values for a HitObject. + /// + /// The HitObject to set default values for. + void SetDefaults(T hitObject); + + /// + /// Post-processes a Beatmap to add mode-specific components that aren't added during conversion. + /// + /// An example of such a usage is for combo colours. + /// + /// + /// The Beatmap to process. + void PostProcess(Beatmap beatmap); + } +} diff --git a/osu.Game/Modes/Objects/Hit.cs b/osu.Game/Modes/Objects/Hit.cs index 48b50ac17d..1f0eaef666 100644 --- a/osu.Game/Modes/Objects/Hit.cs +++ b/osu.Game/Modes/Objects/Hit.cs @@ -6,8 +6,10 @@ using OpenTK; namespace osu.Game.Modes.Objects { - internal class Hit : HitObjectWithCombo, IHasPosition + internal class Hit : HitObject, IHasPosition, IHasCombo { public Vector2 Position { get; set; } + + public bool NewCombo { get; set; } } } diff --git a/osu.Game/Modes/Objects/HitObjectWithCombo.cs b/osu.Game/Modes/Objects/HitObjectWithCombo.cs deleted file mode 100644 index 05710986a1..0000000000 --- a/osu.Game/Modes/Objects/HitObjectWithCombo.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 osu.Game.Modes.Objects.Types; -using OpenTK.Graphics; - -namespace osu.Game.Modes.Objects -{ - internal class HitObjectWithCombo : HitObject, IHasCombo - { - public Color4 ComboColour { get; set; } - public bool NewCombo { get; set; } - public int ComboIndex { get; set; } - } -} diff --git a/osu.Game/Modes/Objects/Slider.cs b/osu.Game/Modes/Objects/Slider.cs index 53ac119dfb..755ec20c1a 100644 --- a/osu.Game/Modes/Objects/Slider.cs +++ b/osu.Game/Modes/Objects/Slider.cs @@ -7,7 +7,7 @@ using OpenTK; namespace osu.Game.Modes.Objects { - internal class Slider : HitObjectWithCombo, IHasCurve, IHasPosition, IHasDistance, IHasRepeats + internal class Slider : HitObject, IHasCurve, IHasPosition, IHasDistance, IHasRepeats, IHasCombo { public List ControlPoints { get; set; } public CurveType CurveType { get; set; } @@ -17,5 +17,7 @@ namespace osu.Game.Modes.Objects public double Distance { get; set; } public int RepeatCount { get; set; } + + public bool NewCombo { get; set; } } } diff --git a/osu.Game/Modes/Objects/Types/IHasCombo.cs b/osu.Game/Modes/Objects/Types/IHasCombo.cs index f342394ba0..1ca381372d 100644 --- a/osu.Game/Modes/Objects/Types/IHasCombo.cs +++ b/osu.Game/Modes/Objects/Types/IHasCombo.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 OpenTK.Graphics; - namespace osu.Game.Modes.Objects.Types { /// @@ -10,19 +8,9 @@ namespace osu.Game.Modes.Objects.Types /// public interface IHasCombo { - /// - /// The colour of this HitObject in the combo. - /// - Color4 ComboColour { get; } - /// /// Whether the HitObject starts a new combo. /// bool NewCombo { get; } - - /// - /// The combo index. - /// - int ComboIndex { get; } } } diff --git a/osu.Game/Modes/UI/HitRenderer.cs b/osu.Game/Modes/UI/HitRenderer.cs index e466dd2b8c..63eefe7e3b 100644 --- a/osu.Game/Modes/UI/HitRenderer.cs +++ b/osu.Game/Modes/UI/HitRenderer.cs @@ -52,7 +52,10 @@ namespace osu.Game.Modes.UI protected HitRenderer(WorkingBeatmap beatmap) { + // Convert + process the beatmap Beatmap = CreateBeatmapConverter().Convert(beatmap.Beatmap); + Beatmap.HitObjects.ForEach(CreateBeatmapProcessor().SetDefaults); + CreateBeatmapProcessor().PostProcess(Beatmap); applyMods(beatmap.Mods.Value); @@ -70,7 +73,6 @@ namespace osu.Game.Modes.UI AddInternal(InputManager); } - [BackgroundDependencyLoader] private void load() { @@ -110,6 +112,8 @@ namespace osu.Game.Modes.UI protected abstract DrawableHitObject GetVisualRepresentation(TObject h); protected abstract Playfield CreatePlayfield(); + protected abstract IBeatmapConverter CreateBeatmapConverter(); + protected abstract IBeatmapProcessor CreateBeatmapProcessor(); } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d2cdb69885..137b95a2a7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -74,6 +74,7 @@ + @@ -94,7 +95,6 @@ -