Skip to content

Commit

Permalink
Merge pull request #8823 from smoogipoo/all-ruleset-encoders
Browse files Browse the repository at this point in the history
Implement legacy beatmap encoding for all rulesets
  • Loading branch information
peppy committed Apr 24, 2020
2 parents f880bd2 + 131f011 commit 59bd2b3
Show file tree
Hide file tree
Showing 12 changed files with 264 additions and 77 deletions.
23 changes: 3 additions & 20 deletions osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
using osu.Game.Rulesets.Mania.MathUtils;
using osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy;
using osuTK;
using osu.Game.Audio;

namespace osu.Game.Rulesets.Mania.Beatmaps
{
Expand Down Expand Up @@ -67,7 +66,7 @@ public ManiaBeatmapConverter(IBeatmap beatmap, Ruleset ruleset)
}
}

public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasXPosition || h is ManiaHitObject);
public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasXPosition);

protected override Beatmap<ManiaHitObject> ConvertBeatmap(IBeatmap original)
{
Expand Down Expand Up @@ -239,8 +238,8 @@ private Pattern generate()
StartTime = HitObject.StartTime,
Duration = endTimeData.Duration,
Column = column,
Head = { Samples = sampleInfoListAt(HitObject.StartTime) },
Tail = { Samples = sampleInfoListAt(endTimeData.EndTime) },
Samples = HitObject.Samples,
NodeSamples = (HitObject as IHasRepeats)?.NodeSamples
});
}
else if (HitObject is IHasXPosition)
Expand All @@ -255,22 +254,6 @@ private Pattern generate()

return pattern;
}

/// <summary>
/// Retrieves the sample info list at a point in time.
/// </summary>
/// <param name="time">The time to retrieve the sample info list from.</param>
/// <returns></returns>
private IList<HitSampleInfo> sampleInfoListAt(double time)
{
if (!(HitObject is IHasCurve curveData))
return HitObject.Samples;

double segmentTime = (curveData.EndTime - HitObject.StartTime) / curveData.SpanCount();

int index = (int)(segmentTime == 0 ? 0 : (time - HitObject.StartTime) / segmentTime);
return curveData.NodeSamples[index];
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -505,16 +505,14 @@ private void addToPattern(Pattern pattern, int column, double startTime, double
}
else
{
var holdNote = new HoldNote
newObject = new HoldNote
{
StartTime = startTime,
Column = column,
Duration = endTime - startTime,
Head = { Samples = sampleInfoListAt(startTime) },
Tail = { Samples = sampleInfoListAt(endTime) }
Column = column,
Samples = HitObject.Samples,
NodeSamples = (HitObject as IHasRepeats)?.NodeSamples
};

newObject = holdNote;
}

pattern.Add(newObject);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,14 @@ private void addToPattern(Pattern pattern, int column, bool holdNote)

if (holdNote)
{
var hold = new HoldNote
newObject = new HoldNote
{
StartTime = HitObject.StartTime,
Duration = endTime - HitObject.StartTime,
Column = column,
Duration = endTime - HitObject.StartTime
Samples = HitObject.Samples,
NodeSamples = (HitObject as IHasRepeats)?.NodeSamples
};

if (hold.Head.Samples == null)
hold.Head.Samples = new List<HitSampleInfo>();

hold.Head.Samples.Add(new HitSampleInfo { Name = HitSampleInfo.HIT_NORMAL });

hold.Tail.Samples = HitObject.Samples;

newObject = hold;
}
else
{
Expand Down
5 changes: 5 additions & 0 deletions osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ protected override void OnDirectionChanged(ValueChangedEvent<ScrollingDirection>
bodyPiece.Anchor = bodyPiece.Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
}

public override void PlaySamples()
{
// Samples are played by the head/tail notes.
}

protected override void Update()
{
base.Update();
Expand Down
46 changes: 37 additions & 9 deletions osu.Game.Rulesets.Mania/Objects/HoldNote.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// 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.Collections.Generic;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Judgements;
Expand Down Expand Up @@ -28,7 +30,9 @@ public double Duration
set
{
duration = value;
Tail.StartTime = EndTime;

if (Tail != null)
Tail.StartTime = EndTime;
}
}

Expand All @@ -38,8 +42,12 @@ public override double StartTime
set
{
base.StartTime = value;
Head.StartTime = value;
Tail.StartTime = EndTime;

if (Head != null)
Head.StartTime = value;

if (Tail != null)
Tail.StartTime = EndTime;
}
}

Expand All @@ -49,20 +57,26 @@ public override int Column
set
{
base.Column = value;
Head.Column = value;
Tail.Column = value;

if (Head != null)
Head.Column = value;

if (Tail != null)
Tail.Column = value;
}
}

