1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 08:02:54 +08:00

Better beatmap conversion model.

This commit is contained in:
smoogipooo 2017-03-12 00:34:21 +09:00
parent 75ed7406e4
commit 592e05a2c8
26 changed files with 196 additions and 66 deletions

View File

@ -0,0 +1,21 @@
// 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.Beatmaps;
using osu.Game.Modes.Catch.Objects;
using System.Collections.Generic;
namespace osu.Game.Modes.Catch.Beatmaps
{
internal class CatchBeatmapConverter : IBeatmapConverter<CatchBaseHit>
{
public Beatmap<CatchBaseHit> Convert(Beatmap original)
{
return new Beatmap<CatchBaseHit>(original)
{
HitObjects = new List<CatchBaseHit>() // Todo: Convert HitObjects
};
}
}
}

View File

@ -3,7 +3,6 @@
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Modes.Catch.Objects; using osu.Game.Modes.Catch.Objects;
using osu.Game.Modes.Objects;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -17,8 +16,6 @@ namespace osu.Game.Modes.Catch
{ {
} }
protected override HitObjectConverter<CatchBaseHit> Converter => new CatchConverter();
protected override double CalculateInternal(Dictionary<String, String> categoryDifficulty) protected override double CalculateInternal(Dictionary<String, String> categoryDifficulty)
{ {
return 0; return 0;

View File

@ -4,6 +4,7 @@
using OpenTK.Input; using OpenTK.Input;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Modes.Catch.Beatmaps;
using osu.Game.Modes.Catch.UI; using osu.Game.Modes.Catch.UI;
using osu.Game.Modes.Objects; using osu.Game.Modes.Objects;
using osu.Game.Modes.UI; using osu.Game.Modes.UI;
@ -91,5 +92,10 @@ namespace osu.Game.Modes.Catch
public override HitObjectParser CreateHitObjectParser() => new NullHitObjectParser(); public override HitObjectParser CreateHitObjectParser() => new NullHitObjectParser();
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new CatchDifficultyCalculator(beatmap); public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new CatchDifficultyCalculator(beatmap);
public override IBeatmapConverter<CatchBaseHit> CreateBeatmapConverter<CatchBaseHit>()
{
return (IBeatmapConverter<CatchBaseHit>)new CatchBeatmapConverter();
}
} }
} }

View File

@ -3,7 +3,6 @@
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Modes.Catch.Objects; using osu.Game.Modes.Catch.Objects;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.UI; using osu.Game.Modes.UI;
@ -16,8 +15,6 @@ namespace osu.Game.Modes.Catch.UI
{ {
} }
protected override HitObjectConverter<CatchBaseHit> Converter => new CatchConverter();
protected override Playfield<CatchBaseHit> CreatePlayfield() => new CatchPlayfield(); protected override Playfield<CatchBaseHit> CreatePlayfield() => new CatchPlayfield();
protected override DrawableHitObject<CatchBaseHit> GetVisualRepresentation(CatchBaseHit h) => null;// new DrawableFruit(h); protected override DrawableHitObject<CatchBaseHit> GetVisualRepresentation(CatchBaseHit h) => null;// new DrawableFruit(h);

View File

@ -47,6 +47,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Beatmaps\CatchBeatmapConverter.cs" />
<Compile Include="CatchDifficultyCalculator.cs" /> <Compile Include="CatchDifficultyCalculator.cs" />
<Compile Include="Objects\CatchBaseHit.cs" /> <Compile Include="Objects\CatchBaseHit.cs" />
<Compile Include="Objects\CatchConverter.cs" /> <Compile Include="Objects\CatchConverter.cs" />

View File

@ -0,0 +1,21 @@
// 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.Beatmaps;
using osu.Game.Modes.Mania.Objects;
using System.Collections.Generic;
namespace osu.Game.Modes.Mania.Beatmaps
{
internal class ManiaBeatmapConverter : IBeatmapConverter<ManiaBaseHit>
{
public Beatmap<ManiaBaseHit> Convert(Beatmap original)
{
return new Beatmap<ManiaBaseHit>(original)
{
HitObjects = new List<ManiaBaseHit>() // Todo: Implement
};
}
}
}

