mirror of
https://github.com/ppy/osu.git
synced 2025-01-31 20:52:54 +08:00
Merge branch 'master' into update-framework-has-flag
This commit is contained in:
commit
cb350470e5
@ -402,6 +402,88 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
void checkPlacementSample(string expected) => AddAssert($"Placement sample is {expected}", () => EditorBeatmap.PlacementObject.Value.Samples.First().Bank, () => Is.EqualTo(expected));
|
void checkPlacementSample(string expected) => AddAssert($"Placement sample is {expected}", () => EditorBeatmap.PlacementObject.Value.Samples.First().Bank, () => Is.EqualTo(expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestHotkeysAffectNodeSamples()
|
||||||
|
{
|
||||||
|
AddStep("add slider", () =>
|
||||||
|
{
|
||||||
|
EditorBeatmap.Add(new Slider
|
||||||
|
{
|
||||||
|
Position = new Vector2(256, 256),
|
||||||
|
StartTime = 1000,
|
||||||
|
Path = new SliderPath(new[] { new PathControlPoint(Vector2.Zero), new PathControlPoint(new Vector2(250, 0)) }),
|
||||||
|
Samples =
|
||||||
|
{
|
||||||
|
new HitSampleInfo(HitSampleInfo.HIT_NORMAL)
|
||||||
|
},
|
||||||
|
NodeSamples = new List<IList<HitSampleInfo>>
|
||||||
|
{
|
||||||
|
new List<HitSampleInfo>
|
||||||
|
{
|
||||||
|
new HitSampleInfo(HitSampleInfo.HIT_NORMAL, bank: HitSampleInfo.BANK_DRUM),
|
||||||
|
new HitSampleInfo(HitSampleInfo.HIT_CLAP, bank: HitSampleInfo.BANK_DRUM),
|
||||||
|
},
|
||||||
|
new List<HitSampleInfo>
|
||||||
|
{
|
||||||
|
new HitSampleInfo(HitSampleInfo.HIT_NORMAL, bank: HitSampleInfo.BANK_SOFT),
|
||||||
|
new HitSampleInfo(HitSampleInfo.HIT_WHISTLE, bank: HitSampleInfo.BANK_SOFT),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
AddStep("select everything", () => EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects));
|
||||||
|
|
||||||
|
AddStep("add clap addition", () => InputManager.Key(Key.R));
|
||||||
|
|
||||||
|
hitObjectHasSampleBank(0, HitSampleInfo.BANK_NORMAL);
|
||||||
|
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_CLAP);
|
||||||
|
|
||||||
|
hitObjectHasSampleBank(1, HitSampleInfo.BANK_SOFT);
|
||||||
|
hitObjectHasSamples(1, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_CLAP);
|
||||||
|
|
||||||
|
hitObjectHasSampleBank(2, HitSampleInfo.BANK_NORMAL);
|
||||||
|
hitObjectHasSamples(2, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_CLAP);
|
||||||
|
hitObjectNodeHasSampleBank(2, 0, HitSampleInfo.BANK_DRUM);
|
||||||
|
hitObjectNodeHasSamples(2, 0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_CLAP);
|
||||||
|
hitObjectNodeHasSampleBank(2, 1, HitSampleInfo.BANK_SOFT);
|
||||||
|
hitObjectNodeHasSamples(2, 1, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_WHISTLE, HitSampleInfo.HIT_CLAP);
|
||||||
|
|
||||||
|
AddStep("remove clap addition", () => InputManager.Key(Key.R));
|
||||||
|
|
||||||
|
hitObjectHasSampleBank(0, HitSampleInfo.BANK_NORMAL);
|
||||||
|
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL);
|
||||||
|
|
||||||
|
hitObjectHasSampleBank(1, HitSampleInfo.BANK_SOFT);
|
||||||
|
hitObjectHasSamples(1, HitSampleInfo.HIT_NORMAL);
|
||||||
|
|
||||||
|
hitObjectHasSampleBank(2, HitSampleInfo.BANK_NORMAL);
|
||||||
|
hitObjectHasSamples(2, HitSampleInfo.HIT_NORMAL);
|
||||||
|
hitObjectNodeHasSampleBank(2, 0, HitSampleInfo.BANK_DRUM);
|
||||||
|
hitObjectNodeHasSamples(2, 0, HitSampleInfo.HIT_NORMAL);
|
||||||
|
hitObjectNodeHasSampleBank(2, 1, HitSampleInfo.BANK_SOFT);
|
||||||
|
hitObjectNodeHasSamples(2, 1, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_WHISTLE);
|
||||||
|
|
||||||
|
AddStep("set drum bank", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.LShift);
|
||||||
|
InputManager.Key(Key.R);
|
||||||
|
InputManager.ReleaseKey(Key.LShift);
|
||||||
|
});
|
||||||
|
|
||||||
|
hitObjectHasSampleBank(0, HitSampleInfo.BANK_DRUM);
|
||||||
|
hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL);
|
||||||
|
|
||||||
|
hitObjectHasSampleBank(1, HitSampleInfo.BANK_DRUM);
|
||||||
|
hitObjectHasSamples(1, HitSampleInfo.HIT_NORMAL);
|
||||||
|
|
||||||
|
hitObjectHasSampleBank(2, HitSampleInfo.BANK_DRUM);
|
||||||
|
hitObjectHasSamples(2, HitSampleInfo.HIT_NORMAL);
|
||||||
|
hitObjectNodeHasSampleBank(2, 0, HitSampleInfo.BANK_DRUM);
|
||||||
|
hitObjectNodeHasSamples(2, 0, HitSampleInfo.HIT_NORMAL);
|
||||||
|
hitObjectNodeHasSampleBank(2, 1, HitSampleInfo.BANK_DRUM);
|
||||||
|
hitObjectNodeHasSamples(2, 1, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_WHISTLE);
|
||||||
|
}
|
||||||
|
|
||||||
private void clickSamplePiece(int objectIndex) => AddStep($"click {objectIndex.ToOrdinalWords()} sample piece", () =>
|
private void clickSamplePiece(int objectIndex) => AddStep($"click {objectIndex.ToOrdinalWords()} sample piece", () =>
|
||||||
{
|
{
|
||||||
var samplePiece = this.ChildrenOfType<SamplePointPiece>().Single(piece => piece.HitObject == EditorBeatmap.HitObjects.ElementAt(objectIndex));
|
var samplePiece = this.ChildrenOfType<SamplePointPiece>().Single(piece => piece.HitObject == EditorBeatmap.HitObjects.ElementAt(objectIndex));
|
||||||
|
@ -117,7 +117,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddSampleBank(bankName);
|
SetSampleBank(bankName);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -177,14 +177,27 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
{
|
{
|
||||||
SelectionNewComboState.Value = GetStateFromSelection(SelectedItems.OfType<IHasComboInformation>(), h => h.NewCombo);
|
SelectionNewComboState.Value = GetStateFromSelection(SelectedItems.OfType<IHasComboInformation>(), h => h.NewCombo);
|
||||||
|
|
||||||
|
var samplesInSelection = SelectedItems.SelectMany(enumerateAllSamples).ToArray();
|
||||||
|
|
||||||
foreach ((string sampleName, var bindable) in SelectionSampleStates)
|
foreach ((string sampleName, var bindable) in SelectionSampleStates)
|
||||||
{
|
{
|
||||||
bindable.Value = GetStateFromSelection(SelectedItems, h => h.Samples.Any(s => s.Name == sampleName));
|
bindable.Value = GetStateFromSelection(samplesInSelection, h => h.Any(s => s.Name == sampleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ((string bankName, var bindable) in SelectionBankStates)
|
foreach ((string bankName, var bindable) in SelectionBankStates)
|
||||||
{
|
{
|
||||||
bindable.Value = GetStateFromSelection(SelectedItems, h => h.Samples.All(s => s.Bank == bankName));
|
bindable.Value = GetStateFromSelection(samplesInSelection, h => h.Any(s => s.Bank == bankName));
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<IList<HitSampleInfo>> enumerateAllSamples(HitObject hitObject)
|
||||||
|
{
|
||||||
|
yield return hitObject.Samples;
|
||||||
|
|
||||||
|
if (hitObject is IHasRepeats withRepeats)
|
||||||
|
{
|
||||||
|
foreach (var node in withRepeats.NodeSamples)
|
||||||
|
yield return node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,12 +206,25 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
#region Ternary state changes
|
#region Ternary state changes
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a sample bank to all selected <see cref="HitObject"/>s.
|
/// Sets the sample bank for all selected <see cref="HitObject"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bankName">The name of the sample bank.</param>
|
/// <param name="bankName">The name of the sample bank.</param>
|
||||||
public void AddSampleBank(string bankName)
|
public void SetSampleBank(string bankName)
|
||||||
{
|
{
|
||||||
if (SelectedItems.All(h => h.Samples.All(s => s.Bank == bankName)))
|
bool hasRelevantBank(HitObject hitObject)
|
||||||
|
{
|
||||||
|
bool result = hitObject.Samples.All(s => s.Bank == bankName);
|
||||||
|
|
||||||
|
if (hitObject is IHasRepeats hasRepeats)
|
||||||
|
{
|
||||||
|
foreach (var node in hasRepeats.NodeSamples)
|
||||||
|
result &= node.All(s => s.Bank == bankName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SelectedItems.All(hasRelevantBank))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EditorBeatmap.PerformOnSelection(h =>
|
EditorBeatmap.PerformOnSelection(h =>
|
||||||
@ -207,17 +233,37 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
h.Samples = h.Samples.Select(s => s.With(newBank: bankName)).ToList();
|
h.Samples = h.Samples.Select(s => s.With(newBank: bankName)).ToList();
|
||||||
|
|
||||||
|
if (h is IHasRepeats hasRepeats)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < hasRepeats.NodeSamples.Count; ++i)
|
||||||
|
hasRepeats.NodeSamples[i] = hasRepeats.NodeSamples[i].Select(s => s.With(newBank: bankName)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
EditorBeatmap.Update(h);
|
EditorBeatmap.Update(h);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool hasRelevantSample(HitObject hitObject, string sampleName)
|
||||||
|
{
|
||||||
|
bool result = hitObject.Samples.Any(s => s.Name == sampleName);
|
||||||
|
|
||||||
|
if (hitObject is IHasRepeats hasRepeats)
|
||||||
|
{
|
||||||
|
foreach (var node in hasRepeats.NodeSamples)
|
||||||
|
result &= node.Any(s => s.Name == sampleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a hit sample to all selected <see cref="HitObject"/>s.
|
/// Adds a hit sample to all selected <see cref="HitObject"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sampleName">The name of the hit sample.</param>
|
/// <param name="sampleName">The name of the hit sample.</param>
|
||||||
public void AddHitSample(string sampleName)
|
public void AddHitSample(string sampleName)
|
||||||
{
|
{
|
||||||
if (SelectedItems.All(h => h.Samples.Any(s => s.Name == sampleName)))
|
if (SelectedItems.All(h => hasRelevantSample(h, sampleName)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EditorBeatmap.PerformOnSelection(h =>
|
EditorBeatmap.PerformOnSelection(h =>
|
||||||
@ -228,6 +274,23 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
|
|
||||||
h.Samples.Add(h.CreateHitSampleInfo(sampleName));
|
h.Samples.Add(h.CreateHitSampleInfo(sampleName));
|
||||||
|
|
||||||
|
if (h is IHasRepeats hasRepeats)
|
||||||
|
{
|
||||||
|
foreach (var node in hasRepeats.NodeSamples)
|
||||||
|
{
|
||||||
|
if (node.Any(s => s.Name == sampleName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var hitSample = h.CreateHitSampleInfo(sampleName);
|
||||||
|
|
||||||
|
string? existingAdditionBank = node.FirstOrDefault(s => s.Name != HitSampleInfo.HIT_NORMAL)?.Bank;
|
||||||
|
if (existingAdditionBank != null)
|
||||||
|
hitSample = hitSample.With(newBank: existingAdditionBank);
|
||||||
|
|
||||||
|
node.Add(hitSample);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EditorBeatmap.Update(h);
|
EditorBeatmap.Update(h);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -238,12 +301,19 @@ 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)
|
||||||
{
|
{
|
||||||
if (SelectedItems.All(h => h.Samples.All(s => s.Name != sampleName)))
|
if (SelectedItems.All(h => !hasRelevantSample(h, sampleName)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EditorBeatmap.PerformOnSelection(h =>
|
EditorBeatmap.PerformOnSelection(h =>
|
||||||
{
|
{
|
||||||
h.SamplesBindable.RemoveAll(s => s.Name == sampleName);
|
h.SamplesBindable.RemoveAll(s => s.Name == sampleName);
|
||||||
|
|
||||||
|
if (h is IHasRepeats hasRepeats)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < hasRepeats.NodeSamples.Count; ++i)
|
||||||
|
hasRepeats.NodeSamples[i] = hasRepeats.NodeSamples[i].Where(s => s.Name != sampleName).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
EditorBeatmap.Update(h);
|
EditorBeatmap.Update(h);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user