mirror of
https://github.com/ppy/osu.git
synced 2025-03-28 00:07:20 +08:00
Merge branch 'master' into UserDimLogic
This commit is contained in:
commit
b2872b47d0
@ -83,8 +83,7 @@ namespace osu.Desktop
|
|||||||
public override void SetHost(GameHost host)
|
public override void SetHost(GameHost host)
|
||||||
{
|
{
|
||||||
base.SetHost(host);
|
base.SetHost(host);
|
||||||
var desktopWindow = host.Window as DesktopGameWindow;
|
if (host.Window is DesktopGameWindow desktopWindow)
|
||||||
if (desktopWindow != null)
|
|
||||||
{
|
{
|
||||||
desktopWindow.CursorState |= CursorState.Hidden;
|
desktopWindow.CursorState |= CursorState.Hidden;
|
||||||
|
|
||||||
|
@ -34,13 +34,16 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
case JuiceStream stream:
|
case JuiceStream stream:
|
||||||
foreach (var nested in stream.NestedHitObjects)
|
foreach (var nested in stream.NestedHitObjects)
|
||||||
yield return new ConvertValue((CatchHitObject)nested);
|
yield return new ConvertValue((CatchHitObject)nested);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case BananaShower shower:
|
case BananaShower shower:
|
||||||
foreach (var nested in shower.NestedHitObjects)
|
foreach (var nested in shower.NestedHitObjects)
|
||||||
yield return new ConvertValue((CatchHitObject)nested);
|
yield return new ConvertValue((CatchHitObject)nested);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
yield return new ConvertValue((CatchHitObject)hitObject);
|
yield return new ConvertValue((CatchHitObject)hitObject);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,8 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCaseCatchPlayer : Game.Tests.Visual.TestCasePlayer
|
public class TestCaseCatchPlayer : Game.Tests.Visual.TestCasePlayer
|
||||||
{
|
{
|
||||||
public TestCaseCatchPlayer() : base(new CatchRuleset())
|
public TestCaseCatchPlayer()
|
||||||
|
: base(new CatchRuleset())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
rng.Next(); // osu!stable retrieved a random banana rotation
|
rng.Next(); // osu!stable retrieved a random banana rotation
|
||||||
rng.Next(); // osu!stable retrieved a random banana colour
|
rng.Next(); // osu!stable retrieved a random banana colour
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case JuiceStream juiceStream:
|
case JuiceStream juiceStream:
|
||||||
foreach (var nested in juiceStream.NestedHitObjects)
|
foreach (var nested in juiceStream.NestedHitObjects)
|
||||||
@ -67,6 +68,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
rng.Next(); // osu!stable retrieved a random droplet rotation
|
rng.Next(); // osu!stable retrieved a random droplet rotation
|
||||||
hitObject.X = MathHelper.Clamp(hitObject.X, 0, 1);
|
hitObject.X = MathHelper.Clamp(hitObject.X, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,10 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
{
|
{
|
||||||
[Description("Move left")]
|
[Description("Move left")]
|
||||||
MoveLeft,
|
MoveLeft,
|
||||||
|
|
||||||
[Description("Move right")]
|
[Description("Move right")]
|
||||||
MoveRight,
|
MoveRight,
|
||||||
|
|
||||||
[Description("Engage dash")]
|
[Description("Engage dash")]
|
||||||
Dash,
|
Dash,
|
||||||
}
|
}
|
||||||
|
@ -68,14 +68,17 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
// We want to only consider fruits that contribute to the combo. Droplets are addressed as accuracy and spinners are not relevant for "skill" calculations.
|
// We want to only consider fruits that contribute to the combo. Droplets are addressed as accuracy and spinners are not relevant for "skill" calculations.
|
||||||
case Fruit fruit:
|
case Fruit fruit:
|
||||||
yield return new CatchDifficultyHitObject(fruit, lastObject, clockRate, halfCatchWidth);
|
yield return new CatchDifficultyHitObject(fruit, lastObject, clockRate, halfCatchWidth);
|
||||||
|
|
||||||
lastObject = hitObject;
|
lastObject = hitObject;
|
||||||
break;
|
break;
|
||||||
case JuiceStream _:
|
case JuiceStream _:
|
||||||
foreach (var nested in hitObject.NestedHitObjects.OfType<CatchHitObject>().Where(o => !(o is TinyDroplet)))
|
foreach (var nested in hitObject.NestedHitObjects.OfType<CatchHitObject>().Where(o => !(o is TinyDroplet)))
|
||||||
{
|
{
|
||||||
yield return new CatchDifficultyHitObject(nested, lastObject, clockRate, halfCatchWidth);
|
yield return new CatchDifficultyHitObject(nested, lastObject, clockRate, halfCatchWidth);
|
||||||
|
|
||||||
lastObject = nested;
|
lastObject = nested;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,11 @@ namespace osu.Game.Rulesets.Catch.MathUtils
|
|||||||
/// <returns>The random value.</returns>
|
/// <returns>The random value.</returns>
|
||||||
public uint NextUInt()
|
public uint NextUInt()
|
||||||
{
|
{
|
||||||
uint t = _x ^ _x << 11;
|
uint t = _x ^ (_x << 11);
|
||||||
_x = _y;
|
_x = _y;
|
||||||
_y = _z;
|
_y = _z;
|
||||||
_z = _w;
|
_z = _w;
|
||||||
return _w = _w ^ _w >> 19 ^ t ^ t >> 8;
|
return _w = _w ^ (_w >> 19) ^ t ^ (t >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
|
|
||||||
public override Color4 AccentColour
|
public override Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return base.AccentColour; }
|
get => base.AccentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.AccentColour = value;
|
base.AccentColour = value;
|
||||||
|
@ -23,9 +23,10 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Color4 accentColour;
|
private Color4 accentColour;
|
||||||
|
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return accentColour; }
|
get => accentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
public Container ExplodingFruitTarget
|
public Container ExplodingFruitTarget
|
||||||
{
|
{
|
||||||
set { MovableCatcher.ExplodingFruitTarget = value; }
|
set => MovableCatcher.ExplodingFruitTarget = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CatcherArea(BeatmapDifficulty difficulty = null)
|
public CatcherArea(BeatmapDifficulty difficulty = null)
|
||||||
@ -158,7 +158,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
protected bool Dashing
|
protected bool Dashing
|
||||||
{
|
{
|
||||||
get { return dashing; }
|
get => dashing;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == dashing) return;
|
if (value == dashing) return;
|
||||||
@ -176,7 +176,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected bool Trail
|
protected bool Trail
|
||||||
{
|
{
|
||||||
get { return trail; }
|
get => trail;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == trail) return;
|
if (value == trail) return;
|
||||||
|
@ -40,29 +40,29 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
protected override Ruleset CreateRuleset() => new ManiaRuleset();
|
protected override Ruleset CreateRuleset() => new ManiaRuleset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ManiaConvertMapping : ConvertMapping<ConvertValue>, IEquatable<ManiaConvertMapping>
|
public class ManiaConvertMapping : ConvertMapping<ConvertValue>, IEquatable<ManiaConvertMapping>
|
||||||
{
|
{
|
||||||
public uint RandomW;
|
public uint RandomW;
|
||||||
public uint RandomX;
|
public uint RandomX;
|
||||||
public uint RandomY;
|
public uint RandomY;
|
||||||
public uint RandomZ;
|
public uint RandomZ;
|
||||||
|
|
||||||
public ManiaConvertMapping()
|
public ManiaConvertMapping()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManiaConvertMapping(IBeatmapConverter converter)
|
public ManiaConvertMapping(IBeatmapConverter converter)
|
||||||
{
|
{
|
||||||
var maniaConverter = (ManiaBeatmapConverter)converter;
|
var maniaConverter = (ManiaBeatmapConverter)converter;
|
||||||
RandomW = maniaConverter.Random.W;
|
RandomW = maniaConverter.Random.W;
|
||||||
RandomX = maniaConverter.Random.X;
|
RandomX = maniaConverter.Random.X;
|
||||||
RandomY = maniaConverter.Random.Y;
|
RandomY = maniaConverter.Random.Y;
|
||||||
RandomZ = maniaConverter.Random.Z;
|
RandomZ = maniaConverter.Random.Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(ManiaConvertMapping other) => other != null && RandomW == other.RandomW && RandomX == other.RandomX && RandomY == other.RandomY && RandomZ == other.RandomZ;
|
public bool Equals(ManiaConvertMapping other) => other != null && RandomW == other.RandomW && RandomX == other.RandomX && RandomY == other.RandomY && RandomZ == other.RandomZ;
|
||||||
public override bool Equals(ConvertMapping<ConvertValue> other) => base.Equals(other) && Equals(other as ManiaConvertMapping);
|
public override bool Equals(ConvertMapping<ConvertValue> other) => base.Equals(other) && Equals(other as ManiaConvertMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ConvertValue : IEquatable<ConvertValue>
|
public struct ConvertValue : IEquatable<ConvertValue>
|
||||||
{
|
{
|
||||||
|
@ -74,10 +74,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
|
|
||||||
protected override IEnumerable<ManiaHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap)
|
protected override IEnumerable<ManiaHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
var maniaOriginal = original as ManiaHitObject;
|
if (original is ManiaHitObject maniaOriginal)
|
||||||
if (maniaOriginal != null)
|
|
||||||
{
|
{
|
||||||
yield return maniaOriginal;
|
yield return maniaOriginal;
|
||||||
|
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,6 +92,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
|
|
||||||
private readonly List<double> prevNoteTimes = new List<double>(max_notes_for_density);
|
private readonly List<double> prevNoteTimes = new List<double>(max_notes_for_density);
|
||||||
private double density = int.MaxValue;
|
private double density = int.MaxValue;
|
||||||
|
|
||||||
private void computeDensity(double newNoteTime)
|
private void computeDensity(double newNoteTime)
|
||||||
{
|
{
|
||||||
if (prevNoteTimes.Count == max_notes_for_density)
|
if (prevNoteTimes.Count == max_notes_for_density)
|
||||||
@ -104,6 +105,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
private double lastTime;
|
private double lastTime;
|
||||||
private Vector2 lastPosition;
|
private Vector2 lastPosition;
|
||||||
private PatternType lastStair = PatternType.Stair;
|
private PatternType lastStair = PatternType.Stair;
|
||||||
|
|
||||||
private void recordNote(double time, Vector2 position)
|
private void recordNote(double time, Vector2 position)
|
||||||
{
|
{
|
||||||
lastTime = time;
|
lastTime = time;
|
||||||
|
@ -65,6 +65,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if (originalPattern.HitObjects.Count() == 1)
|
if (originalPattern.HitObjects.Count() == 1)
|
||||||
{
|
{
|
||||||
yield return originalPattern;
|
yield return originalPattern;
|
||||||
|
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +136,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlag(PatternType.LowProbability))
|
||||||
return generateNRandomNotes(HitObject.StartTime, 0.78, 0.3, 0);
|
return generateNRandomNotes(HitObject.StartTime, 0.78, 0.3, 0);
|
||||||
|
|
||||||
return generateNRandomNotes(HitObject.StartTime, 0.85, 0.36, 0.03);
|
return generateNRandomNotes(HitObject.StartTime, 0.85, 0.36, 0.03);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +144,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlag(PatternType.LowProbability))
|
||||||
return generateNRandomNotes(HitObject.StartTime, 0.43, 0.08, 0);
|
return generateNRandomNotes(HitObject.StartTime, 0.43, 0.08, 0);
|
||||||
|
|
||||||
return generateNRandomNotes(HitObject.StartTime, 0.56, 0.18, 0);
|
return generateNRandomNotes(HitObject.StartTime, 0.56, 0.18, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,11 +152,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlag(PatternType.LowProbability))
|
||||||
return generateNRandomNotes(HitObject.StartTime, 0.3, 0, 0);
|
return generateNRandomNotes(HitObject.StartTime, 0.3, 0, 0);
|
||||||
|
|
||||||
return generateNRandomNotes(HitObject.StartTime, 0.37, 0.08, 0);
|
return generateNRandomNotes(HitObject.StartTime, 0.37, 0.08, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlag(PatternType.LowProbability))
|
||||||
return generateNRandomNotes(HitObject.StartTime, 0.17, 0, 0);
|
return generateNRandomNotes(HitObject.StartTime, 0.17, 0, 0);
|
||||||
|
|
||||||
return generateNRandomNotes(HitObject.StartTime, 0.27, 0, 0);
|
return generateNRandomNotes(HitObject.StartTime, 0.27, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,10 +116,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (convertType.HasFlag(PatternType.Cycle) && PreviousPattern.HitObjects.Count() == 1
|
if (convertType.HasFlag(PatternType.Cycle) && PreviousPattern.HitObjects.Count() == 1
|
||||||
// If we convert to 7K + 1, let's not overload the special key
|
// If we convert to 7K + 1, let's not overload the special key
|
||||||
&& (TotalColumns != 8 || lastColumn != 0)
|
&& (TotalColumns != 8 || lastColumn != 0)
|
||||||
// Make sure the last column was not the centre column
|
// Make sure the last column was not the centre column
|
||||||
&& (TotalColumns % 2 == 0 || lastColumn != TotalColumns / 2))
|
&& (TotalColumns % 2 == 0 || lastColumn != TotalColumns / 2))
|
||||||
{
|
{
|
||||||
// Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object)
|
// Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object)
|
||||||
int column = RandomStart + TotalColumns - lastColumn - 1;
|
int column = RandomStart + TotalColumns - lastColumn - 1;
|
||||||
@ -172,6 +172,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
return pattern = generateRandomPatternWithMirrored(0.12, 0.38, 0.12);
|
return pattern = generateRandomPatternWithMirrored(0.12, 0.38, 0.12);
|
||||||
if (ConversionDifficulty > 4)
|
if (ConversionDifficulty > 4)
|
||||||
return pattern = generateRandomPatternWithMirrored(0.12, 0.17, 0);
|
return pattern = generateRandomPatternWithMirrored(0.12, 0.17, 0);
|
||||||
|
|
||||||
return pattern = generateRandomPatternWithMirrored(0.12, 0, 0);
|
return pattern = generateRandomPatternWithMirrored(0.12, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,6 +180,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlag(PatternType.LowProbability))
|
||||||
return pattern = generateRandomPattern(0.78, 0.42, 0, 0);
|
return pattern = generateRandomPattern(0.78, 0.42, 0, 0);
|
||||||
|
|
||||||
return pattern = generateRandomPattern(1, 0.62, 0, 0);
|
return pattern = generateRandomPattern(1, 0.62, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +188,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlag(PatternType.LowProbability))
|
||||||
return pattern = generateRandomPattern(0.35, 0.08, 0, 0);
|
return pattern = generateRandomPattern(0.35, 0.08, 0, 0);
|
||||||
|
|
||||||
return pattern = generateRandomPattern(0.52, 0.15, 0, 0);
|
return pattern = generateRandomPattern(0.52, 0.15, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,6 +196,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlag(PatternType.LowProbability))
|
||||||
return pattern = generateRandomPattern(0.18, 0, 0, 0);
|
return pattern = generateRandomPattern(0.18, 0, 0, 0);
|
||||||
|
|
||||||
return pattern = generateRandomPattern(0.45, 0, 0, 0);
|
return pattern = generateRandomPattern(0.45, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,6 +254,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
last = GetRandomColumn();
|
last = GetRandomColumn();
|
||||||
|
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
return 4;
|
return 4;
|
||||||
if (val >= 1 - p3)
|
if (val >= 1 - p3)
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
return val >= 1 - p2 ? 2 : 1;
|
return val >= 1 - p2 ? 2 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,51 +12,63 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
internal enum PatternType
|
internal enum PatternType
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Keep the same as last row.
|
/// Keep the same as last row.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ForceStack = 1 << 0,
|
ForceStack = 1 << 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Keep different from last row.
|
/// Keep different from last row.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ForceNotStack = 1 << 1,
|
ForceNotStack = 1 << 1,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Keep as single note at its original position.
|
/// Keep as single note at its original position.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
KeepSingle = 1 << 2,
|
KeepSingle = 1 << 2,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use a lower random value.
|
/// Use a lower random value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
LowProbability = 1 << 3,
|
LowProbability = 1 << 3,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reserved.
|
/// Reserved.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Alternate = 1 << 4,
|
Alternate = 1 << 4,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ignore the repeat count.
|
/// Ignore the repeat count.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ForceSigSlider = 1 << 5,
|
ForceSigSlider = 1 << 5,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert slider to circle.
|
/// Convert slider to circle.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ForceNotSlider = 1 << 6,
|
ForceNotSlider = 1 << 6,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Notes gathered together.
|
/// Notes gathered together.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Gathered = 1 << 7,
|
Gathered = 1 << 7,
|
||||||
Mirror = 1 << 8,
|
Mirror = 1 << 8,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Change 0 -> 6.
|
/// Change 0 -> 6.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Reverse = 1 << 9,
|
Reverse = 1 << 9,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 1 -> 5 -> 1 -> 5 like reverse.
|
/// 1 -> 5 -> 1 -> 5 like reverse.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Cycle = 1 << 10,
|
Cycle = 1 << 10,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Next note will be at column + 1.
|
/// Next note will be at column + 1.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Stair = 1 << 11,
|
Stair = 1 << 11,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Next note will be at column - 1.
|
/// Next note will be at column - 1.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -114,8 +114,8 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
|||||||
// Lots of arbitrary values from testing.
|
// Lots of arbitrary values from testing.
|
||||||
// Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution
|
// Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution
|
||||||
double accuracyValue = Math.Max(0.0, 0.2 - (Attributes.GreatHitWindow - 34) * 0.006667)
|
double accuracyValue = Math.Max(0.0, 0.2 - (Attributes.GreatHitWindow - 34) * 0.006667)
|
||||||
* strainValue
|
* strainValue
|
||||||
* Math.Pow(Math.Max(0.0, scaledScore - 960000) / 40000, 1.1);
|
* Math.Pow(Math.Max(0.0, scaledScore - 960000) / 40000, 1.1);
|
||||||
|
|
||||||
// Bonus for many hitcircles - it's harder to keep good accuracy up for longer
|
// Bonus for many hitcircles - it's harder to keep good accuracy up for longer
|
||||||
// accuracyValue *= Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3));
|
// accuracyValue *= Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3));
|
||||||
|
@ -19,6 +19,7 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
{
|
{
|
||||||
[Description("Special 1")]
|
[Description("Special 1")]
|
||||||
Special1 = 1,
|
Special1 = 1,
|
||||||
|
|
||||||
[Description("Special 2")]
|
[Description("Special 2")]
|
||||||
Special2,
|
Special2,
|
||||||
|
|
||||||
@ -26,38 +27,55 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
// above at a later time, without breaking replays/configs.
|
// above at a later time, without breaking replays/configs.
|
||||||
[Description("Key 1")]
|
[Description("Key 1")]
|
||||||
Key1 = 10,
|
Key1 = 10,
|
||||||
|
|
||||||
[Description("Key 2")]
|
[Description("Key 2")]
|
||||||
Key2,
|
Key2,
|
||||||
|
|
||||||
[Description("Key 3")]
|
[Description("Key 3")]
|
||||||
Key3,
|
Key3,
|
||||||
|
|
||||||
[Description("Key 4")]
|
[Description("Key 4")]
|
||||||
Key4,
|
Key4,
|
||||||
|
|
||||||
[Description("Key 5")]
|
[Description("Key 5")]
|
||||||
Key5,
|
Key5,
|
||||||
|
|
||||||
[Description("Key 6")]
|
[Description("Key 6")]
|
||||||
Key6,
|
Key6,
|
||||||
|
|
||||||
[Description("Key 7")]
|
[Description("Key 7")]
|
||||||
Key7,
|
Key7,
|
||||||
|
|
||||||
[Description("Key 8")]
|
[Description("Key 8")]
|
||||||
Key8,
|
Key8,
|
||||||
|
|
||||||
[Description("Key 9")]
|
[Description("Key 9")]
|
||||||
Key9,
|
Key9,
|
||||||
|
|
||||||
[Description("Key 10")]
|
[Description("Key 10")]
|
||||||
Key10,
|
Key10,
|
||||||
|
|
||||||
[Description("Key 11")]
|
[Description("Key 11")]
|
||||||
Key11,
|
Key11,
|
||||||
|
|
||||||
[Description("Key 12")]
|
[Description("Key 12")]
|
||||||
Key12,
|
Key12,
|
||||||
|
|
||||||
[Description("Key 13")]
|
[Description("Key 13")]
|
||||||
Key13,
|
Key13,
|
||||||
|
|
||||||
[Description("Key 14")]
|
[Description("Key 14")]
|
||||||
Key14,
|
Key14,
|
||||||
|
|
||||||
[Description("Key 15")]
|
[Description("Key 15")]
|
||||||
Key15,
|
Key15,
|
||||||
|
|
||||||
[Description("Key 16")]
|
[Description("Key 16")]
|
||||||
Key16,
|
Key16,
|
||||||
|
|
||||||
[Description("Key 17")]
|
[Description("Key 17")]
|
||||||
Key17,
|
Key17,
|
||||||
|
|
||||||
[Description("Key 18")]
|
[Description("Key 18")]
|
||||||
Key18,
|
Key18,
|
||||||
}
|
}
|
||||||
|
@ -349,6 +349,7 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
/// Number of columns in this stage lies at (item - Single).
|
/// Number of columns in this stage lies at (item - Single).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Single = 0,
|
Single = 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Columns are grouped into two stages.
|
/// Columns are grouped into two stages.
|
||||||
/// Overall number of columns lies at (item - Dual), further computation is required for
|
/// Overall number of columns lies at (item - Dual), further computation is required for
|
||||||
|
@ -37,11 +37,11 @@ namespace osu.Game.Rulesets.Mania.MathUtils
|
|||||||
/// <returns>The random value.</returns>
|
/// <returns>The random value.</returns>
|
||||||
public uint NextUInt()
|
public uint NextUInt()
|
||||||
{
|
{
|
||||||
uint t = X ^ X << 11;
|
uint t = X ^ (X << 11);
|
||||||
X = Y;
|
X = Y;
|
||||||
Y = Z;
|
Y = Z;
|
||||||
Z = W;
|
Z = W;
|
||||||
return W = W ^ W >> 19 ^ t ^ t >> 8;
|
return W = W ^ (W >> 19) ^ t ^ (t >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
|
|
||||||
public override Color4 AccentColour
|
public override Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return base.AccentColour; }
|
get => base.AccentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.AccentColour = value;
|
base.AccentColour = value;
|
||||||
|
@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
|
|
||||||
public override Color4 AccentColour
|
public override Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return base.AccentColour; }
|
get => base.AccentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.AccentColour = value;
|
base.AccentColour = value;
|
||||||
|
@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
|
|
||||||
public override Color4 AccentColour
|
public override Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return base.AccentColour; }
|
get => base.AccentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.AccentColour = value;
|
base.AccentColour = value;
|
||||||
|
@ -77,11 +77,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return accentColour; }
|
get => accentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (accentColour == value)
|
if (accentColour == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
|
||||||
updateAccentColour();
|
updateAccentColour();
|
||||||
@ -90,7 +91,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
public bool Hitting
|
public bool Hitting
|
||||||
{
|
{
|
||||||
get { return hitting; }
|
get => hitting;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
hitting = value;
|
hitting = value;
|
||||||
|
@ -35,13 +35,15 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Color4 accentColour;
|
private Color4 accentColour;
|
||||||
|
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return accentColour; }
|
get => accentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (accentColour == value)
|
if (accentColour == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
|
||||||
updateGlow();
|
updateGlow();
|
||||||
|
@ -78,8 +78,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return Colour; }
|
get => Colour;
|
||||||
set { Colour = value; }
|
set => Colour = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,13 +56,15 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Color4 accentColour;
|
private Color4 accentColour;
|
||||||
|
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return accentColour; }
|
get => accentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (accentColour == value)
|
if (accentColour == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
|
||||||
colouredBox.Colour = AccentColour.Lighten(0.9f);
|
colouredBox.Colour = AccentColour.Lighten(0.9f);
|
||||||
|
@ -17,9 +17,10 @@ namespace osu.Game.Rulesets.Mania.Objects
|
|||||||
public double EndTime => StartTime + Duration;
|
public double EndTime => StartTime + Duration;
|
||||||
|
|
||||||
private double duration;
|
private double duration;
|
||||||
|
|
||||||
public double Duration
|
public double Duration
|
||||||
{
|
{
|
||||||
get { return duration; }
|
get => duration;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
duration = value;
|
duration = value;
|
||||||
@ -29,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Objects
|
|||||||
|
|
||||||
public override double StartTime
|
public override double StartTime
|
||||||
{
|
{
|
||||||
get { return base.StartTime; }
|
get => base.StartTime;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.StartTime = value;
|
base.StartTime = value;
|
||||||
@ -40,7 +41,7 @@ namespace osu.Game.Rulesets.Mania.Objects
|
|||||||
|
|
||||||
public override int Column
|
public override int Column
|
||||||
{
|
{
|
||||||
get { return base.Column; }
|
get => base.Column;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.Column = value;
|
base.Column = value;
|
||||||
|
@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Mania.Objects
|
|||||||
private static readonly IReadOnlyDictionary<HitResult, (double od0, double od5, double od10)> base_ranges = new Dictionary<HitResult, (double, double, double)>
|
private static readonly IReadOnlyDictionary<HitResult, (double od0, double od5, double od10)> base_ranges = new Dictionary<HitResult, (double, double, double)>
|
||||||
{
|
{
|
||||||
{ HitResult.Perfect, (44.8, 38.8, 27.8) },
|
{ HitResult.Perfect, (44.8, 38.8, 27.8) },
|
||||||
{ HitResult.Great, (128, 98, 68 ) },
|
{ HitResult.Great, (128, 98, 68) },
|
||||||
{ HitResult.Good, (194, 164, 134) },
|
{ HitResult.Good, (194, 164, 134) },
|
||||||
{ HitResult.Ok, (254, 224, 194) },
|
{ HitResult.Ok, (254, 224, 194) },
|
||||||
{ HitResult.Meh, (302, 272, 242) },
|
{ HitResult.Meh, (302, 272, 242) },
|
||||||
|
@ -97,13 +97,15 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
public override Axes RelativeSizeAxes => Axes.Y;
|
public override Axes RelativeSizeAxes => Axes.Y;
|
||||||
|
|
||||||
private bool isSpecial;
|
private bool isSpecial;
|
||||||
|
|
||||||
public bool IsSpecial
|
public bool IsSpecial
|
||||||
{
|
{
|
||||||
get { return isSpecial; }
|
get => isSpecial;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (isSpecial == value)
|
if (isSpecial == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
isSpecial = value;
|
isSpecial = value;
|
||||||
|
|
||||||
Width = isSpecial ? special_column_width : column_width;
|
Width = isSpecial ? special_column_width : column_width;
|
||||||
@ -111,13 +113,15 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Color4 accentColour;
|
private Color4 accentColour;
|
||||||
|
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return accentColour; }
|
get => accentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (accentColour == value)
|
if (accentColour == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
|
||||||
background.AccentColour = value;
|
background.AccentColour = value;
|
||||||
|
@ -70,6 +70,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
|||||||
{
|
{
|
||||||
if (accentColour == value)
|
if (accentColour == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
|
||||||
updateColours();
|
updateColours();
|
||||||
|
@ -73,6 +73,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
|||||||
{
|
{
|
||||||
if (accentColour == value)
|
if (accentColour == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
|
||||||
updateColours();
|
updateColours();
|
||||||
|
@ -87,6 +87,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
|||||||
{
|
{
|
||||||
if (accentColour == value)
|
if (accentColour == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
|
||||||
updateColours();
|
updateColours();
|
||||||
|
@ -33,9 +33,11 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
case Slider slider:
|
case Slider slider:
|
||||||
foreach (var nested in slider.NestedHitObjects)
|
foreach (var nested in slider.NestedHitObjects)
|
||||||
yield return createConvertValue(nested);
|
yield return createConvertValue(nested);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
yield return createConvertValue(hitObject);
|
yield return createConvertValue(hitObject);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
private GameplayCursor cursor;
|
private GameplayCursor cursor;
|
||||||
|
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new [] { typeof(CursorTrail) };
|
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(CursorTrail) };
|
||||||
|
|
||||||
public CursorContainer Cursor => cursor;
|
public CursorContainer Cursor => cursor;
|
||||||
|
|
||||||
|
@ -89,7 +89,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
private readonly bool auto;
|
private readonly bool auto;
|
||||||
|
|
||||||
public TestDrawableHitCircle(HitCircle h, bool auto) : base(h)
|
public TestDrawableHitCircle(HitCircle h, bool auto)
|
||||||
|
: base(h)
|
||||||
{
|
{
|
||||||
this.auto = auto;
|
this.auto = auto;
|
||||||
}
|
}
|
||||||
|
@ -301,6 +301,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
private float judgementOffsetDirection = 1;
|
private float judgementOffsetDirection = 1;
|
||||||
|
|
||||||
private void onNewResult(DrawableHitObject judgedObject, JudgementResult result)
|
private void onNewResult(DrawableHitObject judgedObject, JudgementResult result)
|
||||||
{
|
{
|
||||||
var osuObject = judgedObject as DrawableOsuHitObject;
|
var osuObject = judgedObject as DrawableOsuHitObject;
|
||||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
public class TestCaseSpinner : OsuTestCase
|
public class TestCaseSpinner : OsuTestCase
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
{
|
{
|
||||||
typeof(SpinnerDisc),
|
typeof(SpinnerDisc),
|
||||||
typeof(DrawableSpinner),
|
typeof(DrawableSpinner),
|
||||||
typeof(DrawableOsuHitObject)
|
typeof(DrawableOsuHitObject)
|
||||||
@ -67,7 +67,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
private bool auto;
|
private bool auto;
|
||||||
|
|
||||||
public TestDrawableSpinner(Spinner s, bool auto) : base(s)
|
public TestDrawableSpinner(Spinner s, bool auto)
|
||||||
|
: base(s)
|
||||||
{
|
{
|
||||||
this.auto = auto;
|
this.auto = auto;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
|
|
||||||
// Longer maps are worth more
|
// Longer maps are worth more
|
||||||
double lengthBonus = 0.95f + 0.4f * Math.Min(1.0f, totalHits / 2000.0f) +
|
double lengthBonus = 0.95f + 0.4f * Math.Min(1.0f, totalHits / 2000.0f) +
|
||||||
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0f) * 0.5f : 0.0f);
|
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0f) * 0.5f : 0.0f);
|
||||||
|
|
||||||
aimValue *= lengthBonus;
|
aimValue *= lengthBonus;
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
approachRateFactor += 0.3f * (Attributes.ApproachRate - 10.33f);
|
approachRateFactor += 0.3f * (Attributes.ApproachRate - 10.33f);
|
||||||
else if (Attributes.ApproachRate < 8.0f)
|
else if (Attributes.ApproachRate < 8.0f)
|
||||||
{
|
{
|
||||||
approachRateFactor += 0.01f * (8.0f - Attributes.ApproachRate);
|
approachRateFactor += 0.01f * (8.0f - Attributes.ApproachRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
aimValue *= approachRateFactor;
|
aimValue *= approachRateFactor;
|
||||||
@ -126,8 +126,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
{
|
{
|
||||||
// Apply object-based bonus for flashlight.
|
// Apply object-based bonus for flashlight.
|
||||||
aimValue *= 1.0f + 0.35f * Math.Min(1.0f, totalHits / 200.0f) +
|
aimValue *= 1.0f + 0.35f * Math.Min(1.0f, totalHits / 200.0f) +
|
||||||
(totalHits > 200 ? 0.3f * Math.Min(1.0f, (totalHits - 200) / 300.0f) +
|
(totalHits > 200
|
||||||
(totalHits > 500 ? (totalHits - 500) / 1200.0f : 0.0f) : 0.0f);
|
? 0.3f * Math.Min(1.0f, (totalHits - 200) / 300.0f) +
|
||||||
|
(totalHits > 500 ? (totalHits - 500) / 1200.0f : 0.0f)
|
||||||
|
: 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scale the aim value with accuracy _slightly_
|
// Scale the aim value with accuracy _slightly_
|
||||||
@ -144,7 +146,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
|
|
||||||
// Longer maps are worth more
|
// Longer maps are worth more
|
||||||
speedValue *= 0.95f + 0.4f * Math.Min(1.0f, totalHits / 2000.0f) +
|
speedValue *= 0.95f + 0.4f * Math.Min(1.0f, totalHits / 2000.0f) +
|
||||||
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0f) * 0.5f : 0.0f);
|
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0f) * 0.5f : 0.0f);
|
||||||
|
|
||||||
// Penalize misses exponentially. This mainly fixes tag4 maps and the likes until a per-hitobject solution is available
|
// Penalize misses exponentially. This mainly fixes tag4 maps and the likes until a per-hitobject solution is available
|
||||||
speedValue *= Math.Pow(0.97f, countMiss);
|
speedValue *= Math.Pow(0.97f, countMiss);
|
||||||
|
@ -92,6 +92,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
{
|
{
|
||||||
if (slider.LazyEndPosition != null)
|
if (slider.LazyEndPosition != null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
slider.LazyEndPosition = slider.StackedPosition;
|
slider.LazyEndPosition = slider.StackedPosition;
|
||||||
|
|
||||||
float approxFollowCircleRadius = (float)(slider.Radius * 3);
|
float approxFollowCircleRadius = (float)(slider.Radius * 3);
|
||||||
@ -127,8 +128,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
{
|
{
|
||||||
Vector2 pos = hitObject.StackedPosition;
|
Vector2 pos = hitObject.StackedPosition;
|
||||||
|
|
||||||
var slider = hitObject as Slider;
|
if (hitObject is Slider slider)
|
||||||
if (slider != null)
|
|
||||||
{
|
{
|
||||||
computeSliderCursorPosition(slider);
|
computeSliderCursorPosition(slider);
|
||||||
pos = slider.LazyEndPosition ?? pos;
|
pos = slider.LazyEndPosition ?? pos;
|
||||||
|
@ -9,8 +9,10 @@ namespace osu.Game.Rulesets.Osu.Judgements
|
|||||||
{
|
{
|
||||||
[Description(@"")]
|
[Description(@"")]
|
||||||
None,
|
None,
|
||||||
|
|
||||||
[Description(@"Good")]
|
[Description(@"Good")]
|
||||||
Good,
|
Good,
|
||||||
|
|
||||||
[Description(@"Amazing")]
|
[Description(@"Amazing")]
|
||||||
Perfect
|
Perfect
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
foreach (var drawable in drawables)
|
foreach (var drawable in drawables)
|
||||||
{
|
{
|
||||||
var hitObject = (OsuHitObject) drawable.HitObject;
|
var hitObject = (OsuHitObject)drawable.HitObject;
|
||||||
|
|
||||||
float appearDistance = (float)(hitObject.TimePreempt - hitObject.TimeFadeIn) / 2;
|
float appearDistance = (float)(hitObject.TimePreempt - hitObject.TimeFadeIn) / 2;
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
.MoveTo(originalPosition, moveDuration, Easing.InOutSine);
|
.MoveTo(originalPosition, moveDuration, Easing.InOutSine);
|
||||||
}
|
}
|
||||||
|
|
||||||
theta += (float) hitObject.TimeFadeIn / 1000;
|
theta += (float)hitObject.TimeFadeIn / 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connects hit objects visually, for example with follow points.
|
/// Connects hit objects visually, for example with follow points.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class ConnectionRenderer<T> : Container
|
public abstract class ConnectionRenderer<T> : LifetimeManagementContainer
|
||||||
where T : HitObject
|
where T : HitObject
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -12,39 +12,44 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
|||||||
public class FollowPointRenderer : ConnectionRenderer<OsuHitObject>
|
public class FollowPointRenderer : ConnectionRenderer<OsuHitObject>
|
||||||
{
|
{
|
||||||
private int pointDistance = 32;
|
private int pointDistance = 32;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines how much space there is between points.
|
/// Determines how much space there is between points.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int PointDistance
|
public int PointDistance
|
||||||
{
|
{
|
||||||
get { return pointDistance; }
|
get => pointDistance;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (pointDistance == value) return;
|
if (pointDistance == value) return;
|
||||||
|
|
||||||
pointDistance = value;
|
pointDistance = value;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int preEmpt = 800;
|
private int preEmpt = 800;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Follow points to the next hitobject start appearing for this many milliseconds before an hitobject's end time.
|
/// Follow points to the next hitobject start appearing for this many milliseconds before an hitobject's end time.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int PreEmpt
|
public int PreEmpt
|
||||||
{
|
{
|
||||||
get { return preEmpt; }
|
get => preEmpt;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (preEmpt == value) return;
|
if (preEmpt == value) return;
|
||||||
|
|
||||||
preEmpt = value;
|
preEmpt = value;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<OsuHitObject> hitObjects;
|
private IEnumerable<OsuHitObject> hitObjects;
|
||||||
|
|
||||||
public override IEnumerable<OsuHitObject> HitObjects
|
public override IEnumerable<OsuHitObject> HitObjects
|
||||||
{
|
{
|
||||||
get { return hitObjects; }
|
get => hitObjects;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
hitObjects = value;
|
hitObjects = value;
|
||||||
@ -56,7 +61,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
|||||||
|
|
||||||
private void update()
|
private void update()
|
||||||
{
|
{
|
||||||
Clear();
|
ClearInternal();
|
||||||
|
|
||||||
if (hitObjects == null)
|
if (hitObjects == null)
|
||||||
return;
|
return;
|
||||||
@ -86,7 +91,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
|||||||
|
|
||||||
FollowPoint fp;
|
FollowPoint fp;
|
||||||
|
|
||||||
Add(fp = new FollowPoint
|
AddInternal(fp = new FollowPoint
|
||||||
{
|
{
|
||||||
Position = pointStartPosition,
|
Position = pointStartPosition,
|
||||||
Rotation = rotation,
|
Rotation = rotation,
|
||||||
@ -107,6 +112,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
|||||||
fp.Expire(true);
|
fp.Expire(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prevHitObject = currHitObject;
|
prevHitObject = currHitObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
public override Color4 AccentColour
|
public override Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return base.AccentColour; }
|
get => base.AccentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.AccentColour = value;
|
base.AccentColour = value;
|
||||||
@ -139,6 +139,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadeIn * 2, HitObject.TimePreempt));
|
ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadeIn * 2, HitObject.TimePreempt));
|
||||||
ApproachCircle.ScaleTo(1.1f, HitObject.TimePreempt);
|
ApproachCircle.ScaleTo(1.1f, HitObject.TimePreempt);
|
||||||
|
ApproachCircle.Expire(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateCurrentState(ArmedState state)
|
protected override void UpdateCurrentState(ArmedState state)
|
||||||
|
@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
public override Color4 AccentColour
|
public override Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return base.AccentColour; }
|
get => base.AccentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.AccentColour = value;
|
base.AccentColour = value;
|
||||||
|
@ -20,7 +20,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
public override bool DisplayResult => false;
|
public override bool DisplayResult => false;
|
||||||
|
|
||||||
public DrawableSliderTick(SliderTick sliderTick) : base(sliderTick)
|
public DrawableSliderTick(SliderTick sliderTick)
|
||||||
|
: base(sliderTick)
|
||||||
{
|
{
|
||||||
Size = new Vector2(16) * sliderTick.Scale;
|
Size = new Vector2(16) * sliderTick.Scale;
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
@ -42,7 +42,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
private Color4 normalColour;
|
private Color4 normalColour;
|
||||||
private Color4 completeColour;
|
private Color4 completeColour;
|
||||||
|
|
||||||
public DrawableSpinner(Spinner s) : base(s)
|
public DrawableSpinner(Spinner s)
|
||||||
|
: base(s)
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
Position = s.Position;
|
Position = s.Position;
|
||||||
|
@ -12,6 +12,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
{
|
{
|
||||||
public class ApproachCircle : Container
|
public class ApproachCircle : Container
|
||||||
{
|
{
|
||||||
|
public override bool RemoveWhenNotAlive => false;
|
||||||
|
|
||||||
public ApproachCircle()
|
public ApproachCircle()
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre;
|
Anchor = Anchor.Centre;
|
||||||
|
@ -18,8 +18,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
public string Text
|
public string Text
|
||||||
{
|
{
|
||||||
get { return number.Text; }
|
get => number.Text;
|
||||||
set { number.Text = value; }
|
set => number.Text = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NumberPiece()
|
public NumberPiece()
|
||||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return accentColour; }
|
get => accentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
@ -136,11 +136,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
public bool Tracking
|
public bool Tracking
|
||||||
{
|
{
|
||||||
get { return tracking; }
|
get => tracking;
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
if (value == tracking)
|
if (value == tracking)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tracking = value;
|
tracking = value;
|
||||||
|
|
||||||
FollowCircle.ScaleTo(tracking ? 2f : 1, 300, Easing.OutQuint);
|
FollowCircle.ScaleTo(tracking ? 2f : 1, 300, Easing.OutQuint);
|
||||||
|
@ -40,6 +40,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
{
|
{
|
||||||
if (path.AccentColour == value)
|
if (path.AccentColour == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
path.AccentColour = value;
|
path.AccentColour = value;
|
||||||
|
|
||||||
container.ForceRedraw();
|
container.ForceRedraw();
|
||||||
@ -56,6 +57,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
{
|
{
|
||||||
if (path.BorderColour == value)
|
if (path.BorderColour == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
path.BorderColour = value;
|
path.BorderColour = value;
|
||||||
|
|
||||||
container.ForceRedraw();
|
container.ForceRedraw();
|
||||||
@ -105,6 +107,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
{
|
{
|
||||||
if (borderColour == value)
|
if (borderColour == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
borderColour = value;
|
borderColour = value;
|
||||||
|
|
||||||
InvalidateTexture();
|
InvalidateTexture();
|
||||||
@ -120,6 +123,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
{
|
{
|
||||||
if (accentColour == value)
|
if (accentColour == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
|
||||||
InvalidateTexture();
|
InvalidateTexture();
|
||||||
|
@ -15,10 +15,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
{
|
{
|
||||||
get
|
get => Disc.Colour;
|
||||||
{
|
|
||||||
return Disc.Colour;
|
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Disc.Colour = value;
|
Disc.Colour = value;
|
||||||
|
@ -17,8 +17,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return background.AccentColour; }
|
get => background.AccentColour;
|
||||||
set { background.AccentColour = value; }
|
set => background.AccentColour = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly SpinnerBackground background;
|
private readonly SpinnerBackground background;
|
||||||
@ -43,12 +43,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
||||||
|
|
||||||
private bool tracking;
|
private bool tracking;
|
||||||
|
|
||||||
public bool Tracking
|
public bool Tracking
|
||||||
{
|
{
|
||||||
get { return tracking; }
|
get => tracking;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == tracking) return;
|
if (value == tracking) return;
|
||||||
|
|
||||||
tracking = value;
|
tracking = value;
|
||||||
|
|
||||||
background.FadeTo(tracking ? tracking_alpha : idle_alpha, 100);
|
background.FadeTo(tracking ? tracking_alpha : idle_alpha, 100);
|
||||||
@ -56,12 +58,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bool complete;
|
private bool complete;
|
||||||
|
|
||||||
public bool Complete
|
public bool Complete
|
||||||
{
|
{
|
||||||
get { return complete; }
|
get => complete;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == complete) return;
|
if (value == complete) return;
|
||||||
|
|
||||||
complete = value;
|
complete = value;
|
||||||
|
|
||||||
updateCompleteTick();
|
updateCompleteTick();
|
||||||
|
@ -41,10 +41,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
public double SpinsPerMinute
|
public double SpinsPerMinute
|
||||||
{
|
{
|
||||||
get { return spm; }
|
get => spm;
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
if (value == spm) return;
|
if (value == spm) return;
|
||||||
|
|
||||||
spm = value;
|
spm = value;
|
||||||
spmText.Text = Math.Truncate(value).ToString(@"#0");
|
spmText.Text = Math.Truncate(value).ToString(@"#0");
|
||||||
}
|
}
|
||||||
|
@ -262,6 +262,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
{
|
{
|
||||||
if (nodeIndex < NodeSamples.Count)
|
if (nodeIndex < NodeSamples.Count)
|
||||||
return NodeSamples[nodeIndex];
|
return NodeSamples[nodeIndex];
|
||||||
|
|
||||||
return Samples;
|
return Samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
protected override bool Handle(UIEvent e)
|
protected override bool Handle(UIEvent e)
|
||||||
{
|
{
|
||||||
if (!AllowUserPresses) return false;
|
if (!AllowUserPresses) return false;
|
||||||
|
|
||||||
return base.Handle(e);
|
return base.Handle(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,8 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
new OsuModAutopilot(),
|
new OsuModAutopilot(),
|
||||||
};
|
};
|
||||||
case ModType.Fun:
|
case ModType.Fun:
|
||||||
return new Mod[] {
|
return new Mod[]
|
||||||
|
{
|
||||||
new OsuModTransform(),
|
new OsuModTransform(),
|
||||||
new OsuModWiggle(),
|
new OsuModWiggle(),
|
||||||
new OsuModGrow()
|
new OsuModGrow()
|
||||||
|
@ -209,7 +209,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
// Only "snap" to hitcircles if they are far enough apart. As the time between hitcircles gets shorter the snapping threshold goes up.
|
// Only "snap" to hitcircles if they are far enough apart. As the time between hitcircles gets shorter the snapping threshold goes up.
|
||||||
if (timeDifference > 0 && // Sanity checks
|
if (timeDifference > 0 && // Sanity checks
|
||||||
((lastPosition - targetPos).Length > h.Radius * (1.5 + 100.0 / timeDifference) || // Either the distance is big enough
|
((lastPosition - targetPos).Length > h.Radius * (1.5 + 100.0 / timeDifference) || // Either the distance is big enough
|
||||||
timeDifference >= 266)) // ... or the beats are slow enough to tap anyway.
|
timeDifference >= 266)) // ... or the beats are slow enough to tap anyway.
|
||||||
{
|
{
|
||||||
// Perform eased movement
|
// Perform eased movement
|
||||||
for (double time = lastFrame.Time + FrameDelay; time < h.StartTime; time += FrameDelay)
|
for (double time = lastFrame.Time + FrameDelay; time < h.StartTime; time += FrameDelay)
|
||||||
|
@ -20,6 +20,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
/// Constants (for spinners).
|
/// Constants (for spinners).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected static readonly Vector2 SPINNER_CENTRE = OsuPlayfield.BASE_SIZE / 2;
|
protected static readonly Vector2 SPINNER_CENTRE = OsuPlayfield.BASE_SIZE / 2;
|
||||||
|
|
||||||
protected const float SPIN_RADIUS = 50;
|
protected const float SPIN_RADIUS = 50;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -46,6 +47,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Utilities
|
#region Utilities
|
||||||
|
|
||||||
protected double ApplyModsToTime(double v) => v;
|
protected double ApplyModsToTime(double v) => v;
|
||||||
protected double ApplyModsToRate(double v) => v;
|
protected double ApplyModsToRate(double v) => v;
|
||||||
|
|
||||||
|
@ -255,10 +255,13 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
{
|
{
|
||||||
[VertexMember(2, VertexAttribPointerType.Float)]
|
[VertexMember(2, VertexAttribPointerType.Float)]
|
||||||
public Vector2 Position;
|
public Vector2 Position;
|
||||||
|
|
||||||
[VertexMember(4, VertexAttribPointerType.Float)]
|
[VertexMember(4, VertexAttribPointerType.Float)]
|
||||||
public Color4 Colour;
|
public Color4 Colour;
|
||||||
|
|
||||||
[VertexMember(2, VertexAttribPointerType.Float)]
|
[VertexMember(2, VertexAttribPointerType.Float)]
|
||||||
public Vector2 TexturePosition;
|
public Vector2 TexturePosition;
|
||||||
|
|
||||||
[VertexMember(1, VertexAttribPointerType.Float)]
|
[VertexMember(1, VertexAttribPointerType.Float)]
|
||||||
public float Time;
|
public float Time;
|
||||||
|
|
||||||
|
@ -213,6 +213,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
public void Expand()
|
public void Expand()
|
||||||
{
|
{
|
||||||
if (!cursorExpand) return;
|
if (!cursorExpand) return;
|
||||||
|
|
||||||
expandTarget.ScaleTo(released_scale).ScaleTo(pressed_scale, 100, Easing.OutQuad);
|
expandTarget.ScaleTo(released_scale).ScaleTo(pressed_scale, 100, Easing.OutQuad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
{
|
{
|
||||||
public class OsuPlayfield : Playfield
|
public class OsuPlayfield : Playfield
|
||||||
{
|
{
|
||||||
private readonly Container approachCircles;
|
private readonly ApproachCircleProxyContainer approachCircles;
|
||||||
private readonly JudgementContainer<DrawableOsuJudgement> judgementLayer;
|
private readonly JudgementContainer<DrawableOsuJudgement> judgementLayer;
|
||||||
private readonly ConnectionRenderer<OsuHitObject> connectionLayer;
|
private readonly ConnectionRenderer<OsuHitObject> connectionLayer;
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
Depth = 1,
|
Depth = 1,
|
||||||
},
|
},
|
||||||
HitObjectContainer,
|
HitObjectContainer,
|
||||||
approachCircles = new Container
|
approachCircles = new ApproachCircleProxyContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Depth = -1,
|
Depth = -1,
|
||||||
@ -58,13 +58,26 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
{
|
{
|
||||||
h.OnNewResult += onNewResult;
|
h.OnNewResult += onNewResult;
|
||||||
|
|
||||||
var c = h as IDrawableHitObjectWithProxiedApproach;
|
if (h is IDrawableHitObjectWithProxiedApproach c)
|
||||||
if (c != null)
|
{
|
||||||
approachCircles.Add(c.ProxiedLayer.CreateProxy());
|
var original = c.ProxiedLayer;
|
||||||
|
|
||||||
|
// Hitobjects only have lifetimes set on LoadComplete. For nested hitobjects (e.g. SliderHeads), this only happens when the parenting slider becomes visible.
|
||||||
|
// This delegation is required to make sure that the approach circles for those not-yet-loaded objects aren't added prematurely.
|
||||||
|
original.OnLoadComplete += addApproachCircleProxy;
|
||||||
|
}
|
||||||
|
|
||||||
base.Add(h);
|
base.Add(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addApproachCircleProxy(Drawable d)
|
||||||
|
{
|
||||||
|
var proxy = d.CreateProxy();
|
||||||
|
proxy.LifetimeStart = d.LifetimeStart;
|
||||||
|
proxy.LifetimeEnd = d.LifetimeEnd;
|
||||||
|
approachCircles.Add(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
public override void PostProcess()
|
public override void PostProcess()
|
||||||
{
|
{
|
||||||
connectionLayer.HitObjects = HitObjectContainer.Objects.Select(d => d.HitObject).OfType<OsuHitObject>();
|
connectionLayer.HitObjects = HitObjectContainer.Objects.Select(d => d.HitObject).OfType<OsuHitObject>();
|
||||||
@ -86,5 +99,10 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => HitObjectContainer.ReceivePositionalInputAt(screenSpacePos);
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => HitObjectContainer.ReceivePositionalInputAt(screenSpacePos);
|
||||||
|
|
||||||
|
private class ApproachCircleProxyContainer : LifetimeManagementContainer
|
||||||
|
{
|
||||||
|
public void Add(Drawable approachCircleProxy) => AddInternal(approachCircleProxy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,6 +229,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
// Ensure alternating centre and rim hits
|
// Ensure alternating centre and rim hits
|
||||||
if (lastWasCentre == isCentre)
|
if (lastWasCentre == isCentre)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
lastWasCentre = isCentre;
|
lastWasCentre = isCentre;
|
||||||
|
|
||||||
UpdateResult(true);
|
UpdateResult(true);
|
||||||
|
@ -49,6 +49,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
protected void ProxyContent()
|
protected void ProxyContent()
|
||||||
{
|
{
|
||||||
if (isProxied) return;
|
if (isProxied) return;
|
||||||
|
|
||||||
isProxied = true;
|
isProxied = true;
|
||||||
|
|
||||||
nonProxiedContent.Remove(Content);
|
nonProxiedContent.Remove(Content);
|
||||||
@ -62,6 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
protected void UnproxyContent()
|
protected void UnproxyContent()
|
||||||
{
|
{
|
||||||
if (!isProxied) return;
|
if (!isProxied) return;
|
||||||
|
|
||||||
isProxied = false;
|
isProxied = false;
|
||||||
|
|
||||||
proxiedContent.Remove(Content);
|
proxiedContent.Remove(Content);
|
||||||
|
@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public override Color4 AccentColour
|
public override Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return base.AccentColour; }
|
get => base.AccentColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.AccentColour = value;
|
base.AccentColour = value;
|
||||||
@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public override bool KiaiMode
|
public override bool KiaiMode
|
||||||
{
|
{
|
||||||
get { return base.KiaiMode; }
|
get => base.KiaiMode;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.KiaiMode = value;
|
base.KiaiMode = value;
|
||||||
|
@ -11,26 +11,25 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
|||||||
public class TaikoPiece : BeatSyncedContainer, IHasAccentColour
|
public class TaikoPiece : BeatSyncedContainer, IHasAccentColour
|
||||||
{
|
{
|
||||||
private Color4 accentColour;
|
private Color4 accentColour;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The colour of the inner circle and outer glows.
|
/// The colour of the inner circle and outer glows.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual Color4 AccentColour
|
public virtual Color4 AccentColour
|
||||||
{
|
{
|
||||||
get { return accentColour; }
|
get => accentColour;
|
||||||
set { accentColour = value; }
|
set => accentColour = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool kiaiMode;
|
private bool kiaiMode;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether Kiai mode effects are enabled for this circle piece.
|
/// Whether Kiai mode effects are enabled for this circle piece.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual bool KiaiMode
|
public virtual bool KiaiMode
|
||||||
{
|
{
|
||||||
get { return kiaiMode; }
|
get => kiaiMode;
|
||||||
set
|
set => kiaiMode = value;
|
||||||
{
|
|
||||||
kiaiMode = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaikoPiece()
|
public TaikoPiece()
|
||||||
|
@ -23,9 +23,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
|||||||
private const float tick_size = 0.35f;
|
private const float tick_size = 0.35f;
|
||||||
|
|
||||||
private bool filled;
|
private bool filled;
|
||||||
|
|
||||||
public bool Filled
|
public bool Filled
|
||||||
{
|
{
|
||||||
get { return filled; }
|
get => filled;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
filled = value;
|
filled = value;
|
||||||
|
@ -19,7 +19,10 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int RequiredHits = 10;
|
public int RequiredHits = 10;
|
||||||
|
|
||||||
public override bool IsStrong { set => throw new NotSupportedException($"{nameof(Swell)} cannot be a strong hitobject."); }
|
public override bool IsStrong
|
||||||
|
{
|
||||||
|
set => throw new NotSupportedException($"{nameof(Swell)} cannot be a strong hitobject.");
|
||||||
|
}
|
||||||
|
|
||||||
protected override void CreateNestedHitObjects()
|
protected override void CreateNestedHitObjects()
|
||||||
{
|
{
|
||||||
|
@ -19,10 +19,13 @@ namespace osu.Game.Rulesets.Taiko
|
|||||||
{
|
{
|
||||||
[Description("Left (rim)")]
|
[Description("Left (rim)")]
|
||||||
LeftRim,
|
LeftRim,
|
||||||
|
|
||||||
[Description("Left (centre)")]
|
[Description("Left (centre)")]
|
||||||
LeftCentre,
|
LeftCentre,
|
||||||
|
|
||||||
[Description("Right (centre)")]
|
[Description("Right (centre)")]
|
||||||
RightCentre,
|
RightCentre,
|
||||||
|
|
||||||
[Description("Right (rim)")]
|
[Description("Right (rim)")]
|
||||||
RightRim
|
RightRim
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
}
|
}
|
||||||
|
|
||||||
private SortedList<TimingControlPoint> timingPoints => Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints;
|
private SortedList<TimingControlPoint> timingPoints => Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints;
|
||||||
|
|
||||||
private TimingControlPoint getNextTimingPoint(TimingControlPoint current)
|
private TimingControlPoint getNextTimingPoint(TimingControlPoint current)
|
||||||
{
|
{
|
||||||
if (timingPoints[timingPoints.Count - 1] == current)
|
if (timingPoints[timingPoints.Count - 1] == current)
|
||||||
@ -190,7 +191,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
public double Value
|
public double Value
|
||||||
{
|
{
|
||||||
set { valueText.Text = $"{value:G}"; }
|
set => valueText.Text = $"{value:G}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public InfoString(string header)
|
public InfoString(string header)
|
||||||
|
@ -150,6 +150,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
var currentlySelected = carousel.Items.Find(s => s.Item is CarouselBeatmap && s.Item.State.Value == CarouselItemState.Selected);
|
var currentlySelected = carousel.Items.Find(s => s.Item is CarouselBeatmap && s.Item.State.Value == CarouselItemState.Selected);
|
||||||
if (currentlySelected == null)
|
if (currentlySelected == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return currentlySelected.Item.Visible;
|
return currentlySelected.Item.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,8 +167,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
carousel.Filter(new FilterCriteria { SearchText = "Dingo" }, false);
|
carousel.Filter(new FilterCriteria { SearchText = "Dingo" }, false);
|
||||||
carousel.Filter(new FilterCriteria(), false);
|
carousel.Filter(new FilterCriteria(), false);
|
||||||
eagerSelectedIDs.Add(carousel.SelectedBeatmapSet.ID);
|
eagerSelectedIDs.Add(carousel.SelectedBeatmapSet.ID);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -522,6 +522,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
Padding = new MarginPadding(150),
|
Padding = new MarginPadding(150),
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("beatmap all metrics", () => details.Beatmap = new BeatmapInfo
|
AddStep("all metrics", () => details.Beatmap = new BeatmapInfo
|
||||||
{
|
{
|
||||||
Version = "All Metrics",
|
Version = "All Metrics",
|
||||||
Metadata = new BeatmapMetadata
|
Metadata = new BeatmapMetadata
|
||||||
@ -45,7 +45,30 @@ namespace osu.Game.Tests.Visual
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("beatmap ratings", () => details.Beatmap = new BeatmapInfo
|
AddStep("all except source", () => details.Beatmap = new BeatmapInfo
|
||||||
|
{
|
||||||
|
Version = "All Metrics",
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Tags = "this beatmap has all the metrics",
|
||||||
|
},
|
||||||
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
|
{
|
||||||
|
CircleSize = 7,
|
||||||
|
DrainRate = 1,
|
||||||
|
OverallDifficulty = 5.7f,
|
||||||
|
ApproachRate = 3.5f,
|
||||||
|
},
|
||||||
|
StarDifficulty = 5.3f,
|
||||||
|
Metrics = new BeatmapMetrics
|
||||||
|
{
|
||||||
|
Ratings = Enumerable.Range(0, 11),
|
||||||
|
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
||||||
|
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("ratings", () => details.Beatmap = new BeatmapInfo
|
||||||
{
|
{
|
||||||
Version = "Only Ratings",
|
Version = "Only Ratings",
|
||||||
Metadata = new BeatmapMetadata
|
Metadata = new BeatmapMetadata
|
||||||
@ -67,7 +90,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("beatmap fails retries", () => details.Beatmap = new BeatmapInfo
|
AddStep("fails retries", () => details.Beatmap = new BeatmapInfo
|
||||||
{
|
{
|
||||||
Version = "Only Retries and Fails",
|
Version = "Only Retries and Fails",
|
||||||
Metadata = new BeatmapMetadata
|
Metadata = new BeatmapMetadata
|
||||||
@ -90,7 +113,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("beatmap no metrics", () => details.Beatmap = new BeatmapInfo
|
AddStep("no metrics", () => details.Beatmap = new BeatmapInfo
|
||||||
{
|
{
|
||||||
Version = "No Metrics",
|
Version = "No Metrics",
|
||||||
Metadata = new BeatmapMetadata
|
Metadata = new BeatmapMetadata
|
||||||
|
@ -160,7 +160,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
Accuracy = 0.6543,
|
Accuracy = 0.6543,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
foreach(var s in scores)
|
|
||||||
|
foreach (var s in scores)
|
||||||
{
|
{
|
||||||
s.Statistics.Add(HitResult.Great, RNG.Next(2000));
|
s.Statistics.Add(HitResult.Great, RNG.Next(2000));
|
||||||
s.Statistics.Add(HitResult.Good, RNG.Next(2000));
|
s.Statistics.Add(HitResult.Good, RNG.Next(2000));
|
||||||
|
@ -56,7 +56,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
var chatManager = new ChannelManager();
|
var chatManager = new ChannelManager();
|
||||||
BindableList<Channel> availableChannels = (BindableList<Channel>)chatManager.AvailableChannels;
|
BindableList<Channel> availableChannels = (BindableList<Channel>)chatManager.AvailableChannels;
|
||||||
availableChannels.Add(new Channel { Name = "#english"});
|
availableChannels.Add(new Channel { Name = "#english" });
|
||||||
availableChannels.Add(new Channel { Name = "#japanese" });
|
availableChannels.Add(new Channel { Name = "#japanese" });
|
||||||
Dependencies.Cache(chatManager);
|
Dependencies.Cache(chatManager);
|
||||||
|
|
||||||
|
@ -61,10 +61,10 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
// Move box along a square trajectory
|
// Move box along a square trajectory
|
||||||
container.Loop(c => c
|
container.Loop(c => c
|
||||||
.MoveTo(new Vector2(0, 100), duration).Then()
|
.MoveTo(new Vector2(0, 100), duration).Then()
|
||||||
.MoveTo(new Vector2(100, 100), duration).Then()
|
.MoveTo(new Vector2(100, 100), duration).Then()
|
||||||
.MoveTo(new Vector2(100, 0), duration).Then()
|
.MoveTo(new Vector2(100, 0), duration).Then()
|
||||||
.MoveTo(Vector2.Zero, duration)
|
.MoveTo(Vector2.Zero, duration)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
TimingPoints =
|
TimingPoints =
|
||||||
{
|
{
|
||||||
new TimingControlPoint { Time = 0, BeatLength = 200},
|
new TimingControlPoint { Time = 0, BeatLength = 200 },
|
||||||
new TimingControlPoint { Time = 100, BeatLength = 400 },
|
new TimingControlPoint { Time = 100, BeatLength = 400 },
|
||||||
new TimingControlPoint { Time = 175, BeatLength = 800 },
|
new TimingControlPoint { Time = 175, BeatLength = 800 },
|
||||||
new TimingControlPoint { Time = 350, BeatLength = 200 },
|
new TimingControlPoint { Time = 350, BeatLength = 200 },
|
||||||
|
@ -265,6 +265,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
pauseOverlay.OnRetry = lastAction;
|
pauseOverlay.OnRetry = lastAction;
|
||||||
lastAction = null;
|
lastAction = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return triggered;
|
return triggered;
|
||||||
});
|
});
|
||||||
AddAssert("Overlay is closed", () => pauseOverlay.State == Visibility.Hidden);
|
AddAssert("Overlay is closed", () => pauseOverlay.State == Visibility.Hidden);
|
||||||
|
@ -20,7 +20,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
[Description("PlaySongSelect leaderboard")]
|
[Description("PlaySongSelect leaderboard")]
|
||||||
public class TestCaseLeaderboard : OsuTestCase
|
public class TestCaseLeaderboard : OsuTestCase
|
||||||
{
|
{
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[] {
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
typeof(Placeholder),
|
typeof(Placeholder),
|
||||||
typeof(MessagePlaceholder),
|
typeof(MessagePlaceholder),
|
||||||
typeof(RetrievalFailurePlaceholder),
|
typeof(RetrievalFailurePlaceholder),
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Screens;
|
|
||||||
using osu.Game.Screens.Menu;
|
using osu.Game.Screens.Menu;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -21,8 +21,12 @@ namespace osu.Game.Tests.Visual
|
|||||||
typeof(OsuLogo),
|
typeof(OsuLogo),
|
||||||
};
|
};
|
||||||
|
|
||||||
public TestCaseOsuGame()
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(GameHost host)
|
||||||
{
|
{
|
||||||
|
OsuGame game = new OsuGame();
|
||||||
|
game.SetHost(host);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Box
|
new Box
|
||||||
@ -30,10 +34,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = Color4.Black,
|
Colour = Color4.Black,
|
||||||
},
|
},
|
||||||
new ScreenStack(new Loader())
|
game
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Size = new Vector2(200,100)
|
Size = new Vector2(200, 100)
|
||||||
};
|
};
|
||||||
|
|
||||||
Beatmap.Value = new TestWorkingBeatmap(new Beatmap(), Clock);
|
Beatmap.Value = new TestWorkingBeatmap(new Beatmap(), Clock);
|
||||||
|
@ -84,7 +84,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
public TestScreen PushNext()
|
public TestScreen PushNext()
|
||||||
{
|
{
|
||||||
TestScreen screen = CreateNextScreen();
|
TestScreen screen = CreateNextScreen();
|
||||||
this.Push(screen);
|
this.Push(screen);
|
||||||
|
|
||||||
return screen;
|
return screen;
|
||||||
}
|
}
|
||||||
|
153
osu.Game.Tests/Visual/TestCaseSkinReloadable.cs
Normal file
153
osu.Game.Tests/Visual/TestCaseSkinReloadable.cs
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
// 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;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual
|
||||||
|
{
|
||||||
|
public class TestCaseSkinReloadable : OsuTestCase
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestInitialLoad()
|
||||||
|
{
|
||||||
|
var secondarySource = new SecondarySource();
|
||||||
|
SkinConsumer consumer = null;
|
||||||
|
|
||||||
|
AddStep("setup layout", () =>
|
||||||
|
{
|
||||||
|
Child = new SkinSourceContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = new LocalSkinOverrideContainer(secondarySource)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"), source => true)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("consumer using override source", () => consumer.Drawable is SecondarySourceBox);
|
||||||
|
AddAssert("skinchanged only called once", () => consumer.SkinChangedCount == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestOverride()
|
||||||
|
{
|
||||||
|
var secondarySource = new SecondarySource();
|
||||||
|
|
||||||
|
SkinConsumer consumer = null;
|
||||||
|
Container target = null;
|
||||||
|
|
||||||
|
AddStep("setup layout", () =>
|
||||||
|
{
|
||||||
|
Child = new SkinSourceContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = target = new LocalSkinOverrideContainer(secondarySource)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("add permissive", () => target.Add(consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"), source => true)));
|
||||||
|
AddAssert("consumer using override source", () => consumer.Drawable is SecondarySourceBox);
|
||||||
|
AddAssert("skinchanged only called once", () => consumer.SkinChangedCount == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NamedBox : Container
|
||||||
|
{
|
||||||
|
public NamedBox(string name)
|
||||||
|
{
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.Black,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
new SpriteText
|
||||||
|
{
|
||||||
|
Font = OsuFont.Default.With(size: 40),
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Text = name
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SkinConsumer : SkinnableDrawable
|
||||||
|
{
|
||||||
|
public new Drawable Drawable => base.Drawable;
|
||||||
|
public int SkinChangedCount { get; private set; }
|
||||||
|
|
||||||
|
public SkinConsumer(string name, Func<string, Drawable> defaultImplementation, Func<ISkinSource, bool> allowFallback = null, bool restrictSize = true)
|
||||||
|
: base(name, defaultImplementation, allowFallback, restrictSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
||||||
|
{
|
||||||
|
base.SkinChanged(skin, allowFallback);
|
||||||
|
SkinChangedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BaseSourceBox : NamedBox
|
||||||
|
{
|
||||||
|
public BaseSourceBox()
|
||||||
|
: base("Base Source")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SecondarySourceBox : NamedBox
|
||||||
|
{
|
||||||
|
public SecondarySourceBox()
|
||||||
|
: base("Secondary Source")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SecondarySource : ISkinSource
|
||||||
|
{
|
||||||
|
public event Action SourceChanged;
|
||||||
|
|
||||||
|
public void TriggerSourceChanged() => SourceChanged?.Invoke();
|
||||||
|
|
||||||
|
public Drawable GetDrawableComponent(string componentName) => new SecondarySourceBox();
|
||||||
|
|
||||||
|
public Texture GetTexture(string componentName) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public SampleChannel GetSample(string sampleName) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration => throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SkinSourceContainer : Container, ISkinSource
|
||||||
|
{
|
||||||
|
public event Action SourceChanged;
|
||||||
|
|
||||||
|
public void TriggerSourceChanged() => SourceChanged?.Invoke();
|
||||||
|
|
||||||
|
public Drawable GetDrawableComponent(string componentName) => new BaseSourceBox();
|
||||||
|
|
||||||
|
public Texture GetTexture(string componentName) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public SampleChannel GetSample(string sampleName) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration => throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
public class TestCaseSongProgress : OsuTestCase
|
public class TestCaseSongProgress : OsuTestCase
|
||||||
{
|
{
|
||||||
private readonly SongProgress progress;
|
private readonly SongProgress progress;
|
||||||
private readonly SongProgressGraph graph;
|
private readonly TestSongProgressGraph graph;
|
||||||
|
|
||||||
private readonly StopwatchClock clock;
|
private readonly StopwatchClock clock;
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
});
|
});
|
||||||
|
|
||||||
Add(graph = new SongProgressGraph
|
Add(graph = new TestSongProgressGraph
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = 200,
|
Height = 200,
|
||||||
@ -39,13 +39,24 @@ namespace osu.Game.Tests.Visual
|
|||||||
Origin = Anchor.TopLeft,
|
Origin = Anchor.TopLeft,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AddWaitStep(5);
|
||||||
|
AddAssert("ensure not created", () => graph.CreationCount == 0);
|
||||||
|
|
||||||
|
AddStep("display values", displayNewValues);
|
||||||
|
AddWaitStep(5);
|
||||||
|
AddUntilStep(() => graph.CreationCount == 1, "wait for creation count");
|
||||||
|
|
||||||
AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking);
|
AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking);
|
||||||
AddWaitStep(5);
|
AddWaitStep(5);
|
||||||
|
AddUntilStep(() => graph.CreationCount == 1, "wait for creation count");
|
||||||
|
|
||||||
AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking);
|
AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking);
|
||||||
AddWaitStep(2);
|
AddWaitStep(5);
|
||||||
|
AddUntilStep(() => graph.CreationCount == 1, "wait for creation count");
|
||||||
AddRepeatStep("New Values", displayNewValues, 5);
|
AddRepeatStep("New Values", displayNewValues, 5);
|
||||||
|
|
||||||
displayNewValues();
|
AddWaitStep(5);
|
||||||
|
AddAssert("ensure debounced", () => graph.CreationCount == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayNewValues()
|
private void displayNewValues()
|
||||||
@ -60,5 +71,16 @@ namespace osu.Game.Tests.Visual
|
|||||||
progress.AudioClock = clock;
|
progress.AudioClock = clock;
|
||||||
progress.OnSeek = pos => clock.Seek(pos);
|
progress.OnSeek = pos => clock.Seek(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestSongProgressGraph : SongProgressGraph
|
||||||
|
{
|
||||||
|
public int CreationCount { get; private set; }
|
||||||
|
|
||||||
|
protected override void RecreateGraph()
|
||||||
|
{
|
||||||
|
base.RecreateGraph();
|
||||||
|
CreationCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,10 @@ namespace osu.Game.Tests.Visual
|
|||||||
});
|
});
|
||||||
|
|
||||||
AddStep("Restart", restart);
|
AddStep("Restart", restart);
|
||||||
AddToggleStep("Passing", passing => { if (storyboard != null) storyboard.Passing = passing; });
|
AddToggleStep("Passing", passing =>
|
||||||
|
{
|
||||||
|
if (storyboard != null) storyboard.Passing = passing;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Audio
|
|||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
track = GetTrack();
|
track = GetTrack();
|
||||||
track.Completed += Stop;
|
track.Completed += () => Schedule(Stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -63,6 +63,7 @@ namespace osu.Game.Audio
|
|||||||
|
|
||||||
if (hasStarted)
|
if (hasStarted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hasStarted = true;
|
hasStarted = true;
|
||||||
|
|
||||||
track.Restart();
|
track.Restart();
|
||||||
@ -81,6 +82,7 @@ namespace osu.Game.Audio
|
|||||||
|
|
||||||
if (!hasStarted)
|
if (!hasStarted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hasStarted = false;
|
hasStarted = false;
|
||||||
|
|
||||||
track.Stop();
|
track.Stop();
|
||||||
|
@ -50,12 +50,14 @@ namespace osu.Game.Audio
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(Suffix))
|
if (!string.IsNullOrEmpty(Suffix))
|
||||||
yield return $"{Namespace}/{Bank}-{Name}{Suffix}";
|
yield return $"{Namespace}/{Bank}-{Name}{Suffix}";
|
||||||
|
|
||||||
yield return $"{Namespace}/{Bank}-{Name}";
|
yield return $"{Namespace}/{Bank}-{Name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
// check non-namespace as a fallback even when we have a namespace
|
// check non-namespace as a fallback even when we have a namespace
|
||||||
if (!string.IsNullOrEmpty(Suffix))
|
if (!string.IsNullOrEmpty(Suffix))
|
||||||
yield return $"{Bank}-{Name}{Suffix}";
|
yield return $"{Bank}-{Name}{Suffix}";
|
||||||
|
|
||||||
yield return $"{Bank}-{Name}";
|
yield return $"{Bank}-{Name}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ namespace osu.Game.Beatmaps
|
|||||||
where T : HitObject
|
where T : HitObject
|
||||||
{
|
{
|
||||||
private event Action<HitObject, IEnumerable<HitObject>> ObjectConverted;
|
private event Action<HitObject, IEnumerable<HitObject>> ObjectConverted;
|
||||||
|
|
||||||
event Action<HitObject, IEnumerable<HitObject>> IBeatmapConverter.ObjectConverted
|
event Action<HitObject, IEnumerable<HitObject>> IBeatmapConverter.ObjectConverted
|
||||||
{
|
{
|
||||||
add => ObjectConverted += value;
|
add => ObjectConverted += value;
|
||||||
|
@ -48,6 +48,7 @@ namespace osu.Game.Beatmaps
|
|||||||
return mid + (max - mid) * (difficulty - 5) / 5;
|
return mid + (max - mid) * (difficulty - 5) / 5;
|
||||||
if (difficulty < 5)
|
if (difficulty < 5)
|
||||||
return mid - (mid - min) * (5 - difficulty) / 5;
|
return mid - (mid - min) * (5 - difficulty) / 5;
|
||||||
|
|
||||||
return mid;
|
return mid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ namespace osu.Game.Beatmaps
|
|||||||
[Column("Author")]
|
[Column("Author")]
|
||||||
public string AuthorString
|
public string AuthorString
|
||||||
{
|
{
|
||||||
get { return Author?.Username; }
|
get => Author?.Username;
|
||||||
set { Author = new User { Username = value }; }
|
set => Author = new User { Username = value };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -48,6 +48,7 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
[JsonProperty(@"tags")]
|
[JsonProperty(@"tags")]
|
||||||
public string Tags { get; set; }
|
public string Tags { get; set; }
|
||||||
|
|
||||||
public int PreviewTime { get; set; }
|
public int PreviewTime { get; set; }
|
||||||
public string AudioFile { get; set; }
|
public string AudioFile { get; set; }
|
||||||
public string BackgroundFile { get; set; }
|
public string BackgroundFile { get; set; }
|
||||||
@ -72,15 +73,15 @@ namespace osu.Game.Beatmaps
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
return Title == other.Title
|
return Title == other.Title
|
||||||
&& TitleUnicode == other.TitleUnicode
|
&& TitleUnicode == other.TitleUnicode
|
||||||
&& Artist == other.Artist
|
&& Artist == other.Artist
|
||||||
&& ArtistUnicode == other.ArtistUnicode
|
&& ArtistUnicode == other.ArtistUnicode
|
||||||
&& AuthorString == other.AuthorString
|
&& AuthorString == other.AuthorString
|
||||||
&& Source == other.Source
|
&& Source == other.Source
|
||||||
&& Tags == other.Tags
|
&& Tags == other.Tags
|
||||||
&& PreviewTime == other.PreviewTime
|
&& PreviewTime == other.PreviewTime
|
||||||
&& AudioFile == other.AudioFile
|
&& AudioFile == other.AudioFile
|
||||||
&& BackgroundFile == other.BackgroundFile;
|
&& BackgroundFile == other.BackgroundFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ namespace osu.Game.Beatmaps
|
|||||||
Refresh(ref beatmap, Beatmaps);
|
Refresh(ref beatmap, Beatmaps);
|
||||||
|
|
||||||
if (beatmap.Hidden) return false;
|
if (beatmap.Hidden) return false;
|
||||||
|
|
||||||
beatmap.Hidden = true;
|
beatmap.Hidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +54,7 @@ namespace osu.Game.Beatmaps
|
|||||||
Refresh(ref beatmap, Beatmaps);
|
Refresh(ref beatmap, Beatmaps);
|
||||||
|
|
||||||
if (!beatmap.Hidden) return false;
|
if (!beatmap.Hidden) return false;
|
||||||
|
|
||||||
beatmap.Hidden = false;
|
beatmap.Hidden = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
|
|
||||||
public BeatmapBackgroundSprite(WorkingBeatmap working)
|
public BeatmapBackgroundSprite(WorkingBeatmap working)
|
||||||
{
|
{
|
||||||
if (working == null)
|
if (working == null)
|
||||||
throw new ArgumentNullException(nameof(working));
|
throw new ArgumentNullException(nameof(working));
|
||||||
|
|
||||||
this.working = working;
|
this.working = working;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
{
|
{
|
||||||
if (status == value)
|
if (status == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
status = value;
|
status = value;
|
||||||
|
|
||||||
Alpha = value == BeatmapSetOnlineStatus.None ? 0 : 1;
|
Alpha = value == BeatmapSetOnlineStatus.None ? 0 : 1;
|
||||||
|
@ -53,6 +53,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
if (rating < 3.75) return DifficultyRating.Hard;
|
if (rating < 3.75) return DifficultyRating.Hard;
|
||||||
if (rating < 5.25) return DifficultyRating.Insane;
|
if (rating < 5.25) return DifficultyRating.Insane;
|
||||||
if (rating < 6.75) return DifficultyRating.Expert;
|
if (rating < 6.75) return DifficultyRating.Expert;
|
||||||
|
|
||||||
return DifficultyRating.ExpertPlus;
|
return DifficultyRating.ExpertPlus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
|
|
||||||
protected override Drawable CreateDrawable(BeatmapInfo model)
|
protected override Drawable CreateDrawable(BeatmapInfo model)
|
||||||
{
|
{
|
||||||
return new DelayedLoadUnloadWrapper(() => {
|
return new DelayedLoadUnloadWrapper(() =>
|
||||||
|
{
|
||||||
Drawable drawable;
|
Drawable drawable;
|
||||||
|
|
||||||
var localBeatmap = beatmaps.GetWorkingBeatmap(model);
|
var localBeatmap = beatmaps.GetWorkingBeatmap(model);
|
||||||
|
@ -13,12 +13,14 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
private Drawable displayedCover;
|
private Drawable displayedCover;
|
||||||
|
|
||||||
private BeatmapSetInfo beatmapSet;
|
private BeatmapSetInfo beatmapSet;
|
||||||
|
|
||||||
public BeatmapSetInfo BeatmapSet
|
public BeatmapSetInfo BeatmapSet
|
||||||
{
|
{
|
||||||
get { return beatmapSet; }
|
get => beatmapSet;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == beatmapSet) return;
|
if (value == beatmapSet) return;
|
||||||
|
|
||||||
beatmapSet = value;
|
beatmapSet = value;
|
||||||
|
|
||||||
if (IsLoaded)
|
if (IsLoaded)
|
||||||
@ -27,12 +29,14 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
}
|
}
|
||||||
|
|
||||||
private BeatmapSetCoverType coverType = BeatmapSetCoverType.Cover;
|
private BeatmapSetCoverType coverType = BeatmapSetCoverType.Cover;
|
||||||
|
|
||||||
public BeatmapSetCoverType CoverType
|
public BeatmapSetCoverType CoverType
|
||||||
{
|
{
|
||||||
get { return coverType; }
|
get => coverType;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == coverType) return;
|
if (value == coverType) return;
|
||||||
|
|
||||||
coverType = value;
|
coverType = value;
|
||||||
|
|
||||||
if (IsLoaded)
|
if (IsLoaded)
|
||||||
|
@ -72,6 +72,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
var index = line.AsSpan().IndexOf("//".AsSpan());
|
var index = line.AsSpan().IndexOf("//".AsSpan());
|
||||||
if (index > 0)
|
if (index > 0)
|
||||||
return line.Substring(0, index);
|
return line.Substring(0, index);
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,6 +116,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!(output is IHasCustomColours tHasCustomColours)) return;
|
if (!(output is IHasCustomColours tHasCustomColours)) return;
|
||||||
|
|
||||||
tHasCustomColours.CustomColours[pair.Key] = colour;
|
tHasCustomColours.CustomColours[pair.Key] = colour;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,11 @@ using System.ComponentModel;
|
|||||||
|
|
||||||
namespace osu.Game.Configuration
|
namespace osu.Game.Configuration
|
||||||
{
|
{
|
||||||
public enum RandomSelectAlgorithm
|
public enum RandomSelectAlgorithm
|
||||||
{
|
{
|
||||||
[Description("Never repeat")]
|
[Description("Never repeat")]
|
||||||
RandomPermutation,
|
RandomPermutation,
|
||||||
|
|
||||||
[Description("Random")]
|
[Description("Random")]
|
||||||
Random
|
Random
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,10 @@ namespace osu.Game.Configuration
|
|||||||
public enum RankingType
|
public enum RankingType
|
||||||
{
|
{
|
||||||
Local,
|
Local,
|
||||||
|
|
||||||
[Description("Global")]
|
[Description("Global")]
|
||||||
Top,
|
Top,
|
||||||
|
|
||||||
[Description("Selected Mods")]
|
[Description("Selected Mods")]
|
||||||
SelectedMod,
|
SelectedMod,
|
||||||
Friends,
|
Friends,
|
||||||
|
@ -9,6 +9,7 @@ namespace osu.Game.Configuration
|
|||||||
{
|
{
|
||||||
Off,
|
Off,
|
||||||
Everything,
|
Everything,
|
||||||
|
|
||||||
[Description("Excluding overlays")]
|
[Description("Excluding overlays")]
|
||||||
ExcludeOverlays,
|
ExcludeOverlays,
|
||||||
Gameplay,
|
Gameplay,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user