View File

@ -3,7 +3,6 @@
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Modes.Mania.Objects; using osu.Game.Modes.Mania.Objects;
using osu.Game.Modes.Objects;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -20,8 +19,6 @@ namespace osu.Game.Modes.Mania
this.columns = columns; this.columns = columns;
} }
protected override HitObjectConverter<ManiaBaseHit> Converter => new ManiaConverter(columns);
protected override double CalculateInternal(Dictionary<String, String> categoryDifficulty) protected override double CalculateInternal(Dictionary<String, String> categoryDifficulty)
{ {
return 0; return 0;

View File

@ -3,6 +3,7 @@
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Modes.Mania.Beatmaps;
using osu.Game.Modes.Mania.UI; using osu.Game.Modes.Mania.UI;
using osu.Game.Modes.Objects; using osu.Game.Modes.Objects;
using osu.Game.Modes.UI; using osu.Game.Modes.UI;
@ -106,5 +107,10 @@ namespace osu.Game.Modes.Mania
public override HitObjectParser CreateHitObjectParser() => new NullHitObjectParser(); public override HitObjectParser CreateHitObjectParser() => new NullHitObjectParser();
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new ManiaDifficultyCalculator(beatmap); public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new ManiaDifficultyCalculator(beatmap);
public override IBeatmapConverter<ManiaBaseHit> CreateBeatmapConverter<ManiaBaseHit>()
{
return (IBeatmapConverter<ManiaBaseHit>)new ManiaBeatmapConverter();
}
} }
} }

View File

@ -3,7 +3,6 @@
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Modes.Mania.Objects; using osu.Game.Modes.Mania.Objects;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.UI; using osu.Game.Modes.UI;
@ -19,8 +18,6 @@ namespace osu.Game.Modes.Mania.UI
this.columns = columns; this.columns = columns;
} }
protected override HitObjectConverter<ManiaBaseHit> Converter => new ManiaConverter(columns);
protected override Playfield<ManiaBaseHit> CreatePlayfield() => new ManiaPlayfield(columns); protected override Playfield<ManiaBaseHit> CreatePlayfield() => new ManiaPlayfield(columns);
protected override DrawableHitObject<ManiaBaseHit> GetVisualRepresentation(ManiaBaseHit h) protected override DrawableHitObject<ManiaBaseHit> GetVisualRepresentation(ManiaBaseHit h)

View File

@ -47,6 +47,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Beatmaps\ManiaBeatmapConverter.cs" />
<Compile Include="ManiaDifficultyCalculator.cs" /> <Compile Include="ManiaDifficultyCalculator.cs" />
<Compile Include="Objects\Drawable\DrawableNote.cs" /> <Compile Include="Objects\Drawable\DrawableNote.cs" />
<Compile Include="Objects\HoldNote.cs" /> <Compile Include="Objects\HoldNote.cs" />
@ -85,6 +86,7 @@
<None Include="OpenTK.dll.config" /> <None Include="OpenTK.dll.config" />
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -1,35 +1,45 @@
// 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.Collections.Generic;
using osu.Game.Modes.Objects;
using osu.Game.Beatmaps;
using osu.Game.Modes.Osu.Objects.Drawables;
using OpenTK;
namespace osu.Game.Modes.Osu.Objects using OpenTK;
using osu.Game.Beatmaps;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.Objects;
using osu.Game.Modes.Osu.Objects.Drawables;
using System.Collections.Generic;
namespace osu.Game.Modes.Osu.Beatmaps
{ {
public class OsuHitObjectConverter : HitObjectConverter<OsuHitObject> internal class OsuBeatmapConverter : IBeatmapConverter<OsuHitObject>
{ {
public override List<OsuHitObject> Convert(Beatmap beatmap) public Beatmap<OsuHitObject> Convert(Beatmap original)
{ {
List<OsuHitObject> output = new List<OsuHitObject>(); return new Beatmap<OsuHitObject>(original)
{
HitObjects = convertHitObject(original.HitObjects, original.BeatmapInfo?.StackLeniency ?? 0.7f)
};
}
private List<OsuHitObject> convertHitObject(List<HitObject> hitObjects, float stackLeniency)
{
List<OsuHitObject> converted = new List<OsuHitObject>();
int combo = 0; int combo = 0;
foreach (HitObject h in beatmap.HitObjects) foreach (HitObject h in hitObjects)
{ {
if (h.NewCombo) combo = 0; if (h.NewCombo) combo = 0;
h.ComboIndex = combo++; h.ComboIndex = combo++;
output.Add(h as OsuHitObject); converted.Add(h as OsuHitObject);
} }
UpdateStacking(output, beatmap.BeatmapInfo?.StackLeniency ?? 0.7f); updateStacking(converted, stackLeniency);
return output; return converted;
} }
public static void UpdateStacking(List<OsuHitObject> hitObjects, float stackLeniency, int startIndex = 0, int endIndex = -1) private void updateStacking(List<OsuHitObject> hitObjects, float stackLeniency, int startIndex = 0, int endIndex = -1)
{ {
if (endIndex == -1) if (endIndex == -1)
endIndex = hitObjects.Count - 1; endIndex = hitObjects.Count - 1;
@ -171,6 +181,5 @@ namespace osu.Game.Modes.Osu.Objects
} }
} }
} }
} }
} }

