1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-14 10:22:41 +08:00

Compare commits

..

4 Commits

64 changed files with 419 additions and 693 deletions
+4 -20
View File
@@ -11,11 +11,7 @@
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build tests (Debug)",
"linux": {
"env": {
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
}
},
"env": {},
"console": "internalConsole"
},
{
@@ -28,11 +24,7 @@
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build tests (Release)",
"linux": {
"env": {
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
}
},
"env": {},
"console": "internalConsole"
},
{
@@ -45,11 +37,7 @@
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Debug)",
"linux": {
"env": {
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
}
},
"env": {},
"console": "internalConsole"
},
{
@@ -62,11 +50,7 @@
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Release)",
"linux": {
"env": {
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
}
},
"env": {},
"console": "internalConsole"
}
]
@@ -15,8 +15,6 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
{
public class CatchBeatmapProcessor : BeatmapProcessor
{
public const int RNG_SEED = 1337;
public CatchBeatmapProcessor(IBeatmap beatmap)
: base(beatmap)
{
@@ -24,12 +22,12 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
public override void PostProcess()
{
base.PostProcess();
applyPositionOffsets();
initialiseHyperDash((List<CatchHitObject>)Beatmap.HitObjects);
base.PostProcess();
int index = 0;
foreach (var obj in Beatmap.HitObjects.OfType<CatchHitObject>())
{
@@ -39,6 +37,8 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
}
}
public const int RNG_SEED = 1337;
private void applyPositionOffsets()
{
var rng = new FastRandom(RNG_SEED);
@@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Mania.Tests
var obj = new Note { Column = i, StartTime = Time.Current + 2000 };
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
columns[i].Add(new DrawableNote(obj));
columns[i].Add(new DrawableNote(obj, columns[i].Action));
}
}
@@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Mania.Tests
var obj = new HoldNote { Column = i, StartTime = Time.Current + 2000, Duration = 500 };
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
columns[i].Add(new DrawableHoldNote(obj));
columns[i].Add(new DrawableHoldNote(obj, columns[i].Action));
}
}
@@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Mania.Tests
Origin = Anchor.Centre,
Height = 0.85f,
AccentColour = Color4.OrangeRed,
Action = { Value = action },
Action = action,
VisibleTimeRange = { Value = 2000 }
};
+5 -10
View File
@@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -64,7 +63,7 @@ namespace osu.Game.Rulesets.Mania.Tests
AutoSizeAxes = Axes.Both,
Child = new NoteContainer(direction, $"note, scrolling {direction.ToString().ToLower()}")
{
Child = new DrawableNote(note) { AccentColour = Color4.OrangeRed }
Child = new DrawableNote(note, ManiaAction.Key1) { AccentColour = Color4.OrangeRed }
}
};
}
@@ -79,7 +78,7 @@ namespace osu.Game.Rulesets.Mania.Tests
AutoSizeAxes = Axes.Both,
Child = new NoteContainer(direction, $"hold note, scrolling {direction.ToString().ToLower()}")
{
Child = new DrawableHoldNote(note)
Child = new DrawableHoldNote(note, ManiaAction.Key1)
{
RelativeSizeAxes = Axes.Both,
AccentColour = Color4.OrangeRed,
@@ -137,13 +136,6 @@ namespace osu.Game.Rulesets.Mania.Tests
};
}
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
{
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
dependencies.CacheAs<IBindable<ManiaAction>>(new Bindable<ManiaAction>());
return dependencies;
}
protected override void Update()
{
base.Update();
@@ -153,6 +145,9 @@ namespace osu.Game.Rulesets.Mania.Tests
if (!(obj.HitObject is IHasEndTime endTime))
continue;
if (!obj.HasNestedHitObjects)
continue;
foreach (var nested in obj.NestedHitObjects)
{
double finalPosition = (nested.HitObject.StartTime - obj.HitObject.StartTime) / endTime.Duration;
@@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Mania.Tests
var obj = new Note { Column = i, StartTime = Time.Current + 2000 };
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
stage.Add(new DrawableNote(obj));
stage.Add(new DrawableNote(obj, stage.Columns[i].Action));
}
}
}
@@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Mania.Tests
var obj = new HoldNote { Column = i, StartTime = Time.Current + 2000, Duration = 500 };
obj.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
stage.Add(new DrawableHoldNote(obj));
stage.Add(new DrawableHoldNote(obj, stage.Columns[i].Action));
}
}
}
@@ -38,8 +38,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
private readonly Container<DrawableHoldNoteTick> tickContainer;
public DrawableHoldNote(HoldNote hitObject)
: base(hitObject)
public DrawableHoldNote(HoldNote hitObject, ManiaAction action)
: base(hitObject, action)
{
RelativeSizeAxes = Axes.X;
@@ -57,12 +57,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
HoldStartTime = () => holdStartTime
})
},
head = new DrawableHeadNote(this)
head = new DrawableHeadNote(this, action)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre
},
tail = new DrawableTailNote(this)
tail = new DrawableTailNote(this, action)
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre
@@ -118,7 +118,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
if (Time.Current < HitObject.StartTime || Time.Current > HitObject.EndTime)
return false;
if (action != Action.Value)
if (action != Action)
return false;
// The user has pressed during the body of the hold note, after the head note and its hit windows have passed
@@ -135,7 +135,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
if (!holdStartTime.HasValue)
return false;
if (action != Action.Value)
if (action != Action)
return false;
holdStartTime = null;
@@ -154,8 +154,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
private readonly DrawableHoldNote holdNote;
public DrawableHeadNote(DrawableHoldNote holdNote)
: base(holdNote.HitObject.Head)
public DrawableHeadNote(DrawableHoldNote holdNote, ManiaAction action)
: base(holdNote.HitObject.Head, action)
{
this.holdNote = holdNote;
}
@@ -191,8 +191,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
private readonly DrawableHoldNote holdNote;
public DrawableTailNote(DrawableHoldNote holdNote)
: base(holdNote.HitObject.Tail)
public DrawableTailNote(DrawableHoldNote holdNote, ManiaAction action)
: base(holdNote.HitObject.Tail, action)
{
this.holdNote = holdNote;
}
@@ -235,7 +235,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
if (!holdNote.holdStartTime.HasValue)
return false;
if (action != Action.Value)
if (action != Action)
return false;
UpdateJudgement(true);
@@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
@@ -11,26 +10,30 @@ using osu.Game.Rulesets.UI.Scrolling;
namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
public abstract class DrawableManiaHitObject : DrawableHitObject<ManiaHitObject>
public abstract class DrawableManiaHitObject<TObject> : DrawableHitObject<ManiaHitObject>
where TObject : ManiaHitObject
{
/// <summary>
/// The <see cref="ManiaAction"/> which causes this <see cref="DrawableManiaHitObject{TObject}"/> to be hit.
/// The key that will trigger input for this hit object.
/// </summary>
protected readonly IBindable<ManiaAction> Action = new Bindable<ManiaAction>();
protected ManiaAction Action { get; }
public new TObject HitObject;
protected readonly IBindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
protected DrawableManiaHitObject(ManiaHitObject hitObject)
protected DrawableManiaHitObject(TObject hitObject, ManiaAction? action = null)
: base(hitObject)
{
HitObject = hitObject;
if (action != null)
Action = action.Value;
}
[BackgroundDependencyLoader(true)]
private void load([CanBeNull] IBindable<ManiaAction> action, [NotNull] IScrollingInfo scrollingInfo)
[BackgroundDependencyLoader]
private void load(IScrollingInfo scrollingInfo)
{
if (action != null)
Action.BindTo(action);
Direction.BindTo(scrollingInfo.Direction);
Direction.BindValueChanged(OnDirectionChanged, true);
}
@@ -39,18 +42,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
Anchor = Origin = direction == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
}
}
public abstract class DrawableManiaHitObject<TObject> : DrawableManiaHitObject
where TObject : ManiaHitObject
{
public new readonly TObject HitObject;
protected DrawableManiaHitObject(TObject hitObject)
: base(hitObject)
{
HitObject = hitObject;
}
protected override void UpdateState(ArmedState state)
{
@@ -20,8 +20,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
private readonly NotePiece headPiece;
public DrawableNote(Note hitObject)
: base(hitObject)
public DrawableNote(Note hitObject, ManiaAction action)
: base(hitObject, action)
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
@@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
public virtual bool OnPressed(ManiaAction action)
{
if (action != Action.Value)
if (action != Action)
return false;
return UpdateJudgement(true);
+15 -10
View File
@@ -7,8 +7,6 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.UI.Components;
@@ -21,7 +19,21 @@ namespace osu.Game.Rulesets.Mania.UI
private const float column_width = 45;
private const float special_column_width = 70;
public readonly Bindable<ManiaAction> Action = new Bindable<ManiaAction>();
private ManiaAction action;
public ManiaAction Action
{
get => action;
set
{
if (action == value)
return;
action = value;
background.Action = value;
keyArea.Action = value;
}
}
private readonly ColumnBackground background;
private readonly ColumnKeyArea keyArea;
@@ -118,13 +130,6 @@ namespace osu.Game.Rulesets.Mania.UI
}
}
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
{
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
dependencies.CacheAs<IBindable<ManiaAction>>(Action);
return dependencies;
}
/// <summary>
/// Adds a DrawableHitObject to this Playfield.
/// </summary>
@@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
{
public class ColumnBackground : CompositeDrawable, IKeyBindingHandler<ManiaAction>, IHasAccentColour
{
private readonly IBindable<ManiaAction> action = new Bindable<ManiaAction>();
public ManiaAction Action;
private Box background;
private Box backgroundOverlay;
@@ -25,10 +25,8 @@ namespace osu.Game.Rulesets.Mania.UI.Components
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
[BackgroundDependencyLoader]
private void load(IBindable<ManiaAction> action, IScrollingInfo scrollingInfo)
private void load(IScrollingInfo scrollingInfo)
{
this.action.BindTo(action);
InternalChildren = new[]
{
background = new Box
@@ -93,14 +91,14 @@ namespace osu.Game.Rulesets.Mania.UI.Components
public bool OnPressed(ManiaAction action)
{
if (action == this.action.Value)
if (action == Action)
backgroundOverlay.FadeTo(1, 50, Easing.OutQuint).Then().FadeTo(0.5f, 250, Easing.OutQuint);
return false;
}
public bool OnReleased(ManiaAction action)
{
if (action == this.action.Value)
if (action == Action)
backgroundOverlay.FadeTo(0, 250, Easing.OutQuint);
return false;
}
@@ -21,16 +21,15 @@ namespace osu.Game.Rulesets.Mania.UI.Components
private const float key_icon_size = 10;
private const float key_icon_corner_radius = 3;
private readonly IBindable<ManiaAction> action = new Bindable<ManiaAction>();
public ManiaAction Action;
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
private Container keyIcon;
[BackgroundDependencyLoader]
private void load(IBindable<ManiaAction> action, IScrollingInfo scrollingInfo)
private void load(IScrollingInfo scrollingInfo)
{
this.action.BindTo(action);
Drawable gradient;
InternalChildren = new[]
@@ -108,14 +107,14 @@ namespace osu.Game.Rulesets.Mania.UI.Components
public bool OnPressed(ManiaAction action)
{
if (action == this.action.Value)
if (action == Action)
keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint).Then().ScaleTo(1.3f, 250, Easing.OutQuint);
return false;
}
public bool OnReleased(ManiaAction action)
{
if (action == this.action.Value)
if (action == Action)
keyIcon.ScaleTo(1f, 125, Easing.OutQuint);
return false;
}
@@ -101,15 +101,17 @@ namespace osu.Game.Rulesets.Mania.UI
protected override DrawableHitObject<ManiaHitObject> GetVisualRepresentation(ManiaHitObject h)
{
switch (h)
{
case HoldNote holdNote:
return new DrawableHoldNote(holdNote);
case Note note:
return new DrawableNote(note);
default:
return null;
}
ManiaAction action = Playfield.Columns.ElementAt(h.Column).Action;
var holdNote = h as HoldNote;
if (holdNote != null)
return new DrawableHoldNote(holdNote, action);
var note = h as Note;
if (note != null)
return new DrawableNote(note, action);
return null;
}
protected override Vector2 PlayfieldArea => new Vector2(1, 0.8f);
+1 -1
View File
@@ -127,7 +127,7 @@ namespace osu.Game.Rulesets.Mania.UI
var column = new Column(direction)
{
IsSpecial = isSpecial,
Action = { Value = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ }
Action = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++
};
AddColumn(column);
@@ -15,10 +15,10 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
{
}
public override void PreProcess()
public override void PostProcess()
{
base.PreProcess();
applyStacking((Beatmap<OsuHitObject>)Beatmap);
base.PostProcess();
}
private void applyStacking(Beatmap<OsuHitObject> beatmap)
@@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
continue;
double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime;
double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo.StackLeniency;
double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f;
if (objectN.StartTime - endTime > stackThreshold)
//We are no longer within stacking range of the next object.
@@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
OsuHitObject objectI = beatmap.HitObjects[i];
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
double stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo.StackLeniency;
double stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f;
/* If this object is a hitcircle, then we enter this "special" case.
* It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
@@ -93,9 +93,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
base.AccentColour = value;
Body.AccentColour = AccentColour;
Ball.AccentColour = AccentColour;
foreach (var drawableHitObject in NestedHitObjects)
drawableHitObject.AccentColour = AccentColour;
if (HasNestedHitObjects)
foreach (var drawableHitObject in NestedHitObjects)
drawableHitObject.AccentColour = AccentColour;
}
}
@@ -136,7 +136,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
if (!userTriggered && Time.Current >= slider.EndTime)
{
var judgementsCount = NestedHitObjects.Count();
var judgementsCount = NestedHitObjects.Count;
var judgementsHit = NestedHitObjects.Count(h => h.IsHit);
var hitFraction = (double)judgementsHit / judgementsCount;
@@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.UI
private void loadBarLines()
{
TaikoHitObject lastObject = Beatmap.HitObjects[Beatmap.HitObjects.Count - 1];
double lastHitTime = 1 + ((lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime);
double lastHitTime = 1 + (lastObject as IHasEndTime)?.EndTime ?? lastObject.StartTime;
var timingPoints = Beatmap.ControlPointInfo.TimingPoints.ToList();
@@ -11,7 +11,6 @@ using osu.Game.Audio;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.Timing;
using osu.Game.Rulesets.Objects;
using osu.Game.Skinning;
namespace osu.Game.Tests.Beatmaps.Formats
@@ -212,41 +211,5 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.IsTrue(hitObjects[1].Samples.Any(s => s.Name == SampleInfo.HIT_CLAP));
}
}
[Test]
public void TestDecodeCustomSamples()
{
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
using (var resStream = Resource.OpenResource("custom-samples.osu"))
using (var stream = new StreamReader(resStream))
{
var hitObjects = decoder.Decode(stream).HitObjects;
Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[0]).Name);
Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[1]).Name);
Assert.AreEqual("hitnormal2", getTestableSampleInfo(hitObjects[2]).Name);
Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[3]).Name);
}
SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(new SampleInfo { Name = "hitnormal" });
}
[Test]
public void TestDecodeCustomHitObjectSamples()
{
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
using (var resStream = Resource.OpenResource("custom-hitobject-samples.osu"))
using (var stream = new StreamReader(resStream))
{
var hitObjects = decoder.Decode(stream).HitObjects;
Assert.AreEqual("hit_1.wav", hitObjects[0].Samples[0].LookupNames.First());
Assert.AreEqual("hit_2.wav", hitObjects[1].Samples[0].LookupNames.First());
Assert.AreEqual("hitnormal2", getTestableSampleInfo(hitObjects[2]).Name);
Assert.AreEqual("hit_1.wav", hitObjects[3].Samples[0].LookupNames.First());
}
SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(new SampleInfo { Name = "hitnormal" });
}
}
}
@@ -118,11 +118,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
public void TestParity(string beatmap)
{
var legacy = decode(beatmap, out Beatmap json);
json.WithDeepEqual(legacy)
.IgnoreProperty(r => r.DeclaringType == typeof(HitWindows)
// Todo: CustomSampleBank shouldn't exist going forward, we need a conversion mechanism
|| r.Name == nameof(LegacyDecoder<Beatmap>.LegacySampleControlPoint.CustomSampleBank))
.Assert();
json.WithDeepEqual(legacy).IgnoreProperty(r => r.DeclaringType == typeof(HitWindows)).Assert();
}
/// <summary>
@@ -1,16 +0,0 @@
osu file format v14
[General]
SampleSet: Normal
[TimingPoints]
2170,468.75,4,1,0,40,1,0
2638,-100,4,1,1,40,0,0
3107,-100,4,1,2,40,0,0
3576,-100,4,1,0,40,0,0
[HitObjects]
255,193,2170,1,0,0:0:0:0:hit_1.wav
256,191,2638,5,0,0:0:0:0:hit_2.wav
255,193,3107,1,0,0:0:0:0:
256,191,3576,1,0,0:0:0:0:hit_1.wav
@@ -1,16 +0,0 @@
osu file format v14
[General]
SampleSet: Normal
[TimingPoints]
2170,468.75,4,1,0,40,1,0
2638,-100,4,1,1,40,0,0
3107,-100,4,1,2,40,0,0
3576,-100,4,1,0,40,0,0
[HitObjects]
255,193,2170,1,0,0:0:0:0:
256,191,2638,5,0,0:0:0:0:
255,193,3107,1,0,0:0:0:0:
256,191,3576,1,0,0:0:0:0:
@@ -65,19 +65,17 @@ namespace osu.Game.Tests.Visual
foreach (var rulesetInfo in rulesets.AvailableRulesets)
{
var instance = rulesetInfo.CreateInstance();
var ruleset = rulesetInfo.CreateInstance();
var testBeatmap = createTestBeatmap(rulesetInfo);
beatmaps.Add(testBeatmap);
AddStep("set ruleset", () => Ruleset.Value = rulesetInfo);
selectBeatmap(testBeatmap);
testBeatmapLabels(instance);
testBeatmapLabels(ruleset);
// TODO: adjust cases once more info is shown for other gamemodes
switch (instance)
switch (ruleset)
{
case OsuRuleset _:
testInfoLabels(5);
+1 -1
View File
@@ -77,7 +77,7 @@ namespace osu.Game.Tests.Visual
foreach (var rulesetInfo in rulesets.AvailableRulesets)
{
Ruleset ruleset = rulesetInfo.CreateInstance();
AddStep($"switch to {ruleset.Description}", () => Ruleset.Value = rulesetInfo);
AddStep($"switch to {ruleset.Description}", () => modSelect.Ruleset.Value = rulesetInfo);
switch (ruleset)
{
-17
View File
@@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
namespace osu.Game.Audio
{
@@ -33,21 +32,5 @@ namespace osu.Game.Audio
/// The sample volume.
/// </summary>
public int Volume;
/// <summary>
/// Retrieve all possible filenames that can be used as a source, returned in order of preference (highest first).
/// </summary>
public virtual IEnumerable<string> LookupNames
{
get
{
if (!string.IsNullOrEmpty(Namespace))
yield return $"{Namespace}/{Bank}-{Name}";
yield return $"{Bank}-{Name}"; // Without namespace as a fallback even when we have a namespace
}
}
public SampleInfo Clone() => (SampleInfo)MemberwiseClone();
}
}
+22 -6
View File
@@ -6,9 +6,23 @@ using osu.Game.Rulesets.Objects.Types;
namespace osu.Game.Beatmaps
{
public interface IBeatmapProcessor
{
IBeatmap Beatmap { get; }
/// <summary>
/// Post-processes <see cref="Beatmap"/> to add mode-specific components that aren't added during conversion.
/// <para>
/// An example of such a usage is for combo colours.
/// </para>
/// </summary>
void PostProcess();
}
/// <summary>
/// Provides functionality to alter a <see cref="IBeatmap"/> after it has been converted.
/// Processes a post-converted Beatmap.
/// </summary>
/// <typeparam name="TObject">The type of HitObject contained in the Beatmap.</typeparam>
public class BeatmapProcessor : IBeatmapProcessor
{
public IBeatmap Beatmap { get; }
@@ -18,7 +32,13 @@ namespace osu.Game.Beatmaps
Beatmap = beatmap;
}
public virtual void PreProcess()
/// <summary>
/// Post-processes a Beatmap to add mode-specific components that aren't added during conversion.
/// <para>
/// An example of such a usage is for combo colours.
/// </para>
/// </summary>
public virtual void PostProcess()
{
IHasComboInformation lastObj = null;
@@ -42,9 +62,5 @@ namespace osu.Game.Beatmaps
lastObj = obj;
}
}
public virtual void PostProcess()
{
}
}
}
@@ -14,15 +14,6 @@ namespace osu.Game.Beatmaps.ControlPoints
public int CompareTo(ControlPoint other) => Time.CompareTo(other.Time);
/// <summary>
/// Whether this <see cref="ControlPoint"/> provides the same parametric changes as another <see cref="ControlPoint"/>.
/// Basically an equality check without considering the <see cref="Time"/>.
/// </summary>
/// <param name="other">The <see cref="ControlPoint"/> to compare to.</param>
/// <returns>Whether this <see cref="ControlPoint"/> is equivalent to <paramref name="other"/>.</returns>
public virtual bool EquivalentTo(ControlPoint other) => true;
public bool Equals(ControlPoint other)
=> EquivalentTo(other) && Time.Equals(other?.Time);
public bool Equals(ControlPoint other) => Time.Equals(other?.Time);
}
}
@@ -17,10 +17,5 @@ namespace osu.Game.Beatmaps.ControlPoints
}
private double speedMultiplier = 1;
public override bool EquivalentTo(ControlPoint other)
=> base.EquivalentTo(other)
&& other is DifficultyControlPoint difficulty
&& SpeedMultiplier.Equals(difficulty.SpeedMultiplier);
}
}
@@ -14,11 +14,5 @@ namespace osu.Game.Beatmaps.ControlPoints
/// Whether the first bar line of this control point is ignored.
/// </summary>
public bool OmitFirstBarLine;
public override bool EquivalentTo(ControlPoint other)
=> base.EquivalentTo(other)
&& other is EffectControlPoint effect
&& KiaiMode.Equals(effect.KiaiMode)
&& OmitFirstBarLine.Equals(effect.OmitFirstBarLine);
}
}
@@ -30,25 +30,5 @@ namespace osu.Game.Beatmaps.ControlPoints
Name = sampleName,
Volume = SampleVolume,
};
/// <summary>
/// Applies <see cref="SampleBank"/> and <see cref="SampleVolume"/> to a <see cref="SampleInfo"/> if necessary, returning the modified <see cref="SampleInfo"/>.
/// </summary>
/// <param name="sampleInfo">The <see cref="SampleInfo"/>. This will not be modified.</param>
/// <returns>The modified <see cref="SampleInfo"/>. This does not share a reference with <paramref name="sampleInfo"/>.</returns>
public virtual SampleInfo ApplyTo(SampleInfo sampleInfo)
{
var newSampleInfo = sampleInfo.Clone();
newSampleInfo.Bank = sampleInfo.Bank ?? SampleBank;
newSampleInfo.Name = sampleInfo.Name;
newSampleInfo.Volume = sampleInfo.Volume > 0 ? sampleInfo.Volume : SampleVolume;
return newSampleInfo;
}
public override bool EquivalentTo(ControlPoint other)
=> base.EquivalentTo(other)
&& other is SampleControlPoint sample
&& SampleBank.Equals(sample.SampleBank)
&& SampleVolume.Equals(sample.SampleVolume);
}
}
@@ -23,11 +23,5 @@ namespace osu.Game.Beatmaps.ControlPoints
}
private double beatLength = 1000;
public override bool EquivalentTo(ControlPoint other)
=> base.EquivalentTo(other)
&& other is TimingControlPoint timing
&& TimeSignature.Equals(timing.TimeSignature)
&& BeatLength.Equals(timing.BeatLength);
}
}
@@ -289,9 +289,9 @@ namespace osu.Game.Beatmaps.Formats
if (split.Length >= 4)
sampleSet = (LegacySampleBank)int.Parse(split[3]);
int customSampleBank = 0;
if (split.Length >= 5)
customSampleBank = int.Parse(split[4]);
//SampleBank sampleBank = SampleBank.Default;
//if (split.Length >= 5)
// sampleBank = (SampleBank)int.Parse(split[4]);
int sampleVolume = defaultSampleVolume;
if (split.Length >= 6)
@@ -314,9 +314,13 @@ namespace osu.Game.Beatmaps.Formats
if (stringSampleSet == @"none")
stringSampleSet = @"normal";
DifficultyControlPoint difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(time);
SampleControlPoint samplePoint = beatmap.ControlPointInfo.SamplePointAt(time);
EffectControlPoint effectPoint = beatmap.ControlPointInfo.EffectPointAt(time);
if (timingChange)
{
handleTimingControlPoint(new TimingControlPoint
beatmap.ControlPointInfo.TimingPoints.Add(new TimingControlPoint
{
Time = time,
BeatLength = beatLength,
@@ -324,68 +328,41 @@ namespace osu.Game.Beatmaps.Formats
});
}
handleDifficultyControlPoint(new DifficultyControlPoint
if (speedMultiplier != difficultyPoint.SpeedMultiplier)
{
Time = time,
SpeedMultiplier = speedMultiplier
});
beatmap.ControlPointInfo.DifficultyPoints.RemoveAll(x => x.Time == time);
beatmap.ControlPointInfo.DifficultyPoints.Add(new DifficultyControlPoint
{
Time = time,
SpeedMultiplier = speedMultiplier
});
}
handleEffectControlPoint(new EffectControlPoint
if (stringSampleSet != samplePoint.SampleBank || sampleVolume != samplePoint.SampleVolume)
{
Time = time,
KiaiMode = kiaiMode,
OmitFirstBarLine = omitFirstBarSignature
});
beatmap.ControlPointInfo.SamplePoints.Add(new SampleControlPoint
{
Time = time,
SampleBank = stringSampleSet,
SampleVolume = sampleVolume
});
}
handleSampleControlPoint(new LegacySampleControlPoint
if (kiaiMode != effectPoint.KiaiMode || omitFirstBarSignature != effectPoint.OmitFirstBarLine)
{
Time = time,
SampleBank = stringSampleSet,
SampleVolume = sampleVolume,
CustomSampleBank = customSampleBank
});
beatmap.ControlPointInfo.EffectPoints.Add(new EffectControlPoint
{
Time = time,
KiaiMode = kiaiMode,
OmitFirstBarLine = omitFirstBarSignature
});
}
}
catch (FormatException e)
{
}
}
private void handleTimingControlPoint(TimingControlPoint newPoint)
{
beatmap.ControlPointInfo.TimingPoints.Add(newPoint);
}
private void handleDifficultyControlPoint(DifficultyControlPoint newPoint)
{
var existing = beatmap.ControlPointInfo.DifficultyPointAt(newPoint.Time);
if (newPoint.EquivalentTo(existing))
return;
beatmap.ControlPointInfo.DifficultyPoints.RemoveAll(x => x.Time == newPoint.Time);
beatmap.ControlPointInfo.DifficultyPoints.Add(newPoint);
}
private void handleEffectControlPoint(EffectControlPoint newPoint)
{
var existing = beatmap.ControlPointInfo.EffectPointAt(newPoint.Time);
if (newPoint.EquivalentTo(existing))
return;
beatmap.ControlPointInfo.EffectPoints.Add(newPoint);
}
private void handleSampleControlPoint(SampleControlPoint newPoint)
{
var existing = beatmap.ControlPointInfo.SamplePointAt(newPoint.Time);
if (newPoint.EquivalentTo(existing))
return;
beatmap.ControlPointInfo.SamplePoints.Add(newPoint);
}
private void handleHitObject(string line)
{
// If the ruleset wasn't specified, assume the osu!standard ruleset.
@@ -5,8 +5,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using osu.Framework.Logging;
using osu.Game.Audio;
using osu.Game.Beatmaps.ControlPoints;
using OpenTK.Graphics;
namespace osu.Game.Beatmaps.Formats
@@ -169,25 +167,5 @@ namespace osu.Game.Beatmaps.Formats
Pass = 2,
Foreground = 3
}
internal class LegacySampleControlPoint : SampleControlPoint
{
public int CustomSampleBank;
public override SampleInfo ApplyTo(SampleInfo sampleInfo)
{
var baseInfo = base.ApplyTo(sampleInfo);
if (CustomSampleBank > 1)
baseInfo.Name += CustomSampleBank;
return baseInfo;
}
public override bool EquivalentTo(ControlPoint other)
=> base.EquivalentTo(other)
&& other is LegacySampleControlPoint legacy
&& CustomSampleBank == legacy.CustomSampleBank;
}
}
}
-3
View File
@@ -7,9 +7,6 @@ using osu.Game.Rulesets.Objects;
namespace osu.Game.Beatmaps
{
/// <summary>
/// Provides functionality to convert a <see cref="IBeatmap"/> for a <see cref="Ruleset"/>.
/// </summary>
public interface IBeatmapConverter
{
/// <summary>
-40
View File
@@ -1,40 +0,0 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Beatmaps
{
/// <summary>
/// Provides functionality to alter a <see cref="IBeatmap"/> after it has been converted.
/// </summary>
public interface IBeatmapProcessor
{
/// <summary>
/// The <see cref="IBeatmap"/> to process. This should already be converted to the applicable <see cref="Ruleset"/>.
/// </summary>
IBeatmap Beatmap { get; }
/// <summary>
/// Processes the converted <see cref="Beatmap"/> prior to <see cref="HitObject.ApplyDefaults"/> being invoked.
/// <para>
/// Nested <see cref="HitObject"/>s generated during <see cref="HitObject.ApplyDefaults"/> will not be present by this point,
/// and no mods will have been applied to the <see cref="HitObject"/>s.
/// </para>
/// </summary>
/// <remarks>
/// This can only be used to add alterations to <see cref="HitObject"/>s generated directly through the conversion process.
/// </remarks>
void PreProcess();
/// <summary>
/// Processes the converted <see cref="Beatmap"/> after <see cref="HitObject.ApplyDefaults"/> has been invoked.
/// <para>
/// Nested <see cref="HitObject"/>s generated during <see cref="HitObject.ApplyDefaults"/> will be present by this point,
/// and mods will have been applied to all <see cref="HitObject"/>s.
/// </para>
/// </summary>
/// <remarks>
/// This should be used to add alterations to <see cref="HitObject"/>s while they are in their most playable state.
/// </remarks>
void PostProcess();
}
}
+2 -5
View File
@@ -116,10 +116,6 @@ namespace osu.Game.Beatmaps
mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty);
}
IBeatmapProcessor processor = rulesetInstance.CreateBeatmapProcessor(converted);
processor?.PreProcess();
// Compute default values for hitobjects, including creating nested hitobjects in-case they're needed
foreach (var obj in converted.HitObjects)
obj.ApplyDefaults(converted.ControlPointInfo, converted.BeatmapInfo.BaseDifficulty);
@@ -128,7 +124,8 @@ namespace osu.Game.Beatmaps
foreach (var obj in converted.HitObjects)
mod.ApplyToHitObject(obj);
processor?.PostProcess();
// Post-process
rulesetInstance.CreateBeatmapProcessor(converted)?.PostProcess();
return converted;
}
+22 -30
View File
@@ -11,9 +11,9 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Input;
using osu.Game.Configuration;
using System;
using System.Diagnostics;
using JetBrains.Annotations;
using osu.Framework.Graphics.Textures;
using OpenTK.Input;
namespace osu.Game.Graphics.Cursor
{
@@ -25,8 +25,9 @@ namespace osu.Game.Graphics.Cursor
protected override Drawable CreateCursor() => new Cursor();
private Bindable<bool> cursorRotate;
private DragRotationState dragRotationState;
private Vector2 positionMouseDown;
private bool dragging;
private bool startRotation;
[BackgroundDependencyLoader(true)]
private void load([NotNull] OsuConfigManager config, [CanBeNull] ScreenshotManager screenshotManager)
@@ -39,18 +40,18 @@ namespace osu.Game.Graphics.Cursor
protected override bool OnMouseMove(InputState state)
{
if (dragRotationState != DragRotationState.NotDragging)
if (cursorRotate && dragging)
{
var position = state.Mouse.Position;
var distance = Vector2Extensions.Distance(position, positionMouseDown);
Debug.Assert(state.Mouse.PositionMouseDown != null);
// don't start rotating until we're moved a minimum distance away from the mouse down location,
// else it can have an annoying effect.
if (dragRotationState == DragRotationState.DragStarted && distance > 30)
dragRotationState = DragRotationState.Rotating;
// don't rotate when distance is zero to avoid NaN
if (dragRotationState == DragRotationState.Rotating && distance > 0)
// ReSharper disable once PossibleInvalidOperationException
startRotation |= Vector2Extensions.Distance(state.Mouse.Position, state.Mouse.PositionMouseDown.Value) > 30;
if (startRotation)
{
Vector2 offset = state.Mouse.Position - positionMouseDown;
Vector2 offset = state.Mouse.Position - state.Mouse.PositionMouseDown.Value;
float degrees = (float)MathHelper.RadiansToDegrees(Math.Atan2(-offset.X, offset.Y)) + 24.3f;
// Always rotate in the direction of least distance
@@ -66,6 +67,12 @@ namespace osu.Game.Graphics.Cursor
return base.OnMouseMove(state);
}
protected override bool OnDragStart(InputState state)
{
dragging = true;
return base.OnDragStart(state);
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{
ActiveCursor.Scale = new Vector2(1);
@@ -73,12 +80,6 @@ namespace osu.Game.Graphics.Cursor
((Cursor)ActiveCursor).AdditiveLayer.Alpha = 0;
((Cursor)ActiveCursor).AdditiveLayer.FadeInFromZero(800, Easing.OutQuint);
if (args.Button == MouseButton.Left && cursorRotate)
{
dragRotationState = DragRotationState.DragStarted;
positionMouseDown = state.Mouse.Position;
}
return base.OnMouseDown(state, args);
}
@@ -86,16 +87,14 @@ namespace osu.Game.Graphics.Cursor
{
if (!state.Mouse.HasMainButtonPressed)
{
dragging = false;
startRotation = false;
((Cursor)ActiveCursor).AdditiveLayer.FadeOut(500, Easing.OutQuint);
ActiveCursor.RotateTo(0, 600 * (1 + Math.Abs(ActiveCursor.Rotation / 720)), Easing.OutElasticHalf);
ActiveCursor.ScaleTo(1, 500, Easing.OutElastic);
}
if (args.Button == MouseButton.Left)
{
if (dragRotationState == DragRotationState.Rotating)
ActiveCursor.RotateTo(0, 600 * (1 + Math.Abs(ActiveCursor.Rotation / 720)), Easing.OutElasticHalf);
dragRotationState = DragRotationState.NotDragging;
}
return base.OnMouseUp(state, args);
}
@@ -161,12 +160,5 @@ namespace osu.Game.Graphics.Cursor
cursorScale.TriggerChange();
}
}
private enum DragRotationState
{
NotDragging,
DragStarted,
Rotating,
}
}
}
@@ -5,7 +5,6 @@ using OpenTK.Graphics;
using osu.Framework.Input;
using System;
using osu.Game.Input.Bindings;
using OpenTK.Input;
namespace osu.Game.Graphics.UserInterface
{
@@ -45,9 +44,6 @@ namespace osu.Game.Graphics.UserInterface
{
if (!HasFocus) return false;
if (args.Key == Key.Escape)
return false; // disable the framework-level handling of escape key for confority (we use GlobalAction.Back).
return base.OnKeyDown(state, args);
}
@@ -45,9 +45,7 @@ namespace osu.Game.Input.Bindings
public IEnumerable<KeyBinding> InGameKeyBindings => new[]
{
new KeyBinding(InputKey.Space, GlobalAction.SkipCutscene),
new KeyBinding(InputKey.Tilde, GlobalAction.QuickRetry),
new KeyBinding(new[] { InputKey.Control, InputKey.Plus }, GlobalAction.IncreaseScrollSpeed),
new KeyBinding(new[] { InputKey.Control, InputKey.Minus }, GlobalAction.DecreaseScrollSpeed),
new KeyBinding(InputKey.Tilde, GlobalAction.QuickRetry)
};
protected override IEnumerable<Drawable> KeyBindingInputQueue =>
@@ -87,12 +85,6 @@ namespace osu.Game.Input.Bindings
ToggleGameplayMouseButtons,
[Description("Go back")]
Back,
[Description("Increase scroll speed")]
IncreaseScrollSpeed,
[Description("Decrease scroll speed")]
DecreaseScrollSpeed,
Back
}
}
@@ -49,7 +49,7 @@ namespace osu.Game.Online.API.Requests.Responses
private DateTimeOffset submitted { get; set; }
[JsonProperty(@"ranked_date")]
private DateTimeOffset? ranked { get; set; }
private DateTimeOffset ranked { get; set; }
[JsonProperty(@"last_updated")]
private DateTimeOffset lastUpdated { get; set; }
+1 -2
View File
@@ -250,8 +250,7 @@ namespace osu.Game
new VolumeControlReceptor
{
RelativeSizeAxes = Axes.Both,
ActionRequested = action => volume.Adjust(action),
ScrollActionRequested = (action, amount, isPrecise) => volume.Adjust(action, amount, isPrecise),
ActionRequested = action => volume.Adjust(action)
},
mainContent = new Container { RelativeSizeAxes = Axes.Both },
overlayContent = new Container { RelativeSizeAxes = Axes.Both, Depth = float.MinValue },
+70 -82
View File
@@ -6,16 +6,16 @@ using System.Linq;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays.Dialog
{
@@ -23,9 +23,6 @@ namespace osu.Game.Overlays.Dialog
{
public static readonly float ENTER_DURATION = 500;
public static readonly float EXIT_DURATION = 200;
protected override bool BlockPassThroughMouse => false;
private readonly Vector2 ringSize = new Vector2(100f);
private readonly Vector2 ringMinifiedSize = new Vector2(20f);
private readonly Vector2 buttonsEnterSpacing = new Vector2(0f, 50f);
@@ -37,28 +34,26 @@ namespace osu.Game.Overlays.Dialog
private readonly SpriteText header;
private readonly TextFlowContainer body;
private bool actionInvoked;
public FontAwesome Icon
{
get => icon.Icon;
set => icon.Icon = value;
get { return icon.Icon; }
set { icon.Icon = value; }
}
public string HeaderText
{
get => header.Text;
set => header.Text = value;
get { return header.Text; }
set { header.Text = value; }
}
public string BodyText
{
set => body.Text = value;
set { body.Text = value; }
}
public IEnumerable<PopupDialogButton> Buttons
{
get => buttonsContainer.Children;
get { return buttonsContainer.Children; }
set
{
buttonsContainer.ChildrenEnumerable = value;
@@ -67,17 +62,71 @@ namespace osu.Game.Overlays.Dialog
var action = b.Action;
b.Action = () =>
{
if (actionInvoked) return;
actionInvoked = true;
action?.Invoke();
Hide();
action?.Invoke();
};
}
}
}
private void pressButtonAtIndex(int index)
{
if (index < Buttons.Count())
Buttons.Skip(index).First().TriggerOnClick();
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
if (args.Repeat) return false;
if (args.Key == Key.Enter || args.Key == Key.KeypadEnter)
{
Buttons.OfType<PopupDialogOkButton>().FirstOrDefault()?.TriggerOnClick();
return true;
}
// press button at number if 1-9 on number row or keypad are pressed
var k = args.Key;
if (k >= Key.Number1 && k <= Key.Number9)
{
pressButtonAtIndex(k - Key.Number1);
return true;
}
if (k >= Key.Keypad1 && k <= Key.Keypad9)
{
pressButtonAtIndex(k - Key.Keypad1);
return true;
}
return base.OnKeyDown(state, args);
}
protected override void PopIn()
{
base.PopIn();
// Reset various animations but only if the dialog animation fully completed
if (content.Alpha == 0)
{
buttonsContainer.TransformSpacingTo(buttonsEnterSpacing);
buttonsContainer.MoveToY(buttonsEnterSpacing.Y);
ring.ResizeTo(ringMinifiedSize);
}
content.FadeIn(ENTER_DURATION, Easing.OutQuint);
ring.ResizeTo(ringSize, ENTER_DURATION, Easing.OutQuint);
buttonsContainer.TransformSpacingTo(Vector2.Zero, ENTER_DURATION, Easing.OutQuint);
buttonsContainer.MoveToY(0, ENTER_DURATION, Easing.OutQuint);
}
protected override void PopOut()
{
base.PopOut();
content.FadeOut(EXIT_DURATION, Easing.InSine);
}
public PopupDialog()
{
RelativeSizeAxes = Axes.Both;
@@ -87,6 +136,9 @@ namespace osu.Game.Overlays.Dialog
content = new Container
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Width = 0.4f,
Alpha = 0f,
Children = new Drawable[]
{
@@ -191,69 +243,5 @@ namespace osu.Game.Overlays.Dialog
},
};
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
if (args.Repeat) return false;
if (args.Key == Key.Enter || args.Key == Key.KeypadEnter)
{
Buttons.OfType<PopupDialogOkButton>().FirstOrDefault()?.TriggerOnClick();
return true;
}
// press button at number if 1-9 on number row or keypad are pressed
var k = args.Key;
if (k >= Key.Number1 && k <= Key.Number9)
{
pressButtonAtIndex(k - Key.Number1);
return true;
}
if (k >= Key.Keypad1 && k <= Key.Keypad9)
{
pressButtonAtIndex(k - Key.Keypad1);
return true;
}
return base.OnKeyDown(state, args);
}
protected override void PopIn()
{
base.PopIn();
actionInvoked = false;
// Reset various animations but only if the dialog animation fully completed
if (content.Alpha == 0)
{
buttonsContainer.TransformSpacingTo(buttonsEnterSpacing);
buttonsContainer.MoveToY(buttonsEnterSpacing.Y);
ring.ResizeTo(ringMinifiedSize);
}
content.FadeIn(ENTER_DURATION, Easing.OutQuint);
ring.ResizeTo(ringSize, ENTER_DURATION, Easing.OutQuint);
buttonsContainer.TransformSpacingTo(Vector2.Zero, ENTER_DURATION, Easing.OutQuint);
buttonsContainer.MoveToY(0, ENTER_DURATION, Easing.OutQuint);
}
protected override void PopOut()
{
if (!actionInvoked)
// In the case a user did not choose an action before a hide was triggered, press the last button.
// This is presumed to always be a sane default "cancel" action.
buttonsContainer.Last().TriggerOnClick();
base.PopOut();
content.FadeOut(EXIT_DURATION, Easing.InSine);
}
private void pressButtonAtIndex(int index)
{
if (index < Buttons.Count())
Buttons.Skip(index).First().TriggerOnClick();
}
}
}
+28 -23
View File
@@ -1,9 +1,12 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Overlays.Dialog;
using OpenTK.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Overlays
@@ -13,20 +16,6 @@ namespace osu.Game.Overlays
private readonly Container dialogContainer;
private PopupDialog currentDialog;
public DialogOverlay()
{
RelativeSizeAxes = Axes.Both;
Child = dialogContainer = new Container
{
RelativeSizeAxes = Axes.Both,
};
Width = 0.4f;
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
}
public void Push(PopupDialog dialog)
{
if (dialog == currentDialog) return;
@@ -43,8 +32,6 @@ namespace osu.Game.Overlays
protected override bool PlaySamplesOnStateChange => false;
protected override bool BlockPassThroughKeyboard => true;
private void onDialogOnStateChanged(VisibilityContainer dialog, Visibility v)
{
if (v != Visibility.Hidden) return;
@@ -65,14 +52,32 @@ namespace osu.Game.Overlays
protected override void PopOut()
{
base.PopOut();
if (currentDialog?.State == Visibility.Visible)
{
currentDialog.Hide();
return;
}
this.FadeOut(PopupDialog.EXIT_DURATION, Easing.InSine);
}
public DialogOverlay()
{
RelativeSizeAxes = Axes.Both;
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(0.5f),
},
},
},
dialogContainer = new Container
{
RelativeSizeAxes = Axes.Both,
},
};
}
}
}
@@ -186,7 +186,7 @@ namespace osu.Game.Overlays.KeyBinding
{
if (bindTarget.IsHovered)
{
bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(state, state.Mouse.ScrollDelta));
bindTarget.UpdateKeyCombination(new KeyCombination(KeyCombination.FromInputState(state).Keys.Append(state.Mouse.ScrollDelta.Y > 0 ? InputKey.MouseWheelUp : InputKey.MouseWheelDown)));
finalise();
return true;
}
+10 -5
View File
@@ -40,7 +40,7 @@ namespace osu.Game.Overlays.Mods
public readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>();
public readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
private void rulesetChanged(RulesetInfo newRuleset)
{
@@ -51,8 +51,8 @@ namespace osu.Game.Overlays.Mods
refreshSelectedMods();
}
[BackgroundDependencyLoader]
private void load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio)
[BackgroundDependencyLoader(permitNulls: true)]
private void load(OsuColour colours, Bindable<RulesetInfo> ruleset, RulesetStore rulesets, AudioManager audio)
{
SelectedMods.ValueChanged += selectedModsChanged;
@@ -60,8 +60,13 @@ namespace osu.Game.Overlays.Mods
HighMultiplierColour = colours.Green;
UnrankedLabel.Colour = colours.Blue;
Ruleset.BindTo(ruleset);
Ruleset.BindValueChanged(rulesetChanged, true);
if (ruleset != null)
Ruleset.BindTo(ruleset);
else
Ruleset.Value = rulesets.AvailableRulesets.First();
Ruleset.ValueChanged += rulesetChanged;
Ruleset.TriggerChange();
sampleOn = audio.Sample.Get(@"UI/check-on");
sampleOff = audio.Sample.Get(@"UI/check-off");
@@ -56,13 +56,7 @@ namespace osu.Game.Overlays.Settings.Sections
reloadSkins();
var skinBindable = config.GetBindable<int>(OsuSetting.Skin);
// Todo: This should not be necessary when OsuConfigManager is databased
if (skinDropdown.Items.All(s => s.Value != skinBindable.Value))
skinBindable.Value = 0;
skinDropdown.Bindable = skinBindable;
skinDropdown.Bindable = config.GetBindable<int>(OsuSetting.Skin);
}
private void reloadSkins() => skinDropdown.Items = skins.GetAllUsableSkins().Select(s => new KeyValuePair<string, int>(s.ToString(), s.ID));
@@ -67,7 +67,7 @@ namespace osu.Game.Overlays.Toolbar
};
}
[BackgroundDependencyLoader]
[BackgroundDependencyLoader(true)]
private void load(RulesetStore rulesets, Bindable<RulesetInfo> parentRuleset)
{
this.rulesets = rulesets;
@@ -82,7 +82,11 @@ namespace osu.Game.Overlays.Toolbar
ruleset.ValueChanged += rulesetChanged;
ruleset.DisabledChanged += disabledChanged;
ruleset.BindTo(parentRuleset);
if (parentRuleset != null)
ruleset.BindTo(parentRuleset);
else
ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault();
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
@@ -9,13 +9,11 @@ using osu.Game.Input.Bindings;
namespace osu.Game.Overlays.Volume
{
public class VolumeControlReceptor : Container, IScrollBindingHandler<GlobalAction>, IHandleGlobalInput
public class VolumeControlReceptor : Container, IKeyBindingHandler<GlobalAction>, IHandleGlobalInput
{
public Func<GlobalAction, bool> ActionRequested;
public Func<GlobalAction, float, bool, bool> ScrollActionRequested;
public bool OnPressed(GlobalAction action) => ActionRequested?.Invoke(action) ?? false;
public bool OnScroll(GlobalAction action, float amount, bool isPrecise) => ScrollActionRequested?.Invoke(action, amount, isPrecise) ?? false;
public bool OnReleased(GlobalAction action) => false;
}
}
+48 -14
View File
@@ -12,15 +12,17 @@ using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Framework.MathUtils;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Input.Bindings;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Overlays.Volume
{
public class VolumeMeter : Container
public class VolumeMeter : Container, IKeyBindingHandler<GlobalAction>
{
private CircularProgress volumeCircle;
private CircularProgress volumeCircleGlow;
@@ -224,27 +226,59 @@ namespace osu.Game.Overlays.Volume
private const float adjust_step = 0.05f;
public void Increase(double amount = 1, bool isPrecise = false) => adjust(amount, isPrecise);
public void Decrease(double amount = 1, bool isPrecise = false) => adjust(-amount, isPrecise);
public void Increase() => adjust(1);
public void Decrease() => adjust(-1);
private void adjust(int direction)
{
float amount = adjust_step * direction;
// handle the case where the OnPressed action was actually a mouse wheel.
// this allows for precise wheel handling.
var state = GetContainingInputManager().CurrentState;
if (state.Mouse?.ScrollDelta.Y != 0)
{
OnScroll(state);
return;
}
Volume += amount;
}
public bool OnPressed(GlobalAction action)
{
if (!IsHovered) return false;
switch (action)
{
case GlobalAction.DecreaseVolume:
Decrease();
return true;
case GlobalAction.IncreaseVolume:
Increase();
return true;
}
return false;
}
// because volume precision is set to 0.01, this local is required to keep track of more precise adjustments and only apply when possible.
private double adjustAccumulator;
private void adjust(double delta, bool isPrecise)
{
adjustAccumulator += delta * adjust_step * (isPrecise ? 0.1 : 1);
if (Math.Abs(adjustAccumulator) < Bindable.Precision)
return;
Volume += adjustAccumulator;
adjustAccumulator = 0;
}
private double scrollAmount;
protected override bool OnScroll(InputState state)
{
adjust(state.Mouse.ScrollDelta.Y, state.Mouse.HasPreciseScroll);
scrollAmount += adjust_step * state.Mouse.ScrollDelta.Y * (state.Mouse.HasPreciseScroll ? 0.1f : 1);
if (Math.Abs(scrollAmount) < Bindable.Precision)
return true;
Volume += scrollAmount;
scrollAmount = 0;
return true;
}
public bool OnReleased(GlobalAction action) => false;
private const float transition_length = 500;
protected override bool OnHover(InputState state)
+3 -3
View File
@@ -93,7 +93,7 @@ namespace osu.Game.Overlays
muteButton.Current.ValueChanged += _ => Show();
}
public bool Adjust(GlobalAction action, float amount = 1, bool isPrecise = false)
public bool Adjust(GlobalAction action)
{
if (!IsLoaded) return false;
@@ -103,13 +103,13 @@ namespace osu.Game.Overlays
if (State == Visibility.Hidden)
Show();
else
volumeMeterMaster.Decrease(amount, isPrecise);
volumeMeterMaster.Decrease();
return true;
case GlobalAction.IncreaseVolume:
if (State == Visibility.Hidden)
Show();
else
volumeMeterMaster.Increase(amount, isPrecise);
volumeMeterMaster.Increase();
return true;
case GlobalAction.ToggleMute:
Show();
@@ -33,7 +33,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
protected virtual IEnumerable<SampleInfo> GetSamples() => HitObject.Samples;
private readonly Lazy<List<DrawableHitObject>> nestedHitObjects = new Lazy<List<DrawableHitObject>>();
public IEnumerable<DrawableHitObject> NestedHitObjects => nestedHitObjects.IsValueCreated ? nestedHitObjects.Value : Enumerable.Empty<DrawableHitObject>();
public bool HasNestedHitObjects => nestedHitObjects.IsValueCreated;
public IReadOnlyList<DrawableHitObject> NestedHitObjects => nestedHitObjects.Value;
public event Action<DrawableHitObject, Judgement> OnJudgement;
public event Action<DrawableHitObject, Judgement> OnJudgementRemoved;
@@ -49,12 +50,12 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// <summary>
/// Whether this <see cref="DrawableHitObject"/> and all of its nested <see cref="DrawableHitObject"/>s have been hit.
/// </summary>
public bool IsHit => Judgements.Any(j => j.Final && j.IsHit) && NestedHitObjects.All(n => n.IsHit);
public bool IsHit => Judgements.Any(j => j.Final && j.IsHit) && (!HasNestedHitObjects || NestedHitObjects.All(n => n.IsHit));
/// <summary>
/// Whether this <see cref="DrawableHitObject"/> and all of its nested <see cref="DrawableHitObject"/>s have been judged.
/// </summary>
public bool AllJudged => (!ProvidesJudgement || judgementFinalized) && NestedHitObjects.All(h => h.AllJudged);
public bool AllJudged => (!ProvidesJudgement || judgementFinalized) && (!HasNestedHitObjects || NestedHitObjects.All(h => h.AllJudged));
/// <summary>
/// Whether this <see cref="DrawableHitObject"/> can be judged.
@@ -89,12 +90,13 @@ namespace osu.Game.Rulesets.Objects.Drawables
if (HitObject.SampleControlPoint == null)
throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}."
+ $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}.");
samples = samples.Select(s => HitObject.SampleControlPoint.ApplyTo(s)).ToArray();
foreach (var s in samples)
s.Namespace = SampleNamespace;
AddInternal(Samples = new SkinnableSound(samples));
AddInternal(Samples = new SkinnableSound(samples.Select(s => new SampleInfo
{
Bank = s.Bank ?? HitObject.SampleControlPoint.SampleBank,
Name = s.Name,
Volume = s.Volume > 0 ? s.Volume : HitObject.SampleControlPoint.SampleVolume,
Namespace = SampleNamespace
}).ToArray()));
}
}
@@ -204,8 +206,9 @@ namespace osu.Game.Rulesets.Objects.Drawables
if (AllJudged)
return false;
foreach (var d in NestedHitObjects)
judgementOccurred |= d.UpdateJudgement(userTriggered);
if (HasNestedHitObjects)
foreach (var d in NestedHitObjects)
judgementOccurred |= d.UpdateJudgement(userTriggered);
if (!ProvidesJudgement || judgementFinalized || judgementOccurred)
return judgementOccurred;
@@ -6,7 +6,6 @@ using osu.Game.Rulesets.Objects.Types;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using osu.Game.Beatmaps.Formats;
using osu.Game.Audio;
using System.Linq;
@@ -197,6 +196,9 @@ namespace osu.Game.Rulesets.Objects.Legacy
var bank = (LegacyBeatmapDecoder.LegacySampleBank)Convert.ToInt32(split[0]);
var addbank = (LegacyBeatmapDecoder.LegacySampleBank)Convert.ToInt32(split[1]);
// Let's not implement this for now, because this doesn't fit nicely into the bank structure
//string sampleFile = split2.Length > 4 ? split2[4] : string.Empty;
string stringBank = bank.ToString().ToLower();
if (stringBank == @"none")
stringBank = null;
@@ -209,8 +211,6 @@ namespace osu.Game.Rulesets.Objects.Legacy
if (split.Length > 3)
bankInfo.Volume = int.Parse(split[3]);
bankInfo.Filename = split.Length > 4 ? split[4] : null;
}
/// <summary>
@@ -252,10 +252,6 @@ namespace osu.Game.Rulesets.Objects.Legacy
private List<SampleInfo> convertSoundType(LegacySoundType type, SampleBankInfo bankInfo)
{
// Todo: This should return the normal SampleInfos if the specified sample file isn't found, but that's a pretty edge-case scenario
if (!string.IsNullOrEmpty(bankInfo.Filename))
return new List<SampleInfo> { new FileSampleInfo { Filename = bankInfo.Filename } };
var soundTypes = new List<SampleInfo>
{
new SampleInfo
@@ -301,24 +297,14 @@ namespace osu.Game.Rulesets.Objects.Legacy
private class SampleBankInfo
{
public string Filename;
public string Normal;
public string Add;
public int Volume;
public SampleBankInfo Clone() => (SampleBankInfo)MemberwiseClone();
}
private class FileSampleInfo : SampleInfo
{
public string Filename;
public override IEnumerable<string> LookupNames => new[]
public SampleBankInfo Clone()
{
Filename,
Path.ChangeExtension(Filename, null)
};
return (SampleBankInfo)MemberwiseClone();
}
}
[Flags]
-10
View File
@@ -57,18 +57,8 @@ namespace osu.Game.Rulesets
/// <returns></returns>
public abstract RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap);
/// <summary>
/// Creates a <see cref="IBeatmapConverter"/> to convert a <see cref="IBeatmap"/> to one that is applicable for this <see cref="Ruleset"/>.
/// </summary>
/// <param name="beatmap">The <see cref="IBeatmap"/> to be converted.</param>
/// <returns>The <see cref="IBeatmapConverter"/>.</returns>
public abstract IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap);
/// <summary>
/// Optionally creates a <see cref="IBeatmapProcessor"/> to alter a <see cref="IBeatmap"/> after it has been converted.
/// </summary>
/// <param name="beatmap">The <see cref="IBeatmap"/> to be processed.</param>
/// <returns>The <see cref="IBeatmapProcessor"/>.</returns>
public virtual IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => null;
public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap);
+1 -7
View File
@@ -84,13 +84,7 @@ namespace osu.Game.Rulesets
{
try
{
var instanceInfo = ((Ruleset)Activator.CreateInstance(Type.GetType(r.InstantiationInfo, asm =>
{
// for the time being, let's ignore the version being loaded.
// this allows for debug builds to successfully load rulesets (even though debug rulesets have a 0.0.0 version).
asm.Version = null;
return Assembly.Load(asm);
}, null), (RulesetInfo)null)).RulesetInfo;
var instanceInfo = ((Ruleset)Activator.CreateInstance(Type.GetType(r.InstantiationInfo), (RulesetInfo)null)).RulesetInfo;
r.Name = instanceInfo.Name;
r.ShortName = instanceInfo.ShortName;
@@ -4,33 +4,30 @@
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
using osu.Game.Input.Bindings;
using osu.Framework.Input;
using osu.Game.Rulesets.Objects.Drawables;
using OpenTK.Input;
namespace osu.Game.Rulesets.UI.Scrolling
{
/// <summary>
/// A type of <see cref="Playfield"/> specialized towards scrolling <see cref="DrawableHitObject"/>s.
/// </summary>
public abstract class ScrollingPlayfield : Playfield, IKeyBindingHandler<GlobalAction>
public abstract class ScrollingPlayfield : Playfield
{
/// <summary>
/// The default span of time visible by the length of the scrolling axes.
/// This is clamped between <see cref="time_span_min"/> and <see cref="time_span_max"/>.
/// </summary>
private const double time_span_default = 1500;
/// <summary>
/// The minimum span of time that may be visible by the length of the scrolling axes.
/// </summary>
private const double time_span_min = 50;
/// <summary>
/// The maximum span of time that may be visible by the length of the scrolling axes.
/// </summary>
private const double time_span_max = 10000;
/// <summary>
/// The step increase/decrease of the span of time visible by the length of the scrolling axes.
/// </summary>
@@ -81,26 +78,27 @@ namespace osu.Game.Rulesets.UI.Scrolling
HitObjects.TimeRange.BindTo(VisibleTimeRange);
}
public bool OnPressed(GlobalAction action)
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{
if (!UserScrollSpeedAdjustment)
return false;
switch (action)
if (state.Keyboard.ControlPressed)
{
case GlobalAction.IncreaseScrollSpeed:
this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange - time_span_step, 200, Easing.OutQuint);
return true;
case GlobalAction.DecreaseScrollSpeed:
this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange + time_span_step, 200, Easing.OutQuint);
return true;
switch (args.Key)
{
case Key.Minus:
this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange + time_span_step, 600, Easing.OutQuint);
break;
case Key.Plus:
this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange - time_span_step, 600, Easing.OutQuint);
break;
}
}
return false;
}
public bool OnReleased(GlobalAction action) => false;
protected sealed override HitObjectContainer CreateHitObjectContainer()
{
var container = new ScrollingHitObjectContainer();
@@ -47,10 +47,13 @@ namespace osu.Game.Rulesets.UI.Scrolling.Visualisers
}
}
ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length);
if (obj.HasNestedHitObjects)
{
ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length);
// Nested hitobjects don't need to scroll, but they do need accurate positions
UpdatePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length);
// Nested hitobjects don't need to scroll, but they do need accurate positions
UpdatePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length);
}
}
}
@@ -48,10 +48,13 @@ namespace osu.Game.Rulesets.UI.Scrolling.Visualisers
}
}
ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length);
if (obj.HasNestedHitObjects)
{
ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length);
// Nested hitobjects don't need to scroll, but they do need accurate positions
UpdatePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length);
// Nested hitobjects don't need to scroll, but they do need accurate positions
UpdatePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length);
}
}
}
+5 -2
View File
@@ -82,8 +82,11 @@ namespace osu.Game.Screens
[BackgroundDependencyLoader(true)]
private void load(BindableBeatmap beatmap, OsuGame osu, AudioManager audio, Bindable<RulesetInfo> ruleset)
{
Beatmap.BindTo(beatmap);
Ruleset.BindTo(ruleset);
if (beatmap != null)
Beatmap.BindTo(beatmap);
if (ruleset != null)
Ruleset.BindTo(ruleset);
if (osu != null)
{
+2 -1
View File
@@ -55,7 +55,8 @@ namespace osu.Game.Screens.Select
[BackgroundDependencyLoader(true)]
private void load([CanBeNull] Bindable<RulesetInfo> parentRuleset)
{
ruleset.BindTo(parentRuleset);
if (parentRuleset != null)
ruleset.BindTo(parentRuleset);
ruleset.ValueChanged += _ => updateDisplay();
}
+3 -5
View File
@@ -29,7 +29,6 @@ namespace osu.Game.Screens.Select
private readonly TabControl<GroupMode> groupTabs;
private SortMode sort = SortMode.Title;
public SortMode Sort
{
get { return sort; }
@@ -44,7 +43,6 @@ namespace osu.Game.Screens.Select
}
private GroupMode group = GroupMode.All;
public GroupMode Group
{
get { return group; }
@@ -71,8 +69,7 @@ namespace osu.Game.Screens.Select
private readonly SearchTextBox searchTextBox;
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) =>
base.ReceiveMouseInputAt(screenSpacePos) || groupTabs.ReceiveMouseInputAt(screenSpacePos) || sortTabs.ReceiveMouseInputAt(screenSpacePos);
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => base.ReceiveMouseInputAt(screenSpacePos) || groupTabs.ReceiveMouseInputAt(screenSpacePos) || sortTabs.ReceiveMouseInputAt(screenSpacePos);
public FilterControl()
{
@@ -180,7 +177,8 @@ namespace osu.Game.Screens.Select
showConverted = config.GetBindable<bool>(OsuSetting.ShowConvertedBeatmaps);
showConverted.ValueChanged += val => updateCriteria();
ruleset.BindTo(parentRuleset);
if (parentRuleset != null)
ruleset.BindTo(parentRuleset);
ruleset.BindValueChanged(val => updateCriteria(), true);
}
-2
View File
@@ -55,8 +55,6 @@ namespace osu.Game.Screens.Select
private readonly Box box;
private readonly Box light;
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => box.ReceiveMouseInputAt(screenSpacePos);
public FooterButton()
{
Children = new Drawable[]
@@ -40,10 +40,7 @@ namespace osu.Game.Screens.Select.Leaderboards
private ScheduledDelegate showScoresDelegate;
private bool scoresLoadedOnce;
private IEnumerable<Score> scores;
public IEnumerable<Score> Scores
{
get { return scores; }
@@ -51,8 +48,6 @@ namespace osu.Game.Screens.Select.Leaderboards
{
scores = value;
scoresLoadedOnce = true;
scrollFlow?.FadeOut(fade_duration, Easing.OutQuint).Expire();
scrollFlow = null;
@@ -201,7 +196,9 @@ namespace osu.Game.Screens.Select.Leaderboards
{
this.api = api;
ruleset.BindTo(parentRuleset);
if (parentRuleset != null)
ruleset.BindTo(parentRuleset);
ruleset.ValueChanged += _ => updateScores();
if (api != null)
@@ -230,10 +227,6 @@ namespace osu.Game.Screens.Select.Leaderboards
private void updateScores()
{
// don't display any scores or placeholder until the first Scores_Set has been called.
// this avoids scope changes flickering a "no scores" placeholder before initialisation of song select is finished.
if (!scoresLoadedOnce) return;
getScoresRequest?.Cancel();
getScoresRequest = null;
+10 -8
View File
@@ -44,17 +44,19 @@ namespace osu.Game.Skinning
private SampleChannel loadChannel(SampleInfo info, Func<string, SampleChannel> getSampleFunction)
{
foreach (var lookup in info.LookupNames)
{
var ch = getSampleFunction($"Gameplay/{lookup}");
if (ch == null)
continue;
SampleChannel ch = null;
if (info.Namespace != null)
ch = getSampleFunction($"Gameplay/{info.Namespace}/{info.Bank}-{info.Name}");
// try without namespace as a fallback.
if (ch == null)
ch = getSampleFunction($"Gameplay/{info.Bank}-{info.Name}");
if (ch != null)
ch.Volume.Value = info.Volume / 100.0;
return ch;
}
return null;
return ch;
}
}
}
+1 -11
View File
@@ -1,13 +1,10 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Configuration;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
namespace osu.Game.Tests.Visual
{
@@ -16,8 +13,6 @@ namespace osu.Game.Tests.Visual
private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap());
protected BindableBeatmap Beatmap => beatmap;
protected readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
protected DependencyContainer Dependencies { get; private set; }
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
@@ -27,18 +22,13 @@ namespace osu.Game.Tests.Visual
Dependencies.CacheAs<BindableBeatmap>(beatmap);
Dependencies.CacheAs<IBindableBeatmap>(beatmap);
Dependencies.CacheAs(Ruleset);
Dependencies.CacheAs<IBindable<RulesetInfo>>(Ruleset);
return Dependencies;
}
[BackgroundDependencyLoader]
private void load(AudioManager audioManager, RulesetStore rulesets)
private void load(AudioManager audioManager)
{
beatmap.SetAudioManager(audioManager);
Ruleset.Value = rulesets.AvailableRulesets.First();
}
protected override void Dispose(bool isDisposing)
+1 -5
View File
@@ -86,11 +86,7 @@ namespace osu.Game.Tests.Visual
private readonly WeakList<WorkingBeatmap> workingWeakReferences = new WeakList<WorkingBeatmap>();
private readonly WeakList<Player> playerWeakReferences = new WeakList<Player>();
private Player loadPlayerFor(RulesetInfo ri)
{
Ruleset.Value = ri;
return loadPlayerFor(ri.CreateInstance());
}
private Player loadPlayerFor(RulesetInfo ri) => loadPlayerFor(ri.CreateInstance());
private Player loadPlayerFor(Ruleset r)
{
+1 -1
View File
@@ -18,7 +18,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.1" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="ppy.osu.Framework" Version="2018.705.0" />
<PackageReference Include="ppy.osu.Framework" Version="2018.629.0" />
<PackageReference Include="SharpCompress" Version="0.17.1" />
<PackageReference Include="NUnit" Version="3.10.1" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />