1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-15 15:17:44 +08:00
osu-lazer/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs

135 lines
4.2 KiB
C#
Raw Normal View History

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
2018-04-13 17:19:50 +08:00
2022-06-17 15:37:17 +08:00
#nullable disable
using System;
using System.Diagnostics;
using System.Linq;
2019-02-21 18:04:31 +08:00
using osu.Framework.Bindables;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Rulesets.Scoring;
using osuTK;
2018-04-13 17:19:50 +08:00
namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
2022-11-24 13:32:20 +08:00
public partial class DrawableSliderHead : DrawableHitCircle
2018-04-13 17:19:50 +08:00
{
public new SliderHeadCircle HitObject => (SliderHeadCircle)base.HitObject;
public DrawableSlider DrawableSlider => (DrawableSlider)ParentHitObject;
public override bool DisplayResult
{
get
{
if (HitObject?.ClassicSliderBehaviour == true)
return false;
return base.DisplayResult;
}
}
private readonly IBindable<int> pathVersion = new Bindable<int>();
2018-11-09 12:58:46 +08:00
protected override OsuSkinComponents CirclePieceComponent => OsuSkinComponents.SliderHeadHitCircle;
2020-11-12 14:59:48 +08:00
public DrawableSliderHead()
{
}
public DrawableSliderHead(SliderHeadCircle h)
2018-04-13 17:19:50 +08:00
: base(h)
{
2018-11-09 12:58:46 +08:00
}
2018-04-13 17:19:50 +08:00
protected override void OnFree()
2020-11-12 14:59:48 +08:00
{
base.OnFree();
2020-11-12 14:59:48 +08:00
2020-12-03 19:03:39 +08:00
pathVersion.UnbindFrom(DrawableSlider.PathVersion);
2020-11-12 14:59:48 +08:00
}
protected override void UpdatePosition()
{
// Slider head is always drawn at (0,0).
}
2020-12-03 18:46:42 +08:00
protected override void OnApply()
2020-11-12 14:59:48 +08:00
{
2020-12-03 18:46:42 +08:00
base.OnApply();
2020-11-12 14:59:48 +08:00
2020-12-03 19:03:39 +08:00
pathVersion.BindTo(DrawableSlider.PathVersion);
2020-11-12 14:59:48 +08:00
CheckHittable = (d, t, r) => DrawableSlider.CheckHittable?.Invoke(d, t, r) ?? ClickAction.Hit;
2018-04-13 17:19:50 +08:00
}
protected override void CheckForResult(bool userTriggered, double timeOffset)
{
base.CheckForResult(userTriggered, timeOffset);
if (!Judged || !Result.IsHit)
return;
// If the head is hit and in radius of the would-be-expanded follow circle,
// then hit every object that the follow circle has passed through up until the current time.
if (DrawableSlider.Ball.IsMouseInFollowCircleWithState(true))
{
foreach (var nested in DrawableSlider.NestedHitObjects.OfType<DrawableOsuHitObject>())
{
if (nested.Judged)
continue;
if (!check(nested.HitObject))
break;
if (nested is DrawableSliderTick tick)
tick.HitForcefully();
if (nested is DrawableSliderRepeat repeat)
repeat.HitForcefully();
if (nested is DrawableSliderTail tail)
tail.HitForcefully();
}
}
bool check(OsuHitObject h)
{
if (h.StartTime > Time.Current)
return false;
float radius = DrawableSlider.Ball.GetFollowCircleRadius(true);
double objectProgress = Math.Clamp((h.StartTime - DrawableSlider.HitObject.StartTime) / DrawableSlider.HitObject.Duration, 0, 1);
Vector2 objectPosition = DrawableSlider.HitObject.CurvePositionAt(objectProgress);
return objectPosition.LengthSquared <= radius * radius;
}
}
protected override HitResult ResultFor(double timeOffset)
{
Debug.Assert(HitObject != null);
2023-11-02 22:42:52 +08:00
if (HitObject.ClassicSliderBehaviour)
{
// With classic slider behaviour, heads are considered fully hit if in the largest hit window.
// We can't award a full Great because the true Great judgement is awarded on the Slider itself,
2023-11-03 01:52:47 +08:00
// reduced based on number of ticks hit,
// so we use the most suitable LargeTick judgement here instead.
2023-11-02 22:42:52 +08:00
return base.ResultFor(timeOffset).IsHit() ? HitResult.LargeTickHit : HitResult.LargeTickMiss;
}
return base.ResultFor(timeOffset);
}
public override void Shake()
{
base.Shake();
DrawableSlider.Shake();
}
2018-04-13 17:19:50 +08:00
}
}