From b46a9dd0ef18e7da381ddf9259c4d24b719b6695 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 2 Jun 2017 17:33:58 +0900 Subject: [PATCH] Add gravity mod. --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 1 + .../Mods/ManiaModGravity.cs | 65 +++++++++++++++++++ .../Timing/TimingChangeContainer.cs | 2 +- .../UI/ManiaHitRenderer.cs | 47 ++++++++++++-- .../osu.Game.Rulesets.Mania.csproj | 1 + 5 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 30d1846746..bbbce03b19 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -89,6 +89,7 @@ namespace osu.Game.Rulesets.Mania new ModCinema(), }, }, + new ManiaModGravity() }; default: diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs new file mode 100644 index 0000000000..c4b984472c --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.UI; +using osu.Game.Rulesets.Mania.Timing; +using osu.Game.Rulesets.Mania.Timing.Drawables; +using osu.Game.Rulesets.Objects.Types; +using System.Linq; +using osu.Framework.Lists; +using osu.Game.Beatmaps.ControlPoints; +using osu.Framework.MathUtils; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModGravity : Mod, IApplicableMod + { + public override string Name => "Gravity"; + + public override double ScoreMultiplier => 0; + + public void ApplyToHitRenderer(HitRenderer hitRenderer) + { + var maniaHitRenderer = (ManiaHitRenderer)hitRenderer; + + maniaHitRenderer.HitObjectTimingChanges = new Dictionary>(); + maniaHitRenderer.BarlineTimingChanges = new List(); + + foreach (ManiaHitObject obj in maniaHitRenderer.Objects) + { + List timingChanges; + if (!maniaHitRenderer.HitObjectTimingChanges.TryGetValue(obj.Column, out timingChanges)) + maniaHitRenderer.HitObjectTimingChanges[obj.Column] = timingChanges = new List(); + + timingChanges.Add(new DrawableGravityTimingChange(new TimingChange + { + Time = obj.StartTime, + BeatLength = 1000 + })); + } + + double lastObjectTime = (maniaHitRenderer.Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? maniaHitRenderer.Objects.LastOrDefault()?.StartTime ?? double.MaxValue; + + SortedList timingPoints = maniaHitRenderer.Beatmap.ControlPointInfo.TimingPoints; + for (int i = 0; i < timingPoints.Count; i++) + { + TimingControlPoint point = timingPoints[i]; + + // Stop on the beat before the next timing point, or if there is no next timing point stop slightly past the last object + double endTime = i < timingPoints.Count - 1 ? timingPoints[i + 1].Time - point.BeatLength : lastObjectTime + point.BeatLength * (int)point.TimeSignature; + + int index = 0; + for (double t = timingPoints[i].Time; Precision.DefinitelyBigger(endTime, t); t += point.BeatLength, index++) + { + maniaHitRenderer.BarlineTimingChanges.Add(new DrawableGravityTimingChange(new TimingChange + { + Time = t, + BeatLength = 1000 + })); + } + } + } + } +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Timing/TimingChangeContainer.cs b/osu.Game.Rulesets.Mania/Timing/TimingChangeContainer.cs index cb6f4319a3..65f6632a2c 100644 --- a/osu.Game.Rulesets.Mania/Timing/TimingChangeContainer.cs +++ b/osu.Game.Rulesets.Mania/Timing/TimingChangeContainer.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.Timing /// /// The hit object to contain. /// The last timing change which can contain . Null if no timing change can contain the hit object. - private DrawableTimingChange timingChangeFor(DrawableHitObject hitObject) => Children.FirstOrDefault(c => c.CanContain(hitObject)); + private DrawableTimingChange timingChangeFor(DrawableHitObject hitObject) => Children.FirstOrDefault(c => c.CanContain(hitObject)) ?? Children.LastOrDefault(); } /// diff --git a/osu.Game.Rulesets.Mania/UI/ManiaHitRenderer.cs b/osu.Game.Rulesets.Mania/UI/ManiaHitRenderer.cs index 0a2b929446..cc71775c3e 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaHitRenderer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaHitRenderer.cs @@ -31,15 +31,26 @@ namespace osu.Game.Rulesets.Mania.UI { public class ManiaHitRenderer : HitRenderer { - public int? Columns; + private int? columns; + public int Columns => columns ?? (int)Math.Round(Beatmap.BeatmapInfo.Difficulty.CircleSize); + + public Dictionary> HitObjectTimingChanges; + public List BarlineTimingChanges; public ManiaHitRenderer(WorkingBeatmap beatmap, bool isForCurrentRuleset) : base(beatmap, isForCurrentRuleset) { + generateTimingChanges(); } - protected override Playfield CreatePlayfield() + private void generateTimingChanges() { + if (HitObjectTimingChanges != null || BarlineTimingChanges != null) + return; + + HitObjectTimingChanges = new Dictionary>(); + BarlineTimingChanges = new List(); + double lastSpeedMultiplier = 1; double lastBeatLength = 500; @@ -80,7 +91,24 @@ namespace osu.Game.Rulesets.Mania.UI .GroupBy(s => s.BeatLength * s.SpeedMultiplier).Select(g => g.First()) .ToList(); - var playfield = new ManiaPlayfield(Columns ?? (int)Math.Round(Beatmap.BeatmapInfo.Difficulty.CircleSize)) + timingChanges.ForEach(t => + { + for (int i = 0; i < Columns; i++) + { + List columnTimingChanges; + if (!HitObjectTimingChanges.TryGetValue(i, out columnTimingChanges)) + HitObjectTimingChanges[i] = columnTimingChanges = new List(); + + columnTimingChanges.Add(new DrawableScrollingTimingChange(t)); + } + + BarlineTimingChanges.Add(new DrawableScrollingTimingChange(t)); + }); + } + + protected override Playfield CreatePlayfield() + { + var playfield = new ManiaPlayfield(Columns) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -88,8 +116,17 @@ namespace osu.Game.Rulesets.Mania.UI Scale = new Vector2(1, -1) }; - timingChanges.ForEach(t => playfield.Columns.ForEach(c => c.Add(new DrawableScrollingTimingChange(t)))); - timingChanges.ForEach(t => playfield.Add(new DrawableScrollingTimingChange(t))); + foreach (var kvp in HitObjectTimingChanges) + { + int column = kvp.Key; + List timingChanges = kvp.Value; + + foreach (var change in timingChanges) + playfield.Columns.ElementAt(column).Add(change); + } + + foreach (var change in BarlineTimingChanges) + playfield.Add(change); return playfield; } diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 5b8cf0457b..4b0c42f673 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -82,6 +82,7 @@ +