diff --git a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs index 6f406307c9..f82ea1c98c 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs @@ -37,7 +37,7 @@ namespace osu.Desktop.VisualTests.Tests playbackSpeed.ValueChanged += delegate { rateAdjustClock.Rate = playbackSpeed.Value; }; } - HitObjectType mode = HitObjectType.Spinner; + HitObjectType mode = HitObjectType.Slider; BindableNumber playbackSpeed = new BindableDouble(0.5) { MinValue = 0, MaxValue = 1 }; private Container playfieldContainer; diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs index ef153848d4..d6907474f3 100644 --- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -73,5 +73,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables Hit100, [Description(@"300")] Hit300, + [Description(@"10")] + SliderTick } } diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs index 01ddd7a790..745c696fee 100644 --- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs @@ -7,6 +7,7 @@ using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Osu.Objects.Drawables.Pieces; using System.Collections.Generic; using System.Linq; +using osu.Framework.Graphics.Containers; namespace osu.Game.Modes.Osu.Objects.Drawables { @@ -18,11 +19,12 @@ namespace osu.Game.Modes.Osu.Objects.Drawables private List components = new List(); + private Container ticks; + SliderBody body; SliderBall ball; SliderBouncer bouncer1, bouncer2; - SliderTicksRenderer ticks; public DrawableSlider(Slider s) : base(s) { @@ -35,13 +37,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables Position = s.StackedPosition, PathWidth = s.Scale * 64, }, - ticks = new SliderTicksRenderer - { - Position = s.StackedPosition, - StartTime = s.StartTime, - RepeatDuration = s.Curve.Length / s.Velocity, - Ticks = s.Ticks, - }, + ticks = new Container(), bouncer1 = new SliderBouncer(s, false) { Position = s.Curve.PositionAt(1), @@ -72,6 +68,26 @@ namespace osu.Game.Modes.Osu.Objects.Drawables components.Add(ball); components.Add(bouncer1); components.Add(bouncer2); + + AddNested(initialCircle); + + var repeatDuration = s.Curve.Length / s.Velocity; + foreach (var tick in s.Ticks) + { + var repeatStartTime = s.StartTime + tick.RepeatIndex * repeatDuration; + var fadeInTime = repeatStartTime + (tick.StartTime - repeatStartTime) / 2 - (tick.RepeatIndex == 0 ? TIME_FADEIN : TIME_FADEIN / 2); + var fadeOutTime = repeatStartTime + repeatDuration; + + var drawableTick = new DrawableSliderTick(tick) + { + FadeInTime = fadeInTime, + FadeOutTime = fadeOutTime, + Position = tick.Position, + }; + + ticks.Add(drawableTick); + AddNested(drawableTick); + } } // Since the DrawableSlider itself is just a container without a size we need to @@ -105,8 +121,8 @@ namespace osu.Game.Modes.Osu.Objects.Drawables if (initialCircle.Judgement?.Result != HitResult.Hit) initialCircle.Position = slider.Curve.PositionAt(progress); - components.ForEach(c => c.UpdateProgress(progress, repeat)); - ticks.ShouldHit = ball.Tracking; + foreach (var c in components) c.UpdateProgress(progress, repeat); + foreach (var t in ticks.Children) t.Tracking = ball.Tracking; } protected override void CheckJudgement(bool userTriggered) diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs index b3479c0fae..c1c17f1c53 100644 --- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -22,7 +22,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables public double FadeInTime; public double FadeOutTime; - public bool ShouldHit; + public bool Tracking; public override bool RemoveWhenNotAlive => false; @@ -35,7 +35,6 @@ namespace osu.Game.Modes.Osu.Objects.Drawables Masking = true; CornerRadius = Size.X / 2; - Anchor = Anchor.Centre; Origin = Anchor.Centre; BorderThickness = 2; @@ -70,8 +69,13 @@ namespace osu.Game.Modes.Osu.Objects.Drawables protected override void CheckJudgement(bool userTriggered) { + var j = Judgement as OsuJudgementInfo; + if (Judgement.TimeOffset >= 0) - Judgement.Result = ShouldHit ? HitResult.Hit : HitResult.Miss; + { + j.Result = Tracking ? HitResult.Hit : HitResult.Miss; + j.Score = Tracking ? OsuScoreResult.SliderTick : OsuScoreResult.Miss; + } } protected override void UpdatePreemptState() diff --git a/osu.Game.Modes.Osu/Objects/Drawables/SliderTicksLayer.cs b/osu.Game.Modes.Osu/Objects/Drawables/SliderTicksLayer.cs deleted file mode 100644 index 03ab28e495..0000000000 --- a/osu.Game.Modes.Osu/Objects/Drawables/SliderTicksLayer.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Allocation; -using osu.Framework.Caching; -using osu.Framework.Graphics.Containers; -using System.Collections.Generic; - -namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces -{ - public class SliderTicksRenderer : Container - { - private Cached drawableTicks = new Cached(); - - private double startTime; - public double StartTime - { - get { return startTime; } - set - { - startTime = value; - drawableTicks.Invalidate(); - } - } - - private double repeatDuration; - public double RepeatDuration - { - get { return repeatDuration; } - set - { - repeatDuration = value; - drawableTicks.Invalidate(); - } - } - - private IEnumerable ticks; - public IEnumerable Ticks - { - get { return ticks; } - set - { - ticks = value; - drawableTicks.Invalidate(); - } - } - - public bool ShouldHit - { - set - { - foreach (var tick in Children) - tick.ShouldHit = value; - } - } - - protected override void Update() - { - base.Update(); - updateDrawableTicks(); - } - - [BackgroundDependencyLoader] - private void load() - { - updateDrawableTicks(); - } - - private void updateDrawableTicks() - { - if (drawableTicks.EnsureValid()) - return; - - drawableTicks.Refresh(delegate - { - Clear(); - if (ticks == null || repeatDuration == 0) - return; - - foreach (var tick in ticks) - { - var repeatStartTime = startTime + tick.RepeatIndex * repeatDuration; - var fadeInTime = repeatStartTime + (tick.StartTime - repeatStartTime) / 2 - (tick.RepeatIndex == 0 ? DrawableOsuHitObject.TIME_FADEIN : DrawableOsuHitObject.TIME_FADEIN / 2); - var fadeOutTime = repeatStartTime + repeatDuration; - - Add(new DrawableSliderTick(tick) - { - FadeInTime = fadeInTime, - FadeOutTime = fadeOutTime, - Position = tick.Position, - }); - } - }); - } - } -} \ No newline at end of file diff --git a/osu.Game.Modes.Osu/Objects/Slider.cs b/osu.Game.Modes.Osu/Objects/Slider.cs index 72fdd70a70..c3d8190240 100644 --- a/osu.Game.Modes.Osu/Objects/Slider.cs +++ b/osu.Game.Modes.Osu/Objects/Slider.cs @@ -96,7 +96,7 @@ namespace osu.Game.Modes.Osu.Objects { RepeatIndex = repeat, StartTime = repeatStartTime + timeProgress * repeatDuration, - Position = Curve.PositionAt(distanceProgress) - StackedPosition, + Position = Curve.PositionAt(distanceProgress), StackHeight = StackHeight, Scale = Scale, Colour = Colour, diff --git a/osu.Game.Modes.Osu/OsuScoreProcessor.cs b/osu.Game.Modes.Osu/OsuScoreProcessor.cs index 8a9f7d6b2e..224a669746 100644 --- a/osu.Game.Modes.Osu/OsuScoreProcessor.cs +++ b/osu.Game.Modes.Osu/OsuScoreProcessor.cs @@ -53,6 +53,10 @@ namespace osu.Game.Modes.Osu score += 300; maxScore += 300; break; + case OsuScoreResult.SliderTick: + score += 10; + maxScore += 10; + break; } } diff --git a/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj b/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj index f269921cac..1b1ded3d61 100644 --- a/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj +++ b/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj @@ -47,7 +47,6 @@ - diff --git a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs index 4c707c5e62..94369d51aa 100644 --- a/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Modes/Objects/Drawables/DrawableHitObject.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using osu.Framework; @@ -23,8 +24,6 @@ namespace osu.Game.Modes.Objects.Drawables public bool Interactive = true; - public Container ChildObjects; - public JudgementInfo Judgement; public abstract JudgementInfo CreateJudgementInfo(); @@ -85,6 +84,19 @@ namespace osu.Game.Modes.Objects.Drawables Expire(true); } + private List nestedHitObjects; + + protected IEnumerable NestedHitObjects => nestedHitObjects; + + protected void AddNested(DrawableHitObject h) + { + if (nestedHitObjects == null) + nestedHitObjects = new List(); + + h.OnJudgement += (d, j) => { OnJudgement?.Invoke(d, j); } ; + nestedHitObjects.Add(h); + } + /// /// Process a hit of this hitobject. Carries out judgement. /// @@ -119,7 +131,11 @@ namespace osu.Game.Modes.Objects.Drawables protected virtual void CheckJudgement(bool userTriggered) { - //todo: consider making abstract. + if (NestedHitObjects != null) + { + foreach (var d in NestedHitObjects) + d.CheckJudgement(userTriggered); + } } protected override void UpdateAfterChildren()