View File

@ -5,7 +5,6 @@ using osu.Game.Beatmaps;
using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.Objects;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Game.Modes.Objects;
namespace osu.Game.Modes.Osu namespace osu.Game.Modes.Osu
{ {
@ -25,8 +24,6 @@ namespace osu.Game.Modes.Osu
{ {
} }
protected override HitObjectConverter<OsuHitObject> Converter => new OsuHitObjectConverter();
protected override void PreprocessHitObjects() protected override void PreprocessHitObjects()
{ {
foreach (var h in Objects) foreach (var h in Objects)

View File

@ -5,6 +5,7 @@ using OpenTK.Input;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Modes.Objects; using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.Beatmaps;
using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.Objects;
using osu.Game.Modes.Osu.UI; using osu.Game.Modes.Osu.UI;
using osu.Game.Modes.UI; using osu.Game.Modes.UI;
@ -118,5 +119,10 @@ namespace osu.Game.Modes.Osu
new KeyCounterMouse(MouseButton.Left), new KeyCounterMouse(MouseButton.Left),
new KeyCounterMouse(MouseButton.Right) new KeyCounterMouse(MouseButton.Right)
}; };
public override IBeatmapConverter<OsuHitObject> CreateBeatmapConverter<OsuHitObject>()
{
return (IBeatmapConverter<OsuHitObject>)new OsuBeatmapConverter();
}
} }
} }

View File

@ -2,7 +2,6 @@
// 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.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.Objects;
using osu.Game.Modes.Osu.Objects.Drawables; using osu.Game.Modes.Osu.Objects.Drawables;
@ -17,8 +16,6 @@ namespace osu.Game.Modes.Osu.UI
{ {
} }
protected override HitObjectConverter<OsuHitObject> Converter => new OsuHitObjectConverter();
protected override Playfield<OsuHitObject> CreatePlayfield() => new OsuPlayfield(); protected override Playfield<OsuHitObject> CreatePlayfield() => new OsuPlayfield();
protected override DrawableHitObject<OsuHitObject> GetVisualRepresentation(OsuHitObject h) protected override DrawableHitObject<OsuHitObject> GetVisualRepresentation(OsuHitObject h)

View File

@ -43,6 +43,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Beatmaps\OsuBeatmapConverter.cs" />
<Compile Include="Objects\BezierApproximator.cs" /> <Compile Include="Objects\BezierApproximator.cs" />
<Compile Include="Objects\CircularArcApproximator.cs" /> <Compile Include="Objects\CircularArcApproximator.cs" />
<Compile Include="Objects\Drawables\DrawableOsuHitObject.cs" /> <Compile Include="Objects\Drawables\DrawableOsuHitObject.cs" />
@ -80,7 +81,6 @@
<Compile Include="Objects\HitCircle.cs" /> <Compile Include="Objects\HitCircle.cs" />
<Compile Include="Objects\Drawables\DrawableHitCircle.cs" /> <Compile Include="Objects\Drawables\DrawableHitCircle.cs" />
<Compile Include="Objects\OsuHitObject.cs" /> <Compile Include="Objects\OsuHitObject.cs" />
<Compile Include="Objects\OsuHitObjectConverter.cs" />
<Compile Include="Objects\Slider.cs" /> <Compile Include="Objects\Slider.cs" />
<Compile Include="Objects\Spinner.cs" /> <Compile Include="Objects\Spinner.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />

