mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 08:13:31 +08:00
Merge remote-tracking branch 'refs/remotes/ppy/master' into percentage
This commit is contained in:
commit
1f34cec5ce
@ -1 +1 @@
|
||||
Subproject commit 1c95c94fab6852620cd82eb0899ca0132ac82667
|
||||
Subproject commit 682f078b2efc82fa19342f499f14c4a8458843d5
|
@ -10,7 +10,7 @@ namespace osu.Desktop.VisualTests.Beatmaps
|
||||
public class TestWorkingBeatmap : WorkingBeatmap
|
||||
{
|
||||
public TestWorkingBeatmap(Beatmap beatmap)
|
||||
: base(beatmap.BeatmapInfo, beatmap.BeatmapInfo.BeatmapSet)
|
||||
: base(beatmap.BeatmapInfo)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
89
osu.Desktop.VisualTests/Tests/TestCaseManiaHitObjects.cs
Normal file
89
osu.Desktop.VisualTests/Tests/TestCaseManiaHitObjects.cs
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Desktop.VisualTests.Tests
|
||||
{
|
||||
internal class TestCaseManiaHitObjects : TestCase
|
||||
{
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
|
||||
Add(new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(10, 0),
|
||||
// Imagine that the containers containing the drawable notes are the "columns"
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Name = "Normal note column",
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = 50,
|
||||
Children = new[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Name = "Timing section",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativeCoordinateSpace = new Vector2(1, 10000),
|
||||
Children = new[]
|
||||
{
|
||||
new DrawableNote(new Note
|
||||
{
|
||||
StartTime = 5000
|
||||
})
|
||||
{
|
||||
AccentColour = Color4.Red
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Name = "Hold note column",
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = 50,
|
||||
Children = new[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Name = "Timing section",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativeCoordinateSpace = new Vector2(1, 10000),
|
||||
Children = new[]
|
||||
{
|
||||
new DrawableHoldNote(new HoldNote
|
||||
{
|
||||
StartTime = 5000,
|
||||
Duration = 1000
|
||||
})
|
||||
{
|
||||
AccentColour = Color4.Red
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -190,6 +190,7 @@
|
||||
<Compile Include="Tests\TestCaseDrawings.cs" />
|
||||
<Compile Include="Tests\TestCaseGamefield.cs" />
|
||||
<Compile Include="Tests\TestCaseGraph.cs" />
|
||||
<Compile Include="Tests\TestCaseManiaHitObjects.cs" />
|
||||
<Compile Include="Tests\TestCaseManiaPlayfield.cs" />
|
||||
<Compile Include="Tests\TestCaseMenuOverlays.cs" />
|
||||
<Compile Include="Tests\TestCaseMusicController.cs" />
|
||||
|
@ -11,11 +11,11 @@ using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
{
|
||||
internal class ManiaBeatmapConverter : BeatmapConverter<ManiaBaseHit>
|
||||
internal class ManiaBeatmapConverter : BeatmapConverter<ManiaHitObject>
|
||||
{
|
||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
|
||||
|
||||
protected override IEnumerable<ManiaBaseHit> ConvertHitObject(HitObject original, Beatmap beatmap)
|
||||
protected override IEnumerable<ManiaHitObject> ConvertHitObject(HitObject original, Beatmap beatmap)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
179
osu.Game.Rulesets.Mania/Judgements/HitWindows.cs
Normal file
179
osu.Game.Rulesets.Mania/Judgements/HitWindows.cs
Normal file
@ -0,0 +1,179 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Judgements
|
||||
{
|
||||
public class HitWindows
|
||||
{
|
||||
#region Constants
|
||||
|
||||
/// <summary>
|
||||
/// PERFECT hit window at OD = 10.
|
||||
/// </summary>
|
||||
private const double perfect_min = 27.8;
|
||||
/// <summary>
|
||||
/// PERFECT hit window at OD = 5.
|
||||
/// </summary>
|
||||
private const double perfect_mid = 38.8;
|
||||
/// <summary>
|
||||
/// PERFECT hit window at OD = 0.
|
||||
/// </summary>
|
||||
private const double perfect_max = 44.8;
|
||||
|
||||
/// <summary>
|
||||
/// GREAT hit window at OD = 10.
|
||||
/// </summary>
|
||||
private const double great_min = 68;
|
||||
/// <summary>
|
||||
/// GREAT hit window at OD = 5.
|
||||
/// </summary>
|
||||
private const double great_mid = 98;
|
||||
/// <summary>
|
||||
/// GREAT hit window at OD = 0.
|
||||
/// </summary>
|
||||
private const double great_max = 128;
|
||||
|
||||
/// <summary>
|
||||
/// GOOD hit window at OD = 10.
|
||||
/// </summary>
|
||||
private const double good_min = 134;
|
||||
/// <summary>
|
||||
/// GOOD hit window at OD = 5.
|
||||
/// </summary>
|
||||
private const double good_mid = 164;
|
||||
/// <summary>
|
||||
/// GOOD hit window at OD = 0.
|
||||
/// </summary>
|
||||
private const double good_max = 194;
|
||||
|
||||
/// <summary>
|
||||
/// OK hit window at OD = 10.
|
||||
/// </summary>
|
||||
private const double ok_min = 194;
|
||||
/// <summary>
|
||||
/// OK hit window at OD = 5.
|
||||
/// </summary>
|
||||
private const double ok_mid = 224;
|
||||
/// <summary>
|
||||
/// OK hit window at OD = 0.
|
||||
/// </summary>
|
||||
private const double ok_max = 254;
|
||||
|
||||
/// <summary>
|
||||
/// BAD hit window at OD = 10.
|
||||
/// </summary>
|
||||
private const double bad_min = 242;
|
||||
/// <summary>
|
||||
/// BAD hit window at OD = 5.
|
||||
/// </summary>
|
||||
private const double bad_mid = 272;
|
||||
/// <summary>
|
||||
/// BAD hit window at OD = 0.
|
||||
/// </summary>
|
||||
private const double bad_max = 302;
|
||||
|
||||
/// <summary>
|
||||
/// MISS hit window at OD = 10.
|
||||
/// </summary>
|
||||
private const double miss_min = 316;
|
||||
/// <summary>
|
||||
/// MISS hit window at OD = 5.
|
||||
/// </summary>
|
||||
private const double miss_mid = 346;
|
||||
/// <summary>
|
||||
/// MISS hit window at OD = 0.
|
||||
/// </summary>
|
||||
private const double miss_max = 376;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Hit window for a PERFECT hit.
|
||||
/// </summary>
|
||||
public double Perfect = perfect_mid;
|
||||
|
||||
/// <summary>
|
||||
/// Hit window for a GREAT hit.
|
||||
/// </summary>
|
||||
public double Great = great_mid;
|
||||
|
||||
/// <summary>
|
||||
/// Hit window for a GOOD hit.
|
||||
/// </summary>
|
||||
public double Good = good_mid;
|
||||
|
||||
/// <summary>
|
||||
/// Hit window for an OK hit.
|
||||
/// </summary>
|
||||
public double Ok = ok_mid;
|
||||
|
||||
/// <summary>
|
||||
/// Hit window for a BAD hit.
|
||||
/// </summary>
|
||||
public double Bad = bad_mid;
|
||||
|
||||
/// <summary>
|
||||
/// Hit window for a MISS hit.
|
||||
/// </summary>
|
||||
public double Miss = miss_mid;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs default hit windows.
|
||||
/// </summary>
|
||||
public HitWindows()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs hit windows by fitting a parameter to a 2-part piecewise linear function for each hit window.
|
||||
/// </summary>
|
||||
/// <param name="difficulty">The parameter.</param>
|
||||
public HitWindows(double difficulty)
|
||||
{
|
||||
Perfect = BeatmapDifficulty.DifficultyRange(difficulty, perfect_max, perfect_mid, perfect_min);
|
||||
Great = BeatmapDifficulty.DifficultyRange(difficulty, great_max, great_mid, great_min);
|
||||
Good = BeatmapDifficulty.DifficultyRange(difficulty, good_max, good_mid, good_min);
|
||||
Ok = BeatmapDifficulty.DifficultyRange(difficulty, ok_max, ok_mid, ok_min);
|
||||
Bad = BeatmapDifficulty.DifficultyRange(difficulty, bad_max, bad_mid, bad_min);
|
||||
Miss = BeatmapDifficulty.DifficultyRange(difficulty, miss_max, miss_mid, miss_min);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs new hit windows which have been multiplied by a value.
|
||||
/// </summary>
|
||||
/// <param name="windows">The original hit windows.</param>
|
||||
/// <param name="value">The value to multiply each hit window by.</param>
|
||||
public static HitWindows operator *(HitWindows windows, double value)
|
||||
{
|
||||
return new HitWindows
|
||||
{
|
||||
Perfect = windows.Perfect * value,
|
||||
Great = windows.Great * value,
|
||||
Good = windows.Good * value,
|
||||
Ok = windows.Ok * value,
|
||||
Bad = windows.Bad * value,
|
||||
Miss = windows.Miss * value
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs new hit windows which have been divided by a value.
|
||||
/// </summary>
|
||||
/// <param name="windows">The original hit windows.</param>
|
||||
/// <param name="value">The value to divide each hit window by.</param>
|
||||
public static HitWindows operator /(HitWindows windows, double value)
|
||||
{
|
||||
return new HitWindows
|
||||
{
|
||||
Perfect = windows.Perfect / value,
|
||||
Great = windows.Great / value,
|
||||
Good = windows.Good / value,
|
||||
Ok = windows.Ok / value,
|
||||
Bad = windows.Bad / value,
|
||||
Miss = windows.Miss / value
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
public class ManiaDifficultyCalculator : DifficultyCalculator<ManiaBaseHit>
|
||||
public class ManiaDifficultyCalculator : DifficultyCalculator<ManiaHitObject>
|
||||
{
|
||||
public ManiaDifficultyCalculator(Beatmap beatmap)
|
||||
: base(beatmap)
|
||||
@ -21,6 +21,6 @@ namespace osu.Game.Rulesets.Mania
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected override BeatmapConverter<ManiaBaseHit> CreateBeatmapConverter() => new ManiaBeatmapConverter();
|
||||
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter() => new ManiaBeatmapConverter();
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Graphics.Transforms;
|
||||
using osu.Framework.Graphics;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects.Drawable
|
||||
{
|
||||
public class DrawableNote : Sprite
|
||||
{
|
||||
private readonly ManiaBaseHit note;
|
||||
|
||||
public DrawableNote(ManiaBaseHit note)
|
||||
{
|
||||
this.note = note;
|
||||
Origin = Anchor.Centre;
|
||||
Scale = new Vector2(0.1f);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
Texture = textures.Get(@"Menu/logo");
|
||||
|
||||
const double duration = 0;
|
||||
|
||||
Transforms.Add(new TransformPositionY { StartTime = note.StartTime - 200, EndTime = note.StartTime, StartValue = -0.1f, EndValue = 0.9f });
|
||||
Transforms.Add(new TransformAlpha { StartTime = note.StartTime + duration + 200, EndTime = note.StartTime + duration + 400, StartValue = 1, EndValue = 0 });
|
||||
Expire(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
{
|
||||
public class DrawableHoldNote : DrawableManiaHitObject<HoldNote>
|
||||
{
|
||||
private readonly NotePiece headPiece;
|
||||
private readonly BodyPiece bodyPiece;
|
||||
private readonly NotePiece tailPiece;
|
||||
|
||||
public DrawableHoldNote(HoldNote hitObject)
|
||||
: base(hitObject)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Height = (float)HitObject.Duration;
|
||||
|
||||
Add(new Drawable[]
|
||||
{
|
||||
// For now the body piece covers the entire height of the container
|
||||
// whereas possibly in the future we don't want to extend under the head/tail.
|
||||
// This will be fixed when new designs are given or the current design is finalized.
|
||||
bodyPiece = new BodyPiece
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
},
|
||||
headPiece = new NotePiece
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre
|
||||
},
|
||||
tailPiece = new NotePiece
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre
|
||||
}
|
||||
});
|
||||
|
||||
// The "length" of the hold note stops at the "base" of the tail piece
|
||||
// but we want to contain the tail piece within our bounds
|
||||
Height += (float)HitObject.Duration / headPiece.Height;
|
||||
}
|
||||
|
||||
public override Color4 AccentColour
|
||||
{
|
||||
get { return base.AccentColour; }
|
||||
set
|
||||
{
|
||||
if (base.AccentColour == value)
|
||||
return;
|
||||
base.AccentColour = value;
|
||||
|
||||
headPiece.AccentColour = value;
|
||||
bodyPiece.AccentColour = value;
|
||||
tailPiece.AccentColour = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateState(ArmedState state)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Mania.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
{
|
||||
public abstract class DrawableManiaHitObject<TObject> : DrawableHitObject<ManiaHitObject, ManiaJudgement>
|
||||
where TObject : ManiaHitObject
|
||||
{
|
||||
public new TObject HitObject;
|
||||
|
||||
private readonly Container glowContainer;
|
||||
|
||||
protected DrawableManiaHitObject(TObject hitObject)
|
||||
: base(hitObject)
|
||||
{
|
||||
HitObject = hitObject;
|
||||
|
||||
Anchor = Anchor.TopCentre;
|
||||
Origin = Anchor.BottomCentre;
|
||||
|
||||
RelativePositionAxes = Axes.Y;
|
||||
Y = (float)HitObject.StartTime;
|
||||
|
||||
Add(glowContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
Children = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0,
|
||||
AlwaysPresent = true
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override Color4 AccentColour
|
||||
{
|
||||
get { return base.AccentColour; }
|
||||
set
|
||||
{
|
||||
if (base.AccentColour == value)
|
||||
return;
|
||||
base.AccentColour = value;
|
||||
|
||||
glowContainer.EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Glow,
|
||||
Radius = 5,
|
||||
Colour = value
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
protected override ManiaJudgement CreateJudgement() => new ManiaJudgement();
|
||||
}
|
||||
}
|
45
osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs
Normal file
45
osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
{
|
||||
public class DrawableNote : DrawableManiaHitObject<Note>
|
||||
{
|
||||
private readonly NotePiece headPiece;
|
||||
|
||||
public DrawableNote(Note hitObject)
|
||||
: base(hitObject)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
Add(headPiece = new NotePiece
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre
|
||||
});
|
||||
}
|
||||
|
||||
public override Color4 AccentColour
|
||||
{
|
||||
get { return base.AccentColour; }
|
||||
set
|
||||
{
|
||||
if (base.AccentColour == value)
|
||||
return;
|
||||
base.AccentColour = value;
|
||||
|
||||
headPiece.AccentColour = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateState(ArmedState state)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents length-wise portion of a hold note.
|
||||
/// </summary>
|
||||
internal class BodyPiece : Container, IHasAccentColour
|
||||
{
|
||||
private readonly Box box;
|
||||
|
||||
public BodyPiece()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Masking = true;
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
box = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.3f
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Color4 accentColour;
|
||||
public Color4 AccentColour
|
||||
{
|
||||
get { return accentColour; }
|
||||
set
|
||||
{
|
||||
if (accentColour == value)
|
||||
return;
|
||||
accentColour = value;
|
||||
|
||||
box.Colour = accentColour;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the static hit markers of notes.
|
||||
/// </summary>
|
||||
internal class NotePiece : Container, IHasAccentColour
|
||||
{
|
||||
private const float head_height = 10;
|
||||
private const float head_colour_height = 6;
|
||||
|
||||
private readonly Box colouredBox;
|
||||
|
||||
public NotePiece()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Height = head_height;
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
},
|
||||
colouredBox = new Box
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = head_colour_height,
|
||||
Alpha = 0.2f
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Color4 accentColour;
|
||||
public Color4 AccentColour
|
||||
{
|
||||
get { return accentColour; }
|
||||
set
|
||||
{
|
||||
if (accentColour == value)
|
||||
return;
|
||||
accentColour = value;
|
||||
|
||||
colouredBox.Colour = AccentColour.Lighten(0.9f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,37 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Rulesets.Mania.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects
|
||||
{
|
||||
public class HoldNote : Note
|
||||
/// <summary>
|
||||
/// Represents a hit object which requires pressing, holding, and releasing a key.
|
||||
/// </summary>
|
||||
public class HoldNote : Note, IHasEndTime
|
||||
{
|
||||
/// <summary>
|
||||
/// Lenience of release hit windows. This is to make cases where the hold note release
|
||||
/// is timed alongside presses of other hit objects less awkward.
|
||||
/// </summary>
|
||||
private const double release_window_lenience = 1.5;
|
||||
|
||||
public double Duration { get; set; }
|
||||
public double EndTime => StartTime + Duration;
|
||||
|
||||
/// <summary>
|
||||
/// The key-release hit windows for this hold note.
|
||||
/// </summary>
|
||||
protected HitWindows ReleaseHitWindows = new HitWindows();
|
||||
|
||||
public override void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty)
|
||||
{
|
||||
base.ApplyDefaults(timing, difficulty);
|
||||
|
||||
ReleaseHitWindows = HitWindows * release_window_lenience;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Mania.Objects.Types;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects
|
||||
{
|
||||
public abstract class ManiaBaseHit : HitObject
|
||||
public abstract class ManiaHitObject : HitObject, IHasColumn
|
||||
{
|
||||
public int Column;
|
||||
public int Column { get; set; }
|
||||
}
|
||||
}
|
@ -1,9 +1,27 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Rulesets.Mania.Judgements;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects
|
||||
{
|
||||
public class Note : ManiaBaseHit
|
||||
/// <summary>
|
||||
/// Represents a hit object which has a single hit press.
|
||||
/// </summary>
|
||||
public class Note : ManiaHitObject
|
||||
{
|
||||
/// <summary>
|
||||
/// The key-press hit window for this note.
|
||||
/// </summary>
|
||||
protected HitWindows HitWindows = new HitWindows();
|
||||
|
||||
public override void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty)
|
||||
{
|
||||
base.ApplyDefaults(timing, difficulty);
|
||||
|
||||
HitWindows = new HitWindows(difficulty.OverallDifficulty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
16
osu.Game.Rulesets.Mania/Objects/Types/IHasColumn.cs
Normal file
16
osu.Game.Rulesets.Mania/Objects/Types/IHasColumn.cs
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// A type of hit object which lies in one of a number of predetermined columns.
|
||||
/// </summary>
|
||||
public interface IHasColumn
|
||||
{
|
||||
/// <summary>
|
||||
/// The column which the hit object lies in.
|
||||
/// </summary>
|
||||
int Column { get; }
|
||||
}
|
||||
}
|
@ -8,13 +8,13 @@ using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Scoring
|
||||
{
|
||||
internal class ManiaScoreProcessor : ScoreProcessor<ManiaBaseHit, ManiaJudgement>
|
||||
internal class ManiaScoreProcessor : ScoreProcessor<ManiaHitObject, ManiaJudgement>
|
||||
{
|
||||
public ManiaScoreProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
public ManiaScoreProcessor(HitRenderer<ManiaBaseHit, ManiaJudgement> hitRenderer)
|
||||
public ManiaScoreProcessor(HitRenderer<ManiaHitObject, ManiaJudgement> hitRenderer)
|
||||
: base(hitRenderer)
|
||||
{
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
public class ManiaHitRenderer : HitRenderer<ManiaBaseHit, ManiaJudgement>
|
||||
public class ManiaHitRenderer : HitRenderer<ManiaHitObject, ManiaJudgement>
|
||||
{
|
||||
private readonly int columns;
|
||||
|
||||
@ -25,10 +25,10 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this);
|
||||
|
||||
protected override BeatmapConverter<ManiaBaseHit> CreateBeatmapConverter() => new ManiaBeatmapConverter();
|
||||
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter() => new ManiaBeatmapConverter();
|
||||
|
||||
protected override Playfield<ManiaBaseHit, ManiaJudgement> CreatePlayfield() => new ManiaPlayfield(columns);
|
||||
protected override Playfield<ManiaHitObject, ManiaJudgement> CreatePlayfield() => new ManiaPlayfield(columns);
|
||||
|
||||
protected override DrawableHitObject<ManiaBaseHit, ManiaJudgement> GetVisualRepresentation(ManiaBaseHit h) => null;
|
||||
protected override DrawableHitObject<ManiaHitObject, ManiaJudgement> GetVisualRepresentation(ManiaHitObject h) => null;
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
public class ManiaPlayfield : Playfield<ManiaBaseHit, ManiaJudgement>
|
||||
public class ManiaPlayfield : Playfield<ManiaHitObject, ManiaJudgement>
|
||||
{
|
||||
/// <summary>
|
||||
/// Default column keys, expanding outwards from the middle as more column are added.
|
||||
|
@ -48,12 +48,18 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Beatmaps\ManiaBeatmapConverter.cs" />
|
||||
<Compile Include="Judgements\HitWindows.cs" />
|
||||
<Compile Include="Judgements\ManiaJudgement.cs" />
|
||||
<Compile Include="ManiaDifficultyCalculator.cs" />
|
||||
<Compile Include="Objects\Drawables\DrawableHoldNote.cs" />
|
||||
<Compile Include="Objects\Drawables\DrawableManiaHitObject.cs" />
|
||||
<Compile Include="Objects\Drawables\DrawableNote.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\BodyPiece.cs" />
|
||||
<Compile Include="Objects\Drawables\Pieces\NotePiece.cs" />
|
||||
<Compile Include="Objects\Types\IHasColumn.cs" />
|
||||
<Compile Include="Scoring\ManiaScoreProcessor.cs" />
|
||||
<Compile Include="Objects\Drawable\DrawableNote.cs" />
|
||||
<Compile Include="Objects\HoldNote.cs" />
|
||||
<Compile Include="Objects\ManiaBaseHit.cs" />
|
||||
<Compile Include="Objects\ManiaHitObject.cs" />
|
||||
<Compile Include="Objects\Note.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="UI\Column.cs" />
|
||||
|
@ -54,33 +54,33 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
{
|
||||
AddInternal(new Drawable[]
|
||||
{
|
||||
rightBackgroundContainer = new Container
|
||||
{
|
||||
Name = "Transparent playfield background",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
BorderThickness = 2,
|
||||
Masking = true,
|
||||
EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Colour = Color4.Black.Opacity(0.2f),
|
||||
Radius = 5,
|
||||
},
|
||||
Children = new Drawable[]
|
||||
{
|
||||
rightBackground = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.6f
|
||||
},
|
||||
}
|
||||
},
|
||||
new ScaleFixContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = DEFAULT_PLAYFIELD_HEIGHT,
|
||||
Children = new[]
|
||||
{
|
||||
rightBackgroundContainer = new Container
|
||||
{
|
||||
Name = "Transparent playfield background",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
BorderThickness = 2,
|
||||
Masking = true,
|
||||
EdgeEffect = new EdgeEffect
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Colour = Color4.Black.Opacity(0.2f),
|
||||
Radius = 5,
|
||||
},
|
||||
Children = new Drawable[]
|
||||
{
|
||||
rightBackground = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.6f
|
||||
},
|
||||
}
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Name = "Transparent playfield elements",
|
||||
|
@ -135,14 +135,13 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
waitAction = () =>
|
||||
{
|
||||
while ((resultBeatmaps = host.Dependencies.Get<BeatmapDatabase>()
|
||||
.Query<BeatmapInfo>().Where(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() != 12)
|
||||
.GetAllWithChildren<BeatmapInfo>(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() != 12)
|
||||
Thread.Sleep(50);
|
||||
};
|
||||
|
||||
Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout),
|
||||
@"Beatmaps did not import to the database in allocated time");
|
||||
|
||||
//fetch children and check we can load from the post-storage path...
|
||||
var set = host.Dependencies.Get<BeatmapDatabase>().GetChildren(resultSets.First());
|
||||
|
||||
Assert.IsTrue(set.Beatmaps.Count == resultBeatmaps.Count(),
|
||||
|
@ -51,14 +51,12 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
title = new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-BoldItalic",
|
||||
Text = beatmap.BeatmapSetInfo.Metadata.Title,
|
||||
TextSize = 22,
|
||||
Shadow = true,
|
||||
},
|
||||
artist = new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-SemiBoldItalic",
|
||||
Text = beatmap.BeatmapSetInfo.Metadata.Artist,
|
||||
TextSize = 17,
|
||||
Shadow = true,
|
||||
},
|
||||
@ -81,8 +79,8 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(LocalisationEngine localisation)
|
||||
{
|
||||
title.Current = localisation.GetUnicodePreference(beatmap.BeatmapSetInfo.Metadata.TitleUnicode, beatmap.BeatmapSetInfo.Metadata.Title);
|
||||
artist.Current = localisation.GetUnicodePreference(beatmap.BeatmapSetInfo.Metadata.ArtistUnicode, beatmap.BeatmapSetInfo.Metadata.Artist);
|
||||
title.Current = localisation.GetUnicodePreference(beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title);
|
||||
artist.Current = localisation.GetUnicodePreference(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist);
|
||||
}
|
||||
|
||||
private class PanelBackground : BufferedContainer
|
||||
|
@ -18,14 +18,17 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
public readonly BeatmapSetInfo BeatmapSetInfo;
|
||||
|
||||
public readonly BeatmapMetadata Metadata;
|
||||
|
||||
public readonly Bindable<IEnumerable<Mod>> Mods = new Bindable<IEnumerable<Mod>>(new Mod[] { });
|
||||
|
||||
public readonly bool WithStoryboard;
|
||||
|
||||
protected WorkingBeatmap(BeatmapInfo beatmapInfo, BeatmapSetInfo beatmapSetInfo, bool withStoryboard = false)
|
||||
protected WorkingBeatmap(BeatmapInfo beatmapInfo, bool withStoryboard = false)
|
||||
{
|
||||
BeatmapInfo = beatmapInfo;
|
||||
BeatmapSetInfo = beatmapSetInfo;
|
||||
BeatmapSetInfo = beatmapInfo.BeatmapSet;
|
||||
Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo.Metadata;
|
||||
WithStoryboard = withStoryboard;
|
||||
|
||||
Mods.ValueChanged += mods => applyRateAdjustments();
|
||||
|
@ -36,14 +36,12 @@ namespace osu.Game.Database
|
||||
|
||||
private void deletePending()
|
||||
{
|
||||
foreach (var b in Query<BeatmapSetInfo>().Where(b => b.DeletePending))
|
||||
foreach (var b in GetAllWithChildren<BeatmapSetInfo>(b => b.DeletePending))
|
||||
{
|
||||
try
|
||||
{
|
||||
Storage.Delete(b.Path);
|
||||
|
||||
GetChildren(b, true);
|
||||
|
||||
foreach (var i in b.Beatmaps)
|
||||
{
|
||||
if (i.Metadata != null) Connection.Delete(i.Metadata);
|
||||
@ -269,20 +267,16 @@ namespace osu.Game.Database
|
||||
|
||||
public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo, WorkingBeatmap previous = null, bool withStoryboard = false)
|
||||
{
|
||||
var beatmapSetInfo = Query<BeatmapSetInfo>().FirstOrDefault(s => s.ID == beatmapInfo.BeatmapSetInfoID);
|
||||
if (beatmapInfo.BeatmapSet == null)
|
||||
beatmapInfo = GetChildren(beatmapInfo, true);
|
||||
|
||||
if (beatmapSetInfo == null)
|
||||
if (beatmapInfo.BeatmapSet == null)
|
||||
throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetInfoID} is not in the local database.");
|
||||
|
||||
//we need metadata
|
||||
GetChildren(beatmapSetInfo);
|
||||
//we also need a ruleset
|
||||
GetChildren(beatmapInfo);
|
||||
|
||||
if (beatmapInfo.Metadata == null)
|
||||
beatmapInfo.Metadata = beatmapSetInfo.Metadata;
|
||||
beatmapInfo.Metadata = beatmapInfo.BeatmapSet.Metadata;
|
||||
|
||||
WorkingBeatmap working = new DatabaseWorkingBeatmap(this, beatmapInfo, beatmapSetInfo, withStoryboard);
|
||||
WorkingBeatmap working = new DatabaseWorkingBeatmap(this, beatmapInfo, withStoryboard);
|
||||
|
||||
previous?.TransferTo(working);
|
||||
|
||||
|
@ -48,11 +48,9 @@ namespace osu.Game.Database
|
||||
return Connection.Table<T>();
|
||||
}
|
||||
|
||||
public T GetWithChildren<T>(object id) where T : class
|
||||
{
|
||||
return Connection.GetWithChildren<T>(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is expensive. Use with caution.
|
||||
/// </summary>
|
||||
public List<T> GetAllWithChildren<T>(Expression<Func<T, bool>> filter = null, bool recursive = true)
|
||||
where T : class
|
||||
{
|
||||
|
@ -14,8 +14,8 @@ namespace osu.Game.Database
|
||||
{
|
||||
private readonly BeatmapDatabase database;
|
||||
|
||||
public DatabaseWorkingBeatmap(BeatmapDatabase database, BeatmapInfo beatmapInfo, BeatmapSetInfo beatmapSetInfo, bool withStoryboard = false)
|
||||
: base(beatmapInfo, beatmapSetInfo, withStoryboard)
|
||||
public DatabaseWorkingBeatmap(BeatmapDatabase database, BeatmapInfo beatmapInfo, bool withStoryboard = false)
|
||||
: base(beatmapInfo, withStoryboard)
|
||||
{
|
||||
this.database = database;
|
||||
}
|
||||
@ -51,13 +51,13 @@ namespace osu.Game.Database
|
||||
|
||||
protected override Texture GetBackground()
|
||||
{
|
||||
if (BeatmapInfo?.Metadata?.BackgroundFile == null)
|
||||
if (Metadata?.BackgroundFile == null)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
using (var reader = getReader())
|
||||
return new TextureStore(new RawTextureLoaderStore(reader), false).Get(BeatmapInfo.Metadata.BackgroundFile);
|
||||
return new TextureStore(new RawTextureLoaderStore(reader), false).Get(Metadata.BackgroundFile);
|
||||
}
|
||||
catch { return null; }
|
||||
}
|
||||
@ -66,7 +66,7 @@ namespace osu.Game.Database
|
||||
{
|
||||
try
|
||||
{
|
||||
var trackData = getReader()?.GetStream(BeatmapInfo.Metadata.AudioFile);
|
||||
var trackData = getReader()?.GetStream(Metadata.AudioFile);
|
||||
return trackData == null ? null : new TrackBass(trackData);
|
||||
}
|
||||
catch { return null; }
|
||||
|
@ -1,26 +0,0 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input;
|
||||
|
||||
namespace osu.Game.Input
|
||||
{
|
||||
public class GlobalHotkeys : Drawable
|
||||
{
|
||||
public Func<InputState, KeyDownEventArgs, bool> Handler;
|
||||
|
||||
public override bool HandleInput => true;
|
||||
|
||||
public GlobalHotkeys()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
|
||||
{
|
||||
return Handler(state, args);
|
||||
}
|
||||
}
|
||||
}
|
@ -72,21 +72,28 @@ namespace osu.Game.Online.API
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly object access_token_retrieval_lock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Should be run before any API request to make sure we have a valid key.
|
||||
/// </summary>
|
||||
private bool ensureAccessToken()
|
||||
{
|
||||
//todo: we need to mutex this to ensure only one authentication request is running at a time.
|
||||
|
||||
//If we already have a valid access token, let's use it.
|
||||
// if we already have a valid access token, let's use it.
|
||||
if (accessTokenValid) return true;
|
||||
|
||||
//If not, let's try using our refresh token to request a new access token.
|
||||
if (!string.IsNullOrEmpty(Token?.RefreshToken))
|
||||
AuthenticateWithRefresh(Token.RefreshToken);
|
||||
// we want to ensure only a single authentication update is happening at once.
|
||||
lock (access_token_retrieval_lock)
|
||||
{
|
||||
// re-check if valid, in case another request completed and revalidated our access.
|
||||
if (accessTokenValid) return true;
|
||||
|
||||
return accessTokenValid;
|
||||
// if not, let's try using our refresh token to request a new access token.
|
||||
if (!string.IsNullOrEmpty(Token?.RefreshToken))
|
||||
AuthenticateWithRefresh(Token.RefreshToken);
|
||||
|
||||
return accessTokenValid;
|
||||
}
|
||||
}
|
||||
|
||||
private bool accessTokenValid => Token?.IsValid ?? false;
|
||||
|
@ -41,13 +41,13 @@ namespace osu.Game.Online.API
|
||||
[JsonProperty(@"refresh_token")]
|
||||
public string RefreshToken;
|
||||
|
||||
public override string ToString() => $@"{AccessToken}/{AccessTokenExpiry.ToString(NumberFormatInfo.InvariantInfo)}/{RefreshToken}";
|
||||
public override string ToString() => $@"{AccessToken}|{AccessTokenExpiry.ToString(NumberFormatInfo.InvariantInfo)}|{RefreshToken}";
|
||||
|
||||
public static OAuthToken Parse(string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] parts = value.Split('/');
|
||||
string[] parts = value.Split('|');
|
||||
return new OAuthToken
|
||||
{
|
||||
AccessToken = parts[0],
|
||||
|
@ -9,7 +9,6 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Input;
|
||||
using OpenTK.Input;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Graphics.UserInterface.Volume;
|
||||
|
@ -110,12 +110,18 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
MoveToY(0, transition_length, EasingTypes.OutQuint);
|
||||
FadeIn(transition_length, EasingTypes.OutQuint);
|
||||
|
||||
inputTextBox.HoldFocus = true;
|
||||
base.PopIn();
|
||||
}
|
||||
|
||||
protected override void PopOut()
|
||||
{
|
||||
MoveToY(DrawSize.Y, transition_length, EasingTypes.InSine);
|
||||
FadeOut(transition_length, EasingTypes.InSine);
|
||||
|
||||
inputTextBox.HoldFocus = false;
|
||||
base.PopOut();
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
|
@ -315,7 +315,7 @@ namespace osu.Game.Overlays
|
||||
}
|
||||
else
|
||||
{
|
||||
BeatmapMetadata metadata = beatmap.Beatmap.BeatmapInfo.Metadata;
|
||||
BeatmapMetadata metadata = beatmap.Metadata;
|
||||
title.Current = localisation.GetUnicodePreference(metadata.TitleUnicode, metadata.Title);
|
||||
artist.Current = localisation.GetUnicodePreference(metadata.ArtistUnicode, metadata.Artist);
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
@ -12,12 +11,23 @@ using Container = osu.Framework.Graphics.Containers.Container;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Game.Audio;
|
||||
using System.Linq;
|
||||
|
||||
namespace osu.Game.Rulesets.Objects.Drawables
|
||||
{
|
||||
public abstract class DrawableHitObject<TJudgement> : Container, IStateful<ArmedState>
|
||||
public abstract class DrawableHitObject<TObject, TJudgement> : Container
|
||||
where TObject : HitObject
|
||||
where TJudgement : Judgement
|
||||
{
|
||||
public event Action<DrawableHitObject<TObject, TJudgement>> OnJudgement;
|
||||
|
||||
public TObject HitObject;
|
||||
|
||||
/// <summary>
|
||||
/// The colour used for various elements of this DrawableHitObject.
|
||||
/// </summary>
|
||||
public virtual Color4 AccentColour { get; set; }
|
||||
|
||||
public override bool HandleInput => Interactive;
|
||||
|
||||
public bool Interactive = true;
|
||||
@ -56,14 +66,6 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
||||
Samples.ForEach(s => s?.Play());
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
//we may be setting a custom judgement in test cases or what not.
|
||||
if (Judgement == null)
|
||||
Judgement = CreateJudgement();
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
@ -71,20 +73,11 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
||||
//force application of the state that was set before we loaded.
|
||||
UpdateState(State);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class DrawableHitObject<TObject, TJudgement> : DrawableHitObject<TJudgement>
|
||||
where TObject : HitObject
|
||||
where TJudgement : Judgement
|
||||
{
|
||||
public event Action<DrawableHitObject<TObject, TJudgement>> OnJudgement;
|
||||
|
||||
public TObject HitObject;
|
||||
|
||||
/// <summary>
|
||||
/// The colour used for various elements of this DrawableHitObject.
|
||||
/// Whether this hit object and all of its nested hit objects have been judged.
|
||||
/// </summary>
|
||||
public Color4 AccentColour { get; protected set; }
|
||||
public bool Judged => (Judgement?.Result ?? HitResult.None) != HitResult.None && (NestedHitObjects?.All(h => h.Judged) ?? true);
|
||||
|
||||
protected DrawableHitObject(TObject hitObject)
|
||||
{
|
||||
@ -97,7 +90,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
||||
/// <returns>Whether a hit was processed.</returns>
|
||||
protected bool UpdateJudgement(bool userTriggered)
|
||||
{
|
||||
IPartialJudgement partial = Judgement as IPartialJudgement;
|
||||
var partial = Judgement as IPartialJudgement;
|
||||
|
||||
// Never re-process non-partial hits
|
||||
if (Judgement.Result != HitResult.None && partial == null)
|
||||
@ -166,10 +159,13 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
||||
channel.Volume.Value = sample.Volume;
|
||||
Samples.Add(channel);
|
||||
}
|
||||
|
||||
//we may be setting a custom judgement in test cases or what not.
|
||||
if (Judgement == null)
|
||||
Judgement = CreateJudgement();
|
||||
}
|
||||
|
||||
private List<DrawableHitObject<TObject, TJudgement>> nestedHitObjects;
|
||||
|
||||
protected IEnumerable<DrawableHitObject<TObject, TJudgement>> NestedHitObjects => nestedHitObjects;
|
||||
|
||||
protected void AddNested(DrawableHitObject<TObject, TJudgement> h)
|
||||
|
@ -187,17 +187,19 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
public sealed override bool ProvidingUserCursor => !HasReplayLoaded && Playfield.ProvidingUserCursor;
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
protected override bool AllObjectsJudged => Playfield.HitObjects.Children.All(h => h.Judgement.Result != HitResult.None);
|
||||
public override IEnumerable<HitObject> Objects => Beatmap.HitObjects;
|
||||
|
||||
protected override bool AllObjectsJudged => drawableObjects.All(h => h.Judged);
|
||||
|
||||
/// <summary>
|
||||
/// The playfield.
|
||||
/// </summary>
|
||||
protected Playfield<TObject, TJudgement> Playfield;
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
private readonly Container content;
|
||||
|
||||
public override IEnumerable<HitObject> Objects => Beatmap.HitObjects;
|
||||
private readonly List<DrawableHitObject<TObject, TJudgement>> drawableObjects = new List<DrawableHitObject<TObject, TJudgement>>();
|
||||
|
||||
protected HitRenderer(WorkingBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
@ -224,6 +226,8 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
private void loadObjects()
|
||||
{
|
||||
drawableObjects.Capacity = Beatmap.HitObjects.Count;
|
||||
|
||||
foreach (TObject h in Beatmap.HitObjects)
|
||||
{
|
||||
var drawableObject = GetVisualRepresentation(h);
|
||||
@ -233,6 +237,7 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
drawableObject.OnJudgement += onJudgement;
|
||||
|
||||
drawableObjects.Add(drawableObject);
|
||||
Playfield.Add(drawableObject);
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.UI
|
||||
/// <summary>
|
||||
/// The HitObjects contained in this Playfield.
|
||||
/// </summary>
|
||||
public HitObjectContainer<DrawableHitObject<TObject, TJudgement>> HitObjects;
|
||||
protected HitObjectContainer<DrawableHitObject<TObject, TJudgement>> HitObjects;
|
||||
|
||||
internal Container<Drawable> ScaledContent;
|
||||
|
||||
|
@ -1,13 +1,16 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using OpenTK;
|
||||
using OpenTK.Input;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics.Containers;
|
||||
@ -16,14 +19,8 @@ using osu.Game.Screens.Charts;
|
||||
using osu.Game.Screens.Direct;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Multiplayer;
|
||||
using OpenTK;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Screens.Tournament;
|
||||
using osu.Framework.Input;
|
||||
using OpenTK.Input;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
@ -65,7 +62,6 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
private Bindable<bool> menuMusic;
|
||||
private TrackManager trackManager;
|
||||
private WorkingBeatmap song;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuGame game, OsuConfigManager config, BeatmapDatabase beatmaps)
|
||||
@ -76,11 +72,15 @@ namespace osu.Game.Screens.Menu
|
||||
if (!menuMusic)
|
||||
{
|
||||
trackManager = game.Audio.Track;
|
||||
List<BeatmapSetInfo> choosableBeatmapSets = beatmaps.Query<BeatmapSetInfo>().ToList();
|
||||
if (choosableBeatmapSets.Count > 0)
|
||||
|
||||
var query = beatmaps.Query<BeatmapSetInfo>().Where(b => !b.DeletePending);
|
||||
int count = query.Count();
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
song = beatmaps.GetWorkingBeatmap(beatmaps.GetWithChildren<BeatmapSetInfo>(choosableBeatmapSets[RNG.Next(0, choosableBeatmapSets.Count - 1)].ID).Beatmaps[0]);
|
||||
Beatmap = song;
|
||||
var beatmap = query.ElementAt(RNG.Next(0, count - 1));
|
||||
beatmaps.GetChildren(beatmap);
|
||||
Beatmap = beatmaps.GetWorkingBeatmap(beatmap.Beatmaps[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,15 +106,15 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
base.OnEntering(last);
|
||||
buttons.FadeInFromZero(500);
|
||||
if (last is Intro && song != null)
|
||||
if (last is Intro && Beatmap != null)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
trackManager.SetExclusive(song.Track);
|
||||
song.Track.Seek(song.Beatmap.Metadata.PreviewTime);
|
||||
if (song.Beatmap.Metadata.PreviewTime == -1)
|
||||
song.Track.Seek(song.Track.Length * 0.4f);
|
||||
song.Track.Start();
|
||||
trackManager.SetExclusive(Beatmap.Track);
|
||||
Beatmap.Track.Seek(Beatmap.Metadata.PreviewTime);
|
||||
if (Beatmap.Metadata.PreviewTime == -1)
|
||||
Beatmap.Track.Seek(Beatmap.Track.Length * 0.4f);
|
||||
Beatmap.Track.Start();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -220,13 +220,11 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private BeatmapGroup createGroup(BeatmapSetInfo beatmapSet)
|
||||
{
|
||||
database.GetChildren(beatmapSet);
|
||||
beatmapSet.Beatmaps.ForEach(b =>
|
||||
foreach(var b in beatmapSet.Beatmaps)
|
||||
{
|
||||
database.GetChildren(b);
|
||||
if (b.Metadata == null)
|
||||
b.Metadata = beatmapSet.Metadata;
|
||||
});
|
||||
}
|
||||
|
||||
return new BeatmapGroup(beatmapSet, database)
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
Icon = FontAwesome.fa_trash_o;
|
||||
HeaderText = @"Confirm deletion of";
|
||||
BodyText = $@"{beatmap.Beatmap?.Metadata?.Artist} - {beatmap.Beatmap?.Metadata?.Title}";
|
||||
BodyText = $@"{beatmap.Metadata?.Artist} - {beatmap.Metadata?.Title}";
|
||||
Buttons = new PopupDialogButton[]
|
||||
{
|
||||
new PopupDialogOkButton
|
||||
|
@ -183,7 +183,7 @@ namespace osu.Game.Screens.Select
|
||||
initialAddSetsTask = new CancellationTokenSource();
|
||||
|
||||
carousel.BeatmapsChanged = beatmapsLoaded;
|
||||
carousel.Beatmaps = database.Query<BeatmapSetInfo>().Where(b => !b.DeletePending);
|
||||
carousel.Beatmaps = database.GetAllWithChildren<BeatmapSetInfo>(b => !b.DeletePending);
|
||||
}
|
||||
|
||||
private void beatmapsLoaded()
|
||||
@ -343,7 +343,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
trackManager.SetExclusive(track);
|
||||
if (preview)
|
||||
track.Seek(Beatmap.Beatmap.Metadata.PreviewTime);
|
||||
track.Seek(Beatmap.Metadata.PreviewTime);
|
||||
track.Start();
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +285,6 @@
|
||||
<Compile Include="Screens\Play\HUD\ComboResultCounter.cs" />
|
||||
<Compile Include="Graphics\UserInterface\RollingCounter.cs" />
|
||||
<Compile Include="Graphics\UserInterface\Volume\VolumeControlReceptor.cs" />
|
||||
<Compile Include="Input\GlobalHotkeys.cs" />
|
||||
<Compile Include="Graphics\Backgrounds\Background.cs" />
|
||||
<Compile Include="Graphics\Containers\ParallaxContainer.cs" />
|
||||
<Compile Include="Graphics\Cursor\MenuCursor.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user