Merge branch 'master' into general-fixes

This commit is contained in:
Dean Herbert
2017-04-18 16:19:52 +09:00
committed by GitHub
244 changed files with 1387 additions and 913 deletions

View File

@ -4,7 +4,7 @@
using OpenTK.Graphics;
using osu.Game.Beatmaps.Timing;
using osu.Game.Database;
using osu.Game.Modes.Objects;
using osu.Game.Rulesets.Objects;
using System.Collections.Generic;
namespace osu.Game.Beatmaps
@ -56,6 +56,7 @@ namespace osu.Game.Beatmaps
public Beatmap(Beatmap original = null)
: base(original)
{
HitObjects = original?.HitObjects;
}
}
}

View File

@ -1,7 +1,8 @@
// 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.Modes.Objects;
using osu.Game.Rulesets.Beatmaps;
using osu.Game.Rulesets.Objects;
using System.Collections.Generic;
namespace osu.Game.Beatmaps
@ -41,6 +42,6 @@ namespace osu.Game.Beatmaps
{
}
protected abstract IBeatmapConverter<T> CreateBeatmapConverter();
protected abstract BeatmapConverter<T> CreateBeatmapConverter();
}
}

View File

@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using osu.Game.Modes.Objects;
using osu.Game.Rulesets.Objects;
using osu.Game.Database;
namespace osu.Game.Beatmaps.Formats

View File