View File

@ -0,0 +1,20 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using osu.Game.Modes.Taiko.Objects;
using System.Collections.Generic;
namespace osu.Game.Modes.Taiko.Beatmaps
{
internal class TaikoBeatmapConverter : IBeatmapConverter<TaikoBaseHit>
{
public Beatmap<TaikoBaseHit> Convert(Beatmap original)
{
return new Beatmap<TaikoBaseHit>(original)
{
HitObjects = new List<TaikoBaseHit>() // Todo: Implement
};
}
}
}

View File

@ -2,7 +2,6 @@
// 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.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Taiko.Objects; using osu.Game.Modes.Taiko.Objects;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -17,8 +16,6 @@ namespace osu.Game.Modes.Taiko
{ {
} }
protected override HitObjectConverter<TaikoBaseHit> Converter => new TaikoConverter();
protected override double CalculateInternal(Dictionary<String, String> categoryDifficulty) protected override double CalculateInternal(Dictionary<String, String> categoryDifficulty)
{ {
return 0; return 0;

View File

@ -5,6 +5,7 @@ using OpenTK.Input;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Modes.Objects; using osu.Game.Modes.Objects;
using osu.Game.Modes.Taiko.Beatmaps;
using osu.Game.Modes.Taiko.UI; using osu.Game.Modes.Taiko.UI;
using osu.Game.Modes.UI; using osu.Game.Modes.UI;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
@ -92,5 +93,10 @@ namespace osu.Game.Modes.Taiko
public override HitObjectParser CreateHitObjectParser() => new NullHitObjectParser(); public override HitObjectParser CreateHitObjectParser() => new NullHitObjectParser();
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new TaikoDifficultyCalculator(beatmap); public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new TaikoDifficultyCalculator(beatmap);
public override IBeatmapConverter<TaikoBaseHit> CreateBeatmapConverter<TaikoBaseHit>()
{
return (IBeatmapConverter<TaikoBaseHit>)new TaikoBeatmapConverter();
}
} }
} }

View File

@ -2,7 +2,6 @@
// 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.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Modes.Objects;
using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Objects.Drawables;
using osu.Game.Modes.Taiko.Objects; using osu.Game.Modes.Taiko.Objects;
using osu.Game.Modes.UI; using osu.Game.Modes.UI;
@ -16,8 +15,6 @@ namespace osu.Game.Modes.Taiko.UI
{ {
} }
protected override HitObjectConverter<TaikoBaseHit> Converter => new TaikoConverter();
protected override Playfield<TaikoBaseHit> CreatePlayfield() => new TaikoPlayfield(); protected override Playfield<TaikoBaseHit> CreatePlayfield() => new TaikoPlayfield();
protected override DrawableHitObject<TaikoBaseHit> GetVisualRepresentation(TaikoBaseHit h) => null;// new DrawableTaikoHit(h); protected override DrawableHitObject<TaikoBaseHit> GetVisualRepresentation(TaikoBaseHit h) => null;// new DrawableTaikoHit(h);

View File

@ -47,6 +47,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Beatmaps\TaikoBeatmapConverter.cs" />
<Compile Include="TaikoDifficultyCalculator.cs" /> <Compile Include="TaikoDifficultyCalculator.cs" />
<Compile Include="Objects\Drawable\DrawableTaikoHit.cs" /> <Compile Include="Objects\Drawable\DrawableTaikoHit.cs" />
<Compile Include="Objects\TaikoBaseHit.cs" /> <Compile Include="Objects\TaikoBaseHit.cs" />

View File

