Fix instability of taiko double conversion

Until now, the taiko speed multiplier was potentially applied more than
once if conversion was run multiple times.
This commit is contained in:
Dean Herbert 2021-08-30 15:30:17 +09:00
parent 4adfe9a6dc
commit 6a6dac609c
2 changed files with 32 additions and 5 deletions

View File

@ -46,10 +46,12 @@ public TaikoBeatmapConverter(IBeatmap beatmap, Ruleset ruleset)
protected override Beatmap<TaikoHitObject> ConvertBeatmap(IBeatmap original, CancellationToken cancellationToken)
{
// 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 *= LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER;
if (!(original.BeatmapInfo.BaseDifficulty is TaikoMutliplierAppliedDifficulty))
{
// Rewrite the beatmap info to add the slider velocity multiplier
original.BeatmapInfo = original.BeatmapInfo.Clone();
original.BeatmapInfo.BaseDifficulty = new TaikoMutliplierAppliedDifficulty(original.BeatmapInfo.BaseDifficulty);
}
Beatmap<TaikoHitObject> converted = base.ConvertBeatmap(original, cancellationToken);
@ -188,5 +190,14 @@ private bool shouldConvertSliderToHits(HitObject obj, IBeatmap beatmap, IHasDist
}
protected override Beatmap<TaikoHitObject> CreateBeatmap() => new TaikoBeatmap();
private class TaikoMutliplierAppliedDifficulty : BeatmapDifficulty
{
public TaikoMutliplierAppliedDifficulty(BeatmapDifficulty difficulty)
{
difficulty.CopyTo(this);
SliderMultiplier *= LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER;
}
}
}
}

View File

@ -32,7 +32,23 @@ public float ApproachRate
/// <summary>
/// Returns a shallow-clone of this <see cref="BeatmapDifficulty"/>.
/// </summary>
public BeatmapDifficulty Clone() => (BeatmapDifficulty)MemberwiseClone();
public BeatmapDifficulty Clone()
{
var diff = new BeatmapDifficulty();
CopyTo(diff);
return diff;
}
public void CopyTo(BeatmapDifficulty difficulty)
{
difficulty.ApproachRate = ApproachRate;
difficulty.DrainRate = DrainRate;
difficulty.CircleSize = CircleSize;
difficulty.OverallDifficulty = OverallDifficulty;
difficulty.SliderMultiplier = SliderMultiplier;
difficulty.SliderTickRate = SliderTickRate;
}
/// <summary>
/// Maps a difficulty value [0, 10] to a two-piece linear range of values.