1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-06 09:47:52 +08:00

Merge pull request #9057 from peppy/fix-taiko-whistle

Fix taiko rim markers incorrectly playing as whistle samples
This commit is contained in:
Dan Balasescu 2020-05-20 14:24:01 +09:00 committed by GitHub
commit b6c9a50f7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 247 additions and 12 deletions

View File

@ -19,6 +19,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
[NonParallelizable]
[TestCase("basic")]
[TestCase("slider-generating-drumroll")]
[TestCase("sample-to-type-conversions")]
public void Test(string name) => base.Test(name);
protected override IEnumerable<ConvertValue> CreateConvertValue(HitObject hitObject)
@ -41,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
public struct ConvertValue : IEquatable<ConvertValue>
{
/// <summary>
/// A sane value to account for osu!stable using ints everwhere.
/// A sane value to account for osu!stable using ints everywhere.
/// </summary>
private const float conversion_lenience = 2;

View File

@ -0,0 +1,49 @@
// 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.Linq;
using osu.Framework.Testing;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Taiko.Objects.Drawables;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Taiko.Tests
{
/// <summary>
/// Taiko has some interesting rules for legacy mappings.
/// </summary>
[HeadlessTest]
public class TestSceneSampleOutput : PlayerTestScene
{
public TestSceneSampleOutput()
: base(new TaikoRuleset())
{
}
public override void SetUpSteps()
{
base.SetUpSteps();
AddAssert("has correct samples", () =>
{
var names = Player.DrawableRuleset.Playfield.AllHitObjects.OfType<DrawableHit>().Select(h => string.Join(',', h.GetSamples().Select(s => s.Name)));
var expected = new[]
{
string.Empty,
string.Empty,
string.Empty,
string.Empty,
HitSampleInfo.HIT_FINISH,
HitSampleInfo.HIT_WHISTLE,
HitSampleInfo.HIT_WHISTLE,
HitSampleInfo.HIT_WHISTLE,
};
return names.SequenceEqual(expected);
});
}
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TaikoBeatmapConversionTest().GetBeatmap("sample-to-type-conversions");
}
}

View File

@ -49,10 +49,15 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
? new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit)
: new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit);
protected override IEnumerable<HitSampleInfo> GetSamples()
public override IEnumerable<HitSampleInfo> GetSamples()
{
// normal and claps are always handled by the drum (see DrumSampleMapping).
var samples = HitObject.Samples.Where(s => s.Name != HitSampleInfo.HIT_NORMAL && s.Name != HitSampleInfo.HIT_CLAP);
// in addition, whistles are excluded as they are an alternative rim marker.
var samples = HitObject.Samples.Where(s =>
s.Name != HitSampleInfo.HIT_NORMAL
&& s.Name != HitSampleInfo.HIT_CLAP
&& s.Name != HitSampleInfo.HIT_WHISTLE);
if (HitObject.Type == HitType.Rim && HitObject.IsStrong)
{

View File

@ -166,7 +166,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
}
// Most osu!taiko hitsounds are managed by the drum (see DrumSampleMapping).
protected override IEnumerable<HitSampleInfo> GetSamples() => Enumerable.Empty<HitSampleInfo>();
public override IEnumerable<HitSampleInfo> GetSamples() => Enumerable.Empty<HitSampleInfo>();
protected abstract SkinnableDrawable CreateMainPiece();

View File

@ -0,0 +1,116 @@
{
"Mappings": [
{
"StartTime": 110.0,
"Objects": [
{
"StartTime": 110.0,
"EndTime": 110.0,
"IsRim": false,
"IsCentre": true,
"IsDrumRoll": false,
"IsSwell": false,
"IsStrong": false
}
]
},
{
"StartTime": 538.0,
"Objects": [
{
"StartTime": 538.0,
"EndTime": 538.0,
"IsRim": true,
"IsCentre": false,
"IsDrumRoll": false,
"IsSwell": false,
"IsStrong": false
}
]
},
{
"StartTime": 967.0,
"Objects": [
{
"StartTime": 967.0,
"EndTime": 967.0,
"IsRim": true,
"IsCentre": false,
"IsDrumRoll": false,
"IsSwell": false,
"IsStrong": false
}
]
},
{
"StartTime": 1395.0,
"Objects": [
{
"StartTime": 1395.0,
"EndTime": 1395.0,
"IsRim": true,
"IsCentre": false,
"IsDrumRoll": false,
"IsSwell": false,
"IsStrong": false
}
]
},
{
"StartTime": 1824.0,
"Objects": [
{
"StartTime": 1824.0,
"EndTime": 1824.0,
"IsRim": false,
"IsCentre": true,
"IsDrumRoll": false,
"IsSwell": false,
"IsStrong": true
}
]
},
{
"StartTime": 2252.0,
"Objects": [
{
"StartTime": 2252.0,
"EndTime": 2252.0,
"IsRim": true,
"IsCentre": false,
"IsDrumRoll": false,
"IsSwell": false,
"IsStrong": true
}
]
},
{
"StartTime": 2681.0,
"Objects": [
{
"StartTime": 2681.0,
"EndTime": 2681.0,
"IsRim": true,
"IsCentre": false,
"IsDrumRoll": false,
"IsSwell": false,
"IsStrong": true
}
]
},
{
"StartTime": 3110.0,
"Objects": [
{
"StartTime": 3110.0,
"EndTime": 3110.0,
"IsRim": true,
"IsCentre": false,
"IsDrumRoll": false,
"IsSwell": false,
"IsStrong": true
}
]
}
]
}

View File

@ -0,0 +1,62 @@
osu file format v14
[General]
AudioFilename: audio.mp3
AudioLeadIn: 0
PreviewTime: -1
Countdown: 0
SampleSet: Normal
StackLeniency: 0.5
Mode: 1
LetterboxInBreaks: 0
WidescreenStoryboard: 1
[Editor]
Bookmarks: 110,13824,54967,82395,109824
DistanceSpacing: 0.1
BeatDivisor: 4
GridSize: 32
TimelineZoom: 3.099999
[Metadata]
Title:test
TitleUnicode:test
Artist:sample conversion
ArtistUnicode:sample conversion
Creator:banchobot
Version:sample test
Source:
Tags:
BeatmapID:0
BeatmapSetID:-1
[Difficulty]
HPDrainRate:6
CircleSize:2
OverallDifficulty:6
ApproachRate:7
SliderMultiplier:1.4
SliderTickRate:4
[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
[TimingPoints]
110,428.571428571429,4,1,0,100,1,0
[HitObjects]
256,192,110,5,0,0:0:0:0:
256,192,538,1,8,0:0:0:0:
256,192,967,1,2,0:0:0:0:
256,192,1395,1,10,0:0:0:0:
256,192,1824,1,4,0:0:0:0:
256,192,2252,1,12,0:0:0:0:
256,192,2681,1,6,0:0:0:0:
256,192,3110,1,14,0:0:0:0:

View File

@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
protected SkinnableSound Samples { get; private set; }
protected virtual IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples;
public virtual IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples;
private readonly Lazy<List<DrawableHitObject>> nestedHitObjects = new Lazy<List<DrawableHitObject>>();
public IReadOnlyList<DrawableHitObject> NestedHitObjects => nestedHitObjects.IsValueCreated ? nestedHitObjects.Value : (IReadOnlyList<DrawableHitObject>)Array.Empty<DrawableHitObject>();

View File

@ -99,10 +99,7 @@ namespace osu.Game.Tests.Beatmaps
private ConvertResult convert(string name, Mod[] mods)
{
var beatmap = getBeatmap(name);
var rulesetInstance = CreateRuleset();
beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo();
var beatmap = GetBeatmap(name);
var converterResult = new Dictionary<HitObject, IEnumerable<HitObject>>();
@ -115,7 +112,7 @@ namespace osu.Game.Tests.Beatmaps
}
};
working.GetPlayableBeatmap(rulesetInstance.RulesetInfo, mods);
working.GetPlayableBeatmap(CreateRuleset().RulesetInfo, mods);
return new ConvertResult
{
@ -143,14 +140,19 @@ namespace osu.Game.Tests.Beatmaps
}
}
private IBeatmap getBeatmap(string name)
public IBeatmap GetBeatmap(string name)
{
using (var resStream = openResource($"{resource_namespace}.{name}.osu"))
using (var stream = new LineBufferedReader(resStream))
{
var decoder = Decoder.GetDecoder<Beatmap>(stream);
((LegacyBeatmapDecoder)decoder).ApplyOffsets = false;
return decoder.Decode(stream);
var beatmap = decoder.Decode(stream);
var rulesetInstance = CreateRuleset();
beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo();
return beatmap;
}
}