diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 031b70924d..dcb7fdb823 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable } } - protected override void AddNested(DrawableHitObject h) + protected override void AddNested(DrawableHitObject h) { ((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false; dropletContainer.Add(h); diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 1ed7cc594a..6748bc22e6 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -7,7 +7,6 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; using OpenTK.Graphics; -using OpenTK; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Mania.Judgements; using osu.Framework.Extensions.IEnumerableExtensions; @@ -59,12 +58,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, }, - tickContainer = new Container - { - RelativeSizeAxes = Axes.Both, - RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime), - RelativeChildSize = new Vector2(1, (float)HitObject.Duration) - }, + tickContainer = new Container { RelativeSizeAxes = Axes.Both }, head = new DrawableHeadNote(this, action) { Anchor = Anchor.TopCentre, @@ -72,7 +66,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables }, tail = new DrawableTailNote(this, action) { - Anchor = Anchor.BottomCentre, + Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre } }); @@ -174,13 +168,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { this.holdNote = holdNote; - RelativePositionAxes = Axes.None; - Y = 0; - - // Life time managed by the parent DrawableHoldNote - LifetimeStart = double.MinValue; - LifetimeEnd = double.MaxValue; - GlowPiece.Alpha = 0; } @@ -213,13 +200,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { this.holdNote = holdNote; - RelativePositionAxes = Axes.None; - Y = 0; - - // Life time managed by the parent DrawableHoldNote - LifetimeStart = double.MinValue; - LifetimeEnd = double.MaxValue; - GlowPiece.Alpha = 0; } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 0685c7bb2d..f9c0b96d37 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -32,9 +32,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; - RelativePositionAxes = Axes.Y; - Y = (float)HitObject.StartTime; - RelativeSizeAxes = Axes.X; Size = new Vector2(1); diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 0f16f85b63..2fa6c8ed95 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -37,12 +37,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables RelativeSizeAxes = Axes.Y; Container tickContainer; - MainPiece.Add(tickContainer = new Container - { - RelativeSizeAxes = Axes.Both, - RelativeChildOffset = new Vector2((float)HitObject.StartTime, 0), - RelativeChildSize = new Vector2((float)HitObject.Duration, 1) - }); + MainPiece.Add(tickContainer = new Container { RelativeSizeAxes = Axes.Both }); foreach (var tick in drumRoll.NestedHitObjects.OfType()) { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 3408a830ed..bc5abce245 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -15,23 +15,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public DrawableDrumRollTick(DrumRollTick tick) : base(tick) { - // Because ticks aren't added by the ScrollingPlayfield, we need to set the following properties ourselves - RelativePositionAxes = Axes.X; - X = (float)tick.StartTime; - FillMode = FillMode.Fit; } public override bool DisplayJudgement => false; - protected override void LoadComplete() - { - base.LoadComplete(); - - // We need to set this here because RelativeSizeAxes won't/can't set our size by default with a different RelativeChildSize - Width *= Parent.RelativeChildSize.X; - } - protected override TaikoPiece CreateMainPiece() => new TickPiece { Filled = HitObject.FirstTick diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index e461cb96c5..13329a1470 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -38,11 +38,30 @@ namespace osu.Game.Rulesets.Objects.Drawables public override bool RemoveWhenNotAlive => false; protected override bool RequiresChildrenUpdate => true; + public virtual bool AllJudged => false; + protected DrawableHitObject(HitObject hitObject) { HitObject = hitObject; } + /// + /// Processes this , checking if any judgements have occurred. + /// + /// Whether the user triggered this process. + /// Whether a judgement has occurred from this or any nested s. + protected internal virtual bool UpdateJudgement(bool userTriggered) => false; + + private List nestedHitObjects; + public IReadOnlyList NestedHitObjects => nestedHitObjects; + + protected virtual void AddNested(DrawableHitObject h) + { + if (nestedHitObjects == null) + nestedHitObjects = new List(); + nestedHitObjects.Add(h); + } + /// /// The screen-space point that causes this to be selected in the Editor. /// @@ -145,7 +164,7 @@ namespace osu.Game.Rulesets.Objects.Drawables /// /// Whether this and all of its nested s have been judged. /// - public bool AllJudged => (!ProvidesJudgement || judgementFinalized) && (NestedHitObjects?.All(h => h.AllJudged) ?? true); + public sealed override bool AllJudged => (!ProvidesJudgement || judgementFinalized) && (NestedHitObjects?.All(h => h.AllJudged) ?? true); /// /// Notifies that a new judgement has occurred for this . @@ -181,7 +200,7 @@ namespace osu.Game.Rulesets.Objects.Drawables /// /// Whether the user triggered this process. /// Whether a judgement has occurred from this or any nested s. - protected bool UpdateJudgement(bool userTriggered) + protected internal sealed override bool UpdateJudgement(bool userTriggered) { judgementOccurred = false; @@ -238,18 +257,16 @@ namespace osu.Game.Rulesets.Objects.Drawables UpdateJudgement(false); } - private List> nestedHitObjects; - protected IEnumerable> NestedHitObjects => nestedHitObjects; - - protected virtual void AddNested(DrawableHitObject h) + protected override void AddNested(DrawableHitObject h) { - if (nestedHitObjects == null) - nestedHitObjects = new List>(); + base.AddNested(h); - h.OnJudgement += (d, j) => OnJudgement?.Invoke(d, j); - h.OnJudgementRemoved += (d, j) => OnJudgementRemoved?.Invoke(d, j); - h.ApplyCustomUpdateState += (d, s) => ApplyCustomUpdateState?.Invoke(d, s); - nestedHitObjects.Add(h); + if (!(h is DrawableHitObject hWithJudgement)) + return; + + hWithJudgement.OnJudgement += (d, j) => OnJudgement?.Invoke(d, j); + hWithJudgement.OnJudgementRemoved += (d, j) => OnJudgementRemoved?.Invoke(d, j); + hWithJudgement.ApplyCustomUpdateState += (d, s) => ApplyCustomUpdateState?.Invoke(d, s); } /// diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs index 55a0a7c2f3..c1347ad122 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs @@ -29,22 +29,25 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms obj.LifetimeStart = obj.HitObject.StartTime - timeRange - 1000; - if (!(obj.HitObject is IHasEndTime endTime)) - continue; - - var diff = positionAt(endTime.EndTime, timeRange) - startPosition; - - switch (direction) + if (obj.HitObject is IHasEndTime endTime) { - case ScrollingDirection.Up: - case ScrollingDirection.Down: - obj.Height = (float)(diff * length.Y); - break; - case ScrollingDirection.Left: - case ScrollingDirection.Right: - obj.Width = (float)(diff * length.X); - break; + var diff = positionAt(endTime.EndTime, timeRange) - startPosition; + + switch (direction) + { + case ScrollingDirection.Up: + case ScrollingDirection.Down: + obj.Height = (float)(diff * length.Y); + break; + case ScrollingDirection.Left: + case ScrollingDirection.Right: + obj.Width = (float)(diff * length.X); + break; + } } + + if (obj.NestedHitObjects != null) + ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); } } @@ -71,6 +74,9 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms obj.X = (float)(-finalPosition * length.X); break; } + + if (obj.NestedHitObjects != null) + ComputePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); } } diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs index b2d4289a9a..ecb7aaff95 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs @@ -26,6 +26,9 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms { var controlPoint = controlPointAt(obj.HitObject.StartTime); obj.LifetimeStart = obj.HitObject.StartTime - timeRange / controlPoint.Multiplier; + + if (obj.NestedHitObjects != null) + ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); } } @@ -52,6 +55,9 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms obj.X = (float)(-position * length.X); break; } + + if (obj.NestedHitObjects != null) + ComputePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); } }