1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-12 09:47:18 +08:00

Use new mod-related object types for Strict Tracking

This commit is contained in:
apollo-dw 2022-03-19 18:29:44 +00:00
parent e2001148d5
commit 149cfd338d
6 changed files with 132 additions and 17 deletions

View File

@ -0,0 +1,12 @@
// 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.Osu.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Mods.Objects
{
public class StrictTrackingDrawableSliderTail : DrawableSliderTail
{
public override bool DisplayResult => true;
}
}

View File

@ -0,0 +1,70 @@
// 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 System.Threading;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Objects;
namespace osu.Game.Rulesets.Osu.Mods.Objects
{
public class StrictTrackingSlider : Slider
{
public StrictTrackingSlider(Slider original)
{
StartTime = original.StartTime;
Samples = original.Samples;
Path = original.Path;
NodeSamples = original.NodeSamples;
RepeatCount = original.RepeatCount;
Position = original.Position;
NewCombo = original.NewCombo;
ComboOffset = original.ComboOffset;
LegacyLastTickOffset = original.LegacyLastTickOffset;
TickDistanceMultiplier = original.TickDistanceMultiplier;
}
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
var sliderEvents = SliderEventGenerator.Generate(StartTime, SpanDuration, Velocity, TickDistance, Path.Distance, this.SpanCount(), LegacyLastTickOffset, cancellationToken);
foreach (var e in sliderEvents)
{
switch (e.Type)
{
case SliderEventType.Head:
AddNested(HeadCircle = new SliderHeadCircle
{
StartTime = e.Time,
Position = Position,
StackHeight = StackHeight,
});
break;
case SliderEventType.LegacyLastTick:
AddNested(TailCircle = new StrictTrackingSliderTailCircle(this)
{
RepeatIndex = e.SpanIndex,
StartTime = e.Time,
Position = EndPosition,
StackHeight = StackHeight
});
break;
case SliderEventType.Repeat:
AddNested(new SliderRepeat(this)
{
RepeatIndex = e.SpanIndex,
StartTime = StartTime + (e.SpanIndex + 1) * SpanDuration,
Position = Position + Path.PositionAt(e.PathProgress),
StackHeight = StackHeight,
Scale = Scale,
});
break;
}
}
UpdateNestedSamples();
}
}
}

View File

@ -0,0 +1,19 @@
// 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.Judgements;
using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Rulesets.Osu.Objects;
namespace osu.Game.Rulesets.Osu.Mods.Objects
{
public class StrictTrackingSliderTailCircle : SliderTailCircle
{
public StrictTrackingSliderTailCircle(Slider slider)
: base(slider)
{
}
public override Judgement CreateJudgement() => new OsuJudgement();
}
}

View File

@ -2,17 +2,20 @@
// 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.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Beatmaps;
using osu.Game.Rulesets.Osu.Mods.Objects;
using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Osu.Mods namespace osu.Game.Rulesets.Osu.Mods
{ {
public class OsuModStrictTracking : Mod, IApplicableToDifficulty, IApplicableToDrawableHitObject, IApplicableToHitObject public class OsuModStrictTracking : Mod, IApplicableAfterBeatmapConversion, IApplicableToDrawableHitObject, IApplicableToDrawableRuleset<OsuHitObject>
{ {
public override string Name => @"Strict Tracking"; public override string Name => @"Strict Tracking";
public override string Acronym => @"ST"; public override string Acronym => @"ST";
@ -22,11 +25,6 @@ namespace osu.Game.Rulesets.Osu.Mods
public override double ScoreMultiplier => 1.0; public override double ScoreMultiplier => 1.0;
public override Type[] IncompatibleMods => new[] { typeof(ModClassic) }; public override Type[] IncompatibleMods => new[] { typeof(ModClassic) };
public void ApplyToDifficulty(BeatmapDifficulty difficulty)
{
difficulty.SliderTickRate = 0.0;
}
public void ApplyToDrawableHitObject(DrawableHitObject drawable) public void ApplyToDrawableHitObject(DrawableHitObject drawable)
{ {
if (drawable is DrawableSlider slider) if (drawable is DrawableSlider slider)
@ -46,14 +44,30 @@ namespace osu.Game.Rulesets.Osu.Mods
} }
} }
public void ApplyToHitObject(HitObject hitObject) public void ApplyToBeatmap(IBeatmap beatmap)
{ {
switch (hitObject) var osuBeatmap = (OsuBeatmap)beatmap;
if (osuBeatmap.HitObjects.Count == 0) return;
var hitObjects = osuBeatmap.HitObjects.Select(ho =>
{ {
case Slider slider: if (ho is Slider slider)
slider.TailCircle.JudgeAsSliderTick = true; {
break; var newSlider = new StrictTrackingSlider(slider);
} return newSlider;
}
return ho;
}).ToList();
osuBeatmap.HitObjects = hitObjects;
}
public void ApplyToDrawableRuleset(DrawableRuleset<OsuHitObject> drawableRuleset)
{
drawableRuleset.Playfield.RegisterPool<StrictTrackingSlider, DrawableSlider>(10, 100);
drawableRuleset.Playfield.RegisterPool<StrictTrackingSliderTailCircle, StrictTrackingDrawableSliderTail>(10, 100);
} }
} }
} }

View File

@ -137,7 +137,7 @@ namespace osu.Game.Rulesets.Osu.Objects
public Slider() public Slider()
{ {
SamplesBindable.CollectionChanged += (_, __) => updateNestedSamples(); SamplesBindable.CollectionChanged += (_, __) => UpdateNestedSamples();
Path.Version.ValueChanged += _ => updateNestedPositions(); Path.Version.ValueChanged += _ => updateNestedPositions();
} }
@ -210,7 +210,7 @@ namespace osu.Game.Rulesets.Osu.Objects
} }
} }
updateNestedSamples(); UpdateNestedSamples();
} }
private void updateNestedPositions() private void updateNestedPositions()
@ -224,7 +224,7 @@ namespace osu.Game.Rulesets.Osu.Objects
TailCircle.Position = EndPosition; TailCircle.Position = EndPosition;
} }
private void updateNestedSamples() protected void UpdateNestedSamples()
{ {
var firstSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL) var firstSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL)
?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933) ?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)

View File

@ -308,7 +308,7 @@ namespace osu.Game.Rulesets.UI
/// </param> /// </param>
/// <typeparam name="TObject">The <see cref="HitObject"/> type.</typeparam> /// <typeparam name="TObject">The <see cref="HitObject"/> type.</typeparam>
/// <typeparam name="TDrawable">The <see cref="DrawableHitObject"/> receiver for <typeparamref name="TObject"/>s.</typeparam> /// <typeparam name="TDrawable">The <see cref="DrawableHitObject"/> receiver for <typeparamref name="TObject"/>s.</typeparam>
protected void RegisterPool<TObject, TDrawable>(int initialSize, int? maximumSize = null) public void RegisterPool<TObject, TDrawable>(int initialSize, int? maximumSize = null)
where TObject : HitObject where TObject : HitObject
where TDrawable : DrawableHitObject, new() where TDrawable : DrawableHitObject, new()
=> RegisterPool<TObject, TDrawable>(new DrawablePool<TDrawable>(initialSize, maximumSize)); => RegisterPool<TObject, TDrawable>(new DrawablePool<TDrawable>(initialSize, maximumSize));