1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-27 18:32:56 +08:00

Implement Beatmap conversion testing.

This commit is contained in:
smoogipooo 2017-04-17 15:44:46 +09:00
parent 928550b1a8
commit 2767fbd81a
9 changed files with 70 additions and 13 deletions

View File

@ -4,11 +4,15 @@
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Modes.Catch.Objects; using osu.Game.Modes.Catch.Objects;
using System.Collections.Generic; using System.Collections.Generic;
using System;
using osu.Game.Modes.Objects;
namespace osu.Game.Modes.Catch.Beatmaps namespace osu.Game.Modes.Catch.Beatmaps
{ {
internal class CatchBeatmapConverter : IBeatmapConverter<CatchBaseHit> internal class CatchBeatmapConverter : IBeatmapConverter<CatchBaseHit>
{ {
public IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(HitObject) };
public Beatmap<CatchBaseHit> Convert(Beatmap original) public Beatmap<CatchBaseHit> Convert(Beatmap original)
{ {
return new Beatmap<CatchBaseHit>(original) return new Beatmap<CatchBaseHit>(original)

View File

@ -4,11 +4,15 @@
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Modes.Mania.Objects; using osu.Game.Modes.Mania.Objects;
using System.Collections.Generic; using System.Collections.Generic;
using System;
using osu.Game.Modes.Objects;
namespace osu.Game.Modes.Mania.Beatmaps namespace osu.Game.Modes.Mania.Beatmaps
{ {
internal class ManiaBeatmapConverter : IBeatmapConverter<ManiaBaseHit> internal class ManiaBeatmapConverter : IBeatmapConverter<ManiaBaseHit>
{ {
public IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(HitObject) };
public Beatmap<ManiaBaseHit> Convert(Beatmap original) public Beatmap<ManiaBaseHit> Convert(Beatmap original)
{ {
return new Beatmap<ManiaBaseHit>(original) return new Beatmap<ManiaBaseHit>(original)

View File

@ -9,11 +9,14 @@ using osu.Game.Modes.Osu.Objects.Drawables;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Modes.Objects.Types; using osu.Game.Modes.Objects.Types;
using System.Linq; using System.Linq;
using System;
namespace osu.Game.Modes.Osu.Beatmaps namespace osu.Game.Modes.Osu.Beatmaps
{ {
internal class OsuBeatmapConverter : IBeatmapConverter<OsuHitObject> internal class OsuBeatmapConverter : IBeatmapConverter<OsuHitObject>
{ {
public IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasPosition) };
public Beatmap<OsuHitObject> Convert(Beatmap original) public Beatmap<OsuHitObject> Convert(Beatmap original)
{ {
return new Beatmap<OsuHitObject>(original) return new Beatmap<OsuHitObject>(original)
@ -56,8 +59,9 @@ namespace osu.Game.Modes.Osu.Beatmaps
{ {
StartTime = original.StartTime, StartTime = original.StartTime,
Samples = original.Samples, Samples = original.Samples,
Position = new Vector2(512, 384) / 2, EndTime = endTimeData.EndTime,
EndTime = endTimeData.EndTime
Position = positionData?.Position ?? new Vector2(512, 384) / 2,
}; };
} }

View File

@ -38,6 +38,8 @@ namespace osu.Game.Modes.Taiko.Beatmaps
/// </summary> /// </summary>
private const float taiko_base_distance = 100; private const float taiko_base_distance = 100;
public IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(HitObject) };
public Beatmap<TaikoHitObject> Convert(Beatmap original) public Beatmap<TaikoHitObject> Convert(Beatmap original)
{ {
BeatmapInfo info = original.BeatmapInfo.DeepClone<BeatmapInfo>(); BeatmapInfo info = original.BeatmapInfo.DeepClone<BeatmapInfo>();

View File

@ -1,6 +1,9 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Modes.Objects; using osu.Game.Modes.Objects;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
@ -11,6 +14,12 @@ namespace osu.Game.Beatmaps
/// <typeparam name="T">The type of HitObject stored in the Beatmap.</typeparam> /// <typeparam name="T">The type of HitObject stored in the Beatmap.</typeparam>
public interface IBeatmapConverter<T> where T : HitObject public interface IBeatmapConverter<T> where T : HitObject
{ {
/// <summary>
/// The type of HitObjects that can be converted to be used for this Beatmap.
/// </summary>
/// <returns></returns>
IEnumerable<Type> ValidConversionTypes { get; }
/// <summary> /// <summary>
/// Converts a Beatmap to another mode. /// Converts a Beatmap to another mode.
/// </summary> /// </summary>
@ -18,4 +27,16 @@ namespace osu.Game.Beatmaps
/// <returns>The converted Beatmap.</returns> /// <returns>The converted Beatmap.</returns>
Beatmap<T> Convert(Beatmap original); Beatmap<T> Convert(Beatmap original);
} }
public static class BeatmapConverterExtensions
{
/// <summary>
/// Checks if a Beatmap can be converted using a Beatmap Converter.
/// </summary>
/// <param name="converter">The Converter to use.</param>
/// <param name="beatmap">The Beatmap to check.</param>
/// <returns>Whether the Beatmap can be converted using <paramref name="converter" />.</returns>
public static bool CanConvert<TObject>(this IBeatmapConverter<TObject> converter, Beatmap beatmap) where TObject : HitObject
=> converter.ValidConversionTypes.All(t => beatmap.HitObjects.Any(h => t.IsAssignableFrom(h.GetType())));
}
} }

View File

@ -1,4 +1,5 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>. using OpenTK;
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Modes.Objects.Types; using osu.Game.Modes.Objects.Types;
@ -8,10 +9,12 @@ namespace osu.Game.Modes.Objects.Legacy
/// <summary> /// <summary>
/// Legacy Spinner-type, used for parsing Beatmaps. /// Legacy Spinner-type, used for parsing Beatmaps.
/// </summary> /// </summary>
internal class LegacySpinner : HitObject, IHasEndTime internal class LegacySpinner : HitObject, IHasEndTime, IHasPosition
{ {
public double EndTime { get; set; } public double EndTime { get; set; }
public double Duration => EndTime - StartTime; public double Duration => EndTime - StartTime;
public Vector2 Position { get; set; }
} }
} }

View File

@ -100,6 +100,7 @@ namespace osu.Game.Modes.Objects
{ {
result = new LegacySpinner result = new LegacySpinner
{ {
Position = new Vector2(512, 384) / 2,
EndTime = Convert.ToDouble(split[5], CultureInfo.InvariantCulture) EndTime = Convert.ToDouble(split[5], CultureInfo.InvariantCulture)
}; };

View File

@ -122,6 +122,10 @@ namespace osu.Game.Modes.UI
IBeatmapConverter<TObject> converter = CreateBeatmapConverter(); IBeatmapConverter<TObject> converter = CreateBeatmapConverter();
IBeatmapProcessor<TObject> processor = CreateBeatmapProcessor(); IBeatmapProcessor<TObject> processor = CreateBeatmapProcessor();
// Check if the beatmap can be converted
if (!converter.CanConvert(beatmap.Beatmap))
throw new BeatmapInvalidForModeException($"{nameof(Beatmap)} can't be converted to the current mode.");
// Convert the beatmap // Convert the beatmap
Beatmap = converter.Convert(beatmap.Beatmap); Beatmap = converter.Convert(beatmap.Beatmap);
@ -136,7 +140,6 @@ namespace osu.Game.Modes.UI
applyMods(beatmap.Mods.Value); applyMods(beatmap.Mods.Value);
} }
/// <summary> /// <summary>
/// Applies the active mods to this HitRenderer. /// Applies the active mods to this HitRenderer.
/// </summary> /// </summary>
@ -268,4 +271,12 @@ namespace osu.Game.Modes.UI
/// <returns>The Playfield.</returns> /// <returns>The Playfield.</returns>
protected abstract Playfield<TObject, TJudgement> CreatePlayfield(); protected abstract Playfield<TObject, TJudgement> CreatePlayfield();
} }
public class BeatmapInvalidForModeException : Exception
{
public BeatmapInvalidForModeException(string text)
: base(text)
{
}
}
} }

View File

@ -60,8 +60,8 @@ namespace osu.Game.Screens.Play
private PauseOverlay pauseOverlay; private PauseOverlay pauseOverlay;
private FailOverlay failOverlay; private FailOverlay failOverlay;
[BackgroundDependencyLoader] [BackgroundDependencyLoader(permitNulls: true)]
private void load(AudioManager audio, BeatmapDatabase beatmaps, OsuConfigManager config) private void load(AudioManager audio, BeatmapDatabase beatmaps, OsuConfigManager config, OsuGame osu)
{ {
dimLevel = config.GetBindable<int>(OsuConfig.DimLevel); dimLevel = config.GetBindable<int>(OsuConfig.DimLevel);
mouseWheelDisabled = config.GetBindable<bool>(OsuConfig.MouseDisableWheel); mouseWheelDisabled = config.GetBindable<bool>(OsuConfig.MouseDisableWheel);
@ -76,6 +76,19 @@ namespace osu.Game.Screens.Play
if (Beatmap == null) if (Beatmap == null)
throw new Exception("Beatmap was not loaded"); throw new Exception("Beatmap was not loaded");
try
{
// Try using the preferred user ruleset
ruleset = osu == null ? Beatmap.BeatmapInfo.Ruleset : osu.Ruleset;
HitRenderer = ruleset.CreateHitRendererWith(Beatmap);
}
catch (BeatmapInvalidForModeException)
{
// Default to the beatmap ruleset
ruleset = Beatmap.BeatmapInfo.Ruleset;
HitRenderer = ruleset.CreateHitRendererWith(Beatmap);
}
} }
catch (Exception e) catch (Exception e)
{ {
@ -102,12 +115,6 @@ namespace osu.Game.Screens.Play
sourceClock.Reset(); 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(); scoreProcessor = HitRenderer.CreateScoreProcessor();
hudOverlay = new StandardHudOverlay() hudOverlay = new StandardHudOverlay()