1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-14 23:13:12 +08:00

Compare commits

...

7 Commits

14 changed files with 66 additions and 51 deletions
@@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Tests
typeof(DrawableSliderTick),
typeof(DrawableSliderTail),
typeof(DrawableSliderHead),
typeof(DrawableRepeatPoint),
typeof(DrawableSliderRepeat),
typeof(DrawableOsuHitObject)
};
@@ -146,7 +146,7 @@ namespace osu.Game.Rulesets.Osu.Tests
AddAssert("head samples updated", () => assertSamples(((Slider)slider.HitObject).HeadCircle));
AddAssert("tick samples not updated", () => ((Slider)slider.HitObject).NestedHitObjects.OfType<SliderTick>().All(assertTickSamples));
AddAssert("repeat samples updated", () => ((Slider)slider.HitObject).NestedHitObjects.OfType<RepeatPoint>().All(assertSamples));
AddAssert("repeat samples updated", () => ((Slider)slider.HitObject).NestedHitObjects.OfType<SliderRepeat>().All(assertSamples));
AddAssert("tail has no samples", () => ((Slider)slider.HitObject).TailCircle.Samples.Count == 0);
static bool assertTickSamples(SliderTick tick) => tick.Samples.Single().Name == "slidertick";
@@ -181,7 +181,7 @@ namespace osu.Game.Rulesets.Osu.Tests
AddAssert("head samples not updated", () => assertSamples(((Slider)slider.HitObject).HeadCircle));
AddAssert("tick samples not updated", () => ((Slider)slider.HitObject).NestedHitObjects.OfType<SliderTick>().All(assertTickSamples));
AddAssert("repeat samples not updated", () => ((Slider)slider.HitObject).NestedHitObjects.OfType<RepeatPoint>().All(assertSamples));
AddAssert("repeat samples not updated", () => ((Slider)slider.HitObject).NestedHitObjects.OfType<SliderRepeat>().All(assertSamples));
AddAssert("tail has no samples", () => ((Slider)slider.HitObject).TailCircle.Samples.Count == 0);
static bool assertTickSamples(SliderTick tick) => tick.Samples.Single().Name == "slidertick";
@@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Tests
typeof(SliderBall),
typeof(DrawableSlider),
typeof(DrawableSliderTick),
typeof(DrawableRepeatPoint),
typeof(DrawableSliderRepeat),
typeof(DrawableOsuHitObject),
typeof(DrawableSliderHead),
typeof(DrawableSliderTail),
@@ -327,7 +327,7 @@ namespace osu.Game.Rulesets.Osu.Tests
AddAssert("Tracking dropped", assertMidSliderJudgementFail);
}
private bool assertGreatJudge() => judgementResults.Last().Type == HitResult.Great;
private bool assertGreatJudge() => judgementResults.Any() && judgementResults.All(t => t.Type == HitResult.Great);
private bool assertHeadMissTailTracked() => judgementResults[^2].Type == HitResult.Great && judgementResults.First().Type == HitResult.Miss;
@@ -0,0 +1,16 @@
// 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.
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Judgements
{
public class OsuIgnoreJudgement : OsuJudgement
{
public override bool AffectsCombo => false;
protected override int NumericResultFor(HitResult result) => 0;
protected override double HealthIncreaseFor(HitResult result) => 0;
}
}
+1 -1
View File
@@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods
return;
slider.NestedHitObjects.OfType<SliderTick>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
slider.NestedHitObjects.OfType<RepeatPoint>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
slider.NestedHitObjects.OfType<SliderRepeat>().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y));
foreach (var point in slider.Path.ControlPoints)
point.Position.Value = new Vector2(point.Position.Value.X, -point.Position.Value.Y);
@@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Osu.Mods
case DrawableSliderHead _:
case DrawableSliderTail _:
case DrawableSliderTick _:
case DrawableRepeatPoint _:
case DrawableSliderRepeat _:
return;
default:
+1 -1
View File
@@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Mods
// Wiggle the repeat points with the slider instead of independently.
// Also fixes an issue with repeat points being positioned incorrectly.
if (osuObject is RepeatPoint)
if (osuObject is SliderRepeat)
return;
Random objRand = new Random((int)osuObject.StartTime);
@@ -6,13 +6,11 @@ using osuTK;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Skinning;
using osu.Game.Rulesets.Scoring;
using osuTK.Graphics;
using osu.Game.Skinning;
@@ -26,12 +24,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public readonly SliderBall Ball;
public readonly SkinnableDrawable Body;
public override bool DisplayResult => false;
private PlaySliderBody sliderBody => Body.Drawable as PlaySliderBody;
private readonly Container<DrawableSliderHead> headContainer;
private readonly Container<DrawableSliderTail> tailContainer;
private readonly Container<DrawableSliderTick> tickContainer;
private readonly Container<DrawableRepeatPoint> repeatContainer;
private readonly Container<DrawableSliderRepeat> repeatContainer;
private readonly Slider slider;
@@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
Body = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling),
tickContainer = new Container<DrawableSliderTick> { RelativeSizeAxes = Axes.Both },
repeatContainer = new Container<DrawableRepeatPoint> { RelativeSizeAxes = Axes.Both },
repeatContainer = new Container<DrawableSliderRepeat> { RelativeSizeAxes = Axes.Both },
Ball = new SliderBall(s, this)
{
GetInitialHitAction = () => HeadCircle.HitAction,
@@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
tickContainer.Add(tick);
break;
case DrawableRepeatPoint repeat:
case DrawableSliderRepeat repeat:
repeatContainer.Add(repeat);
break;
}
@@ -129,8 +129,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
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 };
case SliderRepeat repeat:
return new DrawableSliderRepeat(repeat, this) { Position = repeat.Position - slider.Position };
}
return base.CreateNestedHitObject(hitObject);
@@ -193,22 +193,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
if (userTriggered || Time.Current < slider.EndTime)
return;
ApplyResult(r =>
{
var judgementsCount = NestedHitObjects.Count;
var judgementsHit = NestedHitObjects.Count(h => h.IsHit);
var hitFraction = (double)judgementsHit / judgementsCount;
if (hitFraction == 1 && HeadCircle.Result.Type == HitResult.Great)
r.Type = HitResult.Great;
else if (hitFraction >= 0.5 && HeadCircle.Result.Type >= HitResult.Good)
r.Type = HitResult.Good;
else if (hitFraction > 0)
r.Type = HitResult.Meh;
else
r.Type = HitResult.Miss;
});
ApplyResult(r => r.Type = r.Judgement.MaxResult);
}
protected override void UpdateStateTransforms(ArmedState state)
@@ -14,19 +14,19 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public class DrawableRepeatPoint : DrawableOsuHitObject, ITrackSnaking
public class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking
{
private readonly RepeatPoint repeatPoint;
private readonly SliderRepeat sliderRepeat;
private readonly DrawableSlider drawableSlider;
private double animDuration;
private readonly Drawable scaleContainer;
public DrawableRepeatPoint(RepeatPoint repeatPoint, DrawableSlider drawableSlider)
: base(repeatPoint)
public DrawableSliderRepeat(SliderRepeat sliderRepeat, DrawableSlider drawableSlider)
: base(sliderRepeat)
{
this.repeatPoint = repeatPoint;
this.sliderRepeat = sliderRepeat;
this.drawableSlider = drawableSlider;
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
@@ -48,13 +48,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
protected override void CheckForResult(bool userTriggered, double timeOffset)
{
if (repeatPoint.StartTime <= Time.Current)
if (sliderRepeat.StartTime <= Time.Current)
ApplyResult(r => r.Type = drawableSlider.Tracking.Value ? HitResult.Great : HitResult.Miss);
}
protected override void UpdateInitialTransforms()
{
animDuration = Math.Min(300, repeatPoint.SpanDuration);
animDuration = Math.Min(300, sliderRepeat.SpanDuration);
this.Animate(
d => d.FadeIn(animDuration),
@@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public void UpdateSnakingPosition(Vector2 start, Vector2 end)
{
bool isRepeatAtEnd = repeatPoint.RepeatIndex % 2 == 0;
bool isRepeatAtEnd = sliderRepeat.RepeatIndex % 2 == 0;
List<Vector2> curve = ((PlaySliderBody)drawableSlider.Body.Drawable).CurrentCurve;
Position = isRepeatAtEnd ? end : start;
@@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
protected override void CheckForResult(bool userTriggered, double timeOffset)
{
if (!userTriggered && timeOffset >= 0)
ApplyResult(r => r.Type = Tracking ? HitResult.Great : HitResult.Miss);
ApplyResult(r => r.Type = Tracking ? r.Judgement.MaxResult : HitResult.Miss);
}
private void updatePosition() => Position = HitObject.Position - slider.Position;
@@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
protected override void CheckForResult(bool userTriggered, double timeOffset)
{
if (timeOffset >= 0)
ApplyResult(r => r.Type = Tracking ? HitResult.Great : HitResult.Miss);
ApplyResult(r => r.Type = Tracking ? r.Judgement.MaxResult : HitResult.Miss);
}
protected override void UpdateInitialTransforms()
+3 -3
View File
@@ -177,7 +177,7 @@ namespace osu.Game.Rulesets.Osu.Objects
break;
case SliderEventType.Repeat:
AddNested(new RepeatPoint
AddNested(new SliderRepeat
{
RepeatIndex = e.SpanIndex,
SpanDuration = SpanDuration,
@@ -223,7 +223,7 @@ namespace osu.Game.Rulesets.Osu.Objects
foreach (var tick in NestedHitObjects.OfType<SliderTick>())
tick.Samples = sampleList;
foreach (var repeat in NestedHitObjects.OfType<RepeatPoint>())
foreach (var repeat in NestedHitObjects.OfType<SliderRepeat>())
repeat.Samples = getNodeSamples(repeat.RepeatIndex + 1);
if (HeadCircle != null)
@@ -233,7 +233,7 @@ namespace osu.Game.Rulesets.Osu.Objects
private IList<HitSampleInfo> getNodeSamples(int nodeIndex) =>
nodeIndex < NodeSamples.Count ? NodeSamples[nodeIndex] : Samples;
public override Judgement CreateJudgement() => new OsuJudgement();
public override Judgement CreateJudgement() => new OsuIgnoreJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
}
@@ -10,7 +10,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Objects
{
public class RepeatPoint : OsuHitObject
public class SliderRepeat : OsuHitObject
{
public int RepeatIndex { get; set; }
public double SpanDuration { get; set; }
@@ -28,8 +28,15 @@ namespace osu.Game.Rulesets.Osu.Objects
TimePreempt = Math.Min(SpanDuration * 2, TimePreempt);
}
public override Judgement CreateJudgement() => new OsuJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
public override Judgement CreateJudgement() => new SliderRepeatJudgement();
public class SliderRepeatJudgement : OsuJudgement
{
public override bool IsBonus => true;
protected override int NumericResultFor(HitResult result) => result == MaxResult ? 30 : 0;
}
}
}
@@ -22,8 +22,8 @@ namespace osu.Game.Rulesets.Osu.Objects
pathVersion.BindValueChanged(_ => Position = slider.EndPosition);
}
public override Judgement CreateJudgement() => new IgnoreJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
public override Judgement CreateJudgement() => new SliderRepeat.SliderRepeatJudgement();
}
}
+9 -2
View File
@@ -30,8 +30,15 @@ namespace osu.Game.Rulesets.Osu.Objects
TimePreempt = (StartTime - SpanStartTime) / 2 + offset;
}
public override Judgement CreateJudgement() => new OsuJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
public override Judgement CreateJudgement() => new SliderTickJudgement();
public class SliderTickJudgement : OsuJudgement
{
public override bool IsBonus => true;
protected override int NumericResultFor(HitResult result) => result == MaxResult ? 10 : 0;
}
}
}