mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 15:07:44 +08:00
Merge pull request #6527 from smoogipoo/dho-apply
Implement nested drawable hitobject reconstruction
This commit is contained in:
commit
7967c73f03
@ -2,35 +2,50 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
{
|
{
|
||||||
public class DrawableBananaShower : DrawableCatchHitObject<BananaShower>
|
public class DrawableBananaShower : DrawableCatchHitObject<BananaShower>
|
||||||
{
|
{
|
||||||
|
private readonly Func<CatchHitObject, DrawableHitObject<CatchHitObject>> createDrawableRepresentation;
|
||||||
private readonly Container bananaContainer;
|
private readonly Container bananaContainer;
|
||||||
|
|
||||||
public DrawableBananaShower(BananaShower s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> createDrawableRepresentation = null)
|
public DrawableBananaShower(BananaShower s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> createDrawableRepresentation = null)
|
||||||
: base(s)
|
: base(s)
|
||||||
{
|
{
|
||||||
|
this.createDrawableRepresentation = createDrawableRepresentation;
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
Origin = Anchor.BottomLeft;
|
Origin = Anchor.BottomLeft;
|
||||||
X = 0;
|
X = 0;
|
||||||
|
|
||||||
AddInternal(bananaContainer = new Container { RelativeSizeAxes = Axes.Both });
|
AddInternal(bananaContainer = new Container { RelativeSizeAxes = Axes.Both });
|
||||||
|
|
||||||
foreach (var b in s.NestedHitObjects.Cast<Banana>())
|
|
||||||
AddNested(createDrawableRepresentation?.Invoke(b));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void AddNested(DrawableHitObject h)
|
protected override void AddNestedHitObject(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false;
|
base.AddNestedHitObject(hitObject);
|
||||||
bananaContainer.Add(h);
|
bananaContainer.Add(hitObject);
|
||||||
base.AddNested(h);
|
}
|
||||||
|
|
||||||
|
protected override void ClearNestedHitObjects()
|
||||||
|
{
|
||||||
|
base.ClearNestedHitObjects();
|
||||||
|
bananaContainer.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
||||||
|
{
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case Banana banana:
|
||||||
|
return createDrawableRepresentation?.Invoke(banana)?.With(o => ((DrawableCatchHitObject)o).CheckPosition = p => CheckPosition?.Invoke(p) ?? false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.CreateNestedHitObject(hitObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,38 +2,50 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||||
{
|
{
|
||||||
public class DrawableJuiceStream : DrawableCatchHitObject<JuiceStream>
|
public class DrawableJuiceStream : DrawableCatchHitObject<JuiceStream>
|
||||||
{
|
{
|
||||||
|
private readonly Func<CatchHitObject, DrawableHitObject<CatchHitObject>> createDrawableRepresentation;
|
||||||
private readonly Container dropletContainer;
|
private readonly Container dropletContainer;
|
||||||
|
|
||||||
public DrawableJuiceStream(JuiceStream s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> createDrawableRepresentation = null)
|
public DrawableJuiceStream(JuiceStream s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> createDrawableRepresentation = null)
|
||||||
: base(s)
|
: base(s)
|
||||||
{
|
{
|
||||||
|
this.createDrawableRepresentation = createDrawableRepresentation;
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
Origin = Anchor.BottomLeft;
|
Origin = Anchor.BottomLeft;
|
||||||
X = 0;
|
X = 0;
|
||||||
|
|
||||||
AddInternal(dropletContainer = new Container { RelativeSizeAxes = Axes.Both, });
|
AddInternal(dropletContainer = new Container { RelativeSizeAxes = Axes.Both, });
|
||||||
|
|
||||||
foreach (var o in s.NestedHitObjects.Cast<CatchHitObject>())
|
|
||||||
AddNested(createDrawableRepresentation?.Invoke(o));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void AddNested(DrawableHitObject h)
|
protected override void AddNestedHitObject(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
var catchObject = (DrawableCatchHitObject)h;
|
base.AddNestedHitObject(hitObject);
|
||||||
|
dropletContainer.Add(hitObject);
|
||||||
|
}
|
||||||
|
|
||||||
catchObject.CheckPosition = o => CheckPosition?.Invoke(o) ?? false;
|
protected override void ClearNestedHitObjects()
|
||||||
|
{
|
||||||
|
base.ClearNestedHitObjects();
|
||||||
|
dropletContainer.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
dropletContainer.Add(h);
|
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
||||||
base.AddNested(h);
|
{
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case CatchHitObject catchObject:
|
||||||
|
return createDrawableRepresentation?.Invoke(catchObject)?.With(o => ((DrawableCatchHitObject)o).CheckPosition = p => CheckPosition?.Invoke(p) ?? false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.CreateNestedHitObject(hitObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,30 +20,36 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
|||||||
|
|
||||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||||
|
|
||||||
private readonly BodyPiece body;
|
[Resolved]
|
||||||
|
private OsuColour colours { get; set; }
|
||||||
|
|
||||||
public HoldNoteSelectionBlueprint(DrawableHoldNote hold)
|
public HoldNoteSelectionBlueprint(DrawableHoldNote hold)
|
||||||
: base(hold)
|
: base(hold)
|
||||||
{
|
{
|
||||||
InternalChildren = new Drawable[]
|
|
||||||
{
|
|
||||||
new HoldNoteNoteSelectionBlueprint(hold.Head),
|
|
||||||
new HoldNoteNoteSelectionBlueprint(hold.Tail),
|
|
||||||
body = new BodyPiece
|
|
||||||
{
|
|
||||||
AccentColour = Color4.Transparent
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours, IScrollingInfo scrollingInfo)
|
private void load(IScrollingInfo scrollingInfo)
|
||||||
{
|
{
|
||||||
body.BorderColour = colours.Yellow;
|
|
||||||
|
|
||||||
direction.BindTo(scrollingInfo.Direction);
|
direction.BindTo(scrollingInfo.Direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new HoldNoteNoteSelectionBlueprint(HitObject.Head),
|
||||||
|
new HoldNoteNoteSelectionBlueprint(HitObject.Tail),
|
||||||
|
new BodyPiece
|
||||||
|
{
|
||||||
|
AccentColour = Color4.Transparent,
|
||||||
|
BorderColour = colours.Yellow
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
@ -2,13 +2,12 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
@ -22,8 +21,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public override bool DisplayResult => false;
|
public override bool DisplayResult => false;
|
||||||
|
|
||||||
public readonly DrawableNote Head;
|
public DrawableNote Head => headContainer.Child;
|
||||||
public readonly DrawableNote Tail;
|
public DrawableNote Tail => tailContainer.Child;
|
||||||
|
|
||||||
|
private readonly Container<DrawableHeadNote> headContainer;
|
||||||
|
private readonly Container<DrawableTailNote> tailContainer;
|
||||||
|
private readonly Container<DrawableHoldNoteTick> tickContainer;
|
||||||
|
|
||||||
private readonly BodyPiece bodyPiece;
|
private readonly BodyPiece bodyPiece;
|
||||||
|
|
||||||
@ -40,50 +43,81 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
public DrawableHoldNote(HoldNote hitObject)
|
public DrawableHoldNote(HoldNote hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
Container<DrawableHoldNoteTick> tickContainer;
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
|
|
||||||
AddRangeInternal(new Drawable[]
|
AddRangeInternal(new Drawable[]
|
||||||
{
|
{
|
||||||
bodyPiece = new BodyPiece
|
bodyPiece = new BodyPiece { RelativeSizeAxes = Axes.X },
|
||||||
{
|
tickContainer = new Container<DrawableHoldNoteTick> { RelativeSizeAxes = Axes.Both },
|
||||||
RelativeSizeAxes = Axes.X,
|
headContainer = new Container<DrawableHeadNote> { RelativeSizeAxes = Axes.Both },
|
||||||
},
|
tailContainer = new Container<DrawableTailNote> { RelativeSizeAxes = Axes.Both },
|
||||||
tickContainer = new Container<DrawableHoldNoteTick>
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
ChildrenEnumerable = HitObject.NestedHitObjects.OfType<HoldNoteTick>().Select(tick => new DrawableHoldNoteTick(tick)
|
|
||||||
{
|
|
||||||
HoldStartTime = () => holdStartTime
|
|
||||||
})
|
|
||||||
},
|
|
||||||
Head = new DrawableHeadNote(this)
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre
|
|
||||||
},
|
|
||||||
Tail = new DrawableTailNote(this)
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (var tick in tickContainer)
|
|
||||||
AddNested(tick);
|
|
||||||
|
|
||||||
AddNested(Head);
|
|
||||||
AddNested(Tail);
|
|
||||||
|
|
||||||
AccentColour.BindValueChanged(colour =>
|
AccentColour.BindValueChanged(colour =>
|
||||||
{
|
{
|
||||||
bodyPiece.AccentColour = colour.NewValue;
|
bodyPiece.AccentColour = colour.NewValue;
|
||||||
Head.AccentColour.Value = colour.NewValue;
|
|
||||||
Tail.AccentColour.Value = colour.NewValue;
|
|
||||||
tickContainer.ForEach(t => t.AccentColour.Value = colour.NewValue);
|
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void AddNestedHitObject(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
base.AddNestedHitObject(hitObject);
|
||||||
|
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case DrawableHeadNote head:
|
||||||
|
headContainer.Child = head;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DrawableTailNote tail:
|
||||||
|
tailContainer.Child = tail;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DrawableHoldNoteTick tick:
|
||||||
|
tickContainer.Add(tick);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ClearNestedHitObjects()
|
||||||
|
{
|
||||||
|
base.ClearNestedHitObjects();
|
||||||
|
headContainer.Clear();
|
||||||
|
tailContainer.Clear();
|
||||||
|
tickContainer.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
||||||
|
{
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case TailNote _:
|
||||||
|
return new DrawableTailNote(this)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
AccentColour = { BindTarget = AccentColour }
|
||||||
|
};
|
||||||
|
|
||||||
|
case Note _:
|
||||||
|
return new DrawableHeadNote(this)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
AccentColour = { BindTarget = AccentColour }
|
||||||
|
};
|
||||||
|
|
||||||
|
case HoldNoteTick tick:
|
||||||
|
return new DrawableHoldNoteTick(tick)
|
||||||
|
{
|
||||||
|
HoldStartTime = () => holdStartTime,
|
||||||
|
AccentColour = { BindTarget = AccentColour }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.CreateNestedHitObject(hitObject);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnDirectionChanged(ValueChangedEvent<ScrollingDirection> e)
|
protected override void OnDirectionChanged(ValueChangedEvent<ScrollingDirection> e)
|
||||||
{
|
{
|
||||||
base.OnDirectionChanged(e);
|
base.OnDirectionChanged(e);
|
||||||
|
@ -5,7 +5,6 @@ using osuTK;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -21,15 +20,19 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public class DrawableSlider : DrawableOsuHitObject, IDrawableHitObjectWithProxiedApproach
|
public class DrawableSlider : DrawableOsuHitObject, IDrawableHitObjectWithProxiedApproach
|
||||||
{
|
{
|
||||||
private readonly Slider slider;
|
public DrawableSliderHead HeadCircle => headContainer.Child;
|
||||||
private readonly List<Drawable> components = new List<Drawable>();
|
public DrawableSliderTail TailCircle => tailContainer.Child;
|
||||||
|
|
||||||
public readonly DrawableHitCircle HeadCircle;
|
|
||||||
public readonly DrawableSliderTail TailCircle;
|
|
||||||
|
|
||||||
public readonly SnakingSliderBody Body;
|
public readonly SnakingSliderBody Body;
|
||||||
public readonly SliderBall Ball;
|
public readonly SliderBall Ball;
|
||||||
|
|
||||||
|
private readonly Container<DrawableSliderHead> headContainer;
|
||||||
|
private readonly Container<DrawableSliderTail> tailContainer;
|
||||||
|
private readonly Container<DrawableSliderTick> tickContainer;
|
||||||
|
private readonly Container<DrawableRepeatPoint> repeatContainer;
|
||||||
|
|
||||||
|
private readonly Slider slider;
|
||||||
|
|
||||||
private readonly IBindable<Vector2> positionBindable = new Bindable<Vector2>();
|
private readonly IBindable<Vector2> positionBindable = new Bindable<Vector2>();
|
||||||
private readonly IBindable<float> scaleBindable = new Bindable<float>();
|
private readonly IBindable<float> scaleBindable = new Bindable<float>();
|
||||||
private readonly IBindable<SliderPath> pathBindable = new Bindable<SliderPath>();
|
private readonly IBindable<SliderPath> pathBindable = new Bindable<SliderPath>();
|
||||||
@ -44,14 +47,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
Position = s.StackedPosition;
|
Position = s.StackedPosition;
|
||||||
|
|
||||||
Container<DrawableSliderTick> ticks;
|
|
||||||
Container<DrawableRepeatPoint> repeatPoints;
|
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
Body = new SnakingSliderBody(s),
|
Body = new SnakingSliderBody(s),
|
||||||
ticks = new Container<DrawableSliderTick> { RelativeSizeAxes = Axes.Both },
|
tickContainer = new Container<DrawableSliderTick> { RelativeSizeAxes = Axes.Both },
|
||||||
repeatPoints = new Container<DrawableRepeatPoint> { RelativeSizeAxes = Axes.Both },
|
repeatContainer = new Container<DrawableRepeatPoint> { RelativeSizeAxes = Axes.Both },
|
||||||
Ball = new SliderBall(s, this)
|
Ball = new SliderBall(s, this)
|
||||||
{
|
{
|
||||||
GetInitialHitAction = () => HeadCircle.HitAction,
|
GetInitialHitAction = () => HeadCircle.HitAction,
|
||||||
@ -60,45 +60,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
AlwaysPresent = true,
|
AlwaysPresent = true,
|
||||||
Alpha = 0
|
Alpha = 0
|
||||||
},
|
},
|
||||||
HeadCircle = new DrawableSliderHead(s, s.HeadCircle)
|
headContainer = new Container<DrawableSliderHead> { RelativeSizeAxes = Axes.Both },
|
||||||
{
|
tailContainer = new Container<DrawableSliderTail> { RelativeSizeAxes = Axes.Both },
|
||||||
OnShake = Shake
|
|
||||||
},
|
|
||||||
TailCircle = new DrawableSliderTail(s, s.TailCircle)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
components.Add(Body);
|
|
||||||
components.Add(Ball);
|
|
||||||
|
|
||||||
AddNested(HeadCircle);
|
|
||||||
|
|
||||||
AddNested(TailCircle);
|
|
||||||
components.Add(TailCircle);
|
|
||||||
|
|
||||||
foreach (var tick in s.NestedHitObjects.OfType<SliderTick>())
|
|
||||||
{
|
|
||||||
var drawableTick = new DrawableSliderTick(tick) { Position = tick.Position - s.Position };
|
|
||||||
|
|
||||||
ticks.Add(drawableTick);
|
|
||||||
components.Add(drawableTick);
|
|
||||||
AddNested(drawableTick);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var repeatPoint in s.NestedHitObjects.OfType<RepeatPoint>())
|
|
||||||
{
|
|
||||||
var drawableRepeatPoint = new DrawableRepeatPoint(repeatPoint, this) { Position = repeatPoint.Position - s.Position };
|
|
||||||
|
|
||||||
repeatPoints.Add(drawableRepeatPoint);
|
|
||||||
components.Add(drawableRepeatPoint);
|
|
||||||
AddNested(drawableRepeatPoint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void UpdateInitialTransforms()
|
|
||||||
{
|
|
||||||
base.UpdateInitialTransforms();
|
|
||||||
|
|
||||||
Body.FadeInFromZero(HitObject.TimeFadeIn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -129,6 +93,67 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void AddNestedHitObject(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
base.AddNestedHitObject(hitObject);
|
||||||
|
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case DrawableSliderHead head:
|
||||||
|
headContainer.Child = head;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DrawableSliderTail tail:
|
||||||
|
tailContainer.Child = tail;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DrawableSliderTick tick:
|
||||||
|
tickContainer.Add(tick);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DrawableRepeatPoint repeat:
|
||||||
|
repeatContainer.Add(repeat);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ClearNestedHitObjects()
|
||||||
|
{
|
||||||
|
base.ClearNestedHitObjects();
|
||||||
|
|
||||||
|
headContainer.Clear();
|
||||||
|
tailContainer.Clear();
|
||||||
|
repeatContainer.Clear();
|
||||||
|
tickContainer.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
||||||
|
{
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case SliderTailCircle tail:
|
||||||
|
return new DrawableSliderTail(slider, tail);
|
||||||
|
|
||||||
|
case HitCircle head:
|
||||||
|
return new DrawableSliderHead(slider, head) { OnShake = Shake };
|
||||||
|
|
||||||
|
case SliderTick tick:
|
||||||
|
return new DrawableSliderTick(tick) { Position = tick.Position - slider.Position };
|
||||||
|
|
||||||
|
case RepeatPoint repeat:
|
||||||
|
return new DrawableRepeatPoint(repeat, this) { Position = repeat.Position - slider.Position };
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.CreateNestedHitObject(hitObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void UpdateInitialTransforms()
|
||||||
|
{
|
||||||
|
base.UpdateInitialTransforms();
|
||||||
|
|
||||||
|
Body.FadeInFromZero(HitObject.TimeFadeIn);
|
||||||
|
}
|
||||||
|
|
||||||
public readonly Bindable<bool> Tracking = new Bindable<bool>();
|
public readonly Bindable<bool> Tracking = new Bindable<bool>();
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
@ -139,9 +164,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
double completionProgress = MathHelper.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1);
|
double completionProgress = MathHelper.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1);
|
||||||
|
|
||||||
foreach (var c in components.OfType<ISliderProgress>()) c.UpdateProgress(completionProgress);
|
Ball.UpdateProgress(completionProgress);
|
||||||
foreach (var c in components.OfType<ITrackSnaking>()) c.UpdateSnakingPosition(slider.Path.PositionAt(Body.SnakedStart ?? 0), slider.Path.PositionAt(Body.SnakedEnd ?? 0));
|
Body.UpdateProgress(completionProgress);
|
||||||
foreach (var t in components.OfType<IRequireTracking>()) t.Tracking = Ball.Tracking;
|
|
||||||
|
foreach (DrawableHitObject hitObject in NestedHitObjects)
|
||||||
|
{
|
||||||
|
if (hitObject is ITrackSnaking s) s.UpdateSnakingPosition(slider.Path.PositionAt(Body.SnakedStart ?? 0), slider.Path.PositionAt(Body.SnakedEnd ?? 0));
|
||||||
|
if (hitObject is IRequireTracking t) t.Tracking = Ball.Tracking;
|
||||||
|
}
|
||||||
|
|
||||||
Size = Body.Size;
|
Size = Body.Size;
|
||||||
OriginPosition = Body.PathOffset;
|
OriginPosition = Body.PathOffset;
|
||||||
@ -187,7 +217,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
ApplyResult(r =>
|
ApplyResult(r =>
|
||||||
{
|
{
|
||||||
var judgementsCount = NestedHitObjects.Count();
|
var judgementsCount = NestedHitObjects.Count;
|
||||||
var judgementsHit = NestedHitObjects.Count(h => h.IsHit);
|
var judgementsHit = NestedHitObjects.Count(h => h.IsHit);
|
||||||
|
|
||||||
var hitFraction = (double)judgementsHit / judgementsCount;
|
var hitFraction = (double)judgementsHit / judgementsCount;
|
||||||
@ -228,7 +258,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Drawable ProxiedLayer => HeadCircle.ApproachCircle;
|
public Drawable ProxiedLayer => HeadCircle.ProxiedLayer;
|
||||||
|
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Body.ReceivePositionalInputAt(screenSpacePos);
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Body.ReceivePositionalInputAt(screenSpacePos);
|
||||||
}
|
}
|
||||||
|
@ -57,21 +57,15 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
public override void Add(DrawableHitObject h)
|
public override void Add(DrawableHitObject h)
|
||||||
{
|
{
|
||||||
h.OnNewResult += onNewResult;
|
h.OnNewResult += onNewResult;
|
||||||
|
h.OnLoadComplete += d =>
|
||||||
if (h is IDrawableHitObjectWithProxiedApproach c)
|
|
||||||
{
|
{
|
||||||
var original = c.ProxiedLayer;
|
if (d is IDrawableHitObjectWithProxiedApproach c)
|
||||||
|
approachCircles.Add(c.ProxiedLayer.CreateProxy());
|
||||||
// Hitobjects only have lifetimes set on LoadComplete. For nested hitobjects (e.g. SliderHeads), this only happens when the parenting slider becomes visible.
|
};
|
||||||
// This delegation is required to make sure that the approach circles for those not-yet-loaded objects aren't added prematurely.
|
|
||||||
original.OnLoadComplete += addApproachCircleProxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
base.Add(h);
|
base.Add(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addApproachCircleProxy(Drawable d) => approachCircles.Add(d.CreateProxy());
|
|
||||||
|
|
||||||
public override void PostProcess()
|
public override void PostProcess()
|
||||||
{
|
{
|
||||||
connectionLayer.HitObjects = HitObjectContainer.Objects.Select(d => d.HitObject).OfType<OsuHitObject>();
|
connectionLayer.HitObjects = HitObjectContainer.Objects.Select(d => d.HitObject).OfType<OsuHitObject>();
|
||||||
|
@ -12,6 +12,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||||
@ -28,30 +29,17 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private int rollingHits;
|
private int rollingHits;
|
||||||
|
|
||||||
|
private readonly Container<DrawableDrumRollTick> tickContainer;
|
||||||
|
|
||||||
|
private Color4 colourIdle;
|
||||||
|
private Color4 colourEngaged;
|
||||||
|
|
||||||
public DrawableDrumRoll(DrumRoll drumRoll)
|
public DrawableDrumRoll(DrumRoll drumRoll)
|
||||||
: base(drumRoll)
|
: base(drumRoll)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y;
|
RelativeSizeAxes = Axes.Y;
|
||||||
|
|
||||||
Container<DrawableDrumRollTick> tickContainer;
|
|
||||||
MainPiece.Add(tickContainer = new Container<DrawableDrumRollTick> { RelativeSizeAxes = Axes.Both });
|
MainPiece.Add(tickContainer = new Container<DrawableDrumRollTick> { RelativeSizeAxes = Axes.Both });
|
||||||
|
|
||||||
foreach (var tick in drumRoll.NestedHitObjects.OfType<DrumRollTick>())
|
|
||||||
{
|
|
||||||
var newTick = new DrawableDrumRollTick(tick);
|
|
||||||
newTick.OnNewResult += onNewTickResult;
|
|
||||||
|
|
||||||
AddNested(newTick);
|
|
||||||
tickContainer.Add(newTick);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece();
|
|
||||||
|
|
||||||
public override bool OnPressed(TaikoAction action) => false;
|
|
||||||
|
|
||||||
private Color4 colourIdle;
|
|
||||||
private Color4 colourEngaged;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
@ -60,8 +48,51 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
colourEngaged = colours.YellowDarker;
|
colourEngaged = colours.YellowDarker;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onNewTickResult(DrawableHitObject obj, JudgementResult result)
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
OnNewResult += onNewResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void AddNestedHitObject(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
base.AddNestedHitObject(hitObject);
|
||||||
|
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case DrawableDrumRollTick tick:
|
||||||
|
tickContainer.Add(tick);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ClearNestedHitObjects()
|
||||||
|
{
|
||||||
|
base.ClearNestedHitObjects();
|
||||||
|
tickContainer.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
||||||
|
{
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case DrumRollTick tick:
|
||||||
|
return new DrawableDrumRollTick(tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.CreateNestedHitObject(hitObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece();
|
||||||
|
|
||||||
|
public override bool OnPressed(TaikoAction action) => false;
|
||||||
|
|
||||||
|
private void onNewResult(DrawableHitObject obj, JudgementResult result)
|
||||||
|
{
|
||||||
|
if (!(obj is DrawableDrumRollTick))
|
||||||
|
return;
|
||||||
|
|
||||||
if (result.Type > HitResult.Miss)
|
if (result.Type > HitResult.Miss)
|
||||||
rollingHits++;
|
rollingHits++;
|
||||||
else
|
else
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
@ -14,6 +13,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
|
|||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||||
@ -30,8 +30,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const double ring_appear_offset = 100;
|
private const double ring_appear_offset = 100;
|
||||||
|
|
||||||
private readonly List<DrawableSwellTick> ticks = new List<DrawableSwellTick>();
|
private readonly Container<DrawableSwellTick> ticks;
|
||||||
|
|
||||||
private readonly Container bodyContainer;
|
private readonly Container bodyContainer;
|
||||||
private readonly CircularContainer targetRing;
|
private readonly CircularContainer targetRing;
|
||||||
private readonly CircularContainer expandingRing;
|
private readonly CircularContainer expandingRing;
|
||||||
@ -108,16 +107,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AddInternal(ticks = new Container<DrawableSwellTick> { RelativeSizeAxes = Axes.Both });
|
||||||
|
|
||||||
MainPiece.Add(symbol = new SwellSymbolPiece());
|
MainPiece.Add(symbol = new SwellSymbolPiece());
|
||||||
|
|
||||||
foreach (var tick in HitObject.NestedHitObjects.OfType<SwellTick>())
|
|
||||||
{
|
|
||||||
var vis = new DrawableSwellTick(tick);
|
|
||||||
|
|
||||||
ticks.Add(vis);
|
|
||||||
AddInternal(vis);
|
|
||||||
AddNested(vis);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -136,11 +128,49 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
Width *= Parent.RelativeChildSize.X;
|
Width *= Parent.RelativeChildSize.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void AddNestedHitObject(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
base.AddNestedHitObject(hitObject);
|
||||||
|
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case DrawableSwellTick tick:
|
||||||
|
ticks.Add(tick);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ClearNestedHitObjects()
|
||||||
|
{
|
||||||
|
base.ClearNestedHitObjects();
|
||||||
|
ticks.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
||||||
|
{
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case SwellTick tick:
|
||||||
|
return new DrawableSwellTick(tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.CreateNestedHitObject(hitObject);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||||
{
|
{
|
||||||
if (userTriggered)
|
if (userTriggered)
|
||||||
{
|
{
|
||||||
var nextTick = ticks.Find(j => !j.IsHit);
|
DrawableSwellTick nextTick = null;
|
||||||
|
|
||||||
|
foreach (var t in ticks)
|
||||||
|
{
|
||||||
|
if (!t.IsHit)
|
||||||
|
{
|
||||||
|
nextTick = t;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nextTick?.TriggerResult(HitResult.Great);
|
nextTick?.TriggerResult(HitResult.Great);
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ using osu.Game.Audio;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Primitives;
|
using osu.Framework.Graphics.Primitives;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||||
{
|
{
|
||||||
@ -109,11 +110,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public override Vector2 OriginPosition => new Vector2(DrawHeight / 2);
|
public override Vector2 OriginPosition => new Vector2(DrawHeight / 2);
|
||||||
|
|
||||||
protected readonly Vector2 BaseSize;
|
public new TaikoHitType HitObject;
|
||||||
|
|
||||||
|
protected readonly Vector2 BaseSize;
|
||||||
protected readonly TaikoPiece MainPiece;
|
protected readonly TaikoPiece MainPiece;
|
||||||
|
|
||||||
public new TaikoHitType HitObject;
|
private readonly Container<DrawableStrongNestedHit> strongHitContainer;
|
||||||
|
|
||||||
protected DrawableTaikoHitObject(TaikoHitType hitObject)
|
protected DrawableTaikoHitObject(TaikoHitType hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
@ -129,15 +131,36 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
Content.Add(MainPiece = CreateMainPiece());
|
Content.Add(MainPiece = CreateMainPiece());
|
||||||
MainPiece.KiaiMode = HitObject.Kiai;
|
MainPiece.KiaiMode = HitObject.Kiai;
|
||||||
|
|
||||||
var strongObject = HitObject.NestedHitObjects.OfType<StrongHitObject>().FirstOrDefault();
|
AddInternal(strongHitContainer = new Container<DrawableStrongNestedHit>());
|
||||||
|
|
||||||
if (strongObject != null)
|
|
||||||
{
|
|
||||||
var strongHit = CreateStrongHit(strongObject);
|
|
||||||
|
|
||||||
AddNested(strongHit);
|
|
||||||
AddInternal(strongHit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void AddNestedHitObject(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
base.AddNestedHitObject(hitObject);
|
||||||
|
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case DrawableStrongNestedHit strong:
|
||||||
|
strongHitContainer.Add(strong);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ClearNestedHitObjects()
|
||||||
|
{
|
||||||
|
base.ClearNestedHitObjects();
|
||||||
|
strongHitContainer.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
|
||||||
|
{
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case StrongHitObject strong:
|
||||||
|
return CreateStrongHit(strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.CreateNestedHitObject(hitObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal and clap samples are handled by the drum
|
// Normal and clap samples are handled by the drum
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.TypeExtensions;
|
using osu.Framework.Extensions.TypeExtensions;
|
||||||
@ -37,7 +38,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
protected virtual IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples;
|
protected virtual IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples;
|
||||||
|
|
||||||
private readonly Lazy<List<DrawableHitObject>> nestedHitObjects = new Lazy<List<DrawableHitObject>>();
|
private readonly Lazy<List<DrawableHitObject>> nestedHitObjects = new Lazy<List<DrawableHitObject>>();
|
||||||
public IEnumerable<DrawableHitObject> NestedHitObjects => nestedHitObjects.IsValueCreated ? nestedHitObjects.Value : Enumerable.Empty<DrawableHitObject>();
|
public IReadOnlyList<DrawableHitObject> NestedHitObjects => nestedHitObjects.IsValueCreated ? nestedHitObjects.Value : (IReadOnlyList<DrawableHitObject>)Array.Empty<DrawableHitObject>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when a <see cref="JudgementResult"/> has been applied by this <see cref="DrawableHitObject"/> or a nested <see cref="DrawableHitObject"/>.
|
/// Invoked when a <see cref="JudgementResult"/> has been applied by this <see cref="DrawableHitObject"/> or a nested <see cref="DrawableHitObject"/>.
|
||||||
@ -125,6 +126,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
|
apply(HitObject);
|
||||||
|
|
||||||
if (HitObject is IHasComboInformation combo)
|
if (HitObject is IHasComboInformation combo)
|
||||||
{
|
{
|
||||||
comboIndexBindable = combo.ComboIndexBindable.GetBoundCopy();
|
comboIndexBindable = combo.ComboIndexBindable.GetBoundCopy();
|
||||||
@ -134,6 +137,68 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
updateState(ArmedState.Idle, true);
|
updateState(ArmedState.Idle, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void apply(HitObject hitObject)
|
||||||
|
{
|
||||||
|
#pragma warning disable 618 // can be removed 20200417
|
||||||
|
if (GetType().GetMethod(nameof(AddNested), BindingFlags.NonPublic | BindingFlags.Instance)?.DeclaringType != typeof(DrawableHitObject))
|
||||||
|
return;
|
||||||
|
#pragma warning restore 618
|
||||||
|
|
||||||
|
if (nestedHitObjects.IsValueCreated)
|
||||||
|
{
|
||||||
|
nestedHitObjects.Value.Clear();
|
||||||
|
ClearNestedHitObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var h in hitObject.NestedHitObjects)
|
||||||
|
{
|
||||||
|
var drawableNested = CreateNestedHitObject(h) ?? throw new InvalidOperationException($"{nameof(CreateNestedHitObject)} returned null for {h.GetType().ReadableName()}.");
|
||||||
|
|
||||||
|
addNested(drawableNested);
|
||||||
|
AddNestedHitObject(drawableNested);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked by the base <see cref="DrawableHitObject"/> to add nested <see cref="DrawableHitObject"/>s to the hierarchy.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The <see cref="DrawableHitObject"/> to be added.</param>
|
||||||
|
protected virtual void AddNestedHitObject(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a nested <see cref="DrawableHitObject"/>. This should not be used except for legacy nested <see cref="DrawableHitObject"/> usages.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="h"></param>
|
||||||
|
[Obsolete("Use AddNestedHitObject() / ClearNestedHitObjects() / CreateNestedHitObject() instead.")] // can be removed 20200417
|
||||||
|
protected virtual void AddNested(DrawableHitObject h) => addNested(h);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked by the base <see cref="DrawableHitObject"/> to remove all previously-added nested <see cref="DrawableHitObject"/>s.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void ClearNestedHitObjects()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the drawable representation for a nested <see cref="HitObject"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The <see cref="HitObject"/>.</param>
|
||||||
|
/// <returns>The drawable representation for <paramref name="hitObject"/>.</returns>
|
||||||
|
protected virtual DrawableHitObject CreateNestedHitObject(HitObject hitObject) => null;
|
||||||
|
|
||||||
|
private void addNested(DrawableHitObject hitObject)
|
||||||
|
{
|
||||||
|
// Todo: Exists for legacy purposes, can be removed 20200417
|
||||||
|
|
||||||
|
hitObject.OnNewResult += (d, r) => OnNewResult?.Invoke(d, r);
|
||||||
|
hitObject.OnRevertResult += (d, r) => OnRevertResult?.Invoke(d, r);
|
||||||
|
hitObject.ApplyCustomUpdateState += (d, j) => ApplyCustomUpdateState?.Invoke(d, j);
|
||||||
|
|
||||||
|
nestedHitObjects.Value.Add(hitObject);
|
||||||
|
}
|
||||||
|
|
||||||
#region State / Transform Management
|
#region State / Transform Management
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -356,15 +421,6 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
UpdateResult(false);
|
UpdateResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void AddNested(DrawableHitObject h)
|
|
||||||
{
|
|
||||||
h.OnNewResult += (d, r) => OnNewResult?.Invoke(d, r);
|
|
||||||
h.OnRevertResult += (d, r) => OnRevertResult?.Invoke(d, r);
|
|
||||||
h.ApplyCustomUpdateState += (d, j) => ApplyCustomUpdateState?.Invoke(d, j);
|
|
||||||
|
|
||||||
nestedHitObjects.Value.Add(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Applies the <see cref="Result"/> of this <see cref="DrawableHitObject"/>, notifying responders such as
|
/// Applies the <see cref="Result"/> of this <see cref="DrawableHitObject"/>, notifying responders such as
|
||||||
/// the <see cref="ScoreProcessor"/> of the <see cref="JudgementResult"/>.
|
/// the <see cref="ScoreProcessor"/> of the <see cref="JudgementResult"/>.
|
||||||
|
Loading…
Reference in New Issue
Block a user