mirror of
https://github.com/ppy/osu.git
synced 2025-01-28 20:32:55 +08:00
Merge branch 'master' into timeline-shift-click-selection
This commit is contained in:
commit
5466fb08fd
@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
|
|
||||||
// In 2B beatmaps, it is possible that a normal Fruit is placed in the middle of a JuiceStream.
|
// In 2B beatmaps, it is possible that a normal Fruit is placed in the middle of a JuiceStream.
|
||||||
foreach (var hitObject in beatmap.HitObjects
|
foreach (var hitObject in beatmap.HitObjects
|
||||||
.SelectMany(obj => obj is JuiceStream stream ? stream.NestedHitObjects : new[] { obj })
|
.SelectMany(obj => obj is JuiceStream stream ? stream.NestedHitObjects.AsEnumerable() : new[] { obj })
|
||||||
.Cast<CatchHitObject>()
|
.Cast<CatchHitObject>()
|
||||||
.OrderBy(x => x.StartTime))
|
.OrderBy(x => x.StartTime))
|
||||||
{
|
{
|
||||||
|
@ -149,7 +149,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
lowerBound ??= RandomStart;
|
lowerBound ??= RandomStart;
|
||||||
upperBound ??= TotalColumns;
|
upperBound ??= TotalColumns;
|
||||||
nextColumn ??= (_ => GetRandomColumn(lowerBound, upperBound));
|
nextColumn ??= _ => GetRandomColumn(lowerBound, upperBound);
|
||||||
|
|
||||||
// Check for the initial column
|
// Check for the initial column
|
||||||
if (isValid(initialColumn))
|
if (isValid(initialColumn))
|
||||||
@ -176,7 +176,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
return initialColumn;
|
return initialColumn;
|
||||||
|
|
||||||
bool isValid(int column) => validation?.Invoke(column) != false && !patterns.Any(p => p.ColumnHasObject(column));
|
bool isValid(int column)
|
||||||
|
{
|
||||||
|
if (validation?.Invoke(column) == false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (var p in patterns)
|
||||||
|
{
|
||||||
|
if (p.ColumnHasObject(column))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -12,46 +12,68 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class Pattern
|
internal class Pattern
|
||||||
{
|
{
|
||||||
private readonly List<ManiaHitObject> hitObjects = new List<ManiaHitObject>();
|
private List<ManiaHitObject> hitObjects;
|
||||||
|
private HashSet<int> containedColumns;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All the hit objects contained in this pattern.
|
/// All the hit objects contained in this pattern.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<ManiaHitObject> HitObjects => hitObjects;
|
public IEnumerable<ManiaHitObject> HitObjects => hitObjects ?? Enumerable.Empty<ManiaHitObject>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check whether a column of this patterns contains a hit object.
|
/// Check whether a column of this patterns contains a hit object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="column">The column index.</param>
|
/// <param name="column">The column index.</param>
|
||||||
/// <returns>Whether the column with index <paramref name="column"/> contains a hit object.</returns>
|
/// <returns>Whether the column with index <paramref name="column"/> contains a hit object.</returns>
|
||||||
public bool ColumnHasObject(int column) => hitObjects.Exists(h => h.Column == column);
|
public bool ColumnHasObject(int column) => containedColumns?.Contains(column) == true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Amount of columns taken up by hit objects in this pattern.
|
/// Amount of columns taken up by hit objects in this pattern.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ColumnWithObjects => HitObjects.GroupBy(h => h.Column).Count();
|
public int ColumnWithObjects => containedColumns?.Count ?? 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a hit object to this pattern.
|
/// Adds a hit object to this pattern.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hitObject">The hit object to add.</param>
|
/// <param name="hitObject">The hit object to add.</param>
|
||||||
public void Add(ManiaHitObject hitObject) => hitObjects.Add(hitObject);
|
public void Add(ManiaHitObject hitObject)
|
||||||
|
{
|
||||||
|
prepareStorage();
|
||||||
|
|
||||||
|
hitObjects.Add(hitObject);
|
||||||
|
containedColumns.Add(hitObject.Column);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Copies hit object from another pattern to this one.
|
/// Copies hit object from another pattern to this one.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="other">The other pattern.</param>
|
/// <param name="other">The other pattern.</param>
|
||||||
public void Add(Pattern other) => hitObjects.AddRange(other.HitObjects);
|
public void Add(Pattern other)
|
||||||
|
{
|
||||||
|
prepareStorage();
|
||||||
|
|
||||||
|
if (other.hitObjects != null)
|
||||||
|
{
|
||||||
|
hitObjects.AddRange(other.hitObjects);
|
||||||
|
|
||||||
|
foreach (var h in other.hitObjects)
|
||||||
|
containedColumns.Add(h.Column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clears this pattern, removing all hit objects.
|
/// Clears this pattern, removing all hit objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Clear() => hitObjects.Clear();
|
public void Clear()
|
||||||
|
{
|
||||||
|
hitObjects?.Clear();
|
||||||
|
containedColumns?.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
private void prepareStorage()
|
||||||
/// Removes a hit object from this pattern.
|
{
|
||||||
/// </summary>
|
hitObjects ??= new List<ManiaHitObject>();
|
||||||
/// <param name="hitObject">The hit object to remove.</param>
|
containedColumns ??= new HashSet<int>();
|
||||||
public bool Remove(ManiaHitObject hitObject) => hitObjects.Remove(hitObject);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions.ListExtensions;
|
||||||
|
using osu.Framework.Lists;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
@ -83,7 +84,7 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
private readonly List<HitObject> nestedHitObjects = new List<HitObject>();
|
private readonly List<HitObject> nestedHitObjects = new List<HitObject>();
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IReadOnlyList<HitObject> NestedHitObjects => nestedHitObjects;
|
public SlimReadOnlyListWrapper<HitObject> NestedHitObjects => nestedHitObjects.AsSlimReadOnly();
|
||||||
|
|
||||||
public HitObject()
|
public HitObject()
|
||||||
{
|
{
|
||||||
@ -91,7 +92,7 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
{
|
{
|
||||||
double offset = time.NewValue - time.OldValue;
|
double offset = time.NewValue - time.OldValue;
|
||||||
|
|
||||||
foreach (var nested in NestedHitObjects)
|
foreach (var nested in nestedHitObjects)
|
||||||
nested.StartTime += offset;
|
nested.StartTime += offset;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -122,13 +123,16 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
|
|
||||||
if (this is IHasComboInformation hasCombo)
|
if (this is IHasComboInformation hasCombo)
|
||||||
{
|
{
|
||||||
foreach (var n in NestedHitObjects.OfType<IHasComboInformation>())
|
foreach (HitObject hitObject in nestedHitObjects)
|
||||||
|
{
|
||||||
|
if (hitObject is IHasComboInformation n)
|
||||||
{
|
{
|
||||||
n.ComboIndexBindable.BindTo(hasCombo.ComboIndexBindable);
|
n.ComboIndexBindable.BindTo(hasCombo.ComboIndexBindable);
|
||||||
n.ComboIndexWithOffsetsBindable.BindTo(hasCombo.ComboIndexWithOffsetsBindable);
|
n.ComboIndexWithOffsetsBindable.BindTo(hasCombo.ComboIndexWithOffsetsBindable);
|
||||||
n.IndexInCurrentComboBindable.BindTo(hasCombo.IndexInCurrentComboBindable);
|
n.IndexInCurrentComboBindable.BindTo(hasCombo.IndexInCurrentComboBindable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nestedHitObjects.Sort((h1, h2) => h1.StartTime.CompareTo(h2.StartTime));
|
nestedHitObjects.Sort((h1, h2) => h1.StartTime.CompareTo(h2.StartTime));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user