1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-27 00:23:01 +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.Modes.Catch.Objects;
using System.Collections.Generic;
using System;
using osu.Game.Modes.Objects;
namespace osu.Game.Modes.Catch.Beatmaps
{
internal class CatchBeatmapConverter : IBeatmapConverter<CatchBaseHit>
{
public IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(HitObject) };
public Beatmap<CatchBaseHit> Convert(Beatmap original)
{
return new Beatmap<CatchBaseHit>(original)

View File

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

View File

@ -9,11 +9,14 @@ using osu.Game.Modes.Osu.Objects.Drawables;
using System.Collections.Generic;
using osu.Game.Modes.Objects.Types;
using System.Linq;
using System;
namespace osu.Game.Modes.Osu.Beatmaps
{
internal class OsuBeatmapConverter : IBeatmapConverter<OsuHitObject>
{
public IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasPosition) };
public Beatmap<OsuHitObject> Convert(Beatmap original)
{
return new Beatmap<OsuHitObject>(original)
@ -56,8 +59,9 @@ namespace osu.Game.Modes.Osu.Beatmaps
{
StartTime = original.StartTime,
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>
private const float taiko_base_distance = 100;
public IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(HitObject) };
public Beatmap<TaikoHitObject> Convert(Beatmap original)
{
BeatmapInfo info = original.BeatmapInfo.DeepClone<BeatmapInfo>();

View File

@ -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 System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Modes.Objects;
namespace osu.Game.Beatmaps
@ -11,6 +14,12 @@ namespace osu.Game.Beatmaps
/// <typeparam name="T">The type of HitObject stored in the Beatmap.</typeparam>
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>
/// Converts a Beatmap to another mode.
/// </summary>
@ -18,4 +27,16 @@ namespace osu.Game.Beatmaps
/// <returns>The converted Beatmap.</returns>
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
using osu.Game.Modes.Objects.Types;
@ -8,10 +9,12 @@ namespace osu.Game.Modes.Objects.Legacy
/// <summary>
/// Legacy Spinner-type, used for parsing Beatmaps.
/// </summary>
internal class LegacySpinner : HitObject, IHasEndTime
internal class LegacySpinner : HitObject, IHasEndTime, IHasPosition
{
public double EndTime { get; set; }
public double Duration => EndTime - StartTime;
public Vector2 Position { get; set; }
}
}

View File

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

View File

@ -122,6 +122,10 @@ namespace osu.Game.Modes.UI
IBeatmapConverter<TObject> converter = CreateBeatmapConverter();
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
Beatmap = converter.Convert(beatmap.Beatmap);
@ -136,7 +140,6 @@ namespace osu.Game.Modes.UI
applyMods(beatmap.Mods.Value);
}
/// <summary>
/// Applies the active mods to this HitRenderer.
/// </summary>
@ -268,4 +271,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

@ -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 : osu.Ruleset;
HitRenderer = ruleset.CreateHitRendererWith(Beatmap);
}
catch (BeatmapInvalidForModeException)
{
// Default to the beatmap ruleset
ruleset = Beatmap.BeatmapInfo.Ruleset;
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()