public List<IList<HitSampleInfo>> NodeSamples { get; set; }

/// <summary>
/// The head note of the hold.
/// </summary>
public readonly Note Head = new Note();
public Note Head { get; private set; }

/// <summary>
/// The tail note of the hold.
/// </summary>
public readonly TailNote Tail = new TailNote();
public TailNote Tail { get; private set; }

/// <summary>
/// The time between ticks of this hold.
Expand All @@ -83,8 +97,19 @@ protected override void CreateNestedHitObjects()

createTicks();

AddNested(Head);
AddNested(Tail);
AddNested(Head = new Note
{
StartTime = StartTime,
Column = Column,
Samples = getNodeSamples(0),
});

AddNested(Tail = new TailNote
{
StartTime = EndTime,
Column = Column,
Samples = getNodeSamples((NodeSamples?.Count - 1) ?? 1),
});
}

private void createTicks()
Expand All @@ -105,5 +130,8 @@ private void createTicks()
public override Judgement CreateJudgement() => new IgnoreJudgement();

protected override HitWindows CreateHitWindows() => HitWindows.Empty;

private IList<HitSampleInfo> getNodeSamples(int nodeIndex) =>
nodeIndex < NodeSamples?.Count ? NodeSamples[nodeIndex] : Samples;
}
}
9 changes: 8 additions & 1 deletion osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
using osu.Game.Rulesets.Mania.Objects.Types;
using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Scoring;

namespace osu.Game.Rulesets.Mania.Objects
{
public abstract class ManiaHitObject : HitObject, IHasColumn
public abstract class ManiaHitObject : HitObject, IHasColumn, IHasXPosition
{
public readonly Bindable<int> ColumnBindable = new Bindable<int>();

Expand All @@ -20,5 +21,11 @@ public virtual int Column
}

protected override HitWindows CreateHitWindows() => new ManiaHitWindows();

#region LegacyBeatmapEncoder

float IHasXPosition.X => Column;

#endregion
}
}
6 changes: 3 additions & 3 deletions osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal class TaikoBeatmapConverter : BeatmapConverter<TaikoHitObject>
/// osu! is generally slower than taiko, so a factor is added to increase
/// speed. This must be used everywhere slider length or beat length is used.
/// </summary>
private const float legacy_velocity_multiplier = 1.4f;
public const float LEGACY_VELOCITY_MULTIPLIER = 1.4f;

/// <summary>
/// Because swells are easier in taiko than spinners are in osu!,
Expand Down Expand Up @@ -52,7 +52,7 @@ protected override Beatmap<TaikoHitObject> ConvertBeatmap(IBeatmap original)
// Rewrite the beatmap info to add the slider velocity multiplier
original.BeatmapInfo = original.BeatmapInfo.Clone();
original.BeatmapInfo.BaseDifficulty = original.BeatmapInfo.BaseDifficulty.Clone();
original.BeatmapInfo.BaseDifficulty.SliderMultiplier *= legacy_velocity_multiplier;
original.BeatmapInfo.BaseDifficulty.SliderMultiplier *= LEGACY_VELOCITY_MULTIPLIER;

Beatmap<TaikoHitObject> converted = base.ConvertBeatmap(original);

