diff --git a/osu.Game.Rulesets.Mania/Timing/TimeRelativeContainer.cs b/osu.Game.Rulesets.Mania/Timing/TimeRelativeContainer.cs index c5060eabbb..8ca30488ff 100644 --- a/osu.Game.Rulesets.Mania/Timing/TimeRelativeContainer.cs +++ b/osu.Game.Rulesets.Mania/Timing/TimeRelativeContainer.cs @@ -7,15 +7,16 @@ using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using OpenTK; +using osu.Game.Beatmaps.Timing; namespace osu.Game.Rulesets.Mania.Timing { /// /// A container in which the Y-relative coordinate space is spanned by a length of time. /// - /// This container contains s which scroll inside this container. - /// Drawables added to this container are moved inside the relevant , - /// and as such, will scroll along with the s. + /// This container contains s which scroll inside this container. + /// Drawables added to this container are moved inside the relevant , + /// and as such, will scroll along with the s. /// /// public class TimeRelativeContainer : Container @@ -31,9 +32,9 @@ namespace osu.Game.Rulesets.Mania.Timing private readonly List drawableTimingSections; - public TimeRelativeContainer(IEnumerable timingSections) + public TimeRelativeContainer(IEnumerable timingChanges) { - drawableTimingSections = timingSections.Select(t => new DrawableTimingSection(t)).ToList(); + drawableTimingSections = timingChanges.Select(t => new DrawableTimingSection(t)).ToList(); Children = drawableTimingSections; } @@ -68,13 +69,7 @@ namespace osu.Game.Rulesets.Mania.Timing /// private class DrawableTimingSection : Container { - protected override Container Content => content; - /// - /// The container which will scroll relative to the current time. - /// - private readonly Container content; - - private readonly TimingSection section; + private readonly ControlPoint timingChange; /// /// Creates a drawable timing section. The height of this container will be proportional @@ -84,26 +79,17 @@ namespace osu.Game.Rulesets.Mania.Timing /// which means that the content container will scroll at twice the normal rate. /// /// - /// The section to create the drawable timing section for. - public DrawableTimingSection(TimingSection section) + /// The timing change to create the drawable timing section for. + public DrawableTimingSection(ControlPoint timingChange) { - this.section = section; + this.timingChange = timingChange; Anchor = Anchor.BottomCentre; Origin = Anchor.BottomCentre; RelativeSizeAxes = Axes.Both; - AddInternal(content = new Container - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativePositionAxes = Axes.Both, - RelativeSizeAxes = Axes.Both, - Y = -(float)section.StartTime, - Height = (float)section.Duration, - RelativeCoordinateSpace = new Vector2(1, (float)section.Duration) - }); + Y = -(float)timingChange.Time; } protected override void Update() @@ -111,11 +97,11 @@ namespace osu.Game.Rulesets.Mania.Timing var parent = (TimeRelativeContainer)Parent; // Adjust our height to account for the speed changes - Height = (float)(parent.TimeSpan * 1000 / section.BeatLength); + Height = (float)(parent.TimeSpan * 1000 / timingChange.BeatLength / timingChange.SpeedMultiplier); RelativeCoordinateSpace = new Vector2(1, (float)parent.TimeSpan); // Scroll the content - content.Y = (float)(Time.Current - section.StartTime); + Y = (float)(Time.Current - timingChange.Time); } public override void Add(Drawable drawable) @@ -124,7 +110,7 @@ namespace osu.Game.Rulesets.Mania.Timing // we need to offset it back by our position so that it becomes correctly relatively-positioned to us // This can be removed if hit objects were stored such that either their StartTime or their "beat offset" was relative to the timing section // they belonged to, but this requires a radical change to the beatmap format which we're not ready to do just yet - drawable.Y += (float)section.StartTime; + drawable.Y += (float)timingChange.Time; base.Add(drawable); } @@ -134,7 +120,7 @@ namespace osu.Game.Rulesets.Mania.Timing /// can be placed within the timing section's bounds (in this case, from the start of the timing section up to infinity). /// /// The drawable to check. - public bool CanContain(Drawable drawable) => content.Y >= drawable.Y; + public bool CanContain(Drawable drawable) => Y >= drawable.Y; } } } \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Timing/TimingSection.cs b/osu.Game.Rulesets.Mania/Timing/TimingSection.cs deleted file mode 100644 index 65a2094c46..0000000000 --- a/osu.Game.Rulesets.Mania/Timing/TimingSection.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Beatmaps.Timing; - -namespace osu.Game.Rulesets.Mania.Timing -{ - /// - /// A point in the map where the beat length or speed multiplier has changed . - /// - public class TimingSection - { - /// - /// The time at which the change occurred. - /// - public double StartTime; - /// - /// The duration of this timing section - lasts until the next timing section. - /// - public double Duration; - /// - /// The beat length, includes any speed multiplier. - /// - public double BeatLength; - /// - /// The time signature of this timing section. - /// - public TimeSignatures TimeSignature; - } -} \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 96f4b17ff8..34d241485c 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -17,6 +17,7 @@ using System.Collections.Generic; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Judgements; +using osu.Game.Beatmaps.Timing; namespace osu.Game.Rulesets.Mania.UI { @@ -40,7 +41,7 @@ namespace osu.Game.Rulesets.Mania.UI public readonly TimeRelativeContainer TimingSectionContainer; - public Column(IEnumerable timingSections) + public Column(IEnumerable timingChanges) { RelativeSizeAxes = Axes.Y; Width = column_width; @@ -87,7 +88,7 @@ namespace osu.Game.Rulesets.Mania.UI } } }, - TimingSectionContainer = new TimeRelativeContainer(timingSections) + TimingSectionContainer = new TimeRelativeContainer(timingChanges) { Name = "Hit objects", RelativeSizeAxes = Axes.Both, diff --git a/osu.Game.Rulesets.Mania/UI/ManiaHitRenderer.cs b/osu.Game.Rulesets.Mania/UI/ManiaHitRenderer.cs index 4cb5b8853b..9b476c4c1a 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaHitRenderer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaHitRenderer.cs @@ -33,53 +33,37 @@ namespace osu.Game.Rulesets.Mania.UI protected override Playfield CreatePlayfield() { - var timingSections = new List(); + ControlPoint firstTimingChange = Beatmap.TimingInfo.ControlPoints.FirstOrDefault(t => t.TimingChange); - // Construct all the relevant timing sections - ControlPoint lastTimingChange = Beatmap.TimingInfo.ControlPoints.FirstOrDefault(t => t.TimingChange); - - if (lastTimingChange == null) + if (firstTimingChange == null) throw new Exception("The Beatmap contains no timing points!"); - foreach (ControlPoint point in Beatmap.TimingInfo.ControlPoints) + // Generate the timing points, making non-timing changes use the previous timing change + var timingChanges = Beatmap.TimingInfo.ControlPoints.Select(c => { - if (point.TimingChange) - lastTimingChange = point; + ControlPoint t = c.Clone(); - timingSections.Add(new TimingSection - { - StartTime = point.Time, - BeatLength = lastTimingChange.BeatLength / point.SpeedMultiplier, - TimeSignature = point.TimeSignature - }); - } + if (c.TimingChange) + firstTimingChange = c; + else + t.BeatLength = firstTimingChange.BeatLength; + + return t; + }); double lastObjectTime = (Objects.Last() as IHasEndTime)?.EndTime ?? Objects.Last().StartTime; - // Perform some post processing of the timing sections - timingSections = timingSections + // Perform some post processing of the timing changes + timingChanges = timingChanges // Collapse sections after the last hit object - .Where(s => s.StartTime <= lastObjectTime) + .Where(s => s.Time <= lastObjectTime) // Collapse sections with the same start time - .GroupBy(s => s.StartTime).Select(g => g.Last()).OrderBy(s => s.StartTime) + .GroupBy(s => s.Time).Select(g => g.Last()).OrderBy(s => s.Time) // Collapse sections with the same beat length - .GroupBy(s => s.BeatLength).Select(g => g.First()) + .GroupBy(s => s.BeatLength * s.SpeedMultiplier).Select(g => g.First()) .ToList(); - // Determine duration of timing sections - for (int i = 0; i < timingSections.Count; i++) - { - if (i < timingSections.Count - 1) - timingSections[i].Duration = timingSections[i + 1].StartTime - timingSections[i].StartTime; - else - { - // Extra length added for the last timing section to extend past the last hitobject - double extraLength = timingSections[i].BeatLength * (int)timingSections[i].TimeSignature; - timingSections[i].Duration = lastObjectTime + extraLength - timingSections[i].StartTime; - } - } - - return new ManiaPlayfield(Columns ?? (int)Math.Round(Beatmap.BeatmapInfo.Difficulty.CircleSize), timingSections) + return new ManiaPlayfield(Columns ?? (int)Math.Round(Beatmap.BeatmapInfo.Difficulty.CircleSize), timingChanges) { Anchor = Anchor.Centre, Origin = Anchor.Centre diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 46fe64ff66..2461ed458f 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -20,6 +20,7 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Mania.Timing; using osu.Framework.Input; +using osu.Game.Beatmaps.Timing; namespace osu.Game.Rulesets.Mania.UI { @@ -62,7 +63,7 @@ namespace osu.Game.Rulesets.Mania.UI private readonly int columnCount; - public ManiaPlayfield(int columnCount, IEnumerable timingSections) + public ManiaPlayfield(int columnCount, IEnumerable timingChanges) { this.columnCount = columnCount; @@ -94,7 +95,7 @@ namespace osu.Game.Rulesets.Mania.UI Padding = new MarginPadding { Left = 1, Right = 1 }, Spacing = new Vector2(1, 0) }, - barlineContainer = new TimeRelativeContainer(timingSections) + barlineContainer = new TimeRelativeContainer(timingChanges) { Name = "Bar lines", Anchor = Anchor.BottomCentre, @@ -107,7 +108,7 @@ namespace osu.Game.Rulesets.Mania.UI }; for (int i = 0; i < columnCount; i++) - Columns.Add(new Column(timingSections)); + Columns.Add(new Column(timingChanges)); TimeSpan = time_span_default; } diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 7ee397e0ea..70c875fd34 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -58,7 +58,6 @@ -