@ -1,23 +1,62 @@
// 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.Collections.Generic;
using System.Linq;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Game.Beatmaps.Timing; using osu.Game.Beatmaps.Timing;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Modes.Objects;
using osu.Game.Modes; using osu.Game.Modes;
using osu.Game.Modes.Objects;
using System.Collections.Generic;
using System.Linq;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
{ {
public class Beatmap public class BeatmapBase
{ {
public BeatmapInfo BeatmapInfo { get; set; } private BeatmapBase original;
public BeatmapBase(BeatmapBase original = null)
{
this.original = original;
}
private BeatmapInfo beatmapInfo;
public BeatmapInfo BeatmapInfo
{
get { return beatmapInfo ?? original?.BeatmapInfo; }
set { beatmapInfo = value; }
}
private List<ControlPoint> controlPoints;
public List<ControlPoint> ControlPoints
{
get { return controlPoints ?? original?.ControlPoints; }
set { controlPoints = value; }
}
private List<Color4> comboColors;
public List<Color4> ComboColors
{
get { return comboColors ?? original?.ComboColors; }
set { comboColors = value; }
}
public BeatmapMetadata Metadata => BeatmapInfo?.Metadata ?? BeatmapInfo?.BeatmapSet?.Metadata; public BeatmapMetadata Metadata => BeatmapInfo?.Metadata ?? BeatmapInfo?.BeatmapSet?.Metadata;
public List<HitObject> HitObjects { get; set; } }
public List<ControlPoint> ControlPoints { get; set; }
public List<Color4> ComboColors { get; set; } /// <summary>
/// A generic beatmap that does not contain HitObjects.
/// </summary>
public class Beatmap<T> : BeatmapBase
where T : HitObject
{
public List<T> HitObjects;
public Beatmap(BeatmapBase original = null)
: base(original)
{
}
public double BPMMaximum => 60000 / (ControlPoints?.Where(c => c.BeatLength != 0).OrderBy(c => c.BeatLength).FirstOrDefault() ?? ControlPoint.Default).BeatLength; public double BPMMaximum => 60000 / (ControlPoints?.Where(c => c.BeatLength != 0).OrderBy(c => c.BeatLength).FirstOrDefault() ?? ControlPoint.Default).BeatLength;
public double BPMMinimum => 60000 / (ControlPoints?.Where(c => c.BeatLength != 0).OrderByDescending(c => c.BeatLength).FirstOrDefault() ?? ControlPoint.Default).BeatLength; public double BPMMinimum => 60000 / (ControlPoints?.Where(c => c.BeatLength != 0).OrderByDescending(c => c.BeatLength).FirstOrDefault() ?? ControlPoint.Default).BeatLength;
public double BPMMode => BPMAt(ControlPoints.Where(c => c.BeatLength != 0).GroupBy(c => c.BeatLength).OrderByDescending(grp => grp.Count()).First().First().Time); public double BPMMode => BPMAt(ControlPoints.Where(c => c.BeatLength != 0).GroupBy(c => c.BeatLength).OrderByDescending(grp => grp.Count()).First().First().Time);
@ -58,7 +97,20 @@ namespace osu.Game.Beatmaps
return timingPoint ?? ControlPoint.Default; return timingPoint ?? ControlPoint.Default;
} }
}
public class Beatmap : Beatmap<HitObject>
{
public Beatmap(BeatmapBase original = null)
: base(original)
{
}
public double CalculateStarDifficulty() => Ruleset.GetRuleset(BeatmapInfo.Mode).CreateDifficultyCalculator(this).Calculate(); public double CalculateStarDifficulty() => Ruleset.GetRuleset(BeatmapInfo.Mode).CreateDifficultyCalculator(this).Calculate();
public Beatmap<T> ConvertTo<T>() where T : HitObject
{
return Ruleset.GetRuleset(BeatmapInfo.Mode).CreateBeatmapConverter<T>().Convert(this);
}
} }
} }

View File

