mirror of
https://github.com/ppy/osu.git
synced 2025-02-22 06:42:54 +08:00
Merge branch 'master' into fix-info-wedge
This commit is contained in:
commit
117b744e37
@ -76,10 +76,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
Duration = endTime - HitObject.StartTime
|
Duration = endTime - HitObject.StartTime
|
||||||
};
|
};
|
||||||
|
|
||||||
hold.Head.Samples.Add(new SampleInfo
|
if (hold.Head.Samples == null)
|
||||||
{
|
hold.Head.Samples = new SampleInfoList();
|
||||||
Name = SampleInfo.HIT_NORMAL
|
|
||||||
});
|
hold.Head.Samples.Add(new SampleInfo { Name = SampleInfo.HIT_NORMAL });
|
||||||
|
|
||||||
hold.Tail.Samples = HitObject.Samples;
|
hold.Tail.Samples = HitObject.Samples;
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
Scale = s.Scale,
|
Scale = s.Scale,
|
||||||
ComboColour = s.ComboColour,
|
ComboColour = s.ComboColour,
|
||||||
Samples = s.Samples,
|
Samples = s.Samples,
|
||||||
SoundControlPoint = s.SoundControlPoint
|
SampleControlPoint = s.SampleControlPoint
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,7 +67,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
{
|
{
|
||||||
validKeyPressed = HitActions.Contains(action);
|
validKeyPressed = HitActions.Contains(action);
|
||||||
|
|
||||||
return UpdateJudgement(true);
|
// Only count this as handled if the new judgement is a hit
|
||||||
|
return UpdateJudgement(true) && Judgements.LastOrDefault()?.IsHit == true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
|
@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Assume the intention was to hit the strong hit with both keys only if the first key is still being held down
|
// Assume the intention was to hit the strong hit with both keys only if the first key is still being held down
|
||||||
return firstKeyHeld && UpdateJudgement(true);
|
return firstKeyHeld && UpdateJudgement(true) && Judgements.LastOrDefault()?.IsHit == true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,17 @@ using osu.Framework.Extensions.Color4Extensions;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||||
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Audio.Sample;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Audio;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.UI
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
{
|
{
|
||||||
public class TaikoPlayfield : ScrollingPlayfield
|
public class TaikoPlayfield : ScrollingPlayfield, IKeyBindingHandler<TaikoAction>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Default height of a <see cref="TaikoPlayfield"/> when inside a <see cref="TaikoRulesetContainer"/>.
|
/// Default height of a <see cref="TaikoPlayfield"/> when inside a <see cref="TaikoRulesetContainer"/>.
|
||||||
@ -54,9 +61,13 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
private readonly Box overlayBackground;
|
private readonly Box overlayBackground;
|
||||||
private readonly Box background;
|
private readonly Box background;
|
||||||
|
|
||||||
public TaikoPlayfield()
|
private readonly ControlPointInfo controlPointInfo;
|
||||||
|
private Dictionary<SampleControlPoint, DrumSamples> drumSampleMappings;
|
||||||
|
|
||||||
|
public TaikoPlayfield(ControlPointInfo controlPointInfo)
|
||||||
: base(Axes.X)
|
: base(Axes.X)
|
||||||
{
|
{
|
||||||
|
this.controlPointInfo = controlPointInfo;
|
||||||
AddRangeInternal(new Drawable[]
|
AddRangeInternal(new Drawable[]
|
||||||
{
|
{
|
||||||
backgroundContainer = new Container
|
backgroundContainer = new Container
|
||||||
@ -194,8 +205,19 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours, AudioManager audio)
|
||||||
{
|
{
|
||||||
|
drumSampleMappings = new Dictionary<SampleControlPoint, DrumSamples>();
|
||||||
|
foreach (var s in controlPointInfo.SamplePoints)
|
||||||
|
{
|
||||||
|
drumSampleMappings.Add(s,
|
||||||
|
new DrumSamples
|
||||||
|
{
|
||||||
|
Centre = s.GetSampleInfo().GetChannel(audio.Sample),
|
||||||
|
Rim = s.GetSampleInfo(SampleInfo.HIT_CLAP).GetChannel(audio.Sample)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
overlayBackgroundContainer.BorderColour = colours.Gray0;
|
overlayBackgroundContainer.BorderColour = colours.Gray0;
|
||||||
overlayBackground.Colour = colours.Gray1;
|
overlayBackground.Colour = colours.Gray1;
|
||||||
|
|
||||||
@ -249,7 +271,9 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
{
|
{
|
||||||
topLevelHitContainer.Add(judgedObject.CreateProxy());
|
topLevelHitContainer.Add(judgedObject.CreateProxy());
|
||||||
}
|
}
|
||||||
catch { }
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hitExplosionContainer.Add(new HitExplosion(judgedObject, isRim));
|
hitExplosionContainer.Add(new HitExplosion(judgedObject, isRim));
|
||||||
@ -258,5 +282,28 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
kiaiExplosionContainer.Add(new KiaiHitExplosion(judgedObject, isRim));
|
kiaiExplosionContainer.Add(new KiaiHitExplosion(judgedObject, isRim));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool OnPressed(TaikoAction action)
|
||||||
|
{
|
||||||
|
var samplePoint = controlPointInfo.SamplePointAt(Clock.CurrentTime);
|
||||||
|
|
||||||
|
if (!drumSampleMappings.TryGetValue(samplePoint, out var samples))
|
||||||
|
throw new InvalidOperationException("Current sample set not found.");
|
||||||
|
|
||||||
|
if (action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre)
|
||||||
|
samples.Centre.Play();
|
||||||
|
else
|
||||||
|
samples.Rim.Play();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnReleased(TaikoAction action) => false;
|
||||||
|
|
||||||
|
private class DrumSamples
|
||||||
|
{
|
||||||
|
public SampleChannel Centre;
|
||||||
|
public SampleChannel Rim;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
|
|
||||||
public override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo);
|
public override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo);
|
||||||
|
|
||||||
protected override Playfield CreatePlayfield() => new TaikoPlayfield
|
protected override Playfield CreatePlayfield() => new TaikoPlayfield(Beatmap.ControlPointInfo)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft
|
Origin = Anchor.CentreLeft
|
||||||
|
@ -146,8 +146,8 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
Assert.AreEqual(116999, difficultyPoint.Time);
|
Assert.AreEqual(116999, difficultyPoint.Time);
|
||||||
Assert.AreEqual(0.75000000000000189d, difficultyPoint.SpeedMultiplier);
|
Assert.AreEqual(0.75000000000000189d, difficultyPoint.SpeedMultiplier);
|
||||||
|
|
||||||
Assert.AreEqual(34, controlPoints.SoundPoints.Count);
|
Assert.AreEqual(34, controlPoints.SamplePoints.Count);
|
||||||
var soundPoint = controlPoints.SoundPoints[0];
|
var soundPoint = controlPoints.SamplePoints[0];
|
||||||
Assert.AreEqual(956, soundPoint.Time);
|
Assert.AreEqual(956, soundPoint.Time);
|
||||||
Assert.AreEqual("soft", soundPoint.SampleBank);
|
Assert.AreEqual("soft", soundPoint.SampleBank);
|
||||||
Assert.AreEqual(60, soundPoint.SampleVolume);
|
Assert.AreEqual(60, soundPoint.SampleVolume);
|
||||||
|
@ -56,7 +56,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
b.ControlPointInfo.EffectPoints.Add(new EffectControlPoint { Time = random.Next(0, length) });
|
b.ControlPointInfo.EffectPoints.Add(new EffectControlPoint { Time = random.Next(0, length) });
|
||||||
|
|
||||||
for (int i = 0; i < random.Next(1, 5); i++)
|
for (int i = 0; i < random.Next(1, 5); i++)
|
||||||
b.ControlPointInfo.SoundPoints.Add(new SoundControlPoint { Time = random.Next(0, length) });
|
b.ControlPointInfo.SamplePoints.Add(new SampleControlPoint { Time = random.Next(0, length) });
|
||||||
|
|
||||||
b.BeatmapInfo.Bookmarks = new int[random.Next(10, 30)];
|
b.BeatmapInfo.Bookmarks = new int[random.Next(10, 30)];
|
||||||
for (int i = 0; i < b.BeatmapInfo.Bookmarks.Length; i++)
|
for (int i = 0; i < b.BeatmapInfo.Bookmarks.Length; i++)
|
||||||
|
@ -36,6 +36,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
AddStep(@"Network failure", () => leaderboard.SetRetrievalState(PlaceholderState.NetworkFailure));
|
AddStep(@"Network failure", () => leaderboard.SetRetrievalState(PlaceholderState.NetworkFailure));
|
||||||
AddStep(@"No supporter", () => leaderboard.SetRetrievalState(PlaceholderState.NotSupporter));
|
AddStep(@"No supporter", () => leaderboard.SetRetrievalState(PlaceholderState.NotSupporter));
|
||||||
AddStep(@"Not logged in", () => leaderboard.SetRetrievalState(PlaceholderState.NotLoggedIn));
|
AddStep(@"Not logged in", () => leaderboard.SetRetrievalState(PlaceholderState.NotLoggedIn));
|
||||||
|
AddStep(@"Unavailable", () => leaderboard.SetRetrievalState(PlaceholderState.Unavailable));
|
||||||
AddStep(@"Real beatmap", realBeatmap);
|
AddStep(@"Real beatmap", realBeatmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using osu.Framework.Audio.Sample;
|
||||||
|
|
||||||
namespace osu.Game.Audio
|
namespace osu.Game.Audio
|
||||||
{
|
{
|
||||||
@ -13,6 +14,13 @@ namespace osu.Game.Audio
|
|||||||
public const string HIT_NORMAL = @"hitnormal";
|
public const string HIT_NORMAL = @"hitnormal";
|
||||||
public const string HIT_CLAP = @"hitclap";
|
public const string HIT_CLAP = @"hitclap";
|
||||||
|
|
||||||
|
public SampleChannel GetChannel(SampleManager manager)
|
||||||
|
{
|
||||||
|
var channel = manager.Get($"Gameplay/{Bank}-{Name}");
|
||||||
|
channel.Volume.Value = Volume / 100.0;
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The bank to load the sample from.
|
/// The bank to load the sample from.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Beatmaps.ControlPoints
|
|||||||
/// All sound points.
|
/// All sound points.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
public SortedList<SoundControlPoint> SoundPoints { get; private set; } = new SortedList<SoundControlPoint>(Comparer<SoundControlPoint>.Default);
|
public SortedList<SampleControlPoint> SamplePoints { get; private set; } = new SortedList<SampleControlPoint>(Comparer<SampleControlPoint>.Default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All effect points.
|
/// All effect points.
|
||||||
@ -55,7 +55,7 @@ namespace osu.Game.Beatmaps.ControlPoints
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="time">The time to find the sound control point at.</param>
|
/// <param name="time">The time to find the sound control point at.</param>
|
||||||
/// <returns>The sound control point.</returns>
|
/// <returns>The sound control point.</returns>
|
||||||
public SoundControlPoint SoundPointAt(double time) => binarySearch(SoundPoints, time);
|
public SampleControlPoint SamplePointAt(double time) => binarySearch(SamplePoints, time, SamplePoints.FirstOrDefault());
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the timing control point that is active at <paramref name="time"/>.
|
/// Finds the timing control point that is active at <paramref name="time"/>.
|
||||||
|
34
osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs
Normal file
34
osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// 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.Audio;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps.ControlPoints
|
||||||
|
{
|
||||||
|
public class SampleControlPoint : ControlPoint
|
||||||
|
{
|
||||||
|
public const string DEFAULT_BANK = "normal";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The default sample bank at this control point.
|
||||||
|
/// </summary>
|
||||||
|
public string SampleBank = DEFAULT_BANK;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The default sample volume at this control point.
|
||||||
|
/// </summary>
|
||||||
|
public int SampleVolume;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a SampleInfo based on the sample settings in this control point.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sampleName">The name of the same.</param>
|
||||||
|
/// <returns>A populated <see cref="SampleInfo"/>.</returns>
|
||||||
|
public SampleInfo GetSampleInfo(string sampleName = SampleInfo.HIT_NORMAL) => new SampleInfo
|
||||||
|
{
|
||||||
|
Bank = SampleBank,
|
||||||
|
Name = sampleName,
|
||||||
|
Volume = SampleVolume,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +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
|
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps.ControlPoints
|
|
||||||
{
|
|
||||||
public class SoundControlPoint : ControlPoint
|
|
||||||
{
|
|
||||||
public const string DEFAULT_BANK = "normal";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The default sample bank at this control point.
|
|
||||||
/// </summary>
|
|
||||||
public string SampleBank = DEFAULT_BANK;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The default sample volume at this control point.
|
|
||||||
/// </summary>
|
|
||||||
public int SampleVolume;
|
|
||||||
}
|
|
||||||
}
|
|
@ -313,7 +313,7 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
stringSampleSet = @"normal";
|
stringSampleSet = @"normal";
|
||||||
|
|
||||||
DifficultyControlPoint difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(time);
|
DifficultyControlPoint difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(time);
|
||||||
SoundControlPoint soundPoint = beatmap.ControlPointInfo.SoundPointAt(time);
|
SampleControlPoint samplePoint = beatmap.ControlPointInfo.SamplePointAt(time);
|
||||||
EffectControlPoint effectPoint = beatmap.ControlPointInfo.EffectPointAt(time);
|
EffectControlPoint effectPoint = beatmap.ControlPointInfo.EffectPointAt(time);
|
||||||
|
|
||||||
if (timingChange)
|
if (timingChange)
|
||||||
@ -336,9 +336,9 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stringSampleSet != soundPoint.SampleBank || sampleVolume != soundPoint.SampleVolume)
|
if (stringSampleSet != samplePoint.SampleBank || sampleVolume != samplePoint.SampleVolume)
|
||||||
{
|
{
|
||||||
beatmap.ControlPointInfo.SoundPoints.Add(new SoundControlPoint
|
beatmap.ControlPointInfo.SamplePoints.Add(new SampleControlPoint
|
||||||
{
|
{
|
||||||
Time = time,
|
Time = time,
|
||||||
SampleBank = stringSampleSet,
|
SampleBank = stringSampleSet,
|
||||||
|
@ -84,26 +84,27 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio)
|
private void load(AudioManager audio)
|
||||||
{
|
{
|
||||||
foreach (SampleInfo sample in HitObject.Samples)
|
if (HitObject.Samples != null)
|
||||||
{
|
{
|
||||||
if (HitObject.SoundControlPoint == null)
|
if (HitObject.SampleControlPoint == null)
|
||||||
throw new ArgumentNullException(nameof(HitObject.SoundControlPoint), $"{nameof(HitObject)} must always have an attached {nameof(HitObject.SoundControlPoint)}.");
|
throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)} must always have an attached {nameof(HitObject.SampleControlPoint)}.");
|
||||||
|
|
||||||
var bank = sample.Bank;
|
foreach (SampleInfo s in HitObject.Samples)
|
||||||
if (string.IsNullOrEmpty(bank))
|
{
|
||||||
bank = HitObject.SoundControlPoint.SampleBank;
|
SampleInfo localSampleInfo = new SampleInfo
|
||||||
|
{
|
||||||
|
Bank = s.Bank ?? HitObject.SampleControlPoint.SampleBank,
|
||||||
|
Name = s.Name,
|
||||||
|
Volume = s.Volume > 0 ? s.Volume : HitObject.SampleControlPoint.SampleVolume
|
||||||
|
};
|
||||||
|
|
||||||
int volume = sample.Volume;
|
SampleChannel channel = localSampleInfo.GetChannel(audio.Sample);
|
||||||
if (volume == 0)
|
|
||||||
volume = HitObject.SoundControlPoint.SampleVolume;
|
|
||||||
|
|
||||||
SampleChannel channel = audio.Sample.Get($@"Gameplay/{bank}-{sample.Name}");
|
if (channel == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (channel == null)
|
Samples.Add(channel);
|
||||||
continue;
|
}
|
||||||
|
|
||||||
channel.Volume.Value = volume;
|
|
||||||
Samples.Add(channel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,10 +32,10 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
/// and can be treated as the default samples for the hit object.
|
/// and can be treated as the default samples for the hit object.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SampleInfoList Samples = new SampleInfoList();
|
public SampleInfoList Samples;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public SoundControlPoint SoundControlPoint;
|
public SampleControlPoint SampleControlPoint;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this <see cref="HitObject"/> is in Kiai time.
|
/// Whether this <see cref="HitObject"/> is in Kiai time.
|
||||||
@ -64,11 +64,11 @@ namespace osu.Game.Rulesets.Objects
|
|||||||
|
|
||||||
protected virtual void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
|
protected virtual void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
|
||||||
{
|
{
|
||||||
SoundControlPoint soundPoint = controlPointInfo.SoundPointAt(StartTime);
|
SampleControlPoint samplePoint = controlPointInfo.SamplePointAt(StartTime);
|
||||||
EffectControlPoint effectPoint = controlPointInfo.EffectPointAt(StartTime);
|
EffectControlPoint effectPoint = controlPointInfo.EffectPointAt(StartTime);
|
||||||
|
|
||||||
Kiai = effectPoint.KiaiMode;
|
Kiai = effectPoint.KiaiMode;
|
||||||
SoundControlPoint = soundPoint;
|
SampleControlPoint = samplePoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void CreateNestedHitObjects()
|
protected virtual void CreateNestedHitObjects()
|
||||||
|
@ -25,7 +25,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
|
|||||||
cpi.TimingPoints.ForEach(addTimingPoint);
|
cpi.TimingPoints.ForEach(addTimingPoint);
|
||||||
|
|
||||||
// Consider all non-timing points as the same type
|
// Consider all non-timing points as the same type
|
||||||
cpi.SoundPoints.Select(c => (ControlPoint)c)
|
cpi.SamplePoints.Select(c => (ControlPoint)c)
|
||||||
.Concat(cpi.EffectPoints)
|
.Concat(cpi.EffectPoints)
|
||||||
.Concat(cpi.DifficultyPoints)
|
.Concat(cpi.DifficultyPoints)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
|
@ -19,17 +19,14 @@ using osu.Game.Online.API;
|
|||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Game.Graphics.Sprites;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Framework.Input;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select.Leaderboards
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
{
|
{
|
||||||
public class Leaderboard : Container
|
public class Leaderboard : Container
|
||||||
{
|
{
|
||||||
private const double fade_duration = 200;
|
private const double fade_duration = 300;
|
||||||
|
|
||||||
private readonly ScrollContainer scrollContainer;
|
private readonly ScrollContainer scrollContainer;
|
||||||
private readonly Container placeholderContainer;
|
private readonly Container placeholderContainer;
|
||||||
@ -51,7 +48,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
{
|
{
|
||||||
scores = value;
|
scores = value;
|
||||||
|
|
||||||
scrollFlow?.FadeOut(fade_duration).Expire();
|
scrollFlow?.FadeOut(fade_duration, Easing.OutQuint).Expire();
|
||||||
scrollFlow = null;
|
scrollFlow = null;
|
||||||
|
|
||||||
loading.Hide();
|
loading.Hide();
|
||||||
@ -90,6 +87,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
}
|
}
|
||||||
|
|
||||||
private LeaderboardScope scope;
|
private LeaderboardScope scope;
|
||||||
|
|
||||||
public LeaderboardScope Scope
|
public LeaderboardScope Scope
|
||||||
{
|
{
|
||||||
get { return scope; }
|
get { return scope; }
|
||||||
@ -103,6 +101,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
}
|
}
|
||||||
|
|
||||||
private PlaceholderState placeholderState;
|
private PlaceholderState placeholderState;
|
||||||
|
|
||||||
protected PlaceholderState PlaceholderState
|
protected PlaceholderState PlaceholderState
|
||||||
{
|
{
|
||||||
get { return placeholderState; }
|
get { return placeholderState; }
|
||||||
@ -118,19 +117,18 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
OnRetry = updateScores,
|
OnRetry = updateScores,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case PlaceholderState.Unavailable:
|
||||||
|
replacePlaceholder(new MessagePlaceholder(@"Leaderboards are not available for this beatmap!"));
|
||||||
|
break;
|
||||||
case PlaceholderState.NoScores:
|
case PlaceholderState.NoScores:
|
||||||
replacePlaceholder(new MessagePlaceholder(@"No records yet!"));
|
replacePlaceholder(new MessagePlaceholder(@"No records yet!"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlaceholderState.NotLoggedIn:
|
case PlaceholderState.NotLoggedIn:
|
||||||
replacePlaceholder(new MessagePlaceholder(@"Please login to view online leaderboards!"));
|
replacePlaceholder(new MessagePlaceholder(@"Please login to view online leaderboards!"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlaceholderState.NotSupporter:
|
case PlaceholderState.NotSupporter:
|
||||||
replacePlaceholder(new MessagePlaceholder(@"Please invest in a supporter tag to view this leaderboard!"));
|
replacePlaceholder(new MessagePlaceholder(@"Please invest in a supporter tag to view this leaderboard!"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
replacePlaceholder(null);
|
replacePlaceholder(null);
|
||||||
break;
|
break;
|
||||||
@ -150,18 +148,13 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
loading = new LoadingAnimation(),
|
loading = new LoadingAnimation(),
|
||||||
placeholderContainer = new Container
|
placeholderContainer = new Container
|
||||||
{
|
{
|
||||||
Alpha = 0,
|
RelativeSizeAxes = Axes.Both
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private APIAccess api;
|
private APIAccess api;
|
||||||
|
|
||||||
private BeatmapInfo beatmap;
|
private BeatmapInfo beatmap;
|
||||||
|
|
||||||
private OsuGame osuGame;
|
private OsuGame osuGame;
|
||||||
|
|
||||||
private ScheduledDelegate pendingBeatmapSwitch;
|
private ScheduledDelegate pendingBeatmapSwitch;
|
||||||
@ -229,15 +222,15 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api?.IsLoggedIn != true)
|
if (Beatmap?.OnlineBeatmapID == null)
|
||||||
{
|
{
|
||||||
PlaceholderState = PlaceholderState.NotLoggedIn;
|
PlaceholderState = PlaceholderState.Unavailable;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Beatmap?.OnlineBeatmapID == null)
|
if (api?.IsLoggedIn != true)
|
||||||
{
|
{
|
||||||
PlaceholderState = PlaceholderState.NetworkFailure;
|
PlaceholderState = PlaceholderState.NotLoggedIn;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,23 +265,22 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
|
|
||||||
private void replacePlaceholder(Placeholder placeholder)
|
private void replacePlaceholder(Placeholder placeholder)
|
||||||
{
|
{
|
||||||
if (placeholder == null)
|
var existingPlaceholder = placeholderContainer.Children.LastOrDefault() as Placeholder;
|
||||||
{
|
|
||||||
placeholderContainer.FadeOutFromOne(fade_duration, Easing.OutQuint);
|
if (placeholder != null && placeholder.Equals(existingPlaceholder))
|
||||||
placeholderContainer.Clear(true);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var existingPlaceholder = placeholderContainer.Children.FirstOrDefault() as Placeholder;
|
existingPlaceholder?.FadeOut(150, Easing.OutQuint).Expire();
|
||||||
|
|
||||||
if (placeholder.Equals(existingPlaceholder))
|
if (placeholder == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Scores = null;
|
Scores = null;
|
||||||
|
|
||||||
placeholderContainer.Clear(true);
|
placeholderContainer.Add(placeholder);
|
||||||
placeholderContainer.Child = placeholder;
|
|
||||||
placeholderContainer.FadeInFromZero(fade_duration, Easing.OutQuint);
|
placeholder.ScaleTo(0.8f).Then().ScaleTo(1, fade_duration * 3, Easing.OutQuint);
|
||||||
|
placeholder.FadeInFromZero(fade_duration, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
@ -319,101 +311,6 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract class Placeholder : FillFlowContainer, IEquatable<Placeholder>
|
|
||||||
{
|
|
||||||
public virtual bool Equals(Placeholder other) => GetType() == other?.GetType();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MessagePlaceholder : Placeholder
|
|
||||||
{
|
|
||||||
private readonly string message;
|
|
||||||
|
|
||||||
public MessagePlaceholder(string message)
|
|
||||||
{
|
|
||||||
Direction = FillDirection.Horizontal;
|
|
||||||
AutoSizeAxes = Axes.Both;
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new SpriteIcon
|
|
||||||
{
|
|
||||||
Icon = FontAwesome.fa_exclamation_circle,
|
|
||||||
Size = new Vector2(26),
|
|
||||||
Margin = new MarginPadding { Right = 10 },
|
|
||||||
},
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Text = this.message = message,
|
|
||||||
TextSize = 22,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(Placeholder other) => (other as MessagePlaceholder)?.message == message;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RetrievalFailurePlaceholder : Placeholder
|
|
||||||
{
|
|
||||||
public Action OnRetry;
|
|
||||||
|
|
||||||
public RetrievalFailurePlaceholder()
|
|
||||||
{
|
|
||||||
Direction = FillDirection.Horizontal;
|
|
||||||
AutoSizeAxes = Axes.Both;
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new RetryButton
|
|
||||||
{
|
|
||||||
Action = () => OnRetry?.Invoke(),
|
|
||||||
Margin = new MarginPadding { Right = 10 },
|
|
||||||
},
|
|
||||||
new OsuSpriteText
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopLeft,
|
|
||||||
Text = @"Couldn't retrieve scores!",
|
|
||||||
TextSize = 22,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RetryButton : OsuHoverContainer
|
|
||||||
{
|
|
||||||
private readonly SpriteIcon icon;
|
|
||||||
|
|
||||||
public Action Action;
|
|
||||||
|
|
||||||
public RetryButton()
|
|
||||||
{
|
|
||||||
Height = 26;
|
|
||||||
Width = 26;
|
|
||||||
Child = new OsuClickableContainer
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Action = () => Action?.Invoke(),
|
|
||||||
Child = icon = new SpriteIcon
|
|
||||||
{
|
|
||||||
Icon = FontAwesome.fa_refresh,
|
|
||||||
Size = new Vector2(26),
|
|
||||||
Shadow = true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
|
||||||
{
|
|
||||||
icon.ScaleTo(0.8f, 4000, Easing.OutQuint);
|
|
||||||
return base.OnMouseDown(state, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
|
||||||
{
|
|
||||||
icon.ScaleTo(1, 1000, Easing.OutElastic);
|
|
||||||
return base.OnMouseUp(state, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum LeaderboardScope
|
public enum LeaderboardScope
|
||||||
@ -429,6 +326,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
Successful,
|
Successful,
|
||||||
Retrieving,
|
Retrieving,
|
||||||
NetworkFailure,
|
NetworkFailure,
|
||||||
|
Unavailable,
|
||||||
NoScores,
|
NoScores,
|
||||||
NotLoggedIn,
|
NotLoggedIn,
|
||||||
NotSupporter,
|
NotSupporter,
|
||||||
|
38
osu.Game/Screens/Select/Leaderboards/MessagePlaceholder.cs
Normal file
38
osu.Game/Screens/Select/Leaderboards/MessagePlaceholder.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// 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.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
|
{
|
||||||
|
public class MessagePlaceholder : Placeholder
|
||||||
|
{
|
||||||
|
private readonly string message;
|
||||||
|
|
||||||
|
public MessagePlaceholder(string message)
|
||||||
|
{
|
||||||
|
Direction = FillDirection.Horizontal;
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new SpriteIcon
|
||||||
|
{
|
||||||
|
Icon = FontAwesome.fa_exclamation_circle,
|
||||||
|
Size = new Vector2(26),
|
||||||
|
Margin = new MarginPadding { Right = 10 },
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Text = this.message = message,
|
||||||
|
TextSize = 22,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(Placeholder other) => (other as MessagePlaceholder)?.message == message;
|
||||||
|
}
|
||||||
|
}
|
20
osu.Game/Screens/Select/Leaderboards/Placeholder.cs
Normal file
20
osu.Game/Screens/Select/Leaderboards/Placeholder.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// 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.Graphics.Containers;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
|
{
|
||||||
|
public abstract class Placeholder : FillFlowContainer, IEquatable<Placeholder>
|
||||||
|
{
|
||||||
|
protected Placeholder()
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre;
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool Equals(Placeholder other) => GetType() == other?.GetType();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
// 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.Graphics.Containers;
|
||||||
|
using osu.Framework.Input;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Select.Leaderboards
|
||||||
|
{
|
||||||
|
public class RetrievalFailurePlaceholder : Placeholder
|
||||||
|
{
|
||||||
|
public Action OnRetry;
|
||||||
|
|
||||||
|
public RetrievalFailurePlaceholder()
|
||||||
|
{
|
||||||
|
Direction = FillDirection.Horizontal;
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new RetryButton
|
||||||
|
{
|
||||||
|
Action = () => OnRetry?.Invoke(),
|
||||||
|
Margin = new MarginPadding { Right = 10 },
|
||||||
|
},
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
Text = @"Couldn't retrieve scores!",
|
||||||
|
TextSize = 22,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RetryButton : OsuHoverContainer
|
||||||
|
{
|
||||||
|
private readonly SpriteIcon icon;
|
||||||
|
|
||||||
|
public Action Action;
|
||||||
|
|
||||||
|
public RetryButton()
|
||||||
|
{
|
||||||
|
Height = 26;
|
||||||
|
Width = 26;
|
||||||
|
Child = new OsuClickableContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Action = () => Action?.Invoke(),
|
||||||
|
Child = icon = new SpriteIcon
|
||||||
|
{
|
||||||
|
Icon = FontAwesome.fa_refresh,
|
||||||
|
Size = new Vector2(26),
|
||||||
|
Shadow = true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||||
|
{
|
||||||
|
icon.ScaleTo(0.8f, 4000, Easing.OutQuint);
|
||||||
|
return base.OnMouseDown(state, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
||||||
|
{
|
||||||
|
icon.ScaleTo(1, 1000, Easing.OutElastic);
|
||||||
|
return base.OnMouseUp(state, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -258,7 +258,7 @@
|
|||||||
<Compile Include="Beatmaps\ControlPoints\ControlPointInfo.cs" />
|
<Compile Include="Beatmaps\ControlPoints\ControlPointInfo.cs" />
|
||||||
<Compile Include="Beatmaps\ControlPoints\DifficultyControlPoint.cs" />
|
<Compile Include="Beatmaps\ControlPoints\DifficultyControlPoint.cs" />
|
||||||
<Compile Include="Beatmaps\ControlPoints\EffectControlPoint.cs" />
|
<Compile Include="Beatmaps\ControlPoints\EffectControlPoint.cs" />
|
||||||
<Compile Include="Beatmaps\ControlPoints\SoundControlPoint.cs" />
|
<Compile Include="Beatmaps\ControlPoints\SampleControlPoint.cs" />
|
||||||
<Compile Include="Beatmaps\ControlPoints\TimingControlPoint.cs" />
|
<Compile Include="Beatmaps\ControlPoints\TimingControlPoint.cs" />
|
||||||
<Compile Include="Beatmaps\DifficultyCalculator.cs" />
|
<Compile Include="Beatmaps\DifficultyCalculator.cs" />
|
||||||
<Compile Include="Beatmaps\Drawables\BeatmapBackgroundSprite.cs" />
|
<Compile Include="Beatmaps\Drawables\BeatmapBackgroundSprite.cs" />
|
||||||
@ -785,6 +785,9 @@
|
|||||||
<Compile Include="Screens\Select\Leaderboards\DrawableRank.cs" />
|
<Compile Include="Screens\Select\Leaderboards\DrawableRank.cs" />
|
||||||
<Compile Include="Screens\Select\Leaderboards\Leaderboard.cs" />
|
<Compile Include="Screens\Select\Leaderboards\Leaderboard.cs" />
|
||||||
<Compile Include="Screens\Select\Leaderboards\LeaderboardScore.cs" />
|
<Compile Include="Screens\Select\Leaderboards\LeaderboardScore.cs" />
|
||||||
|
<Compile Include="Screens\Select\Leaderboards\MessagePlaceholder.cs" />
|
||||||
|
<Compile Include="Screens\Select\Leaderboards\Placeholder.cs" />
|
||||||
|
<Compile Include="Screens\Select\Leaderboards\RetrievalFailurePlaceholder.cs" />
|
||||||
<Compile Include="Screens\Select\MatchSongSelect.cs" />
|
<Compile Include="Screens\Select\MatchSongSelect.cs" />
|
||||||
<Compile Include="Screens\Select\Options\BeatmapOptionsButton.cs" />
|
<Compile Include="Screens\Select\Options\BeatmapOptionsButton.cs" />
|
||||||
<Compile Include="Screens\Select\Options\BeatmapOptionsOverlay.cs" />
|
<Compile Include="Screens\Select\Options\BeatmapOptionsOverlay.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user