1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 07:22:55 +08:00

Merge pull request #12916 from peppy/fix-taiko-editor-sample-mutations

Fix osu!taiko editor operations not always updating the menu/visual state correctly
This commit is contained in:
Dan Balasescu 2021-05-27 23:55:16 +09:00 committed by GitHub
commit bc4ccb8a21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 53 additions and 33 deletions

View File

@ -79,8 +79,6 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
// Old osu! used hit sounding to determine various hit type information // Old osu! used hit sounding to determine various hit type information
IList<HitSampleInfo> samples = obj.Samples; IList<HitSampleInfo> samples = obj.Samples;
bool strong = samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH);
switch (obj) switch (obj)
{ {
case IHasDistance distanceData: case IHasDistance distanceData:
@ -94,15 +92,11 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing) for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing)
{ {
IList<HitSampleInfo> currentSamples = allSamples[i]; IList<HitSampleInfo> currentSamples = allSamples[i];
bool isRim = currentSamples.Any(s => s.Name == HitSampleInfo.HIT_CLAP || s.Name == HitSampleInfo.HIT_WHISTLE);
strong = currentSamples.Any(s => s.Name == HitSampleInfo.HIT_FINISH);
yield return new Hit yield return new Hit
{ {
StartTime = j, StartTime = j,
Type = isRim ? HitType.Rim : HitType.Centre,
Samples = currentSamples, Samples = currentSamples,
IsStrong = strong
}; };
i = (i + 1) % allSamples.Count; i = (i + 1) % allSamples.Count;
@ -117,7 +111,6 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
{ {
StartTime = obj.StartTime, StartTime = obj.StartTime,
Samples = obj.Samples, Samples = obj.Samples,
IsStrong = strong,
Duration = taikoDuration, Duration = taikoDuration,
TickRate = beatmap.BeatmapInfo.BaseDifficulty.SliderTickRate == 3 ? 3 : 4 TickRate = beatmap.BeatmapInfo.BaseDifficulty.SliderTickRate == 3 ? 3 : 4
}; };
@ -143,16 +136,10 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
default: default:
{ {
bool isRimDefinition(HitSampleInfo s) => s.Name == HitSampleInfo.HIT_CLAP || s.Name == HitSampleInfo.HIT_WHISTLE;
bool isRim = samples.Any(isRimDefinition);
yield return new Hit yield return new Hit
{ {
StartTime = obj.StartTime, StartTime = obj.StartTime,
Type = isRim ? HitType.Rim : HitType.Centre,
Samples = samples, Samples = samples,
IsStrong = strong
}; };
break; break;

View File

@ -69,7 +69,11 @@ namespace osu.Game.Rulesets.Taiko.Edit
{ {
EditorBeatmap.PerformOnSelection(h => EditorBeatmap.PerformOnSelection(h =>
{ {
if (h is Hit taikoHit) taikoHit.Type = state ? HitType.Rim : HitType.Centre; if (h is Hit taikoHit)
{
taikoHit.Type = state ? HitType.Rim : HitType.Centre;
EditorBeatmap.Update(h);
}
}); });
} }

View File

@ -17,13 +17,25 @@ namespace osu.Game.Rulesets.Taiko.Objects
public HitType Type public HitType Type
{ {
get => TypeBindable.Value; get => TypeBindable.Value;
set set => TypeBindable.Value = value;
}
public Hit()
{ {
TypeBindable.Value = value; TypeBindable.BindValueChanged(_ => updateSamplesFromType());
updateSamplesFromType(); SamplesBindable.BindCollectionChanged((_, __) => updateTypeFromSamples());
} }
private void updateTypeFromSamples()
{
Type = getRimSamples().Any() ? HitType.Rim : HitType.Centre;
} }
/// <summary>
/// Returns an array of any samples which would cause this object to be a "rim" type hit.
/// </summary>
private HitSampleInfo[] getRimSamples() => Samples.Where(s => s.Name == HitSampleInfo.HIT_CLAP || s.Name == HitSampleInfo.HIT_WHISTLE).ToArray();
private void updateSamplesFromType() private void updateSamplesFromType()
{ {
var rimSamples = getRimSamples(); var rimSamples = getRimSamples();
@ -42,11 +54,6 @@ namespace osu.Game.Rulesets.Taiko.Objects
} }
} }
/// <summary>
/// Returns an array of any samples which would cause this object to be a "rim" type hit.
/// </summary>
private HitSampleInfo[] getRimSamples() => Samples.Where(s => s.Name == HitSampleInfo.HIT_CLAP || s.Name == HitSampleInfo.HIT_WHISTLE).ToArray();
protected override StrongNestedHitObject CreateStrongNestedHit(double startTime) => new StrongNestedHit { StartTime = startTime }; protected override StrongNestedHitObject CreateStrongNestedHit(double startTime) => new StrongNestedHit { StartTime = startTime };
public class StrongNestedHit : StrongNestedHitObject public class StrongNestedHit : StrongNestedHitObject

View File

@ -33,14 +33,21 @@ namespace osu.Game.Rulesets.Taiko.Objects
public bool IsStrong public bool IsStrong
{ {
get => IsStrongBindable.Value; get => IsStrongBindable.Value;
set set => IsStrongBindable.Value = value;
{
IsStrongBindable.Value = value;
updateSamplesFromStrong();
}
} }
private void updateSamplesFromStrong() protected TaikoStrongableHitObject()
{
IsStrongBindable.BindValueChanged(_ => updateSamplesFromType());
SamplesBindable.BindCollectionChanged((_, __) => updateTypeFromSamples());
}
private void updateTypeFromSamples()
{
IsStrong = getStrongSamples().Any();
}
private void updateSamplesFromType()
{ {
var strongSamples = getStrongSamples(); var strongSamples = getStrongSamples();

View File

@ -77,7 +77,13 @@ namespace osu.Game.Screens.Edit.Compose.Components
double offset = result.Time.Value - blueprints.First().Item.StartTime; double offset = result.Time.Value - blueprints.First().Item.StartTime;
if (offset != 0) if (offset != 0)
Beatmap.PerformOnSelection(obj => obj.StartTime += offset); {
Beatmap.PerformOnSelection(obj =>
{
obj.StartTime += offset;
Beatmap.Update(obj);
});
}
} }
return true; return true;

View File

@ -125,6 +125,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
return; return;
h.Samples.Add(new HitSampleInfo(sampleName)); h.Samples.Add(new HitSampleInfo(sampleName));
EditorBeatmap.Update(h);
}); });
} }
@ -134,7 +135,11 @@ namespace osu.Game.Screens.Edit.Compose.Components
/// <param name="sampleName">The name of the hit sample.</param> /// <param name="sampleName">The name of the hit sample.</param>
public void RemoveHitSample(string sampleName) public void RemoveHitSample(string sampleName)
{ {
EditorBeatmap.PerformOnSelection(h => h.SamplesBindable.RemoveAll(s => s.Name == sampleName)); EditorBeatmap.PerformOnSelection(h =>
{
h.SamplesBindable.RemoveAll(s => s.Name == sampleName);
EditorBeatmap.Update(h);
});
} }
/// <summary> /// <summary>

View File

@ -276,7 +276,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
var timingPoint = EditorBeatmap.ControlPointInfo.TimingPointAt(selected.First().StartTime); var timingPoint = EditorBeatmap.ControlPointInfo.TimingPointAt(selected.First().StartTime);
double adjustment = timingPoint.BeatLength / EditorBeatmap.BeatDivisor * amount; double adjustment = timingPoint.BeatLength / EditorBeatmap.BeatDivisor * amount;
EditorBeatmap.PerformOnSelection(h => h.StartTime += adjustment); EditorBeatmap.PerformOnSelection(h =>
{
h.StartTime += adjustment;
EditorBeatmap.Update(h);
});
} }
} }