@ -35,11 +35,9 @@ namespace osu.Game.Beatmaps
{ {
protected List<T> Objects; protected List<T> Objects;
protected abstract HitObjectConverter<T> Converter { get; }
protected DifficultyCalculator(Beatmap beatmap) protected DifficultyCalculator(Beatmap beatmap)
{ {
Objects = Converter.Convert(beatmap); Objects = beatmap.ConvertTo<T>().HitObjects;
PreprocessHitObjects(); PreprocessHitObjects();
} }

View File

@ -0,0 +1,12 @@
// 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
{
public interface IBeatmapConverter<T> where T : HitObject
{
Beatmap<T> Convert(Beatmap original);
}
}

View File

@ -37,6 +37,8 @@ namespace osu.Game.Modes
public abstract DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap); public abstract DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap);
public abstract IBeatmapConverter<T> CreateBeatmapConverter<T>() where T : HitObject;
public static void Register(Ruleset ruleset) => availableRulesets.TryAdd(ruleset.PlayMode, ruleset.GetType()); public static void Register(Ruleset ruleset) => availableRulesets.TryAdd(ruleset.PlayMode, ruleset.GetType());
protected abstract PlayMode PlayMode { get; } protected abstract PlayMode PlayMode { get; }

View File

@ -32,19 +32,9 @@ namespace osu.Game.Modes.UI
/// </summary> /// </summary>
protected abstract int JudgementCount { get; } protected abstract int JudgementCount { get; }
/// <summary>
/// The beatmap this HitRenderer is initialized with.
/// </summary>
protected readonly Beatmap Beatmap;
private int maxJudgements; private int maxJudgements;
private int countJudgements; private int countJudgements;
protected HitRenderer(Beatmap beatmap)
{
Beatmap = beatmap;
}
protected override void LoadComplete() protected override void LoadComplete()
{ {
base.LoadComplete(); base.LoadComplete();
@ -69,9 +59,6 @@ namespace osu.Game.Modes.UI
public override Func<Vector2, Vector2> MapPlayfieldToScreenSpace => Playfield.ScaledContent.ToScreenSpace; public override Func<Vector2, Vector2> MapPlayfieldToScreenSpace => Playfield.ScaledContent.ToScreenSpace;
public IEnumerable<DrawableHitObject> DrawableObjects => Playfield.HitObjects.Children; public IEnumerable<DrawableHitObject> DrawableObjects => Playfield.HitObjects.Children;
protected abstract HitObjectConverter<TObject> Converter { get; }
protected virtual List<TObject> Convert(Beatmap beatmap) => Converter.Convert(beatmap);
protected override Container<Drawable> Content => content; protected override Container<Drawable> Content => content;
private int judgementCount; private int judgementCount;
@ -79,11 +66,14 @@ namespace osu.Game.Modes.UI
protected Playfield<TObject> Playfield; protected Playfield<TObject> Playfield;
protected Beatmap<TObject> Beatmap;
private Container content; private Container content;
protected HitRenderer(Beatmap beatmap) protected HitRenderer(Beatmap beatmap)
: base(beatmap)
{ {
Beatmap = beatmap.ConvertTo<TObject>();
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
InputManager.Add(content = new Container InputManager.Add(content = new Container
@ -107,7 +97,7 @@ namespace osu.Game.Modes.UI
private void loadObjects() private void loadObjects()
{ {
foreach (TObject h in Convert(Beatmap)) foreach (TObject h in Beatmap.HitObjects)
{ {
DrawableHitObject<TObject> drawableObject = GetVisualRepresentation(h); DrawableHitObject<TObject> drawableObject = GetVisualRepresentation(h);

View File

@ -73,6 +73,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="Beatmaps\Drawables\BeatmapBackgroundSprite.cs" /> <Compile Include="Beatmaps\Drawables\BeatmapBackgroundSprite.cs" />
<Compile Include="Beatmaps\DifficultyCalculator.cs" /> <Compile Include="Beatmaps\DifficultyCalculator.cs" />
<Compile Include="Beatmaps\IBeatmapCoverter.cs" />
<Compile Include="Database\ScoreDatabase.cs" /> <Compile Include="Database\ScoreDatabase.cs" />
<Compile Include="Graphics\Backgrounds\Triangles.cs" /> <Compile Include="Graphics\Backgrounds\Triangles.cs" />
<Compile Include="Graphics\Cursor\CursorTrail.cs" /> <Compile Include="Graphics\Cursor\CursorTrail.cs" />