mirror of
https://github.com/ppy/osu.git
synced 2025-01-28 02:02:53 +08:00
Merge branch 'master' of https://github.com/ppy/osu into intro-improvements
This commit is contained in:
commit
630c556b80
16
.vscode/tasks.json
vendored
16
.vscode/tasks.json
vendored
@ -10,10 +10,16 @@
|
||||
"showOutput": "silent",
|
||||
"command": "msbuild",
|
||||
"args": [
|
||||
// Ask msbuild to generate full paths for file names.
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/property:DebugType=portable"
|
||||
],
|
||||
"windows": {
|
||||
"args": [
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/property:DebugType=portable",
|
||||
"/m" //parallel compiling support. doesn't work well with mono atm
|
||||
]
|
||||
},
|
||||
// Use the standard MS compiler pattern to detect errors, warnings and infos
|
||||
"problemMatcher": "$msCompile",
|
||||
"isBuildCommand": true
|
||||
@ -29,6 +35,14 @@
|
||||
"/property:DebugType=portable",
|
||||
"/target:Clean,Build"
|
||||
],
|
||||
"windows": {
|
||||
"args": [
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/property:DebugType=portable",
|
||||
"/target:Clean,Build",
|
||||
"/m" //parallel compiling support. doesn't work well with mono atm
|
||||
]
|
||||
},
|
||||
// Use the standard MS compiler pattern to detect errors, warnings and infos
|
||||
"problemMatcher": "$msCompile",
|
||||
"isBuildCommand": true
|
||||
|
@ -10,7 +10,6 @@ using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.Judgements;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
@ -62,15 +61,12 @@ namespace osu.Desktop.VisualTests.Tests
|
||||
add(new DrawableSlider(new Slider
|
||||
{
|
||||
StartTime = framedClock.CurrentTime + 600,
|
||||
CurveObject = new CurvedHitObject
|
||||
ControlPoints = new List<Vector2>
|
||||
{
|
||||
ControlPoints = new List<Vector2>
|
||||
{
|
||||
new Vector2(-200, 0),
|
||||
new Vector2(400, 0),
|
||||
},
|
||||
Distance = 400
|
||||
new Vector2(-200, 0),
|
||||
new Vector2(400, 0),
|
||||
},
|
||||
Distance = 400,
|
||||
Position = new Vector2(-200, 0),
|
||||
Velocity = 1,
|
||||
TickDistance = 100,
|
||||
|
@ -19,10 +19,10 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||
|
||||
protected override IEnumerable<OsuHitObject> ConvertHitObject(HitObject original, Beatmap beatmap)
|
||||
{
|
||||
IHasCurve curveData = original as IHasCurve;
|
||||
IHasEndTime endTimeData = original as IHasEndTime;
|
||||
IHasPosition positionData = original as IHasPosition;
|
||||
IHasCombo comboData = original as IHasCombo;
|
||||
var curveData = original as IHasCurve;
|
||||
var endTimeData = original as IHasEndTime;
|
||||
var positionData = original as IHasPosition;
|
||||
var comboData = original as IHasCombo;
|
||||
|
||||
if (curveData != null)
|
||||
{
|
||||
@ -30,7 +30,11 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||
{
|
||||
StartTime = original.StartTime,
|
||||
Samples = original.Samples,
|
||||
CurveObject = curveData,
|
||||
ControlPoints = curveData.ControlPoints,
|
||||
CurveType = curveData.CurveType,
|
||||
Distance = curveData.Distance,
|
||||
RepeatSamples = curveData.RepeatSamples,
|
||||
RepeatCount = curveData.RepeatCount,
|
||||
Position = positionData?.Position ?? Vector2.Zero,
|
||||
NewCombo = comboData?.NewCombo ?? false
|
||||
};
|
||||
|
@ -20,24 +20,33 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
/// </summary>
|
||||
private const float base_scoring_distance = 100;
|
||||
|
||||
public IHasCurve CurveObject { get; set; }
|
||||
|
||||
public SliderCurve Curve => CurveObject.Curve;
|
||||
public readonly SliderCurve Curve = new SliderCurve();
|
||||
|
||||
public double EndTime => StartTime + RepeatCount * Curve.Distance / Velocity;
|
||||
public double Duration => EndTime - StartTime;
|
||||
|
||||
public override Vector2 EndPosition => PositionAt(1);
|
||||
|
||||
public Vector2 PositionAt(double progress) => CurveObject.PositionAt(progress);
|
||||
public double ProgressAt(double progress) => CurveObject.ProgressAt(progress);
|
||||
public int RepeatAt(double progress) => CurveObject.RepeatAt(progress);
|
||||
public List<Vector2> ControlPoints
|
||||
{
|
||||
get { return Curve.ControlPoints; }
|
||||
set { Curve.ControlPoints = value; }
|
||||
}
|
||||
|
||||
public List<Vector2> ControlPoints => CurveObject.ControlPoints;
|
||||
public CurveType CurveType => CurveObject.CurveType;
|
||||
public double Distance => CurveObject.Distance;
|
||||
public CurveType CurveType
|
||||
{
|
||||
get { return Curve.CurveType; }
|
||||
set { Curve.CurveType = value; }
|
||||
}
|
||||
|
||||
public int RepeatCount => CurveObject.RepeatCount;
|
||||
public double Distance
|
||||
{
|
||||
get { return Curve.Distance; }
|
||||
set { Curve.Distance = value; }
|
||||
}
|
||||
|
||||
public List<List<SampleInfo>> RepeatSamples { get; set; } = new List<List<SampleInfo>>();
|
||||
public int RepeatCount { get; set; } = 1;
|
||||
|
||||
private int stackHeight;
|
||||
public override int StackHeight
|
||||
@ -63,6 +72,18 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
TickDistance = scoringDistance / difficulty.SliderTickRate;
|
||||
}
|
||||
|
||||
public Vector2 PositionAt(double progress) => Curve.PositionAt(ProgressAt(progress));
|
||||
|
||||
public double ProgressAt(double progress)
|
||||
{
|
||||
double p = progress * RepeatCount % 1;
|
||||
if (RepeatAt(progress) % 2 == 1)
|
||||
p = 1 - p;
|
||||
return p;
|
||||
}
|
||||
|
||||
public int RepeatAt(double progress) => (int)(progress * RepeatCount);
|
||||
|
||||
public IEnumerable<SliderTick> Ticks
|
||||
{
|
||||
get
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using System;
|
||||
@ -28,7 +27,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
protected override void PreprocessHitObjects()
|
||||
{
|
||||
foreach (var h in Objects)
|
||||
(h as IHasCurve)?.Curve?.Calculate();
|
||||
(h as Slider)?.Curve?.Calculate();
|
||||
}
|
||||
|
||||
protected override double CalculateInternal(Dictionary<string, string> categoryDifficulty)
|
||||
@ -190,4 +189,4 @@ namespace osu.Game.Rulesets.Osu
|
||||
Aim,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
69
osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs
Normal file
69
osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs
Normal file
@ -0,0 +1,69 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Beatmaps.Drawables
|
||||
{
|
||||
internal class DifficultyColouredContainer : Container, IHasAccentColour
|
||||
{
|
||||
public Color4 AccentColour { get; set; }
|
||||
|
||||
private readonly BeatmapInfo beatmap;
|
||||
private OsuColour palette;
|
||||
|
||||
public DifficultyColouredContainer(BeatmapInfo beatmap)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour palette)
|
||||
{
|
||||
this.palette = palette;
|
||||
AccentColour = getColour(beatmap);
|
||||
}
|
||||
|
||||
private enum DifficultyRating
|
||||
{
|
||||
Easy,
|
||||
Normal,
|
||||
Hard,
|
||||
Insane,
|
||||
Expert
|
||||
}
|
||||
|
||||
private DifficultyRating getDifficultyRating(BeatmapInfo beatmap)
|
||||
{
|
||||
var rating = beatmap.StarDifficulty;
|
||||
|
||||
if (rating < 1.5) return DifficultyRating.Easy;
|
||||
if (rating < 2.25) return DifficultyRating.Normal;
|
||||
if (rating < 3.75) return DifficultyRating.Hard;
|
||||
if (rating < 5.25) return DifficultyRating.Insane;
|
||||
return DifficultyRating.Expert;
|
||||
}
|
||||
|
||||
private Color4 getColour(BeatmapInfo beatmap)
|
||||
{
|
||||
switch (getDifficultyRating(beatmap))
|
||||
{
|
||||
case DifficultyRating.Easy:
|
||||
return palette.Green;
|
||||
default:
|
||||
case DifficultyRating.Normal:
|
||||
return palette.Yellow;
|
||||
case DifficultyRating.Hard:
|
||||
return palette.Pink;
|
||||
case DifficultyRating.Insane:
|
||||
return palette.Purple;
|
||||
case DifficultyRating.Expert:
|
||||
return palette.Gray0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using OpenTK;
|
||||
@ -11,23 +10,20 @@ using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Beatmaps.Drawables
|
||||
{
|
||||
internal class DifficultyIcon : Container
|
||||
|
||||
internal class DifficultyIcon : DifficultyColouredContainer
|
||||
{
|
||||
private readonly BeatmapInfo beatmap;
|
||||
private OsuColour palette;
|
||||
|
||||
public DifficultyIcon(BeatmapInfo beatmap)
|
||||
public DifficultyIcon(BeatmapInfo beatmap) : base(beatmap)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
const float size = 20;
|
||||
Size = new Vector2(size);
|
||||
Size = new Vector2(20);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour palette)
|
||||
private void load()
|
||||
{
|
||||
this.palette = palette;
|
||||
|
||||
Children = new[]
|
||||
{
|
||||
new TextAwesome
|
||||
@ -35,7 +31,7 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
TextSize = Size.X,
|
||||
Colour = getColour(beatmap),
|
||||
Colour = AccentColour,
|
||||
Icon = FontAwesome.fa_circle
|
||||
},
|
||||
new TextAwesome
|
||||
@ -48,43 +44,5 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private enum DifficultyRating
|
||||
{
|
||||
Easy,
|
||||
Normal,
|
||||
Hard,
|
||||
Insane,
|
||||
Expert
|
||||
}
|
||||
|
||||
private DifficultyRating getDifficultyRating(BeatmapInfo beatmap)
|
||||
{
|
||||
var rating = beatmap.StarDifficulty;
|
||||
|
||||
if (rating < 1.5) return DifficultyRating.Easy;
|
||||
if (rating < 2.25) return DifficultyRating.Normal;
|
||||
if (rating < 3.75) return DifficultyRating.Hard;
|
||||
if (rating < 5.25) return DifficultyRating.Insane;
|
||||
return DifficultyRating.Expert;
|
||||
}
|
||||
|
||||
private Color4 getColour(BeatmapInfo beatmap)
|
||||
{
|
||||
switch (getDifficultyRating(beatmap))
|
||||
{
|
||||
case DifficultyRating.Easy:
|
||||
return palette.Green;
|
||||
default:
|
||||
case DifficultyRating.Normal:
|
||||
return palette.Yellow;
|
||||
case DifficultyRating.Hard:
|
||||
return palette.Pink;
|
||||
case DifficultyRating.Insane:
|
||||
return palette.Purple;
|
||||
case DifficultyRating.Expert:
|
||||
return palette.Gray0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
// TODO: Not sure how far back to go, or differences between versions
|
||||
}
|
||||
|
||||
private HitObjectParser parser;
|
||||
private ConvertHitObjectParser parser;
|
||||
|
||||
private LegacySampleBank defaultSampleBank;
|
||||
private int defaultSampleVolume = 100;
|
||||
@ -90,16 +90,16 @@ namespace osu.Game.Beatmaps.Formats
|
||||
switch (beatmap.BeatmapInfo.RulesetID)
|
||||
{
|
||||
case 0:
|
||||
parser = new Rulesets.Objects.Legacy.Osu.HitObjectParser();
|
||||
parser = new Rulesets.Objects.Legacy.Osu.ConvertHitObjectParser();
|
||||
break;
|
||||
case 1:
|
||||
parser = new Rulesets.Objects.Legacy.Taiko.HitObjectParser();
|
||||
parser = new Rulesets.Objects.Legacy.Taiko.ConvertHitObjectParser();
|
||||
break;
|
||||
case 2:
|
||||
parser = new Rulesets.Objects.Legacy.Catch.HitObjectParser();
|
||||
parser = new Rulesets.Objects.Legacy.Catch.ConvertHitObjectParser();
|
||||
break;
|
||||
case 3:
|
||||
parser = new Rulesets.Objects.Legacy.Mania.HitObjectParser();
|
||||
parser = new Rulesets.Objects.Legacy.Mania.ConvertHitObjectParser();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Screens.Select;
|
||||
|
||||
namespace osu.Game.Configuration
|
||||
{
|
||||
@ -34,8 +35,7 @@ namespace osu.Game.Configuration
|
||||
|
||||
Set(OsuConfig.MenuParallax, true);
|
||||
|
||||
Set(OsuConfig.MenuVoice, true);
|
||||
Set(OsuConfig.MenuMusic, true);
|
||||
Set(OsuConfig.BeatmapDetailTab, BeatmapDetailTab.Details);
|
||||
|
||||
Set(OsuConfig.ShowInterface, true);
|
||||
Set(OsuConfig.KeyOverlay, false);
|
||||
@ -148,6 +148,8 @@ namespace osu.Game.Configuration
|
||||
Set(OsuConfig.YahooIntegration, false).Disabled = true;
|
||||
Set(OsuConfig.ForceFrameFlush, false).Disabled = true;
|
||||
Set(OsuConfig.DetectPerformanceIssues, true).Disabled = true;
|
||||
Set(OsuConfig.MenuMusic, true).Disabled = true;
|
||||
Set(OsuConfig.MenuVoice, true).Disabled = true;
|
||||
Set(OsuConfig.RawInput, false).Disabled = true;
|
||||
Set(OsuConfig.AbsoluteToOsuWindow, Get<bool>(OsuConfig.RawInput)).Disabled = true;
|
||||
Set(OsuConfig.ShowMenuTips, true).Disabled = true;
|
||||
@ -317,6 +319,7 @@ namespace osu.Game.Configuration
|
||||
MenuMusic,
|
||||
MenuVoice,
|
||||
MenuParallax,
|
||||
BeatmapDetailTab,
|
||||
RawInput,
|
||||
AbsoluteToOsuWindow,
|
||||
ConfineMouse,
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Database
|
||||
{
|
||||
@ -18,11 +19,13 @@ namespace osu.Game.Database
|
||||
/// <summary>
|
||||
/// Points of failure on a relative time scale (usually 0..100).
|
||||
/// </summary>
|
||||
[JsonProperty(@"fail")]
|
||||
public IEnumerable<int> Fails { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Points of retry on a relative time scale (usually 0..100).
|
||||
/// </summary>
|
||||
[JsonProperty(@"exit")]
|
||||
public IEnumerable<int> Retries { get; set; }
|
||||
}
|
||||
}
|
||||
|
46
osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs
Normal file
46
osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetBeatmapDetailsRequest : APIRequest<GetBeatmapDeatilsResponse>
|
||||
{
|
||||
private readonly BeatmapInfo beatmap;
|
||||
|
||||
private string lookupString => beatmap.OnlineBeatmapID > 0 ? beatmap.OnlineBeatmapID.ToString() : $@"lookup?checksum={beatmap.Hash}&filename={beatmap.Path}";
|
||||
|
||||
public GetBeatmapDetailsRequest(BeatmapInfo beatmap)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
protected override string Target => $@"beatmaps/{lookupString}";
|
||||
}
|
||||
|
||||
public class GetBeatmapDeatilsResponse : BeatmapMetrics
|
||||
{
|
||||
//the online API returns some metrics as a nested object.
|
||||
[JsonProperty(@"failtimes")]
|
||||
private BeatmapMetrics failTimes
|
||||
{
|
||||
set
|
||||
{
|
||||
Fails = value.Fails;
|
||||
Retries = value.Retries;
|
||||
}
|
||||
}
|
||||
|
||||
//and other metrics in the beatmap set.
|
||||
[JsonProperty(@"beatmapset")]
|
||||
private BeatmapMetrics beatmapSet
|
||||
{
|
||||
set
|
||||
{
|
||||
Ratings = value.Ratings;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -294,7 +294,7 @@ namespace osu.Game.Overlays
|
||||
trackManager.SetExclusive(current.Track);
|
||||
current.Track.Start();
|
||||
beatmapSource.Value = current;
|
||||
}).ContinueWith(task => Schedule(() => task.ThrowIfFaulted()), TaskContinuationOptions.OnlyOnFaulted);
|
||||
}).ContinueWith(task => Schedule(task.ThrowIfFaulted), TaskContinuationOptions.OnlyOnFaulted);
|
||||
updateDisplay(current, isNext ? TransformDirection.Next : TransformDirection.Prev);
|
||||
}
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Rulesets.Objects
|
||||
{
|
||||
public class CurvedHitObject : HitObject, IHasCurve
|
||||
{
|
||||
public SliderCurve Curve { get; } = new SliderCurve();
|
||||
|
||||
public int RepeatCount { get; set; } = 1;
|
||||
|
||||
public double EndTime => 0;
|
||||
public double Duration => 0;
|
||||
|
||||
public List<Vector2> ControlPoints
|
||||
{
|
||||
get { return Curve.ControlPoints; }
|
||||
set { Curve.ControlPoints = value; }
|
||||
}
|
||||
|
||||
public CurveType CurveType
|
||||
{
|
||||
get { return Curve.CurveType; }
|
||||
set { Curve.CurveType = value; }
|
||||
}
|
||||
|
||||
public double Distance
|
||||
{
|
||||
get { return Curve.Distance; }
|
||||
set { Curve.Distance = value; }
|
||||
}
|
||||
|
||||
public Vector2 PositionAt(double progress) => Curve.PositionAt(ProgressAt(progress));
|
||||
|
||||
public double ProgressAt(double progress)
|
||||
{
|
||||
var p = progress * RepeatCount % 1;
|
||||
if (RepeatAt(progress) % 2 == 1)
|
||||
p = 1 - p;
|
||||
return p;
|
||||
}
|
||||
|
||||
public int RepeatAt(double progress) => (int)(progress * RepeatCount);
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Rulesets.Objects
|
||||
@ -19,10 +20,14 @@ namespace osu.Game.Rulesets.Objects
|
||||
/// <summary>
|
||||
/// The time at which the HitObject starts.
|
||||
/// </summary>
|
||||
public double StartTime { get; set; }
|
||||
public double StartTime;
|
||||
|
||||
/// <summary>
|
||||
/// The samples to be played when this hit object is hit.
|
||||
/// <para>
|
||||
/// In the case of <see cref="IHasRepeats"/> types, this is the sample of the curve body
|
||||
/// and can be treated as the default samples for the hit object.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public List<SampleInfo> Samples = new List<SampleInfo>();
|
||||
|
||||
@ -36,17 +41,24 @@ namespace osu.Game.Rulesets.Objects
|
||||
ControlPoint overridePoint;
|
||||
ControlPoint timingPoint = timing.TimingPointAt(StartTime, out overridePoint);
|
||||
|
||||
foreach (var sample in Samples)
|
||||
{
|
||||
if (sample.Volume == 0)
|
||||
sample.Volume = (overridePoint ?? timingPoint)?.SampleVolume ?? 0;
|
||||
ControlPoint samplePoint = overridePoint ?? timingPoint;
|
||||
|
||||
// If the bank is not assigned a name, assign it from the control point
|
||||
if (!string.IsNullOrEmpty(sample.Bank))
|
||||
continue;
|
||||
// Initialize first sample
|
||||
Samples.ForEach(s => initializeSampleInfo(s, samplePoint));
|
||||
|
||||
sample.Bank = (overridePoint ?? timingPoint)?.SampleBank ?? @"normal";
|
||||
}
|
||||
// Initialize any repeat samples
|
||||
var repeatData = this as IHasRepeats;
|
||||
repeatData?.RepeatSamples?.ForEach(r => r.ForEach(s => initializeSampleInfo(s, samplePoint)));
|
||||
}
|
||||
|
||||
private void initializeSampleInfo(SampleInfo sample, ControlPoint controlPoint)
|
||||
{
|
||||
if (sample.Volume == 0)
|
||||
sample.Volume = controlPoint?.SampleVolume ?? 0;
|
||||
|
||||
// If the bank is not assigned a name, assign it from the control point
|
||||
if (string.IsNullOrEmpty(sample.Bank))
|
||||
sample.Bank = controlPoint?.SampleBank ?? @"normal";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch
|
||||
/// <summary>
|
||||
/// Legacy osu!catch Hit-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Hit : HitObject, IHasCombo, IHasXPosition
|
||||
internal sealed class ConvertHit : HitObject, IHasCombo, IHasXPosition
|
||||
{
|
||||
public float X { get; set; }
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -10,33 +11,34 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch
|
||||
/// <summary>
|
||||
/// A HitObjectParser to parse legacy osu!catch Beatmaps.
|
||||
/// </summary>
|
||||
internal class HitObjectParser : Legacy.HitObjectParser
|
||||
internal class ConvertHitObjectParser : Legacy.ConvertHitObjectParser
|
||||
{
|
||||
protected override HitObject CreateHit(Vector2 position, bool newCombo)
|
||||
{
|
||||
return new Hit
|
||||
return new ConvertHit
|
||||
{
|
||||
X = position.X,
|
||||
NewCombo = newCombo,
|
||||
};
|
||||
}
|
||||
|
||||
protected override HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount)
|
||||
protected override HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples)
|
||||
{
|
||||
return new Slider
|
||||
return new ConvertSlider
|
||||
{
|
||||
X = position.X,
|
||||
NewCombo = newCombo,
|
||||
ControlPoints = controlPoints,
|
||||
Distance = length,
|
||||
CurveType = curveType,
|
||||
RepeatSamples = repeatSamples,
|
||||
RepeatCount = repeatCount
|
||||
};
|
||||
}
|
||||
|
||||
protected override HitObject CreateSpinner(Vector2 position, double endTime)
|
||||
{
|
||||
return new Spinner
|
||||
return new ConvertSpinner
|
||||
{
|
||||
EndTime = endTime
|
||||
};
|
@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch
|
||||
/// <summary>
|
||||
/// Legacy osu!catch Slider-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Slider : CurvedHitObject, IHasXPosition, IHasCombo
|
||||
internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasXPosition, IHasCombo
|
||||
{
|
||||
public float X { get; set; }
|
||||
|
@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch
|
||||
/// <summary>
|
||||
/// Legacy osu!catch Spinner-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Spinner : HitObject, IHasEndTime
|
||||
internal sealed class ConvertSpinner : HitObject, IHasEndTime
|
||||
{
|
||||
public double EndTime { get; set; }
|
||||
|
@ -14,29 +14,28 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
/// <summary>
|
||||
/// A HitObjectParser to parse legacy Beatmaps.
|
||||
/// </summary>
|
||||
internal abstract class HitObjectParser : Objects.HitObjectParser
|
||||
internal abstract class ConvertHitObjectParser : HitObjectParser
|
||||
{
|
||||
public override HitObject Parse(string text)
|
||||
{
|
||||
string[] split = text.Split(',');
|
||||
var type = (HitObjectType)int.Parse(split[3]) & ~HitObjectType.ColourHax;
|
||||
bool combo = type.HasFlag(HitObjectType.NewCombo);
|
||||
type &= ~HitObjectType.NewCombo;
|
||||
ConvertHitObjectType type = (ConvertHitObjectType)int.Parse(split[3]) & ~ConvertHitObjectType.ColourHax;
|
||||
bool combo = type.HasFlag(ConvertHitObjectType.NewCombo);
|
||||
type &= ~ConvertHitObjectType.NewCombo;
|
||||
|
||||
int sampleVolume = 0;
|
||||
string normalSampleBank = null;
|
||||
string addSampleBank = null;
|
||||
var soundType = (LegacySoundType)int.Parse(split[4]);
|
||||
var bankInfo = new SampleBankInfo();
|
||||
|
||||
HitObject result;
|
||||
|
||||
if ((type & HitObjectType.Circle) > 0)
|
||||
if ((type & ConvertHitObjectType.Circle) > 0)
|
||||
{
|
||||
result = CreateHit(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo);
|
||||
|
||||
if (split.Length > 5)
|
||||
readCustomSampleBanks(split[5], ref normalSampleBank, ref addSampleBank, ref sampleVolume);
|
||||
readCustomSampleBanks(split[5], bankInfo);
|
||||
}
|
||||
else if ((type & HitObjectType.Slider) > 0)
|
||||
else if ((type & ConvertHitObjectType.Slider) > 0)
|
||||
{
|
||||
CurveType curveType = CurveType.Catmull;
|
||||
double length = 0;
|
||||
@ -77,26 +76,74 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
if (split.Length > 7)
|
||||
length = Convert.ToDouble(split[7], CultureInfo.InvariantCulture);
|
||||
|
||||
result = CreateSlider(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo, points, length, curveType, repeatCount);
|
||||
|
||||
if (split.Length > 10)
|
||||
readCustomSampleBanks(split[10], ref normalSampleBank, ref addSampleBank, ref sampleVolume);
|
||||
readCustomSampleBanks(split[10], bankInfo);
|
||||
|
||||
// One node for each repeat + the start and end nodes
|
||||
// Note that the first length of the slider is considered a repeat, but there are no actual repeats happening
|
||||
int nodes = Math.Max(0, repeatCount - 1) + 2;
|
||||
|
||||
// Populate node sample bank infos with the default hit object sample bank
|
||||
var nodeBankInfos = new List<SampleBankInfo>();
|
||||
for (int i = 0; i < nodes; i++)
|
||||
nodeBankInfos.Add(bankInfo.Clone());
|
||||
|
||||
// Read any per-node sample banks
|
||||
if (split.Length > 9 && split[9].Length > 0)
|
||||
{
|
||||
string[] sets = split[9].Split('|');
|
||||
for (int i = 0; i < nodes; i++)
|
||||
{
|
||||
if (i >= sets.Length)
|
||||
break;
|
||||
|
||||
SampleBankInfo info = nodeBankInfos[i];
|
||||
readCustomSampleBanks(sets[i], info);
|
||||
}
|
||||
}
|
||||
|
||||
// Populate node sound types with the default hit object sound type
|
||||
var nodeSoundTypes = new List<LegacySoundType>();
|
||||
for (int i = 0; i < nodes; i++)
|
||||
nodeSoundTypes.Add(soundType);
|
||||
|
||||
// Read any per-node sound types
|
||||
if (split.Length > 8 && split[8].Length > 0)
|
||||
{
|
||||
string[] adds = split[8].Split('|');
|
||||
for (int i = 0; i < nodes; i++)
|
||||
{
|
||||
if (i >= adds.Length)
|
||||
break;
|
||||
|
||||
int sound;
|
||||
int.TryParse(adds[i], out sound);
|
||||
nodeSoundTypes[i] = (LegacySoundType)sound;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the final per-node samples
|
||||
var nodeSamples = new List<List<SampleInfo>>(nodes);
|
||||
for (int i = 0; i <= repeatCount; i++)
|
||||
nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i]));
|
||||
|
||||
result = CreateSlider(new Vector2(int.Parse(split[0]), int.Parse(split[1])), combo, points, length, curveType, repeatCount, nodeSamples);
|
||||
}
|
||||
else if ((type & HitObjectType.Spinner) > 0)
|
||||
else if ((type & ConvertHitObjectType.Spinner) > 0)
|
||||
{
|
||||
result = CreateSpinner(new Vector2(512, 384) / 2, Convert.ToDouble(split[5], CultureInfo.InvariantCulture));
|
||||
|
||||
if (split.Length > 6)
|
||||
readCustomSampleBanks(split[6], ref normalSampleBank, ref addSampleBank, ref sampleVolume);
|
||||
readCustomSampleBanks(split[6], bankInfo);
|
||||
}
|
||||
else if ((type & HitObjectType.Hold) > 0)
|
||||
else if ((type & ConvertHitObjectType.Hold) > 0)
|
||||
{
|
||||
// Note: Hold is generated by BMS converts
|
||||
|
||||
// Todo: Apparently end time is determined by samples??
|
||||
// Shouldn't need implementation until mania
|
||||
|
||||
result = new Hold
|
||||
result = new ConvertHold
|
||||
{
|
||||
Position = new Vector2(int.Parse(split[0]), int.Parse(split[1])),
|
||||
NewCombo = combo
|
||||
@ -106,50 +153,12 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
throw new InvalidOperationException($@"Unknown hit object type {type}");
|
||||
|
||||
result.StartTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture);
|
||||
|
||||
var soundType = (LegacySoundType)int.Parse(split[4]);
|
||||
|
||||
result.Samples.Add(new SampleInfo
|
||||
{
|
||||
Bank = normalSampleBank,
|
||||
Name = SampleInfo.HIT_NORMAL,
|
||||
Volume = sampleVolume
|
||||
});
|
||||
|
||||
if ((soundType & LegacySoundType.Finish) > 0)
|
||||
{
|
||||
result.Samples.Add(new SampleInfo
|
||||
{
|
||||
Bank = addSampleBank,
|
||||
Name = SampleInfo.HIT_FINISH,
|
||||
Volume = sampleVolume
|
||||
});
|
||||
}
|
||||
|
||||
if ((soundType & LegacySoundType.Whistle) > 0)
|
||||
{
|
||||
result.Samples.Add(new SampleInfo
|
||||
{
|
||||
Bank = addSampleBank,
|
||||
Name = SampleInfo.HIT_WHISTLE,
|
||||
Volume = sampleVolume
|
||||
});
|
||||
}
|
||||
|
||||
if ((soundType & LegacySoundType.Clap) > 0)
|
||||
{
|
||||
result.Samples.Add(new SampleInfo
|
||||
{
|
||||
Bank = addSampleBank,
|
||||
Name = SampleInfo.HIT_CLAP,
|
||||
Volume = sampleVolume
|
||||
});
|
||||
}
|
||||
result.Samples = convertSoundType(soundType, bankInfo);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void readCustomSampleBanks(string str, ref string normalSampleBank, ref string addSampleBank, ref int sampleVolume)
|
||||
private void readCustomSampleBanks(string str, SampleBankInfo bankInfo)
|
||||
{
|
||||
if (string.IsNullOrEmpty(str))
|
||||
return;
|
||||
@ -169,9 +178,11 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
if (stringAddBank == @"none")
|
||||
stringAddBank = null;
|
||||
|
||||
normalSampleBank = stringBank;
|
||||
addSampleBank = stringAddBank;
|
||||
sampleVolume = split.Length > 3 ? int.Parse(split[3]) : 0;
|
||||
bankInfo.Normal = stringBank;
|
||||
bankInfo.Add = stringAddBank;
|
||||
|
||||
if (split.Length > 3)
|
||||
bankInfo.Volume = int.Parse(split[3]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -191,8 +202,9 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
/// <param name="length">The slider length.</param>
|
||||
/// <param name="curveType">The slider curve type.</param>
|
||||
/// <param name="repeatCount">The slider repeat count.</param>
|
||||
/// <param name="repeatSamples">The samples to be played when the repeat nodes are hit. This includes the head and tail of the slider.</param>
|
||||
/// <returns>The hit object.</returns>
|
||||
protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount);
|
||||
protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a legacy Spinner-type hit object.
|
||||
@ -202,6 +214,63 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
/// <returns>The hit object.</returns>
|
||||
protected abstract HitObject CreateSpinner(Vector2 position, double endTime);
|
||||
|
||||
private List<SampleInfo> convertSoundType(LegacySoundType type, SampleBankInfo bankInfo)
|
||||
{
|
||||
var soundTypes = new List<SampleInfo>
|
||||
{
|
||||
new SampleInfo
|
||||
{
|
||||
Bank = bankInfo.Normal,
|
||||
Name = SampleInfo.HIT_NORMAL,
|
||||
Volume = bankInfo.Volume
|
||||
}
|
||||
};
|
||||
|
||||
if ((type & LegacySoundType.Finish) > 0)
|
||||
{
|
||||
soundTypes.Add(new SampleInfo
|
||||
{
|
||||
Bank = bankInfo.Add,
|
||||
Name = SampleInfo.HIT_FINISH,
|
||||
Volume = bankInfo.Volume
|
||||
});
|
||||
}
|
||||
|
||||
if ((type & LegacySoundType.Whistle) > 0)
|
||||
{
|
||||
soundTypes.Add(new SampleInfo
|
||||
{
|
||||
Bank = bankInfo.Add,
|
||||
Name = SampleInfo.HIT_WHISTLE,
|
||||
Volume = bankInfo.Volume
|
||||
});
|
||||
}
|
||||
|
||||
if ((type & LegacySoundType.Clap) > 0)
|
||||
{
|
||||
soundTypes.Add(new SampleInfo
|
||||
{
|
||||
Bank = bankInfo.Add,
|
||||
Name = SampleInfo.HIT_CLAP,
|
||||
Volume = bankInfo.Volume
|
||||
});
|
||||
}
|
||||
|
||||
return soundTypes;
|
||||
}
|
||||
|
||||
private class SampleBankInfo
|
||||
{
|
||||
public string Normal;
|
||||
public string Add;
|
||||
public int Volume;
|
||||
|
||||
public SampleBankInfo Clone()
|
||||
{
|
||||
return (SampleBankInfo)MemberwiseClone();
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum LegacySoundType
|
||||
{
|
@ -6,7 +6,7 @@ using System;
|
||||
namespace osu.Game.Rulesets.Objects.Legacy
|
||||
{
|
||||
[Flags]
|
||||
public enum HitObjectType
|
||||
internal enum ConvertHitObjectType
|
||||
{
|
||||
Circle = 1 << 0,
|
||||
Slider = 1 << 1,
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
/// <summary>
|
||||
/// Legacy Hold-type, used for parsing "specials" in beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Hold : HitObject, IHasPosition, IHasCombo, IHasHold
|
||||
internal sealed class ConvertHold : HitObject, IHasPosition, IHasCombo, IHasHold
|
||||
{
|
||||
public Vector2 Position { get; set; }
|
||||
|
39
osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs
Normal file
39
osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenTK;
|
||||
using osu.Game.Audio;
|
||||
|
||||
namespace osu.Game.Rulesets.Objects.Legacy
|
||||
{
|
||||
internal abstract class ConvertSlider : HitObject, IHasCurve
|
||||
{
|
||||
public List<Vector2> ControlPoints { get; set; }
|
||||
public CurveType CurveType { get; set; }
|
||||
public double Distance { get; set; }
|
||||
|
||||
public List<List<SampleInfo>> RepeatSamples { get; set; }
|
||||
public int RepeatCount { get; set; } = 1;
|
||||
|
||||
public double EndTime { get; set; }
|
||||
public double Duration { get; set; }
|
||||
|
||||
public Vector2 PositionAt(double progress)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public double ProgressAt(double progress)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int RepeatAt(double progress)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania
|
||||
/// <summary>
|
||||
/// Legacy osu!mania Hit-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Hit : HitObject, IHasXPosition, IHasCombo
|
||||
internal sealed class ConvertHit : HitObject, IHasXPosition, IHasCombo
|
||||
{
|
||||
public float X { get; set; }
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -10,33 +11,34 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania
|
||||
/// <summary>
|
||||
/// A HitObjectParser to parse legacy osu!mania Beatmaps.
|
||||
/// </summary>
|
||||
internal class HitObjectParser : Legacy.HitObjectParser
|
||||
internal class ConvertHitObjectParser : Legacy.ConvertHitObjectParser
|
||||
{
|
||||
protected override HitObject CreateHit(Vector2 position, bool newCombo)
|
||||
{
|
||||
return new Hit
|
||||
return new ConvertHit
|
||||
{
|
||||
X = position.X,
|
||||
NewCombo = newCombo,
|
||||
};
|
||||
}
|
||||
|
||||
protected override HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount)
|
||||
protected override HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples)
|
||||
{
|
||||
return new Slider
|
||||
return new ConvertSlider
|
||||
{
|
||||
X = position.X,
|
||||
NewCombo = newCombo,
|
||||
ControlPoints = controlPoints,
|
||||
Distance = length,
|
||||
CurveType = curveType,
|
||||
RepeatSamples = repeatSamples,
|
||||
RepeatCount = repeatCount
|
||||
};
|
||||
}
|
||||
|
||||
protected override HitObject CreateSpinner(Vector2 position, double endTime)
|
||||
{
|
||||
return new Spinner
|
||||
return new ConvertSpinner
|
||||
{
|
||||
X = position.X,
|
||||
EndTime = endTime
|
@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania
|
||||
/// <summary>
|
||||
/// Legacy osu!mania Slider-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Slider : CurvedHitObject, IHasXPosition, IHasCombo
|
||||
internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasXPosition, IHasCombo
|
||||
{
|
||||
public float X { get; set; }
|
||||
|
@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania
|
||||
/// <summary>
|
||||
/// Legacy osu!mania Spinner-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Spinner : HitObject, IHasEndTime, IHasXPosition
|
||||
internal sealed class ConvertSpinner : HitObject, IHasEndTime, IHasXPosition
|
||||
{
|
||||
public double EndTime { get; set; }
|
||||
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
|
||||
/// <summary>
|
||||
/// Legacy osu! Hit-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Hit : HitObject, IHasPosition, IHasCombo
|
||||
internal sealed class ConvertHit : HitObject, IHasPosition, IHasCombo
|
||||
{
|
||||
public Vector2 Position { get; set; }
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -10,33 +11,34 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
|
||||
/// <summary>
|
||||
/// A HitObjectParser to parse legacy osu! Beatmaps.
|
||||
/// </summary>
|
||||
internal class HitObjectParser : Legacy.HitObjectParser
|
||||
internal class ConvertHitObjectParser : Legacy.ConvertHitObjectParser
|
||||
{
|
||||
protected override HitObject CreateHit(Vector2 position, bool newCombo)
|
||||
{
|
||||
return new Hit
|
||||
return new ConvertHit
|
||||
{
|
||||
Position = position,
|
||||
NewCombo = newCombo,
|
||||
};
|
||||
}
|
||||
|
||||
protected override HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount)
|
||||
protected override HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples)
|
||||
{
|
||||
return new Slider
|
||||
return new ConvertSlider
|
||||
{
|
||||
Position = position,
|
||||
NewCombo = newCombo,
|
||||
ControlPoints = controlPoints,
|
||||
Distance = length,
|
||||
CurveType = curveType,
|
||||
RepeatSamples = repeatSamples,
|
||||
RepeatCount = repeatCount
|
||||
};
|
||||
}
|
||||
|
||||
protected override HitObject CreateSpinner(Vector2 position, double endTime)
|
||||
{
|
||||
return new Spinner
|
||||
return new ConvertSpinner
|
||||
{
|
||||
Position = position,
|
||||
EndTime = endTime
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
|
||||
/// <summary>
|
||||
/// Legacy osu! Slider-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Slider : CurvedHitObject, IHasPosition, IHasCombo
|
||||
internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasPosition, IHasCombo
|
||||
{
|
||||
public Vector2 Position { get; set; }
|
||||
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
|
||||
/// <summary>
|
||||
/// Legacy osu! Spinner-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Spinner : HitObject, IHasEndTime, IHasPosition
|
||||
internal sealed class ConvertSpinner : HitObject, IHasEndTime, IHasPosition
|
||||
{
|
||||
public double EndTime { get; set; }
|
||||
|
@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko
|
||||
/// <summary>
|
||||
/// Legacy osu!taiko Hit-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Hit : HitObject, IHasCombo
|
||||
internal sealed class ConvertHit : HitObject, IHasCombo
|
||||
{
|
||||
public bool NewCombo { get; set; }
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using OpenTK;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -10,31 +11,32 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko
|
||||
/// <summary>
|
||||
/// A HitObjectParser to parse legacy osu!taiko Beatmaps.
|
||||
/// </summary>
|
||||
internal class HitObjectParser : Legacy.HitObjectParser
|
||||
internal class ConvertHitObjectParser : Legacy.ConvertHitObjectParser
|
||||
{
|
||||
protected override HitObject CreateHit(Vector2 position, bool newCombo)
|
||||
{
|
||||
return new Hit
|
||||
return new ConvertHit
|
||||
{
|
||||
NewCombo = newCombo,
|
||||
};
|
||||
}
|
||||
|
||||
protected override HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount)
|
||||
protected override HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount, List<List<SampleInfo>> repeatSamples)
|
||||
{
|
||||
return new Slider
|
||||
return new ConvertSlider
|
||||
{
|
||||
NewCombo = newCombo,
|
||||
ControlPoints = controlPoints,
|
||||
Distance = length,
|
||||
CurveType = curveType,
|
||||
RepeatSamples = repeatSamples,
|
||||
RepeatCount = repeatCount
|
||||
};
|
||||
}
|
||||
|
||||
protected override HitObject CreateSpinner(Vector2 position, double endTime)
|
||||
{
|
||||
return new Spinner
|
||||
return new ConvertSpinner
|
||||
{
|
||||
EndTime = endTime
|
||||
};
|
@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko
|
||||
/// <summary>
|
||||
/// Legacy osu!taiko Slider-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Slider : CurvedHitObject, IHasCombo
|
||||
internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasCombo
|
||||
{
|
||||
public bool NewCombo { get; set; }
|
||||
}
|
@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko
|
||||
/// <summary>
|
||||
/// Legacy osu!taiko Spinner-type, used for parsing Beatmaps.
|
||||
/// </summary>
|
||||
internal sealed class Spinner : HitObject, IHasEndTime
|
||||
internal sealed class ConvertSpinner : HitObject, IHasEndTime
|
||||
{
|
||||
public double EndTime { get; set; }
|
||||
|
@ -11,11 +11,6 @@ namespace osu.Game.Rulesets.Objects.Types
|
||||
/// </summary>
|
||||
public interface IHasCurve : IHasDistance, IHasRepeats
|
||||
{
|
||||
/// <summary>
|
||||
/// The curve.
|
||||
/// </summary>
|
||||
SliderCurve Curve { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The control points that shape the curve.
|
||||
/// </summary>
|
||||
|
@ -1,6 +1,9 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Rulesets.Objects.Types
|
||||
{
|
||||
/// <summary>
|
||||
@ -12,5 +15,10 @@ namespace osu.Game.Rulesets.Objects.Types
|
||||
/// The amount of times the HitObject repeats.
|
||||
/// </summary>
|
||||
int RepeatCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The samples to be played when each repeat node is hit (0 -> first repeat node, 1 -> second repeat node, etc).
|
||||
/// </summary>
|
||||
List<List<SampleInfo>> RepeatSamples { get; }
|
||||
}
|
||||
}
|
||||
|
@ -38,8 +38,6 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (parentClock == null) return;
|
||||
|
||||
clock.Rate = parentClock.Rate;
|
||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
beatmap = value;
|
||||
Leaderboard.Beatmap = beatmap?.BeatmapInfo;
|
||||
Details.Beatmap = beatmap?.Beatmap.BeatmapInfo;
|
||||
Details.Beatmap = beatmap?.BeatmapInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,16 +66,16 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
Details = new BeatmapDetails
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding(5),
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Masking = true,
|
||||
Height = 352,
|
||||
Alpha = 0,
|
||||
},
|
||||
Leaderboard = new Leaderboard
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,12 @@
|
||||
using System;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
|
||||
@ -21,15 +23,22 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
public Action<BeatmapDetailTab, bool> OnFilter; //passed the selected tab and if mods is checked
|
||||
|
||||
private Bindable<BeatmapDetailTab> selectedTab;
|
||||
|
||||
private void invokeOnFilter()
|
||||
{
|
||||
OnFilter?.Invoke(tabs.Current, modsCheckbox.Current);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colour)
|
||||
private void load(OsuColour colour, OsuConfigManager config)
|
||||
{
|
||||
modsCheckbox.AccentColour = tabs.AccentColour = colour.YellowLight;
|
||||
|
||||
selectedTab = config.GetBindable<BeatmapDetailTab>(OsuConfig.BeatmapDetailTab);
|
||||
|
||||
tabs.Current.BindTo(selectedTab);
|
||||
tabs.Current.TriggerChange();
|
||||
}
|
||||
|
||||
public BeatmapDetailAreaTabControl()
|
||||
@ -62,8 +71,6 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
tabs.Current.ValueChanged += item => invokeOnFilter();
|
||||
modsCheckbox.Current.ValueChanged += item => invokeOnFilter();
|
||||
|
||||
tabs.Current.Value = BeatmapDetailTab.Global;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,9 @@ using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Framework.Threading;
|
||||
|
||||
namespace osu.Game.Screens.Select
|
||||
{
|
||||
@ -39,60 +42,108 @@ namespace osu.Game.Screens.Select
|
||||
private readonly BarGraph retryGraph;
|
||||
private readonly BarGraph failGraph;
|
||||
|
||||
private ScheduledDelegate pendingBeatmapSwitch;
|
||||
private BeatmapInfo beatmap;
|
||||
|
||||
public BeatmapInfo Beatmap
|
||||
{
|
||||
get
|
||||
{
|
||||
return beatmap;
|
||||
}
|
||||
get { return beatmap; }
|
||||
set
|
||||
{
|
||||
beatmap = value;
|
||||
if (beatmap == null) return;
|
||||
|
||||
description.Text = beatmap.Version;
|
||||
source.Text = beatmap.Metadata.Source;
|
||||
tags.Text = beatmap.Metadata.Tags;
|
||||
|
||||
circleSize.Value = beatmap.Difficulty.CircleSize;
|
||||
drainRate.Value = beatmap.Difficulty.DrainRate;
|
||||
overallDifficulty.Value = beatmap.Difficulty.OverallDifficulty;
|
||||
approachRate.Value = beatmap.Difficulty.ApproachRate;
|
||||
stars.Value = (float)beatmap.StarDifficulty;
|
||||
|
||||
if (beatmap.Metrics?.Ratings.Any() ?? false)
|
||||
{
|
||||
var ratings = beatmap.Metrics.Ratings.ToList();
|
||||
ratingsContainer.Show();
|
||||
|
||||
negativeRatings.Text = ratings.GetRange(0, ratings.Count / 2).Sum().ToString();
|
||||
positiveRatings.Text = ratings.GetRange(ratings.Count / 2, ratings.Count / 2).Sum().ToString();
|
||||
ratingsBar.Length = (float)ratings.GetRange(0, ratings.Count / 2).Sum() / ratings.Sum();
|
||||
|
||||
ratingsGraph.Values = ratings.Select(rating => (float)rating);
|
||||
}
|
||||
else
|
||||
ratingsContainer.Hide();
|
||||
|
||||
if ((beatmap.Metrics?.Retries.Any() ?? false) && beatmap.Metrics.Fails.Any())
|
||||
{
|
||||
var retries = beatmap.Metrics.Retries;
|
||||
var fails = beatmap.Metrics.Fails;
|
||||
retryFailContainer.Show();
|
||||
|
||||
float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max();
|
||||
failGraph.MaxValue = maxValue;
|
||||
retryGraph.MaxValue = maxValue;
|
||||
|
||||
failGraph.Values = fails.Select(fail => (float)fail);
|
||||
retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + MathHelper.Clamp(fail, 0, maxValue));
|
||||
}
|
||||
else
|
||||
retryFailContainer.Hide();
|
||||
pendingBeatmapSwitch?.Cancel();
|
||||
pendingBeatmapSwitch = Schedule(updateStats);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStats()
|
||||
{
|
||||
if (beatmap == null) return;
|
||||
|
||||
description.Text = beatmap.Version;
|
||||
source.Text = beatmap.Metadata.Source;
|
||||
tags.Text = beatmap.Metadata.Tags;
|
||||
|
||||
circleSize.Value = beatmap.Difficulty.CircleSize;
|
||||
drainRate.Value = beatmap.Difficulty.DrainRate;
|
||||
overallDifficulty.Value = beatmap.Difficulty.OverallDifficulty;
|
||||
approachRate.Value = beatmap.Difficulty.ApproachRate;
|
||||
stars.Value = (float)beatmap.StarDifficulty;
|
||||
|
||||
var requestedBeatmap = beatmap;
|
||||
if (requestedBeatmap.Metrics == null)
|
||||
{
|
||||
var lookup = new GetBeatmapDetailsRequest(requestedBeatmap);
|
||||
lookup.Success += res =>
|
||||
{
|
||||
if (beatmap != requestedBeatmap)
|
||||
//the beatmap has been changed since we started the lookup.
|
||||
return;
|
||||
|
||||
requestedBeatmap.Metrics = res;
|
||||
Schedule(() => updateMetrics(res));
|
||||
};
|
||||
lookup.Failure += e => updateMetrics(null);
|
||||
|
||||
api.Queue(lookup);
|
||||
}
|
||||
|
||||
updateMetrics(requestedBeatmap.Metrics, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update displayed metrics.
|
||||
/// </summary>
|
||||
/// <param name="metrics">New metrics to overwrite the existing display. Can be null.</param>
|
||||
/// <param name="failOnMissing">Whether to hide the display on null or empty metrics. If false, we will dim as if waiting for further updates.</param>
|
||||
private void updateMetrics(BeatmapMetrics metrics, bool failOnMissing = true)
|
||||
{
|
||||
var hasRatings = metrics?.Ratings.Any() ?? false;
|
||||
var hasRetriesFails = (metrics?.Retries.Any() ?? false) && metrics.Fails.Any();
|
||||
|
||||
if (hasRatings)
|
||||
{
|
||||
var ratings = metrics.Ratings.ToList();
|
||||
ratingsContainer.Show();
|
||||
|
||||
negativeRatings.Text = ratings.GetRange(0, ratings.Count / 2).Sum().ToString();
|
||||
positiveRatings.Text = ratings.GetRange(ratings.Count / 2, ratings.Count / 2).Sum().ToString();
|
||||
ratingsBar.Length = (float)ratings.GetRange(0, ratings.Count / 2).Sum() / ratings.Sum();
|
||||
|
||||
ratingsGraph.Values = ratings.Select(rating => (float)rating);
|
||||
|
||||
ratingsContainer.FadeColour(Color4.White, 500, EasingTypes.Out);
|
||||
}
|
||||
else if (failOnMissing)
|
||||
ratingsGraph.Values = new float[10];
|
||||
else
|
||||
ratingsContainer.FadeColour(Color4.Gray, 500, EasingTypes.Out);
|
||||
|
||||
if (hasRetriesFails)
|
||||
{
|
||||
var retries = metrics.Retries;
|
||||
var fails = metrics.Fails;
|
||||
retryFailContainer.Show();
|
||||
|
||||
float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max();
|
||||
failGraph.MaxValue = maxValue;
|
||||
retryGraph.MaxValue = maxValue;
|
||||
|
||||
failGraph.Values = fails.Select(fail => (float)fail);
|
||||
retryGraph.Values = retries.Zip(fails, (retry, fail) => retry + MathHelper.Clamp(fail, 0, maxValue));
|
||||
|
||||
retryFailContainer.FadeColour(Color4.White, 500, EasingTypes.Out);
|
||||
}
|
||||
else if (failOnMissing)
|
||||
{
|
||||
failGraph.Values = new float[100];
|
||||
retryGraph.Values = new float[100];
|
||||
}
|
||||
else
|
||||
retryFailContainer.FadeColour(Color4.Gray, 500, EasingTypes.Out);
|
||||
}
|
||||
|
||||
public BeatmapDetails()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
@ -113,7 +164,6 @@ namespace osu.Game.Screens.Select
|
||||
Direction = FillDirection.Vertical,
|
||||
LayoutDuration = 200,
|
||||
LayoutEasing = EasingTypes.OutQuint,
|
||||
Padding = new MarginPadding(10) { Top = 25 },
|
||||
Children = new []
|
||||
{
|
||||
description = new MetadataSegment("Description"),
|
||||
@ -148,8 +198,8 @@ namespace osu.Game.Screens.Select
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0,10),
|
||||
Padding = new MarginPadding(15) { Top = 25 },
|
||||
Spacing = new Vector2(0,5),
|
||||
Padding = new MarginPadding(10),
|
||||
Children = new []
|
||||
{
|
||||
circleSize = new DifficultyRow("Circle Size", 7),
|
||||
@ -252,7 +302,7 @@ namespace osu.Game.Screens.Select
|
||||
new Container<BarGraph>
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Size = new Vector2(1/0.6f, 50),
|
||||
Size = new Vector2(1 / 0.6f, 50),
|
||||
Children = new[]
|
||||
{
|
||||
retryGraph = new BarGraph
|
||||
@ -272,9 +322,13 @@ namespace osu.Game.Screens.Select
|
||||
};
|
||||
}
|
||||
|
||||
private APIAccess api;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colour)
|
||||
private void load(OsuColour colour, APIAccess api)
|
||||
{
|
||||
this.api = api;
|
||||
|
||||
description.AccentColour = colour.GrayB;
|
||||
source.AccentColour = colour.GrayB;
|
||||
tags.AccentColour = colour.YellowLight;
|
||||
@ -308,7 +362,7 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
difficultyValue = value;
|
||||
bar.Length = value / maxValue;
|
||||
valueText.Text = value.ToString(CultureInfo.InvariantCulture);
|
||||
valueText.Text = value.ToString("N1", CultureInfo.CurrentCulture);
|
||||
}
|
||||
}
|
||||
|
||||
@ -431,4 +485,4 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
@ -148,11 +149,16 @@ namespace osu.Game.Screens.Select
|
||||
},
|
||||
},
|
||||
},
|
||||
// Text for beatmap info
|
||||
new DifficultyColourBar(beatmap.BeatmapInfo)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = 20,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Name = "Top-aligned metadata",
|
||||
Anchor = Anchor.TopLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
Direction = FillDirection.Vertical,
|
||||
Margin = new MarginPadding { Top = 10, Left = 25, Right = 10, Bottom = 20 },
|
||||
AutoSizeAxes = Axes.Both,
|
||||
@ -161,16 +167,32 @@ namespace osu.Game.Screens.Select
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
Text = metadata.Artist + " -- " + metadata.Title,
|
||||
Text = beatmapInfo.Version,
|
||||
TextSize = 24,
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Name = "Bottom-aligned metadata",
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Direction = FillDirection.Vertical,
|
||||
Margin = new MarginPadding { Top = 15, Left = 25, Right = 10, Bottom = 20 },
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
Text = !string.IsNullOrEmpty(metadata.Source) ? metadata.Source + " — " + metadata.Title : metadata.Title,
|
||||
TextSize = 28,
|
||||
Shadow = true,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-MediumItalic",
|
||||
Text = beatmapInfo.Version,
|
||||
Text = metadata.Artist,
|
||||
TextSize = 17,
|
||||
Shadow = true,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
@ -184,20 +206,18 @@ namespace osu.Game.Screens.Select
|
||||
Font = @"Exo2.0-Medium",
|
||||
Text = "mapped by ",
|
||||
TextSize = 15,
|
||||
Shadow = true,
|
||||
},
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Font = @"Exo2.0-Bold",
|
||||
Text = metadata.Author,
|
||||
TextSize = 15,
|
||||
Shadow = true,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Margin = new MarginPadding { Top = 20 },
|
||||
Margin = new MarginPadding { Top = 20, Left = 10 },
|
||||
Spacing = new Vector2(40, 0),
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = labels
|
||||
@ -256,5 +276,37 @@ namespace osu.Game.Screens.Select
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class DifficultyColourBar : DifficultyColouredContainer
|
||||
{
|
||||
public DifficultyColourBar(BeatmapInfo beatmap) : base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
const float full_opacity_ratio = 0.7f;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = AccentColour,
|
||||
Width = full_opacity_ratio,
|
||||
},
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Colour = AccentColour,
|
||||
Alpha = 0.5f,
|
||||
X = full_opacity_ratio,
|
||||
Width = 1 - full_opacity_ratio,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Online.API;
|
||||
@ -93,13 +94,18 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
|
||||
private BeatmapInfo beatmap;
|
||||
|
||||
private ScheduledDelegate pendingBeatmapSwitch;
|
||||
|
||||
public BeatmapInfo Beatmap
|
||||
{
|
||||
get { return beatmap; }
|
||||
set
|
||||
{
|
||||
beatmap = value;
|
||||
Schedule(updateScores);
|
||||
Scores = null;
|
||||
|
||||
pendingBeatmapSwitch?.Cancel();
|
||||
pendingBeatmapSwitch = Schedule(updateScores);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,20 @@
|
||||
<Compile Include="IO\Serialization\IJsonSerializable.cs" />
|
||||
<Compile Include="IPC\ScoreIPCChannel.cs" />
|
||||
<Compile Include="Rulesets\BeatmapStatistic.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Catch\ConvertHit.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Catch\ConvertHitObjectParser.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Catch\ConvertSlider.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Catch\ConvertSpinner.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\ConvertSlider.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\ConvertHit.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\ConvertHitObjectParser.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\ConvertSlider.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\ConvertSpinner.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Osu\ConvertHitObjectParser.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Taiko\ConvertHit.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Taiko\ConvertHitObjectParser.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Taiko\ConvertSlider.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Taiko\ConvertSpinner.cs" />
|
||||
<Compile Include="Rulesets\Mods\IApplicableToClock.cs" />
|
||||
<Compile Include="Rulesets\Mods\ModAutoplay.cs" />
|
||||
<Compile Include="Rulesets\Mods\ModCinema.cs" />
|
||||
@ -124,19 +138,6 @@
|
||||
<Compile Include="Rulesets\Mods\ModRelax.cs" />
|
||||
<Compile Include="Rulesets\Mods\ModSuddenDeath.cs" />
|
||||
<Compile Include="Rulesets\Mods\MultiMod.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Catch\Hit.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Catch\HitObjectParser.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Catch\Slider.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Catch\Spinner.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\Hit.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\HitObjectParser.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\Slider.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Mania\Spinner.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Osu\HitObjectParser.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Taiko\Hit.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Taiko\HitObjectParser.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Taiko\Slider.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Taiko\Spinner.cs" />
|
||||
<Compile Include="Rulesets\Objects\Types\IHasXPosition.cs" />
|
||||
<Compile Include="Rulesets\Objects\Types\IHasYPosition.cs" />
|
||||
<Compile Include="Rulesets\Replays\Replay.cs" />
|
||||
@ -149,12 +150,11 @@
|
||||
<Compile Include="Rulesets\Objects\Drawables\HitResult.cs" />
|
||||
<Compile Include="Rulesets\Objects\BezierApproximator.cs" />
|
||||
<Compile Include="Rulesets\Objects\CircularArcApproximator.cs" />
|
||||
<Compile Include="Rulesets\Objects\CurvedHitObject.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Osu\Hit.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\HitObjectParser.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Hold.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Osu\Slider.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Osu\Spinner.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Osu\ConvertHit.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\ConvertHitObjectParser.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\ConvertHold.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Osu\ConvertSlider.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\Osu\ConvertSpinner.cs" />
|
||||
<Compile Include="Rulesets\Objects\SliderCurve.cs" />
|
||||
<Compile Include="Rulesets\Objects\Types\CurveType.cs" />
|
||||
<Compile Include="Rulesets\Objects\Drawables\IDrawableHitObjectWithProxiedApproach.cs" />
|
||||
@ -167,7 +167,7 @@
|
||||
<Compile Include="Rulesets\Objects\Types\IHasRepeats.cs" />
|
||||
<Compile Include="Rulesets\Objects\Types\IHasPosition.cs" />
|
||||
<Compile Include="Rulesets\Objects\Types\IHasHold.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\HitObjectType.cs" />
|
||||
<Compile Include="Rulesets\Objects\Legacy\ConvertHitObjectType.cs" />
|
||||
<Compile Include="Rulesets\Replays\ReplayButtonState.cs" />
|
||||
<Compile Include="Rulesets\Replays\ReplayFrame.cs" />
|
||||
<Compile Include="Database\RulesetDatabase.cs" />
|
||||
@ -179,6 +179,7 @@
|
||||
<Compile Include="Rulesets\UI\StandardHudOverlay.cs" />
|
||||
<Compile Include="Online\API\IOnlineComponent.cs" />
|
||||
<Compile Include="Online\API\Requests\GetScoresRequest.cs" />
|
||||
<Compile Include="Online\API\Requests\GetBeatmapDetailsRequest.cs" />
|
||||
<Compile Include="Online\API\Requests\GetUserRequest.cs" />
|
||||
<Compile Include="Overlays\DragBar.cs" />
|
||||
<Compile Include="Overlays\LoginOverlay.cs" />
|
||||
@ -187,6 +188,7 @@
|
||||
<Compile Include="Beatmaps\WorkingBeatmap.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\BeatmapSetHeader.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\DifficultyIcon.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\DifficultyColouredContainer.cs" />
|
||||
<Compile Include="Beatmaps\Drawables\Panel.cs" />
|
||||
<Compile Include="Rulesets\Objects\Drawables\DrawableHitObject.cs" />
|
||||
<Compile Include="Rulesets\Objects\HitObject.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user