diff --git a/osu.Game.Modes.Taiko/Objects/DrumRoll.cs b/osu.Game.Modes.Taiko/Objects/DrumRoll.cs new file mode 100644 index 0000000000..cdb8ef2405 --- /dev/null +++ b/osu.Game.Modes.Taiko/Objects/DrumRoll.cs @@ -0,0 +1,104 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps.Samples; +using osu.Game.Modes.Objects.Types; +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Game.Beatmaps.Timing; +using osu.Game.Database; + +namespace osu.Game.Modes.Taiko.Objects +{ + public class DrumRoll : TaikoHitObject, IHasDistance + { + public double EndTime => StartTime + Distance / Velocity; + + public double Duration => EndTime - StartTime; + + /// + /// Raw length of the drum roll in positional length units. + /// + public double Distance { get; set; } + + /// + /// Velocity of the drum roll in positional length units per millisecond. + /// + public double Velocity { get; protected set; } + + /// + /// The distance between ticks of this drumroll. + /// Half of this value is the hit window of the ticks. + /// + public double TickTimeDistance { get; protected set; } + + /// + /// Number of drum roll ticks required for a "Good" hit. + /// + public double RequiredGoodHits { get; protected set; } + + /// + /// Number of drum roll ticks required for a "Great" hit. + /// + public double RequiredGreatHits { get; protected set; } + + /// + /// Total number of drum roll ticks. + /// + public int TotalTicks => Ticks.Count(); + + /// + /// Initializes the drum roll ticks if not initialized and returns them. + /// + public IEnumerable Ticks => ticks ?? (ticks = createTicks()); + + private List ticks; + + public override void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty) + { + base.ApplyDefaults(timing, difficulty); + + Velocity = timing.SliderVelocityAt(StartTime) * difficulty.SliderMultiplier / 1000; + TickTimeDistance = timing.BeatLengthAt(StartTime); + + //TODO: move this to legacy conversion code to allow for direct division without special case. + if (difficulty.SliderTickRate == 3) + TickTimeDistance /= 3; + else + TickTimeDistance /= 4; + + RequiredGoodHits = TotalTicks * Math.Min(0.15, 0.05 + 0.10 / 6 * difficulty.OverallDifficulty); + RequiredGreatHits = TotalTicks * Math.Min(0.30, 0.10 + 0.20 / 6 * difficulty.OverallDifficulty); + } + + private List createTicks() + { + var ret = new List(); + + if (TickTimeDistance == 0) + return ret; + + bool first = true; + for (double t = StartTime; t < EndTime + (int)TickTimeDistance; t += TickTimeDistance) + { + ret.Add(new DrumRollTick + { + FirstTick = first, + PreEmpt = PreEmpt, + TickTimeDistance = TickTimeDistance, + StartTime = t, + Sample = new HitSampleInfo + { + Type = SampleType.None, + Set = SampleSet.Soft + } + }); + + first = false; + } + + return ret; + } + } +} diff --git a/osu.Game.Modes.Taiko/Objects/DrumRollTick.cs b/osu.Game.Modes.Taiko/Objects/DrumRollTick.cs new file mode 100644 index 0000000000..66a2d16fe1 --- /dev/null +++ b/osu.Game.Modes.Taiko/Objects/DrumRollTick.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Modes.Taiko.Objects +{ + public class DrumRollTick : TaikoHitObject + { + /// + /// Whether this is the first (initial) tick of the slider. + /// + public bool FirstTick; + + /// + /// The distance between this tick and the next in milliseconds. + /// Half of this value is the hit window of the tick. + /// + public double TickTimeDistance; + } +} \ No newline at end of file diff --git a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj b/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj index 65ee442d33..177873669b 100644 --- a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj +++ b/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj @@ -51,6 +51,8 @@ + +