Expand Down Expand Up @@ -92,7 +92,7 @@ protected override IEnumerable<TaikoHitObject> ConvertHitObject(HitObject obj, I
double speedAdjustedBeatLength = timingPoint.BeatLength / speedAdjustment;

// The true distance, accounting for any repeats. This ends up being the drum roll distance later
double distance = distanceData.Distance * spans * legacy_velocity_multiplier;
double distance = distanceData.Distance * spans * LEGACY_VELOCITY_MULTIPLIER;

// The velocity of the taiko hit object - calculated as the velocity of a drum roll
double taikoVelocity = taiko_base_distance * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier / speedAdjustedBeatLength;
Expand Down
29 changes: 28 additions & 1 deletion osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@

using osu.Game.Rulesets.Objects.Types;
using System;
using System.Collections.Generic;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Beatmaps;
using osu.Game.Rulesets.Taiko.Judgements;
using osuTK;

namespace osu.Game.Rulesets.Taiko.Objects
{
public class DrumRoll : TaikoHitObject, IHasEndTime
public class DrumRoll : TaikoHitObject, IHasCurve
{
/// <summary>
/// Drum roll distance that results in a duration of 1 speed-adjusted beat length.
Expand All @@ -26,6 +31,11 @@ public double EndTime

public double Duration { get; set; }

/// <summary>
/// Velocity of this <see cref="DrumRoll"/>.
/// </summary>
public double Velocity { get; private set; }

/// <summary>
/// Numer of ticks per beat length.
/// </summary>
Expand Down Expand Up @@ -54,6 +64,10 @@ protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, B
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);

TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime);
DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(StartTime);

double scoringDistance = base_distance * difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier;
Velocity = scoringDistance / timingPoint.BeatLength;

tickSpacing = timingPoint.BeatLength / TickRate;
overallDifficulty = difficulty.OverallDifficulty;
Expand Down Expand Up @@ -93,5 +107,18 @@ private void createTicks()
public override Judgement CreateJudgement() => new TaikoDrumRollJudgement();

protected override HitWindows CreateHitWindows() => HitWindows.Empty;

#region LegacyBeatmapEncoder

double IHasDistance.Distance => Duration * Velocity;

int IHasRepeats.RepeatCount { get => 0; set { } }

List<IList<HitSampleInfo>> IHasRepeats.NodeSamples => new List<IList<HitSampleInfo>>();

SliderPath IHasCurve.Path
=> new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(1) }, ((IHasDistance)this).Distance / TaikoBeatmapConverter.LEGACY_VELOCITY_MULTIPLIER);

#endregion
}
}
30 changes: 30 additions & 0 deletions osu.Game.Tests/Resources/sample-beatmap-catch.osu
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
osu file format v14

[General]
SampleSet: Normal
StackLeniency: 0.7
Mode: 2

[Difficulty]
HPDrainRate:3
CircleSize:5
OverallDifficulty:8
ApproachRate:8
SliderMultiplier:3.59999990463257
SliderTickRate:2

[TimingPoints]
24,352.941176470588,4,1,1,100,1,0
6376,-50,4,1,1,100,0,0

[HitObjects]
32,183,24,5,0,0:0:0:0:
106,123,200,1,10,0:0:0:0:
199,108,376,1,2,0:0:0:0:
305,105,553,5,4,0:0:0:0:
386,112,729,1,14,0:0:0:0:
486,197,906,5,12,0:0:0:0:
14,199,1082,2,0,L|473:198,1,449.999988079071
14,199,1700,6,6,P|248:33|490:222,1,629.9999833107,0|8,0:0|0:0,0:0:0:0:
10,190,2494,2,8,B|252:29|254:335|468:167,1,449.999988079071,10|12,0:0|0:0,0:0:0:0:
256,192,3112,12,0,3906,0:0:0:0:
39 changes: 39 additions & 0 deletions osu.Game.Tests/Resources/sample-beatmap-mania.osu
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
osu file format v14

[General]
SampleSet: Normal
StackLeniency: 0.7
Mode: 3

[Difficulty]
HPDrainRate:3
CircleSize:5
OverallDifficulty:8
ApproachRate:8
SliderMultiplier:3.59999990463257
SliderTickRate:2

[TimingPoints]
24,352.941176470588,4,1,1,100,1,0
6376,-50,4,1,1,100,0,0

[HitObjects]
51,192,24,1,0,0:0:0:0:
153,192,200,1,0,0:0:0:0:
358,192,376,1,0,0:0:0:0:
460,192,553,1,0,0:0:0:0:
460,192,729,128,0,1435:0:0:0:0:
358,192,906,128,0,1612:0:0:0:0:
256,192,1082,128,0,1788:0:0:0:0:
153,192,1259,128,0,1965:0:0:0:0:
51,192,1435,128,0,2141:0:0:0:0:
51,192,2318,1,12,0:0:0:0:
153,192,2318,1,4,0:0:0:0:
256,192,2318,1,6,0:0:0:0:
358,192,2318,1,14,0:0:0:0:
460,192,2318,1,0,0:0:0:0:
51,192,2494,128,0,2582:0:0:0:0:
153,192,2494,128,14,2582:0:0:0:0:
256,192,2494,128,6,2582:0:0:0:0:
358,192,2494,128,4,2582:0:0:0:0:
460,192,2494,128,12,2582:0:0:0:0:

0 comments on commit 59bd2b3

Please sign in to comment.