@ -7,8 +7,8 @@ using System.IO;
using OpenTK.Graphics;
using osu.Game.Beatmaps.Events;
using osu.Game.Beatmaps.Timing;
using osu.Game.Modes.Objects;
using osu.Game.Beatmaps.Legacy;
using osu.Game.Rulesets.Objects.Legacy;
namespace osu.Game.Beatmaps.Formats
{
@ -29,6 +29,8 @@ namespace osu.Game.Beatmaps.Formats
// TODO: Not sure how far back to go, or differences between versions
}
private HitObjectParser parser;
private LegacySampleBank defaultSampleBank;
private int defaultSampleVolume = 100;
@ -84,6 +86,22 @@ namespace osu.Game.Beatmaps.Formats
break;
case @"Mode":
beatmap.BeatmapInfo.RulesetID = int.Parse(val);
switch (beatmap.BeatmapInfo.RulesetID)
{
case 0:
parser = new Rulesets.Objects.Legacy.Osu.HitObjectParser();
break;
case 1:
parser = new Rulesets.Objects.Legacy.Taiko.HitObjectParser();
break;
case 2:
parser = new Rulesets.Objects.Legacy.Catch.HitObjectParser();
break;
case 3:
parser = new Rulesets.Objects.Legacy.Mania.HitObjectParser();
break;
}
break;
case @"LetterboxInBreaks":
beatmap.BeatmapInfo.LetterboxInBreaks = int.Parse(val) == 1;
@ -303,8 +321,6 @@ namespace osu.Game.Beatmaps.Formats
{
beatmap.BeatmapInfo.BeatmapVersion = beatmapVersion;
HitObjectParser parser = new LegacyHitObjectParser();
Section section = Section.None;
bool hasCustomColours = false;

View File

@ -1,21 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Objects;
namespace osu.Game.Beatmaps
{
/// <summary>
/// Converts a Beatmap for another mode.
/// </summary>
/// <typeparam name="T">The type of HitObject stored in the Beatmap.</typeparam>
public interface IBeatmapConverter<T> where T : HitObject
{
/// <summary>
/// Converts a Beatmap to another mode.
/// </summary>
/// <param name="original">The original Beatmap.</param>
/// <returns>The converted Beatmap.</returns>
Beatmap<T> Convert(Beatmap original);
}
}

View File

@ -5,7 +5,7 @@ using osu.Framework.Audio.Track;
using osu.Framework.Configuration;
using osu.Framework.Graphics.Textures;
using osu.Game.Database;
using osu.Game.Modes.Mods;
using osu.Game.Rulesets.Mods;
using System;
using System.Collections.Generic;

View File

@ -7,7 +7,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using osu.Framework.Platform;
using osu.Game.Modes;
using osu.Game.Rulesets;
using SQLite.Net;
namespace osu.Game.Database
@ -35,7 +35,7 @@ namespace osu.Game.Database
List<Ruleset> instances = new List<Ruleset>();
foreach (string file in Directory.GetFiles(Environment.CurrentDirectory, @"osu.Game.Modes.*.dll"))
foreach (string file in Directory.GetFiles(Environment.CurrentDirectory, @"osu.Game.Rulesets.*.dll"))
{
try
{

View File

@ -2,7 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Game.Modes;
using osu.Game.Rulesets;
using SQLite.Net.Attributes;
namespace osu.Game.Database

View File

@ -7,7 +7,7 @@ using System.Linq;
using osu.Framework.Platform;
using osu.Game.IO.Legacy;
using osu.Game.IPC;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Scoring;
using SharpCompress.Compressors.LZMA;
using SQLite.Net;

View File

@ -817,13 +817,13 @@ namespace osu.Game.Graphics
fa_youtube_play = 0xf16a,
fa_youtube_square = 0xf166,
// gamemode icons in circles
// ruleset icons in circles
fa_osu_osu_o = 0xe000,
fa_osu_mania_o = 0xe001,
fa_osu_fruits_o = 0xe002,
fa_osu_taiko_o = 0xe003,
// gamemode icons without circles
// ruleset icons without circles
fa_osu_filled_circle = 0xe004,
fa_osu_cross_o = 0xe005,
fa_osu_logo = 0xe006,

View File

@ -1,18 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Objects.Types;
using OpenTK;
namespace osu.Game.Modes.Objects.Legacy
{
/// <summary>
/// Legacy Hit-type, used for parsing Beatmaps.
/// </summary>
public sealed class LegacyHit : HitObject, IHasPosition, IHasCombo
{
public Vector2 Position { get; set; }
public bool NewCombo { get; set; }
}
}

View File

@ -5,7 +5,7 @@ using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Framework.IO.Network;
using osu.Game.Database;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Online.API.Requests
{

View File

@ -25,7 +25,7 @@ using System.Threading.Tasks;
using osu.Framework.Threading;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Scoring;
using osu.Game.Overlays.Notifications;
using osu.Game.Screens.Play;
@ -205,7 +205,7 @@ namespace osu.Game
OnRulesetChange = r => Ruleset.Value = r,
}, t =>
{
Ruleset.ValueChanged += delegate { Toolbar.SetGameMode(Ruleset.Value); };
Ruleset.ValueChanged += delegate { Toolbar.SetRuleset(Ruleset.Value); };
Ruleset.TriggerChange();
overlayContent.Add(Toolbar);
});
@ -279,7 +279,7 @@ namespace osu.Game
return;
}
//central game mode change logic.
//central game screen change logic.
if (!currentScreen.ShowOverlays)
{
options.State = Visibility.Hidden;

View File

@ -4,7 +4,7 @@
using OpenTK.Input;
using osu.Framework.Allocation;
using osu.Game.Graphics;
using osu.Game.Modes.Mods;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Overlays.Mods
{

View File

@ -4,7 +4,7 @@
using OpenTK.Input;
using osu.Framework.Allocation;
using osu.Game.Graphics;
using osu.Game.Modes.Mods;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Overlays.Mods
{

View File

@ -4,7 +4,7 @@
using OpenTK.Input;
using osu.Framework.Allocation;
using osu.Game.Graphics;
using osu.Game.Modes.Mods;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Overlays.Mods
{

View File

@ -12,8 +12,8 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input;
using osu.Game.Graphics.Sprites;
using osu.Game.Modes.Mods;
using osu.Game.Modes.UI;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using System;
using System.Linq;

View File

@ -9,7 +9,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Input;
using osu.Game.Graphics.Sprites;
using osu.Game.Modes.Mods;
using osu.Game.Rulesets.Mods;
using System;
namespace osu.Game.Overlays.Mods

View File

@ -13,7 +13,7 @@ using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Sprites;
using osu.Game.Modes.Mods;
using osu.Game.Rulesets.Mods;
using System;
using System.Collections.Generic;
using System.Linq;

View File

@ -129,7 +129,7 @@ namespace osu.Game.Overlays.Toolbar
}
}
public void SetGameMode(RulesetInfo ruleset) => modeSelector.SetGameMode(ruleset);
public void SetRuleset(RulesetInfo ruleset) => modeSelector.SetRuleset(ruleset);
protected override void PopIn()
{

View File

@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Toolbar
Ruleset = ruleset,
Action = delegate
{
SetGameMode(ruleset);
SetRuleset(ruleset);
OnRulesetChange?.Invoke(ruleset);
}
});
@ -89,7 +89,7 @@ namespace osu.Game.Overlays.Toolbar
Size = new Vector2(modeButtons.DrawSize.X, 1);
}
public void SetGameMode(RulesetInfo ruleset)
public void SetRuleset(RulesetInfo ruleset)
{
foreach (ToolbarModeButton m in modeButtons.Children.Cast<ToolbarModeButton>())
{

View File

@ -3,7 +3,7 @@
using osu.Game.Graphics;
namespace osu.Game.Modes
namespace osu.Game.Rulesets
{
public class BeatmapStatistic
{

View File

@ -0,0 +1,90 @@
// 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 System.Collections.Generic;
using System.Linq;
using osu.Game.Rulesets.Objects;
using osu.Game.Beatmaps;
namespace osu.Game.Rulesets.Beatmaps
{
/// <summary>
/// Converts a Beatmap for another mode.
/// </summary>
/// <typeparam name="T">The type of HitObject stored in the Beatmap.</typeparam>
public abstract class BeatmapConverter<T> where T : HitObject
{
/// <summary>
/// Checks if a Beatmap can be converted using this Beatmap Converter.
/// </summary>
/// <param name="beatmap">The Beatmap to check.</param>
/// <returns>Whether the Beatmap can be converted using this Beatmap Converter.</returns>
public bool CanConvert(Beatmap beatmap) => ValidConversionTypes.All(t => beatmap.HitObjects.Any(t.IsInstanceOfType));
/// <summary>
/// Converts a Beatmap using this Beatmap Converter.
/// </summary>
/// <param name="original">The un-converted Beatmap.</param>
/// <returns>The converted Beatmap.</returns>
public Beatmap<T> Convert(Beatmap original)
{
// We always operate on a clone of the original beatmap, to not modify it game-wide
return ConvertBeatmap(new Beatmap(original));
}
/// <summary>
/// Performs the conversion of a Beatmap using this Beatmap Converter.
/// </summary>
/// <param name="original">The un-converted Beatmap.</param>
/// <returns>The converted Beatmap.</returns>
protected virtual Beatmap<T> ConvertBeatmap(Beatmap original)
{
return new Beatmap<T>
{
BeatmapInfo = original.BeatmapInfo,
TimingInfo = original.TimingInfo,
HitObjects = original.HitObjects.SelectMany(h => convert(h, original)).ToList()
};
}
/// <summary>
/// Converts a hit object.
/// </summary>
/// <param name="original">The hit object to convert.</param>
/// <param name="beatmap">The un-converted Beatmap.</param>
/// <returns>The converted hit object.</returns>
private IEnumerable<T> convert(HitObject original, Beatmap beatmap)
{
// Check if the hitobject is already the converted type
T tObject = original as T;
if (tObject != null)
{
yield return tObject;
yield break;
}
// Convert the hit object
foreach (var obj in ConvertHitObject(original, beatmap))
{
if (obj == null)
continue;
yield return obj;
}
}
/// <summary>
/// The types of HitObjects that can be converted to be used for this Beatmap.
/// </summary>
protected abstract IEnumerable<Type> ValidConversionTypes { get; }
/// <summary>
/// Performs the conversion of a hit object.
/// </summary>
/// <param name="original">The hit object to convert.</param>
/// <param name="beatmap">The un-converted Beatmap.</param>
/// <returns>The converted hit object.</returns>
protected abstract IEnumerable<T> ConvertHitObject(HitObject original, Beatmap beatmap);
}
}

View File

@ -1,15 +1,16 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Objects;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Beatmaps
namespace osu.Game.Rulesets.Beatmaps
{
/// <summary>
/// Processes a post-converted Beatmap.
/// </summary>
/// <typeparam name="TObject">The type of HitObject contained in the Beatmap.</typeparam>
public interface IBeatmapProcessor<TObject>
public class BeatmapProcessor<TObject>
where TObject : HitObject
{
/// <summary>
@ -19,6 +20,6 @@ namespace osu.Game.Beatmaps
/// </para>
/// </summary>
/// <param name="beatmap">The Beatmap to process.</param>
void PostProcess(Beatmap<TObject> beatmap);
public virtual void PostProcess(Beatmap<TObject> beatmap) { }
}
}

View File

@ -9,9 +9,9 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Modes.Judgements
namespace osu.Game.Rulesets.Judgements
{
/// <summary>
/// A drawable object which visualises the hit result of a <see cref="Judgements.Judgement"/>.

View File

@ -1,10 +1,10 @@
// 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.Modes.Objects.Drawables;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Modes.Judgements
namespace osu.Game.Rulesets.Judgements
{
/// <summary>
/// Inidicates that the judgement this is attached to is a partial judgement and the scoring value may change.

View File

@ -1,9 +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.Modes.Objects.Drawables;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Modes.Judgements
namespace osu.Game.Rulesets.Judgements
{
public abstract class Judgement
{

View File

@ -1,10 +1,10 @@
// 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.Modes.Objects;
using osu.Game.Modes.UI;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.UI;
namespace osu.Game.Modes.Mods
namespace osu.Game.Rulesets.Mods
{
/// <summary>
/// An interface for mods that are applied to a HitRenderer.

View File

@ -3,12 +3,12 @@
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Modes.Objects;
using osu.Game.Modes.UI;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.UI;
using System;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Modes.Mods
namespace osu.Game.Rulesets.Mods
{
/// <summary>
/// The base class for gameplay modifiers.

View File

@ -1,7 +1,7 @@
// 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.Modes.Mods
namespace osu.Game.Rulesets.Mods
{
public enum ModType
{

View File

@ -4,7 +4,7 @@
using System.Collections.Generic;
using OpenTK;
namespace osu.Game.Modes.Objects
namespace osu.Game.Rulesets.Objects
{
public class BezierApproximator
{

View File

@ -6,7 +6,7 @@ using System.Collections.Generic;
using osu.Framework.MathUtils;
using OpenTK;
namespace osu.Game.Modes.Objects
namespace osu.Game.Rulesets.Objects
{
public class CircularArcApproximator
{

View File

@ -2,10 +2,10 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Game.Modes.Objects.Types;
using osu.Game.Rulesets.Objects.Types;
using System.Collections.Generic;
namespace osu.Game.Modes.Objects
namespace osu.Game.Rulesets.Objects
{
public class CurvedHitObject : HitObject, IHasCurve
{

View File

@ -1,7 +1,7 @@
// 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.Modes.Objects.Drawables
namespace osu.Game.Rulesets.Objects.Drawables
{
public enum ArmedState
{

View File

@ -7,13 +7,13 @@ using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Game.Modes.Judgements;
using osu.Game.Rulesets.Judgements;
using Container = osu.Framework.Graphics.Containers.Container;
using osu.Game.Modes.Objects.Types;
using osu.Game.Rulesets.Objects.Types;
using OpenTK.Graphics;
using osu.Game.Audio;
namespace osu.Game.Modes.Objects.Drawables
namespace osu.Game.Rulesets.Objects.Drawables
{
public abstract class DrawableHitObject<TJudgement> : Container, IStateful<ArmedState>
where TJudgement : Judgement

View File

@ -3,7 +3,7 @@
using System.ComponentModel;
namespace osu.Game.Modes.Objects.Drawables
namespace osu.Game.Rulesets.Objects.Drawables
{
public enum HitResult
{

View File

@ -3,7 +3,7 @@
using osu.Framework.Graphics;
namespace osu.Game.Modes.Objects.Drawables
namespace osu.Game.Rulesets.Objects.Drawables
{
public interface IDrawableHitObjectWithProxiedApproach
{

View File

@ -6,7 +6,7 @@ using osu.Game.Beatmaps.Timing;
using osu.Game.Database;
using System.Collections.Generic;
namespace osu.Game.Modes.Objects
namespace osu.Game.Rulesets.Objects
{
/// <summary>
/// A HitObject describes an object in a Beatmap.

View File

@ -1,7 +1,7 @@
// 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.Modes.Objects
namespace osu.Game.Rulesets.Objects
{
public abstract class HitObjectParser
{

View File

@ -0,0 +1,17 @@
// 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;
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
{
public float X { get; set; }
public bool NewCombo { get; set; }
}
}

View File

@ -0,0 +1,45 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Game.Rulesets.Objects.Types;
using System.Collections.Generic;
namespace osu.Game.Rulesets.Objects.Legacy.Catch
{
/// <summary>
/// A HitObjectParser to parse legacy osu!catch Beatmaps.
/// </summary>
internal class HitObjectParser : Legacy.HitObjectParser
{
protected override HitObject CreateHit(Vector2 position, bool newCombo)
{
return new Hit
{
X = position.X,
NewCombo = newCombo,
};
}
protected override HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount)
{
return new Slider
{
X = position.X,
NewCombo = newCombo,
ControlPoints = controlPoints,
Distance = length,
CurveType = curveType,
RepeatCount = repeatCount
};
}
protected override HitObject CreateSpinner(Vector2 position, double endTime)
{
return new Spinner
{
EndTime = endTime
};
}
}
}

View File

@ -0,0 +1,17 @@
// 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;
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
{
public float X { get; set; }
public bool NewCombo { get; set; }
}
}

View File

@ -1,14 +1,14 @@
// 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.Modes.Objects.Types;
using osu.Game.Rulesets.Objects.Types;
namespace osu.Game.Modes.Objects.Legacy
namespace osu.Game.Rulesets.Objects.Legacy.Catch
{
/// <summary>
/// Legacy Spinner-type, used for parsing Beatmaps.
/// Legacy osu!catch Spinner-type, used for parsing Beatmaps.
/// </summary>
internal class LegacySpinner : HitObject, IHasEndTime
internal sealed class Spinner : HitObject, IHasEndTime
{
public double EndTime { get; set; }

View File

@ -2,24 +2,26 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Game.Modes.Objects.Types;
using osu.Game.Rulesets.Objects.Types;
using System;
using System.Collections.Generic;
using System.Globalization;
using osu.Game.Modes.Objects.Legacy;
using osu.Game.Beatmaps.Formats;
using osu.Game.Audio;
namespace osu.Game.Modes.Objects
namespace osu.Game.Rulesets.Objects.Legacy
{
internal class LegacyHitObjectParser : HitObjectParser
/// <summary>
/// A HitObjectParser to parse legacy Beatmaps.
/// </summary>
internal abstract class HitObjectParser : Objects.HitObjectParser
{
public override HitObject Parse(string text)
{
string[] split = text.Split(',');
var type = (LegacyHitObjectType)int.Parse(split[3]) & ~LegacyHitObjectType.ColourHax;
bool combo = type.HasFlag(LegacyHitObjectType.NewCombo);
type &= ~LegacyHitObjectType.NewCombo;
var type = (HitObjectType)int.Parse(split[3]) & ~HitObjectType.ColourHax;
bool combo = type.HasFlag(HitObjectType.NewCombo);
type &= ~HitObjectType.NewCombo;
int sampleVolume = 0;
string normalSampleBank = null;
@ -27,22 +29,18 @@ namespace osu.Game.Modes.Objects
HitObject result;
if ((type & LegacyHitObjectType.Circle) > 0)
if ((type & HitObjectType.Circle) > 0)
{
result = new LegacyHit
{
Position = new Vector2(int.Parse(split[0]), int.Parse(split[1])),
NewCombo = combo
};
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);
}
else if ((type & LegacyHitObjectType.Slider) > 0)
else if ((type & HitObjectType.Slider) > 0)
{
CurveType curveType = CurveType.Catmull;
double length = 0;
List<Vector2> points = new List<Vector2> { new Vector2(int.Parse(split[0]), int.Parse(split[1])) };
var points = new List<Vector2> { new Vector2(int.Parse(split[0]), int.Parse(split[1])) };
string[] pointsplit = split[5].Split('|');
foreach (string t in pointsplit)
@ -68,11 +66,7 @@ namespace osu.Game.Modes.Objects
}
string[] temp = t.Split(':');
Vector2 v = new Vector2(
(int)Convert.ToDouble(temp[0], CultureInfo.InvariantCulture),
(int)Convert.ToDouble(temp[1], CultureInfo.InvariantCulture)
);
points.Add(v);
points.Add(new Vector2((int)Convert.ToDouble(temp[0], CultureInfo.InvariantCulture), (int)Convert.ToDouble(temp[1], CultureInfo.InvariantCulture)));
}
int repeatCount = Convert.ToInt32(split[6], CultureInfo.InvariantCulture);
@ -83,37 +77,26 @@ namespace osu.Game.Modes.Objects
if (split.Length > 7)
length = Convert.ToDouble(split[7], CultureInfo.InvariantCulture);
result = new LegacySlider
{
ControlPoints = points,
Distance = length,
CurveType = curveType,
RepeatCount = repeatCount,
Position = new Vector2(int.Parse(split[0]), int.Parse(split[1])),
NewCombo = combo
};
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);
}
else if ((type & LegacyHitObjectType.Spinner) > 0)
else if ((type & HitObjectType.Spinner) > 0)
{
result = new LegacySpinner
{
EndTime = Convert.ToDouble(split[5], CultureInfo.InvariantCulture)
};
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);
}
else if ((type & LegacyHitObjectType.Hold) > 0)
else if ((type & HitObjectType.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 LegacyHold
result = new Hold
{
Position = new Vector2(int.Parse(split[0]), int.Parse(split[1])),
NewCombo = combo
@ -191,6 +174,34 @@ namespace osu.Game.Modes.Objects
sampleVolume = split.Length > 3 ? int.Parse(split[3]) : 0;
}
/// <summary>
/// Creates a legacy Hit-type hit object.
/// </summary>
/// <param name="position">The position of the hit object.</param>
/// <param name="newCombo">Whether the hit object creates a new combo.</param>
/// <returns>The hit object.</returns>
protected abstract HitObject CreateHit(Vector2 position, bool newCombo);
/// <summary>
/// Creats a legacy Slider-type hit object.
/// </summary>
/// <param name="position">The position of the hit object.</param>
/// <param name="newCombo">Whether the hit object creates a new combo.</param>
/// <param name="controlPoints">The slider control points.</param>
/// <param name="length">The slider length.</param>
/// <param name="curveType">The slider curve type.</param>
/// <param name="repeatCount">The slider repeat count.</param>
/// <returns>The hit object.</returns>
protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount);
/// <summary>
/// Creates a legacy Spinner-type hit object.
/// </summary>
/// <param name="position">The position of the hit object.</param>
/// <param name="endTime">The spinner end time.</param>
/// <returns>The hit object.</returns>
protected abstract HitObject CreateSpinner(Vector2 position, double endTime);
[Flags]
private enum LegacySoundType
{

View File

@ -3,10 +3,10 @@
using System;
namespace osu.Game.Modes.Objects.Legacy
namespace osu.Game.Rulesets.Objects.Legacy
{
[Flags]
public enum LegacyHitObjectType
public enum HitObjectType
{
Circle = 1 << 0,
Slider = 1 << 1,

View File

@ -2,17 +2,21 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Game.Modes.Objects.Types;
using osu.Game.Rulesets.Objects.Types;
namespace osu.Game.Modes.Objects.Legacy
namespace osu.Game.Rulesets.Objects.Legacy
{
/// <summary>
/// Legacy Hold-type, used for parsing "specials" in beatmaps.
/// </summary>
public sealed class LegacyHold : HitObject, IHasPosition, IHasCombo, IHasHold
internal sealed class Hold : HitObject, IHasPosition, IHasCombo, IHasHold
{
public Vector2 Position { get; set; }
public float X => Position.X;
public float Y => Position.Y;
public bool NewCombo { get; set; }
}
}

View File

@ -0,0 +1,17 @@
// 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;
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
{
public float X { get; set; }
public bool NewCombo { get; set; }
}
}

View 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 OpenTK;
using osu.Game.Rulesets.Objects.Types;
using System.Collections.Generic;
namespace osu.Game.Rulesets.Objects.Legacy.Mania
{
/// <summary>
/// A HitObjectParser to parse legacy osu!mania Beatmaps.
/// </summary>
internal class HitObjectParser : Legacy.HitObjectParser
{
protected override HitObject CreateHit(Vector2 position, bool newCombo)
{
return new Hit
{
X = position.X,
NewCombo = newCombo,
};
}
protected override HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount)
{
return new Slider
{
X = position.X,
NewCombo = newCombo,
ControlPoints = controlPoints,
Distance = length,
CurveType = curveType,
RepeatCount = repeatCount
};
}
protected override HitObject CreateSpinner(Vector2 position, double endTime)
{
return new Spinner
{
X = position.X,
EndTime = endTime
};
}
}
}

View File

@ -0,0 +1,17 @@
// 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;
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
{
public float X { get; set; }
public bool NewCombo { get; set; }
}
}

View File

@ -0,0 +1,19 @@
// 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;
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
{
public double EndTime { get; set; }
public double Duration => EndTime - StartTime;
public float X { get; set; }
}
}

View File

@ -1,18 +1,22 @@
// 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.Modes.Objects.Types;
using osu.Game.Rulesets.Objects.Types;
using OpenTK;
namespace osu.Game.Modes.Objects.Legacy
namespace osu.Game.Rulesets.Objects.Legacy.Osu
{
/// <summary>
/// Legacy Slider-type, used for parsing Beatmaps.
/// Legacy osu! Hit-type, used for parsing Beatmaps.
/// </summary>
public sealed class LegacySlider : CurvedHitObject, IHasPosition, IHasCombo
internal sealed class Hit : HitObject, IHasPosition, IHasCombo
{
public Vector2 Position { get; set; }
public float X => Position.X;
public float Y => Position.Y;
public bool NewCombo { get; set; }
}
}

View 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 OpenTK;
using osu.Game.Rulesets.Objects.Types;
using System.Collections.Generic;
namespace osu.Game.Rulesets.Objects.Legacy.Osu
{
/// <summary>
/// A HitObjectParser to parse legacy osu! Beatmaps.
/// </summary>
internal class HitObjectParser : Legacy.HitObjectParser
{
protected override HitObject CreateHit(Vector2 position, bool newCombo)
{
return new Hit
{
Position = position,
NewCombo = newCombo,
};
}
protected override HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount)
{
return new Slider
{
Position = position,
NewCombo = newCombo,
ControlPoints = controlPoints,
Distance = length,
CurveType = curveType,
RepeatCount = repeatCount
};
}
protected override HitObject CreateSpinner(Vector2 position, double endTime)
{
return new Spinner
{
Position = position,
EndTime = endTime
};
}
}
}

View File

@ -0,0 +1,22 @@
// 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 OpenTK;
namespace osu.Game.Rulesets.Objects.Legacy.Osu
{
/// <summary>
/// Legacy osu! Slider-type, used for parsing Beatmaps.
/// </summary>
internal sealed class Slider : CurvedHitObject, IHasPosition, IHasCombo
{
public Vector2 Position { get; set; }
public float X => Position.X;
public float Y => Position.Y;
public bool NewCombo { get; set; }
}
}

View File

@ -0,0 +1,24 @@
// 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 OpenTK;
namespace osu.Game.Rulesets.Objects.Legacy.Osu
{
/// <summary>
/// Legacy osu! Spinner-type, used for parsing Beatmaps.
/// </summary>
internal sealed class Spinner : HitObject, IHasEndTime, IHasPosition
{
public double EndTime { get; set; }
public double Duration => EndTime - StartTime;
public Vector2 Position { get; set; }
public float X => Position.X;
public float Y => Position.Y;
}
}

View File

@ -0,0 +1,15 @@
// 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;
namespace osu.Game.Rulesets.Objects.Legacy.Taiko
{
/// <summary>
/// Legacy osu!taiko Hit-type, used for parsing Beatmaps.
/// </summary>
internal sealed class Hit : HitObject, IHasCombo
{
public bool NewCombo { get; set; }
}
}

View File

@ -0,0 +1,43 @@
// 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.Legacy.Taiko
{
/// <summary>
/// A HitObjectParser to parse legacy osu!taiko Beatmaps.
/// </summary>
internal class HitObjectParser : Legacy.HitObjectParser
{
protected override HitObject CreateHit(Vector2 position, bool newCombo)
{
return new Hit
{
NewCombo = newCombo,
};
}
protected override HitObject CreateSlider(Vector2 position, bool newCombo, List<Vector2> controlPoints, double length, CurveType curveType, int repeatCount)
{
return new Slider
{
NewCombo = newCombo,
ControlPoints = controlPoints,
Distance = length,
CurveType = curveType,
RepeatCount = repeatCount
};
}
protected override HitObject CreateSpinner(Vector2 position, double endTime)
{
return new Spinner
{
EndTime = endTime
};
}
}
}

View File

@ -0,0 +1,15 @@
// 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;
namespace osu.Game.Rulesets.Objects.Legacy.Taiko
{
/// <summary>
/// Legacy osu!taiko Slider-type, used for parsing Beatmaps.
/// </summary>
internal sealed class Slider : CurvedHitObject, IHasCombo
{
public bool NewCombo { get; set; }
}
}

View File

@ -0,0 +1,17 @@
// 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;
namespace osu.Game.Rulesets.Objects.Legacy.Taiko
{
/// <summary>
/// Legacy osu!taiko Spinner-type, used for parsing Beatmaps.
/// </summary>
internal sealed class Spinner : HitObject, IHasEndTime
{
public double EndTime { get; set; }
public double Duration => EndTime - StartTime;
}
}

View File

@ -4,10 +4,10 @@
using System.Collections.Generic;
using System.Linq;
using osu.Framework.MathUtils;
using osu.Game.Modes.Objects.Types;
using osu.Game.Rulesets.Objects.Types;
using OpenTK;
namespace osu.Game.Modes.Objects
namespace osu.Game.Rulesets.Objects
{
public class SliderCurve
{

View File

@ -1,7 +1,7 @@
// 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.Modes.Objects.Types
namespace osu.Game.Rulesets.Objects.Types
{
public enum CurveType
{

View File

@ -1,7 +1,7 @@
// 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.Modes.Objects.Types
namespace osu.Game.Rulesets.Objects.Types
{
/// <summary>
/// A HitObject that is part of a combo.

View File

@ -4,7 +4,7 @@
using System.Collections.Generic;
using OpenTK;
namespace osu.Game.Modes.Objects.Types
namespace osu.Game.Rulesets.Objects.Types
{
/// <summary>
/// A HitObject that has a curve.

View File

@ -1,7 +1,7 @@
// 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.Modes.Objects.Types
namespace osu.Game.Rulesets.Objects.Types
{
/// <summary>
/// A HitObject that has a positional length.

View File

@ -1,7 +1,7 @@
// 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.Modes.Objects.Types
namespace osu.Game.Rulesets.Objects.Types
{
/// <summary>
/// A HitObject that ends at a different time than its start time.

View File

@ -1,7 +1,7 @@
// 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.Modes.Objects.Types
namespace osu.Game.Rulesets.Objects.Types
{
/// <summary>
/// A special type of HitObject, mostly used for legacy conversion of "holds".

View File

@ -3,12 +3,12 @@
using OpenTK;
namespace osu.Game.Modes.Objects.Types
namespace osu.Game.Rulesets.Objects.Types
{
/// <summary>
/// A HitObject that has a starting position.
/// </summary>
public interface IHasPosition
public interface IHasPosition : IHasXPosition, IHasYPosition
{
/// <summary>
/// The starting position of the HitObject.

View File

@ -1,7 +1,7 @@
// 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.Modes.Objects.Types
namespace osu.Game.Rulesets.Objects.Types
{
/// <summary>
/// A HitObject that spans some length.

View File

@ -0,0 +1,17 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Rulesets.Objects.Types
{
/// <summary>
/// A HitObject that has a starting X-position.
/// </summary>
public interface IHasXPosition
{
/// <summary>
/// The starting X-position of this HitObject.
/// </summary>
float X { get; }
}
}

View File

@ -0,0 +1,17 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Rulesets.Objects.Types
{
/// <summary>
/// A HitObject that has a starting Y-position.
/// </summary>
public interface IHasYPosition
{
/// <summary>
/// The starting Y-position of this HitObject.
/// </summary>
float Y { get; }
}
}

View File

@ -12,7 +12,7 @@ using OpenTK.Input;
using KeyboardState = osu.Framework.Input.KeyboardState;
using MouseState = osu.Framework.Input.MouseState;
namespace osu.Game.Modes.Replays
namespace osu.Game.Rulesets.Replays
{
/// <summary>
/// The ReplayHandler will take a replay and handle the propagation of updates to the input stack.

View File

@ -3,7 +3,7 @@
using System.Collections.Generic;
namespace osu.Game.Modes.Replays
namespace osu.Game.Rulesets.Replays
{
public class Replay
{

View File

@ -3,7 +3,7 @@
using System;
namespace osu.Game.Modes.Replays
namespace osu.Game.Rulesets.Replays
{
[Flags]
public enum ReplayButtonState

View File

@ -3,7 +3,7 @@
using OpenTK;
namespace osu.Game.Modes.Replays
namespace osu.Game.Rulesets.Replays
{
public class ReplayFrame
{

View File

@ -3,13 +3,13 @@
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Modes.Mods;
using osu.Game.Modes.UI;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using System.Collections.Generic;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Modes
namespace osu.Game.Rulesets
{
public abstract class Ruleset
{

View File

@ -5,12 +5,12 @@ using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Game.Database;
using osu.Game.Modes.Mods;
using osu.Game.Rulesets.Mods;
using osu.Game.Users;
using System.IO;
using osu.Game.Modes.Replays;
using osu.Game.Rulesets.Replays;
namespace osu.Game.Modes.Scoring
namespace osu.Game.Rulesets.Scoring
{
public class Score
{

View File

@ -5,12 +5,12 @@ using System;
using System.Collections.Generic;
using osu.Framework.Configuration;
using osu.Game.Beatmaps;
using osu.Game.Modes.Judgements;
using osu.Game.Modes.Objects;
using osu.Game.Modes.UI;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Modes.Scoring
namespace osu.Game.Rulesets.Scoring
{
public abstract class ScoreProcessor
{
@ -62,7 +62,7 @@ namespace osu.Game.Modes.Scoring
}
/// <summary>
/// Creates a Score applicable to the game mode in which this ScoreProcessor resides.
/// Creates a Score applicable to the ruleset in which this ScoreProcessor resides.
/// </summary>
/// <returns>The Score.</returns>
public virtual Score CreateScore() => new Score
@ -193,4 +193,4 @@ namespace osu.Game.Modes.Scoring
/// <param name="judgement">The judgement that triggered this calculation.</param>
protected virtual void OnJudgementChanged(TJudgement judgement) { }
}
}
}

View File

@ -3,7 +3,7 @@
using System.ComponentModel;
namespace osu.Game.Modes.Scoring
namespace osu.Game.Rulesets.Scoring
{
public enum ScoreRank
{

View File

@ -10,7 +10,7 @@ using osu.Framework.Graphics.Transforms;
using osu.Framework.MathUtils;
using osu.Game.Graphics.Sprites;
namespace osu.Game.Modes.UI
namespace osu.Game.Rulesets.UI
{
public abstract class ComboCounter : Container
{

View File

@ -7,7 +7,7 @@ using osu.Framework.MathUtils;
using osu.Game.Graphics.UserInterface;
using System;
namespace osu.Game.Modes.UI
namespace osu.Game.Rulesets.UI
{
/// <summary>
/// Used to display combo with a roll-up animation in results screen.

View File

@ -4,7 +4,7 @@
using osu.Framework.Configuration;
using osu.Framework.Graphics.Containers;
namespace osu.Game.Modes.UI
namespace osu.Game.Rulesets.UI
{
public abstract class HealthDisplay : Container
{

View File

@ -5,20 +5,21 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Modes.Judgements;
using osu.Game.Modes.Mods;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Screens.Play;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using osu.Game.Modes.Replays;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Scoring;
using OpenTK;
using osu.Game.Rulesets.Beatmaps;
namespace osu.Game.Modes.UI
namespace osu.Game.Rulesets.UI
{
/// <summary>
/// Base HitRenderer. Doesn't hold objects.
@ -119,8 +120,12 @@ namespace osu.Game.Modes.UI
RelativeSizeAxes = Axes.Both;
IBeatmapConverter<TObject> converter = CreateBeatmapConverter();
IBeatmapProcessor<TObject> processor = CreateBeatmapProcessor();
BeatmapConverter<TObject> converter = CreateBeatmapConverter();
BeatmapProcessor<TObject> processor = CreateBeatmapProcessor();
// Check if the beatmap can be converted
if (!converter.CanConvert(beatmap.Beatmap))
throw new BeatmapInvalidForModeException($"{nameof(Beatmap)} can't be converted for the current ruleset.");
// Convert the beatmap
Beatmap = converter.Convert(beatmap.Beatmap);
@ -136,7 +141,6 @@ namespace osu.Game.Modes.UI
applyMods(beatmap.Mods.Value);
}
/// <summary>
/// Applies the active mods to this HitRenderer.
/// </summary>
@ -150,18 +154,18 @@ namespace osu.Game.Modes.UI
mod.Apply(this);
}
/// <summary>
/// Creates a converter to convert Beatmap to a specific mode.
/// </summary>
/// <returns>The Beatmap converter.</returns>
protected abstract IBeatmapConverter<TObject> CreateBeatmapConverter();
/// <summary>
/// Creates a processor to perform post-processing operations
/// on HitObjects in converted Beatmaps.
/// </summary>
/// <returns>The Beatmap processor.</returns>
protected abstract IBeatmapProcessor<TObject> CreateBeatmapProcessor();
protected virtual BeatmapProcessor<TObject> CreateBeatmapProcessor() => new BeatmapProcessor<TObject>();
/// <summary>
/// Creates a converter to convert Beatmap to a specific mode.
/// </summary>
/// <returns>The Beatmap converter.</returns>
protected abstract BeatmapConverter<TObject> CreateBeatmapConverter();
}
/// <summary>
@ -268,4 +272,12 @@ namespace osu.Game.Modes.UI
/// <returns>The Playfield.</returns>
protected abstract Playfield<TObject, TJudgement> CreatePlayfield();
}
public class BeatmapInvalidForModeException : Exception
{
public BeatmapInvalidForModeException(string text)
: base(text)
{
}
}
}

View File

@ -8,13 +8,13 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Play;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Scoring;
using osu.Framework.Input;
using OpenTK.Input;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
namespace osu.Game.Modes.UI
namespace osu.Game.Rulesets.UI
{
public abstract class HudOverlay : Container
{

View File

@ -6,7 +6,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
namespace osu.Game.Modes.UI
namespace osu.Game.Rulesets.UI
{
public class ModIcon : Container
{

View File

@ -4,13 +4,13 @@
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using OpenTK;
using osu.Game.Modes.Judgements;
using osu.Game.Rulesets.Judgements;
using osu.Framework.Allocation;
namespace osu.Game.Modes.UI
namespace osu.Game.Rulesets.UI
{
public abstract class Playfield<TObject, TJudgement> : Container
where TObject : HitObject

View File

@ -3,7 +3,7 @@
using OpenTK;
namespace osu.Game.Modes.UI
namespace osu.Game.Rulesets.UI
{
/// <summary>
/// Uses the 'x' symbol and has a pop-out effect while rolling over.

View File

@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
namespace osu.Game.Modes.UI
namespace osu.Game.Rulesets.UI
{
public class StandardHealthDisplay : HealthDisplay, IHasAccentColour
{

View File

@ -10,7 +10,7 @@ using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Play;
namespace osu.Game.Modes.UI
namespace osu.Game.Rulesets.UI
{
public class StandardHudOverlay : HudOverlay
{

View File

@ -28,7 +28,7 @@ namespace osu.Game.Screens
public override bool Push(Screen screen)
{
// When trying to push a non-loaded GameMode, load it asynchronously and re-invoke Push
// When trying to push a non-loaded screen, load it asynchronously and re-invoke Push
// once it's done.
if (screen.LoadState == LoadState.NotLoaded)
{
@ -36,7 +36,7 @@ namespace osu.Game.Screens
return true;
}
// Make sure the in-progress loading is complete before pushing the GameMode.
// Make sure the in-progress loading is complete before pushing the screen.
while (screen.LoadState < LoadState.Loaded)
Thread.Sleep(1);

View File

@ -14,7 +14,7 @@ namespace osu.Game.Screens
internal BackgroundScreen Background { get; private set; }
/// <summary>
/// Override to create a BackgroundMode for the current GameMode.
/// Override to create a BackgroundMode for the current screen.
/// Note that the instance created may not be the used instance if it matches the BackgroundMode equality clause.
/// </summary>
protected virtual BackgroundScreen CreateBackground() => null;
@ -99,7 +99,7 @@ namespace osu.Game.Screens
if (Background != null && !Background.Equals(nextOsu?.Background))
{
if (nextOsu != null)
//We need to use MakeCurrent in case we are jumping up multiple game modes.
//We need to use MakeCurrent in case we are jumping up multiple game screens.
nextOsu.Background?.MakeCurrent();
else
Background.Exit();

View File

@ -14,14 +14,14 @@ using osu.Framework.Screens;
using osu.Framework.Timing;
using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Modes;
using osu.Game.Modes.UI;
using osu.Game.Rulesets;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Backgrounds;
using osu.Game.Screens.Ranking;
using System;
using System.Linq;
using osu.Framework.Threading;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Screens.Play
{
@ -60,8 +60,8 @@ namespace osu.Game.Screens.Play
private PauseOverlay pauseOverlay;
private FailOverlay failOverlay;
[BackgroundDependencyLoader]
private void load(AudioManager audio, BeatmapDatabase beatmaps, OsuConfigManager config)
[BackgroundDependencyLoader(permitNulls: true)]
private void load(AudioManager audio, BeatmapDatabase beatmaps, OsuConfigManager config, OsuGame osu)
{
dimLevel = config.GetBindable<int>(OsuConfig.DimLevel);
mouseWheelDisabled = config.GetBindable<bool>(OsuConfig.MouseDisableWheel);
@ -76,6 +76,19 @@ namespace osu.Game.Screens.Play
if (Beatmap == null)
throw new Exception("Beatmap was not loaded");
try
{
// Try using the preferred user ruleset
ruleset = osu == null ? Beatmap.BeatmapInfo.Ruleset.CreateInstance() : osu.Ruleset.Value.CreateInstance();
HitRenderer = ruleset.CreateHitRendererWith(Beatmap);
}
catch (BeatmapInvalidForModeException)
{
// Default to the beatmap ruleset
ruleset = Beatmap.BeatmapInfo.Ruleset.CreateInstance();
HitRenderer = ruleset.CreateHitRendererWith(Beatmap);
}
}
catch (Exception e)
{
@ -102,12 +115,6 @@ namespace osu.Game.Screens.Play
sourceClock.Reset();
});
ruleset = Beatmap.BeatmapInfo.Ruleset.CreateInstance();
// Todo: This should be done as early as possible, and should check if the hit renderer
// can actually convert the hit objects... Somehow...
HitRenderer = ruleset.CreateHitRendererWith(Beatmap);
scoreProcessor = HitRenderer.CreateScoreProcessor();
hudOverlay = new StandardHudOverlay()

View File

@ -1,7 +1,7 @@
// 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.Modes.Replays;
using osu.Game.Rulesets.Replays;
namespace osu.Game.Screens.Play
{

View File

@ -11,8 +11,8 @@ using osu.Game.Graphics;
using osu.Framework.Allocation;
using System.Linq;
using osu.Framework.Timing;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Types;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
namespace osu.Game.Screens.Play
{

View File

@ -5,7 +5,7 @@ using osu.Framework.Screens;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Backgrounds;
using OpenTK;
using OpenTK.Graphics;

View File

@ -33,7 +33,7 @@ namespace osu.Game.Screens
{
base.OnEntering(last);
//only show the pop button if we are entered form another gamemode.
//only show the pop button if we are entered form another screen.
if (last != null)
popButton.Alpha = 1;

View File

@ -18,9 +18,9 @@ using osu.Game.Beatmaps.Drawables;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Modes;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Types;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
namespace osu.Game.Screens.Select
{

View File

@ -7,7 +7,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Extensions;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Screens.Select.Leaderboards
{

View File

@ -12,7 +12,7 @@ using osu.Framework.Graphics.Primitives;
using System;
using osu.Framework.Allocation;
using osu.Game.Database;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Scoring;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;

View File

@ -10,10 +10,10 @@ using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Framework.Extensions.Color4Extensions;
using osu.Game.Modes.Mods;
using osu.Game.Rulesets.Mods;
using osu.Game.Users;
using osu.Framework;
using osu.Game.Modes.Scoring;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Screens.Select.Leaderboards
{

View File

@ -72,8 +72,8 @@
<Compile Include="Audio\SampleInfo.cs" />
<Compile Include="Beatmaps\Drawables\BeatmapBackgroundSprite.cs" />
<Compile Include="Beatmaps\DifficultyCalculator.cs" />
<Compile Include="Beatmaps\IBeatmapConverter.cs" />
<Compile Include="Beatmaps\IBeatmapProcessor.cs" />
<Compile Include="Rulesets\Beatmaps\BeatmapConverter.cs" />
<Compile Include="Rulesets\Beatmaps\BeatmapProcessor.cs" />
<Compile Include="Beatmaps\Legacy\LegacyBeatmap.cs" />
<Compile Include="Beatmaps\Timing\TimeSignatures.cs" />
<Compile Include="Beatmaps\Timing\TimingInfo.cs" />
@ -103,45 +103,60 @@
<Compile Include="IO\Legacy\SerializationWriter.cs" />
<Compile Include="IO\Serialization\IJsonSerializable.cs" />
<Compile Include="IPC\ScoreIPCChannel.cs" />
<Compile Include="Modes\BeatmapStatistic.cs" />
<Compile Include="Modes\Replays\Replay.cs" />
<Compile Include="Modes\Judgements\DrawableJudgement.cs" />
<Compile Include="Modes\Judgements\IPartialJudgement.cs" />
<Compile Include="Modes\Replays\FramedReplayInputHandler.cs" />
<Compile Include="Modes\Mods\IApplicableMod.cs" />
<Compile Include="Modes\Mods\ModType.cs" />
<Compile Include="Modes\Objects\Drawables\ArmedState.cs" />
<Compile Include="Modes\Objects\Drawables\HitResult.cs" />
<Compile Include="Modes\Objects\BezierApproximator.cs" />
<Compile Include="Modes\Objects\CircularArcApproximator.cs" />
<Compile Include="Modes\Objects\CurvedHitObject.cs" />
<Compile Include="Modes\Objects\Legacy\LegacyHit.cs" />
<Compile Include="Modes\Objects\LegacyHitObjectParser.cs" />
<Compile Include="Modes\Objects\Legacy\LegacyHold.cs" />
<Compile Include="Modes\Objects\Legacy\LegacySlider.cs" />
<Compile Include="Modes\Objects\Legacy\LegacySpinner.cs" />
<Compile Include="Modes\Objects\SliderCurve.cs" />
<Compile Include="Modes\Objects\Types\CurveType.cs" />
<Compile Include="Modes\Objects\Drawables\IDrawableHitObjectWithProxiedApproach.cs" />
<Compile Include="Modes\Judgements\Judgement.cs" />
<Compile Include="Modes\Objects\HitObjectParser.cs" />
<Compile Include="Modes\Objects\Types\IHasCombo.cs" />
<Compile Include="Modes\Objects\Types\IHasEndTime.cs" />
<Compile Include="Modes\Objects\Types\IHasDistance.cs" />
<Compile Include="Modes\Objects\Types\IHasCurve.cs" />
<Compile Include="Modes\Objects\Types\IHasRepeats.cs" />
<Compile Include="Modes\Objects\Types\IHasPosition.cs" />
<Compile Include="Modes\Objects\Types\IHasHold.cs" />
<Compile Include="Modes\Objects\Legacy\LegacyHitObjectType.cs" />
<Compile Include="Modes\Replays\ReplayButtonState.cs" />
<Compile Include="Modes\Replays\ReplayFrame.cs" />
<Compile Include="Rulesets\BeatmapStatistic.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" />
<Compile Include="Rulesets\Judgements\DrawableJudgement.cs" />
<Compile Include="Rulesets\Judgements\IPartialJudgement.cs" />
<Compile Include="Rulesets\Replays\FramedReplayInputHandler.cs" />
<Compile Include="Rulesets\Mods\IApplicableMod.cs" />
<Compile Include="Rulesets\Mods\ModType.cs" />
<Compile Include="Rulesets\Objects\Drawables\ArmedState.cs" />
<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\SliderCurve.cs" />
<Compile Include="Rulesets\Objects\Types\CurveType.cs" />
<Compile Include="Rulesets\Objects\Drawables\IDrawableHitObjectWithProxiedApproach.cs" />
<Compile Include="Rulesets\Judgements\Judgement.cs" />
<Compile Include="Rulesets\Objects\HitObjectParser.cs" />
<Compile Include="Rulesets\Objects\Types\IHasCombo.cs" />
<Compile Include="Rulesets\Objects\Types\IHasEndTime.cs" />
<Compile Include="Rulesets\Objects\Types\IHasDistance.cs" />
<Compile Include="Rulesets\Objects\Types\IHasCurve.cs" />
<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\Replays\ReplayButtonState.cs" />
<Compile Include="Rulesets\Replays\ReplayFrame.cs" />
<Compile Include="Database\RulesetDatabase.cs" />
<Compile Include="Modes\Scoring\Score.cs" />
<Compile Include="Modes\Scoring\ScoreProcessor.cs" />
<Compile Include="Modes\UI\HealthDisplay.cs" />
<Compile Include="Modes\UI\HudOverlay.cs" />
<Compile Include="Modes\UI\StandardHealthDisplay.cs" />
<Compile Include="Modes\UI\StandardHudOverlay.cs" />
<Compile Include="Rulesets\Scoring\Score.cs" />
<Compile Include="Rulesets\Scoring\ScoreProcessor.cs" />
<Compile Include="Rulesets\UI\HealthDisplay.cs" />
<Compile Include="Rulesets\UI\HudOverlay.cs" />
<Compile Include="Rulesets\UI\StandardHealthDisplay.cs" />
<Compile Include="Rulesets\UI\StandardHudOverlay.cs" />
<Compile Include="Online\API\IOnlineComponent.cs" />
<Compile Include="Online\API\Requests\GetScoresRequest.cs" />
<Compile Include="Online\API\Requests\GetUserRequest.cs" />
@ -153,8 +168,8 @@
<Compile Include="Beatmaps\Drawables\BeatmapSetHeader.cs" />
<Compile Include="Beatmaps\Drawables\DifficultyIcon.cs" />
<Compile Include="Beatmaps\Drawables\Panel.cs" />
<Compile Include="Modes\Objects\Drawables\DrawableHitObject.cs" />
<Compile Include="Modes\Objects\HitObject.cs" />
<Compile Include="Rulesets\Objects\Drawables\DrawableHitObject.cs" />
<Compile Include="Rulesets\Objects\HitObject.cs" />
<Compile Include="Beatmaps\Timing\ControlPoint.cs" />
<Compile Include="Configuration\OsuConfigManager.cs" />
<Compile Include="Overlays\Notifications\IHasCompletionTarget.cs" />
@ -208,7 +223,7 @@
<Compile Include="Screens\Play\PlayerLoader.cs" />
<Compile Include="Screens\Play\ReplayPlayer.cs" />
<Compile Include="Screens\Play\SkipButton.cs" />
<Compile Include="Modes\UI\StandardComboCounter.cs" />
<Compile Include="Rulesets\UI\StandardComboCounter.cs" />
<Compile Include="Screens\Select\BeatmapCarousel.cs" />
<Compile Include="Screens\Select\BeatmapDetails.cs" />
<Compile Include="Graphics\UserInterface\BarGraph.cs" />
@ -221,16 +236,16 @@
<Compile Include="Beatmaps\Drawables\BeatmapPanel.cs" />
<Compile Include="Screens\Play\Player.cs" />
<Compile Include="Screens\Charts\ChartListing.cs" />
<Compile Include="Modes\Ruleset.cs" />
<Compile Include="Rulesets\Ruleset.cs" />
<Compile Include="Screens\Ranking\Results.cs" />
<Compile Include="Screens\Direct\OnlineListing.cs" />
<Compile Include="Screens\Select\PlaySongSelect.cs" />
<Compile Include="Screens\Select\SongSelect.cs" />
<Compile Include="Modes\UI\HitRenderer.cs" />
<Compile Include="Modes\UI\Playfield.cs" />
<Compile Include="Rulesets\UI\HitRenderer.cs" />
<Compile Include="Rulesets\UI\Playfield.cs" />
<Compile Include="Screens\Select\EditSongSelect.cs" />
<Compile Include="Modes\UI\ComboCounter.cs" />
<Compile Include="Modes\UI\ComboResultCounter.cs" />
<Compile Include="Rulesets\UI\ComboCounter.cs" />
<Compile Include="Rulesets\UI\ComboResultCounter.cs" />
<Compile Include="Graphics\UserInterface\RollingCounter.cs" />
<Compile Include="Graphics\UserInterface\Volume\VolumeControlReceptor.cs" />
<Compile Include="Input\GlobalHotkeys.cs" />
@ -347,9 +362,9 @@
<Compile Include="Screens\Play\Pause\PauseProgressBar.cs" />
<Compile Include="Screens\Play\Pause\PauseProgressGraph.cs" />
<Compile Include="Overlays\Mods\ModSelectOverlay.cs" />
<Compile Include="Modes\Mods\Mod.cs" />
<Compile Include="Rulesets\Mods\Mod.cs" />
<Compile Include="Overlays\Mods\ModButton.cs" />
<Compile Include="Modes\UI\ModIcon.cs" />
<Compile Include="Rulesets\UI\ModIcon.cs" />
<Compile Include="Overlays\Mods\ModSection.cs" />
<Compile Include="Overlays\Mods\DifficultyReductionSection.cs" />
<Compile Include="Overlays\Mods\DifficultyIncreaseSection.cs" />
@ -368,7 +383,7 @@
<Compile Include="Screens\Select\Leaderboards\LeaderboardScore.cs" />
<Compile Include="Users\Country.cs" />
<Compile Include="Users\Team.cs" />
<Compile Include="Modes\Scoring\ScoreRank.cs" />
<Compile Include="Rulesets\Scoring\ScoreRank.cs" />
<Compile Include="Users\Avatar.cs" />
<Compile Include="Screens\Select\Leaderboards\DrawableRank.cs" />
<Compile Include="Graphics\UserInterface\OsuTabControl.cs" />