mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 12:57:36 +08:00
Merge pull request #2491 from smoogipoo/beatmap-conversion-rework
Rework beatmap conversion process to use IBeatmap
This commit is contained in:
commit
0afe33d32f
@ -14,7 +14,7 @@ using osu.Game.Tests.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
public class CatchBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
|
||||
public class CatchBeatmapConversionTest : BeatmapConversionTest<TestCatchRuleset, ConvertValue>
|
||||
{
|
||||
protected override string ResourceAssembly => "osu.Game.Rulesets.Catch";
|
||||
|
||||
@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
}
|
||||
}
|
||||
|
||||
protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new CatchBeatmapConverter();
|
||||
protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap);
|
||||
}
|
||||
|
||||
public struct ConvertValue : IEquatable<ConvertValue>
|
||||
@ -64,4 +64,8 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
=> Precision.AlmostEquals(StartTime, other.StartTime, conversion_lenience)
|
||||
&& Precision.AlmostEquals(Position, other.Position, conversion_lenience);
|
||||
}
|
||||
|
||||
public class TestCatchRuleset : CatchRuleset
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,11 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
{
|
||||
public class CatchBeatmapConverter : BeatmapConverter<CatchHitObject>
|
||||
{
|
||||
public CatchBeatmapConverter(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
|
||||
|
||||
protected override IEnumerable<CatchHitObject> ConvertHitObject(HitObject obj, IBeatmap beatmap)
|
||||
|
@ -12,16 +12,21 @@ using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
{
|
||||
public class CatchBeatmapProcessor : BeatmapProcessor<CatchHitObject>
|
||||
public class CatchBeatmapProcessor : BeatmapProcessor
|
||||
{
|
||||
public override void PostProcess(Beatmap<CatchHitObject> beatmap)
|
||||
public CatchBeatmapProcessor(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
initialiseHyperDash(beatmap.HitObjects);
|
||||
}
|
||||
|
||||
base.PostProcess(beatmap);
|
||||
public override void PostProcess()
|
||||
{
|
||||
initialiseHyperDash((List<CatchHitObject>)Beatmap.HitObjects);
|
||||
|
||||
base.PostProcess();
|
||||
|
||||
int index = 0;
|
||||
foreach (var obj in beatmap.HitObjects)
|
||||
foreach (var obj in Beatmap.HitObjects.OfType<CatchHitObject>())
|
||||
obj.IndexInBeatmap = index++;
|
||||
}
|
||||
|
||||
|
@ -2,20 +2,16 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch
|
||||
{
|
||||
public class CatchDifficultyCalculator : DifficultyCalculator<CatchHitObject>
|
||||
public class CatchDifficultyCalculator : DifficultyCalculator
|
||||
{
|
||||
public CatchDifficultyCalculator(IBeatmap beatmap) : base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
public override double Calculate(Dictionary<string, double> categoryDifficulty = null) => 0;
|
||||
|
||||
protected override BeatmapConverter<CatchHitObject> CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter();
|
||||
}
|
||||
}
|
||||
|
@ -13,12 +13,15 @@ using osu.Framework.Input.Bindings;
|
||||
using osu.Game.Rulesets.Catch.Replays;
|
||||
using osu.Game.Rulesets.Replays.Types;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch
|
||||
{
|
||||
public class CatchRuleset : Ruleset
|
||||
{
|
||||
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchRulesetContainer(this, beatmap, isForCurrentRuleset);
|
||||
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) => new CatchRulesetContainer(this, beatmap);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap);
|
||||
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap);
|
||||
|
||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||
{
|
||||
|
@ -6,10 +6,11 @@ using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Catch.UI;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using System;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Mods
|
||||
{
|
||||
public class CatchModHardRock : ModHardRock, IApplicableToHitObject<CatchHitObject>
|
||||
public class CatchModHardRock : ModHardRock, IApplicableToHitObject
|
||||
{
|
||||
public override double ScoreMultiplier => 1.12;
|
||||
public override bool Ranked => true;
|
||||
@ -17,9 +18,11 @@ namespace osu.Game.Rulesets.Catch.Mods
|
||||
private float lastStartX;
|
||||
private int lastStartTime;
|
||||
|
||||
public void ApplyToHitObject(CatchHitObject hitObject)
|
||||
public void ApplyToHitObject(HitObject hitObject)
|
||||
{
|
||||
float position = hitObject.X;
|
||||
var catchObject = (CatchHitObject)hitObject;
|
||||
|
||||
float position = catchObject.X;
|
||||
int startTime = (int)hitObject.StartTime;
|
||||
|
||||
if (lastStartX == 0)
|
||||
@ -60,7 +63,7 @@ namespace osu.Game.Rulesets.Catch.Mods
|
||||
position += rand;
|
||||
}
|
||||
|
||||
hitObject.X = position;
|
||||
catchObject.X = position;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -79,7 +82,7 @@ namespace osu.Game.Rulesets.Catch.Mods
|
||||
}
|
||||
}
|
||||
|
||||
hitObject.X = position;
|
||||
catchObject.X = position;
|
||||
|
||||
lastStartX = position;
|
||||
lastStartTime = startTime;
|
||||
|
@ -4,7 +4,6 @@
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Input.Handlers;
|
||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
||||
using osu.Game.Rulesets.Catch.Replays;
|
||||
@ -20,8 +19,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
{
|
||||
public class CatchRulesetContainer : ScrollingRulesetContainer<CatchPlayfield, CatchHitObject>
|
||||
{
|
||||
public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(ruleset, beatmap, isForCurrentRuleset)
|
||||
public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
: base(ruleset, beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
@ -29,10 +28,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay);
|
||||
|
||||
protected override BeatmapProcessor<CatchHitObject> CreateBeatmapProcessor() => new CatchBeatmapProcessor();
|
||||
|
||||
protected override BeatmapConverter<CatchHitObject> CreateBeatmapConverter() => new CatchBeatmapConverter();
|
||||
|
||||
protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, GetVisualRepresentation);
|
||||
|
||||
public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
|
||||
|
@ -14,17 +14,14 @@ using osu.Game.Tests.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests
|
||||
{
|
||||
public class ManiaBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
|
||||
public class ManiaBeatmapConversionTest : BeatmapConversionTest<TestManiaRuleset, ConvertValue>
|
||||
{
|
||||
protected override string ResourceAssembly => "osu.Game.Rulesets.Mania";
|
||||
|
||||
private bool isForCurrentRuleset;
|
||||
|
||||
[NonParallelizable]
|
||||
[TestCase("basic", false)]
|
||||
public void Test(string name, bool isForCurrentRuleset)
|
||||
[TestCase("basic")]
|
||||
public new void Test(string name)
|
||||
{
|
||||
this.isForCurrentRuleset = isForCurrentRuleset;
|
||||
base.Test(name);
|
||||
}
|
||||
|
||||
@ -38,7 +35,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
};
|
||||
}
|
||||
|
||||
protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(isForCurrentRuleset, beatmap);
|
||||
protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
|
||||
}
|
||||
|
||||
public struct ConvertValue : IEquatable<ConvertValue>
|
||||
@ -57,4 +54,8 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
&& Precision.AlmostEquals(EndTime, other.EndTime, conversion_lenience)
|
||||
&& Column == other.Column;
|
||||
}
|
||||
|
||||
public class TestManiaRuleset : ManiaRuleset
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -33,18 +33,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
|
||||
private ManiaBeatmap beatmap;
|
||||
|
||||
public ManiaBeatmapConverter(bool isForCurrentRuleset, IBeatmap original)
|
||||
public ManiaBeatmapConverter(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
IsForCurrentRuleset = isForCurrentRuleset;
|
||||
IsForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(new ManiaRuleset().RulesetInfo);
|
||||
|
||||
var roundedCircleSize = Math.Round(original.BeatmapInfo.BaseDifficulty.CircleSize);
|
||||
var roundedOverallDifficulty = Math.Round(original.BeatmapInfo.BaseDifficulty.OverallDifficulty);
|
||||
var roundedCircleSize = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.CircleSize);
|
||||
var roundedOverallDifficulty = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);
|
||||
|
||||
if (isForCurrentRuleset)
|
||||
if (IsForCurrentRuleset)
|
||||
TargetColumns = (int)Math.Max(1, roundedCircleSize);
|
||||
else
|
||||
{
|
||||
float percentSliderOrSpinner = (float)original.HitObjects.Count(h => h is IHasEndTime) / original.HitObjects.Count();
|
||||
float percentSliderOrSpinner = (float)beatmap.HitObjects.Count(h => h is IHasEndTime) / beatmap.HitObjects.Count();
|
||||
if (percentSliderOrSpinner < 0.2)
|
||||
TargetColumns = 7;
|
||||
else if (percentSliderOrSpinner < 0.3 || roundedCircleSize >= 5)
|
||||
@ -58,6 +59,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
|
||||
protected override Beatmap<ManiaHitObject> ConvertBeatmap(IBeatmap original)
|
||||
{
|
||||
|
||||
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
|
||||
|
||||
int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate);
|
||||
|
@ -10,7 +10,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
internal class ManiaDifficultyCalculator : DifficultyCalculator<ManiaHitObject>
|
||||
internal class ManiaDifficultyCalculator : DifficultyCalculator
|
||||
{
|
||||
private const double star_scaling_factor = 0.018;
|
||||
|
||||
@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
int columnCount = (Beatmap as ManiaBeatmap)?.TotalColumns ?? 7;
|
||||
|
||||
foreach (var hitObject in Beatmap.HitObjects)
|
||||
difficultyHitObjects.Add(new ManiaHitObjectDifficulty(hitObject, columnCount));
|
||||
difficultyHitObjects.Add(new ManiaHitObjectDifficulty((ManiaHitObject)hitObject, columnCount));
|
||||
|
||||
// Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure.
|
||||
difficultyHitObjects.Sort((a, b) => a.BaseHitObject.StartTime.CompareTo(b.BaseHitObject.StartTime));
|
||||
@ -140,7 +140,5 @@ namespace osu.Game.Rulesets.Mania
|
||||
|
||||
return difficulty;
|
||||
}
|
||||
|
||||
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(true, beatmap);
|
||||
}
|
||||
}
|
||||
|
@ -15,12 +15,14 @@ using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Mania.Replays;
|
||||
using osu.Game.Rulesets.Replays.Types;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
public class ManiaRuleset : Ruleset
|
||||
{
|
||||
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new ManiaRulesetContainer(this, beatmap, isForCurrentRuleset);
|
||||
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) => new ManiaRulesetContainer(this, beatmap);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
|
||||
|
||||
public override IEnumerable<Mod> ConvertLegacyMods(LegacyMods mods)
|
||||
{
|
||||
|
@ -3,19 +3,18 @@
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Mods
|
||||
{
|
||||
public abstract class ManiaKeyMod : Mod, IApplicableToBeatmapConverter<ManiaHitObject>
|
||||
public abstract class ManiaKeyMod : Mod, IApplicableToBeatmapConverter
|
||||
{
|
||||
public override string ShortenedName => Name;
|
||||
public abstract int KeyCount { get; }
|
||||
public override double ScoreMultiplier => 1; // TODO: Implement the mania key mod score multiplier
|
||||
public override bool Ranked => true;
|
||||
|
||||
public void ApplyToBeatmapConverter(BeatmapConverter<ManiaHitObject> beatmapConverter)
|
||||
public void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter)
|
||||
{
|
||||
var mbc = (ManiaBeatmapConverter)beatmapConverter;
|
||||
|
||||
|
@ -11,19 +11,23 @@ using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Mods
|
||||
{
|
||||
public class ManiaModDualStages : Mod, IPlayfieldTypeMod, IApplicableToBeatmapConverter<ManiaHitObject>, IApplicableToRulesetContainer<ManiaHitObject>
|
||||
public class ManiaModDualStages : Mod, IPlayfieldTypeMod, IApplicableToBeatmapConverter, IApplicableToRulesetContainer<ManiaHitObject>
|
||||
{
|
||||
public override string Name => "Dual Stages";
|
||||
public override string ShortenedName => "DS";
|
||||
public override string Description => @"Double the stages, double the fun!";
|
||||
public override double ScoreMultiplier => 0;
|
||||
|
||||
public void ApplyToBeatmapConverter(BeatmapConverter<ManiaHitObject> beatmapConverter)
|
||||
private bool isForCurrentRuleset;
|
||||
|
||||
public void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter)
|
||||
{
|
||||
var mbc = (ManiaBeatmapConverter)beatmapConverter;
|
||||
|
||||
isForCurrentRuleset = mbc.IsForCurrentRuleset;
|
||||
|
||||
// Although this can work, for now let's not allow keymods for mania-specific beatmaps
|
||||
if (mbc.IsForCurrentRuleset)
|
||||
if (isForCurrentRuleset)
|
||||
return;
|
||||
|
||||
mbc.TargetColumns *= 2;
|
||||
@ -34,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
||||
var mrc = (ManiaRulesetContainer)rulesetContainer;
|
||||
|
||||
// Although this can work, for now let's not allow keymods for mania-specific beatmaps
|
||||
if (mrc.IsForCurrentRuleset)
|
||||
if (isForCurrentRuleset)
|
||||
return;
|
||||
|
||||
var newDefinitions = new List<StageDefinition>();
|
||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Replays
|
||||
public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap)
|
||||
{
|
||||
// We don't need to fully convert, just create the converter
|
||||
var converter = new ManiaBeatmapConverter(beatmap.BeatmapInfo.RulesetID == 3, beatmap);
|
||||
var converter = new ManiaBeatmapConverter(beatmap);
|
||||
|
||||
// NB: Via co-op mod, osu-stable can have two stages with floor(col/2) and ceil(col/2) columns. This will need special handling
|
||||
// elsewhere in the game if we do choose to support the old co-op mod anyway. For now, assume that there is only one stage.
|
||||
|
@ -36,8 +36,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
|
||||
public IEnumerable<BarLine> BarLines;
|
||||
|
||||
public ManiaRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(ruleset, beatmap, isForCurrentRuleset)
|
||||
public ManiaRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
: base(ruleset, beatmap)
|
||||
{
|
||||
// Generate the bar lines
|
||||
double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue;
|
||||
@ -85,8 +85,6 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
|
||||
public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Variant);
|
||||
|
||||
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter() => new ManiaBeatmapConverter(IsForCurrentRuleset, WorkingBeatmap.Beatmap);
|
||||
|
||||
protected override DrawableHitObject<ManiaHitObject> GetVisualRepresentation(ManiaHitObject h)
|
||||
{
|
||||
ManiaAction action = Playfield.Columns.ElementAt(h.Column).Action;
|
||||
|
@ -15,7 +15,7 @@ using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests
|
||||
{
|
||||
public class OsuBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
|
||||
public class OsuBeatmapConversionTest : BeatmapConversionTest<TestOsuRuleset, ConvertValue>
|
||||
{
|
||||
protected override string ResourceAssembly => "osu.Game.Rulesets.Osu";
|
||||
|
||||
@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
};
|
||||
}
|
||||
|
||||
protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new OsuBeatmapConverter();
|
||||
protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap);
|
||||
}
|
||||
|
||||
public struct ConvertValue : IEquatable<ConvertValue>
|
||||
@ -67,4 +67,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
&& Precision.AlmostEquals(EndX, other.EndX, conversion_lenience)
|
||||
&& Precision.AlmostEquals(EndY, other.EndY, conversion_lenience);
|
||||
}
|
||||
|
||||
public class TestOsuRuleset : OsuRuleset
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,11 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||
{
|
||||
internal class OsuBeatmapConverter : BeatmapConverter<OsuHitObject>
|
||||
{
|
||||
public OsuBeatmapConverter(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasPosition) };
|
||||
|
||||
protected override IEnumerable<OsuHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap)
|
||||
|
@ -8,12 +8,17 @@ using osu.Game.Rulesets.Osu.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||
{
|
||||
internal class OsuBeatmapProcessor : BeatmapProcessor<OsuHitObject>
|
||||
internal class OsuBeatmapProcessor : BeatmapProcessor
|
||||
{
|
||||
public override void PostProcess(Beatmap<OsuHitObject> beatmap)
|
||||
public OsuBeatmapProcessor(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
applyStacking(beatmap);
|
||||
base.PostProcess(beatmap);
|
||||
}
|
||||
|
||||
public override void PostProcess()
|
||||
{
|
||||
applyStacking((Beatmap<OsuHitObject>)Beatmap);
|
||||
base.PostProcess();
|
||||
}
|
||||
|
||||
private void applyStacking(Beatmap<OsuHitObject> beatmap)
|
||||
|
@ -11,8 +11,8 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
public class OsuEditRulesetContainer : OsuRulesetContainer
|
||||
{
|
||||
public OsuEditRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(ruleset, beatmap, isForCurrentRuleset)
|
||||
public OsuEditRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
: base(ruleset, beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
}
|
||||
|
||||
protected override RulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => new OsuEditRulesetContainer(ruleset, beatmap, true);
|
||||
protected override RulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => new OsuEditRulesetContainer(ruleset, beatmap);
|
||||
|
||||
protected override IReadOnlyList<ICompositionTool> CompositionTools => new ICompositionTool[]
|
||||
{
|
||||
|
@ -5,20 +5,23 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.UI;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Mods
|
||||
{
|
||||
public class OsuModHardRock : ModHardRock, IApplicableToHitObject<OsuHitObject>
|
||||
public class OsuModHardRock : ModHardRock, IApplicableToHitObject
|
||||
{
|
||||
public override double ScoreMultiplier => 1.06;
|
||||
public override bool Ranked => true;
|
||||
|
||||
public void ApplyToHitObject(OsuHitObject hitObject)
|
||||
public void ApplyToHitObject(HitObject hitObject)
|
||||
{
|
||||
hitObject.Position = new Vector2(hitObject.Position.X, OsuPlayfield.BASE_SIZE.Y - hitObject.Y);
|
||||
var osuObject = (OsuHitObject)hitObject;
|
||||
|
||||
osuObject.Position = new Vector2(osuObject.Position.X, OsuPlayfield.BASE_SIZE.Y - osuObject.Y);
|
||||
|
||||
var slider = hitObject as Slider;
|
||||
if (slider == null)
|
||||
|
@ -5,14 +5,13 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing;
|
||||
using osu.Game.Rulesets.Osu.OsuDifficulty.Skills;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.OsuDifficulty
|
||||
{
|
||||
public class OsuDifficultyCalculator : DifficultyCalculator<OsuHitObject>
|
||||
public class OsuDifficultyCalculator : DifficultyCalculator
|
||||
{
|
||||
private const int section_length = 400;
|
||||
private const double difficulty_multiplier = 0.0675;
|
||||
@ -27,14 +26,9 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty
|
||||
{
|
||||
}
|
||||
|
||||
protected override void PreprocessHitObjects()
|
||||
{
|
||||
new OsuBeatmapProcessor().PostProcess(Beatmap);
|
||||
}
|
||||
|
||||
public override double Calculate(Dictionary<string, double> categoryDifficulty = null)
|
||||
{
|
||||
OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap(Beatmap.HitObjects, TimeRate);
|
||||
OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap((List<OsuHitObject>)Beatmap.HitObjects, TimeRate);
|
||||
Skill[] skills =
|
||||
{
|
||||
new Aim(),
|
||||
@ -72,7 +66,5 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty
|
||||
|
||||
return starRating;
|
||||
}
|
||||
|
||||
protected override BeatmapConverter<OsuHitObject> CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter();
|
||||
}
|
||||
}
|
||||
|
@ -22,12 +22,15 @@ using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Replays;
|
||||
using osu.Game.Rulesets.Replays.Types;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu
|
||||
{
|
||||
public class OsuRuleset : Ruleset
|
||||
{
|
||||
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new OsuRulesetContainer(this, beatmap, isForCurrentRuleset);
|
||||
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) => new OsuRulesetContainer(this, beatmap);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap);
|
||||
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new OsuBeatmapProcessor(beatmap);
|
||||
|
||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||
{
|
||||
|
@ -6,14 +6,13 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Scoring
|
||||
{
|
||||
public class OsuPerformanceCalculator : PerformanceCalculator<OsuHitObject>
|
||||
public class OsuPerformanceCalculator : PerformanceCalculator
|
||||
{
|
||||
private readonly int countHitCircles;
|
||||
private readonly int beatmapMaxCombo;
|
||||
@ -32,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
||||
{
|
||||
countHitCircles = Beatmap.HitObjects.Count(h => h is HitCircle);
|
||||
|
||||
beatmapMaxCombo = Beatmap.HitObjects.Count;
|
||||
beatmapMaxCombo = Beatmap.HitObjects.Count();
|
||||
beatmapMaxCombo += Beatmap.HitObjects.OfType<Slider>().Sum(s => s.NestedHitObjects.Count) + 1;
|
||||
}
|
||||
|
||||
@ -193,7 +192,5 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
||||
|
||||
private double totalHits => count300 + count100 + count50 + countMiss;
|
||||
private double totalSuccessfulHits => count300 + count100 + count50;
|
||||
|
||||
protected override BeatmapConverter<OsuHitObject> CreateBeatmapConverter() => new OsuBeatmapConverter();
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ using OpenTK;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Input.Handlers;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Osu.Replays;
|
||||
@ -21,17 +20,13 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
{
|
||||
public class OsuRulesetContainer : RulesetContainer<OsuHitObject>
|
||||
{
|
||||
public OsuRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(ruleset, beatmap, isForCurrentRuleset)
|
||||
public OsuRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
: base(ruleset, beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor(this);
|
||||
|
||||
protected override BeatmapConverter<OsuHitObject> CreateBeatmapConverter() => new OsuBeatmapConverter();
|
||||
|
||||
protected override BeatmapProcessor<OsuHitObject> CreateBeatmapProcessor() => new OsuBeatmapProcessor();
|
||||
|
||||
protected override Playfield CreatePlayfield() => new OsuPlayfield();
|
||||
|
||||
public override PassThroughInputManager CreateInputManager() => new OsuInputManager(Ruleset.RulesetInfo);
|
||||
|
@ -14,18 +14,15 @@ using osu.Game.Tests.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Tests
|
||||
{
|
||||
public class TaikoBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
|
||||
public class TaikoBeatmapConversionTest : BeatmapConversionTest<TestTaikoRuleset, ConvertValue>
|
||||
{
|
||||
protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko";
|
||||
|
||||
private bool isForCurrentRuleset;
|
||||
|
||||
[NonParallelizable]
|
||||
[TestCase("basic", false), Ignore("See: https://github.com/ppy/osu/issues/2152")]
|
||||
[TestCase("slider-generating-drumroll", false)]
|
||||
public void Test(string name, bool isForCurrentRuleset)
|
||||
public new void Test(string name)
|
||||
{
|
||||
this.isForCurrentRuleset = isForCurrentRuleset;
|
||||
base.Test(name);
|
||||
}
|
||||
|
||||
@ -43,7 +40,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
};
|
||||
}
|
||||
|
||||
protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(isForCurrentRuleset);
|
||||
protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap);
|
||||
}
|
||||
|
||||
public struct ConvertValue : IEquatable<ConvertValue>
|
||||
@ -70,4 +67,8 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
&& IsSwell == other.IsSwell
|
||||
&& IsStrong == other.IsStrong;
|
||||
}
|
||||
|
||||
public class TestTaikoRuleset : TaikoRuleset
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
private Container playfieldContainer;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(RulesetStore rulesets)
|
||||
private void load()
|
||||
{
|
||||
AddStep("Hit!", () => addHitJudgement(false));
|
||||
AddStep("Kiai hit", () => addHitJudgement(true));
|
||||
@ -73,6 +73,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
Title = @"Sample Beatmap",
|
||||
AuthorString = @"peppy",
|
||||
},
|
||||
Ruleset = new TaikoRuleset().RulesetInfo
|
||||
},
|
||||
ControlPointInfo = controlPointInfo
|
||||
});
|
||||
@ -86,7 +87,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 768,
|
||||
Clock = new FramedClock(rateAdjustClock),
|
||||
Children = new[] { rulesetContainer = new TaikoRulesetContainer(rulesets.GetRuleset(1).CreateInstance(), beatmap, true) }
|
||||
Children = new[] { rulesetContainer = new TaikoRulesetContainer(new TaikoRuleset(), beatmap) }
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,10 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
|
||||
|
||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(HitObject) };
|
||||
|
||||
public TaikoBeatmapConverter(bool isForCurrentRuleset)
|
||||
public TaikoBeatmapConverter(IBeatmap beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
this.isForCurrentRuleset = isForCurrentRuleset;
|
||||
isForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(new TaikoRuleset().RulesetInfo);
|
||||
}
|
||||
|
||||
protected override Beatmap<TaikoHitObject> ConvertBeatmap(IBeatmap original)
|
||||
|
@ -2,14 +2,13 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko
|
||||
{
|
||||
internal class TaikoDifficultyCalculator : DifficultyCalculator<TaikoHitObject>
|
||||
internal class TaikoDifficultyCalculator : DifficultyCalculator
|
||||
{
|
||||
private const double star_scaling_factor = 0.04125;
|
||||
|
||||
@ -41,7 +40,7 @@ namespace osu.Game.Rulesets.Taiko
|
||||
difficultyHitObjects.Clear();
|
||||
|
||||
foreach (var hitObject in Beatmap.HitObjects)
|
||||
difficultyHitObjects.Add(new TaikoHitObjectDifficulty(hitObject));
|
||||
difficultyHitObjects.Add(new TaikoHitObjectDifficulty((TaikoHitObject)hitObject));
|
||||
|
||||
// Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure.
|
||||
difficultyHitObjects.Sort((a, b) => a.BaseHitObject.StartTime.CompareTo(b.BaseHitObject.StartTime));
|
||||
@ -132,7 +131,5 @@ namespace osu.Game.Rulesets.Taiko
|
||||
|
||||
return difficulty;
|
||||
}
|
||||
|
||||
protected override BeatmapConverter<TaikoHitObject> CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(true);
|
||||
}
|
||||
}
|
||||
|
@ -13,12 +13,14 @@ using osu.Framework.Input.Bindings;
|
||||
using osu.Game.Rulesets.Replays.Types;
|
||||
using osu.Game.Rulesets.Taiko.Replays;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko
|
||||
{
|
||||
public class TaikoRuleset : Ruleset
|
||||
{
|
||||
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new TaikoRulesetContainer(this, beatmap, isForCurrentRuleset);
|
||||
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) => new TaikoRulesetContainer(this, beatmap);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap);
|
||||
|
||||
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
|
||||
{
|
||||
|
@ -8,7 +8,6 @@ using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Replays;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Taiko.Scoring;
|
||||
@ -24,8 +23,8 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
{
|
||||
public class TaikoRulesetContainer : ScrollingRulesetContainer<TaikoPlayfield, TaikoHitObject>
|
||||
{
|
||||
public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(ruleset, beatmap, isForCurrentRuleset)
|
||||
public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
: base(ruleset, beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
@ -93,8 +92,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this);
|
||||
|
||||
protected override BeatmapConverter<TaikoHitObject> CreateBeatmapConverter() => new TaikoBeatmapConverter(IsForCurrentRuleset);
|
||||
|
||||
public override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo);
|
||||
|
||||
protected override Playfield CreatePlayfield() => new TaikoPlayfield(Beatmap.ControlPointInfo)
|
||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual
|
||||
// We create a dummy RulesetContainer just to get the replay - we don't want to use mods here
|
||||
// to simulate setting a replay rather than having the replay already set for us
|
||||
beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
|
||||
var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(beatmap, beatmap.BeatmapInfo.Ruleset.Equals(ruleset.RulesetInfo));
|
||||
var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(beatmap);
|
||||
|
||||
// We have the replay
|
||||
var replay = dummyRulesetContainer.Replay;
|
||||
|
@ -22,25 +22,27 @@ namespace osu.Game.Beatmaps
|
||||
remove => ObjectConverted -= value;
|
||||
}
|
||||
|
||||
/// <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(IBeatmap beatmap) => ValidConversionTypes.All(t => beatmap.HitObjects.Any(t.IsInstanceOfType));
|
||||
public IBeatmap Beatmap { get; }
|
||||
|
||||
/// <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(IBeatmap original)
|
||||
protected BeatmapConverter(IBeatmap beatmap)
|
||||
{
|
||||
// We always operate on a clone of the original beatmap, to not modify it game-wide
|
||||
return ConvertBeatmap(original.Clone());
|
||||
Beatmap = beatmap;
|
||||
}
|
||||
|
||||
void IBeatmapConverter.Convert(IBeatmap original) => Convert(original);
|
||||
/// <summary>
|
||||
/// Whether <see cref="Beatmap"/> can be converted by this <see cref="BeatmapConverter{T}"/>.
|
||||
/// </summary>
|
||||
public bool CanConvert => !Beatmap.HitObjects.Any() || ValidConversionTypes.All(t => Beatmap.HitObjects.Any(t.IsInstanceOfType));
|
||||
|
||||
/// <summary>
|
||||
/// Converts <see cref="Beatmap"/>.
|
||||
/// </summary>
|
||||
/// <returns>The converted Beatmap.</returns>
|
||||
public IBeatmap Convert()
|
||||
{
|
||||
// We always operate on a clone of the original beatmap, to not modify it game-wide
|
||||
return ConvertBeatmap(Beatmap.Clone());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the conversion of a Beatmap using this Beatmap Converter.
|
||||
|
@ -9,7 +9,9 @@ using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
@ -341,9 +343,16 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);
|
||||
|
||||
// TODO: this should be done in a better place once we actually need to dynamically update it.
|
||||
beatmap.BeatmapInfo.Ruleset = ruleset;
|
||||
beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance()?.CreateDifficultyCalculator(beatmap).Calculate() ?? 0;
|
||||
|
||||
if (ruleset != null)
|
||||
{
|
||||
// TODO: this should be done in a better place once we actually need to dynamically update it.
|
||||
var converted = new DummyConversionBeatmap(beatmap).GetPlayableBeatmap(ruleset);
|
||||
beatmap.BeatmapInfo.StarDifficulty = ruleset.CreateInstance().CreateDifficultyCalculator(converted).Calculate();
|
||||
}
|
||||
else
|
||||
beatmap.BeatmapInfo.StarDifficulty = 0;
|
||||
|
||||
beatmapInfos.Add(beatmap.BeatmapInfo);
|
||||
}
|
||||
@ -351,5 +360,23 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
return beatmapInfos;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A dummy WorkingBeatmap for the purpose of retrieving a beatmap for star difficulty calculation.
|
||||
/// </summary>
|
||||
private class DummyConversionBeatmap : WorkingBeatmap
|
||||
{
|
||||
private readonly IBeatmap beatmap;
|
||||
|
||||
public DummyConversionBeatmap(IBeatmap beatmap)
|
||||
: base(beatmap.BeatmapInfo)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
||||
protected override IBeatmap GetBeatmap() => beatmap;
|
||||
protected override Texture GetBackground() => null;
|
||||
protected override Track GetTrack() => null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,30 +2,47 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Linq;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
public interface IBeatmapProcessor
|
||||
{
|
||||
IBeatmap Beatmap { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Post-processes <see cref="Beatmap"/> to add mode-specific components that aren't added during conversion.
|
||||
/// <para>
|
||||
/// An example of such a usage is for combo colours.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
void PostProcess();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a post-converted Beatmap.
|
||||
/// </summary>
|
||||
/// <typeparam name="TObject">The type of HitObject contained in the Beatmap.</typeparam>
|
||||
public class BeatmapProcessor<TObject>
|
||||
where TObject : HitObject
|
||||
public class BeatmapProcessor : IBeatmapProcessor
|
||||
{
|
||||
public IBeatmap Beatmap { get; }
|
||||
|
||||
public BeatmapProcessor(IBeatmap beatmap)
|
||||
{
|
||||
Beatmap = beatmap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Post-processes a Beatmap to add mode-specific components that aren't added during conversion.
|
||||
/// <para>
|
||||
/// An example of such a usage is for combo colours.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="beatmap">The Beatmap to process.</param>
|
||||
public virtual void PostProcess(Beatmap<TObject> beatmap)
|
||||
public virtual void PostProcess()
|
||||
{
|
||||
IHasComboInformation lastObj = null;
|
||||
|
||||
foreach (var obj in beatmap.HitObjects.OfType<IHasComboInformation>())
|
||||
foreach (var obj in Beatmap.HitObjects.OfType<IHasComboInformation>())
|
||||
{
|
||||
if (obj.NewCombo)
|
||||
{
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Framework.Timing;
|
||||
@ -12,30 +11,17 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
public abstract class DifficultyCalculator
|
||||
{
|
||||
protected double TimeRate = 1;
|
||||
|
||||
public abstract double Calculate(Dictionary<string, double> categoryDifficulty = null);
|
||||
}
|
||||
|
||||
public abstract class DifficultyCalculator<T> : DifficultyCalculator where T : HitObject
|
||||
{
|
||||
protected readonly Beatmap<T> Beatmap;
|
||||
protected readonly IBeatmap Beatmap;
|
||||
protected readonly Mod[] Mods;
|
||||
|
||||
protected double TimeRate = 1;
|
||||
|
||||
protected DifficultyCalculator(IBeatmap beatmap, Mod[] mods = null)
|
||||
{
|
||||
Beatmap = beatmap;
|
||||
Mods = mods ?? new Mod[0];
|
||||
|
||||
var converter = CreateBeatmapConverter(beatmap);
|
||||
|
||||
foreach (var mod in Mods.OfType<IApplicableToBeatmapConverter<T>>())
|
||||
mod.ApplyToBeatmapConverter(converter);
|
||||
|
||||
Beatmap = converter.Convert(beatmap);
|
||||
|
||||
ApplyMods(Mods);
|
||||
|
||||
PreprocessHitObjects();
|
||||
}
|
||||
|
||||
protected virtual void ApplyMods(Mod[] mods)
|
||||
@ -43,22 +29,12 @@ namespace osu.Game.Beatmaps
|
||||
var clock = new StopwatchClock();
|
||||
mods.OfType<IApplicableToClock>().ForEach(m => m.ApplyToClock(clock));
|
||||
TimeRate = clock.Rate;
|
||||
|
||||
foreach (var mod in Mods.OfType<IApplicableToDifficulty>())
|
||||
mod.ApplyToDifficulty(Beatmap.BeatmapInfo.BaseDifficulty);
|
||||
|
||||
foreach (var h in Beatmap.HitObjects)
|
||||
h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty);
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToHitObject<T>>())
|
||||
foreach (var obj in Beatmap.HitObjects)
|
||||
mod.ApplyToHitObject(obj);
|
||||
}
|
||||
|
||||
protected virtual void PreprocessHitObjects()
|
||||
{
|
||||
}
|
||||
|
||||
protected abstract BeatmapConverter<T> CreateBeatmapConverter(IBeatmap beatmap);
|
||||
public abstract double Calculate(Dictionary<string, double> categoryDifficulty = null);
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
@ -53,11 +54,13 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type) => new Mod[] { };
|
||||
|
||||
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new DummyBeatmapConverter { Beatmap = beatmap };
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => null;
|
||||
|
||||
public override string Description => "dummy";
|
||||
@ -68,6 +71,14 @@ namespace osu.Game.Beatmaps
|
||||
: base(rulesetInfo)
|
||||
{
|
||||
}
|
||||
|
||||
private class DummyBeatmapConverter : IBeatmapConverter
|
||||
{
|
||||
public event Action<HitObject, IEnumerable<HitObject>> ObjectConverted;
|
||||
public IBeatmap Beatmap { get; set; }
|
||||
public bool CanConvert => true;
|
||||
public IBeatmap Convert() => Beatmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,10 +16,16 @@ namespace osu.Game.Beatmaps
|
||||
/// </summary>
|
||||
event Action<HitObject, IEnumerable<HitObject>> ObjectConverted;
|
||||
|
||||
IBeatmap Beatmap { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Beatmap using this Beatmap Converter.
|
||||
/// Whether <see cref="Beatmap"/> can be converted by this <see cref="IBeatmapConverter"/>.
|
||||
/// </summary>
|
||||
/// <param name="beatmap">The un-converted Beatmap.</param>
|
||||
void Convert(IBeatmap beatmap);
|
||||
bool CanConvert { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Converts <see cref="Beatmap"/>.
|
||||
/// </summary>
|
||||
IBeatmap Convert();
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ using osu.Framework.IO.File;
|
||||
using System.IO;
|
||||
using osu.Game.IO.Serialization;
|
||||
using System.Diagnostics;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
@ -45,7 +47,7 @@ namespace osu.Game.Beatmaps
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the <see cref="Beatmap"/>.
|
||||
/// Saves the <see cref="Beatmaps.Beatmap"/>.
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
@ -65,7 +67,6 @@ namespace osu.Game.Beatmaps
|
||||
public bool BeatmapLoaded => beatmap.IsResultAvailable;
|
||||
public IBeatmap Beatmap => beatmap.Value.Result;
|
||||
public async Task<IBeatmap> GetBeatmapAsync() => await beatmap.Value;
|
||||
|
||||
private readonly AsyncLazy<IBeatmap> beatmap;
|
||||
|
||||
private IBeatmap populateBeatmap()
|
||||
@ -78,6 +79,51 @@ namespace osu.Game.Beatmaps
|
||||
return b;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a playable <see cref="IBeatmap"/> from <see cref="Beatmap"/> using the applicable converters for a specific <see cref="RulesetInfo"/>.
|
||||
/// <para>
|
||||
/// The returned <see cref="IBeatmap"/> is in a playable state - all <see cref="HitObject"/> and <see cref="BeatmapDifficulty"/> <see cref="Mod"/>s
|
||||
/// have been applied, and <see cref="HitObject"/>s have been fully constructed.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="ruleset">The <see cref="RulesetInfo"/> to create a playable <see cref="IBeatmap"/> for.</param>
|
||||
/// <returns>The converted <see cref="IBeatmap"/>.</returns>
|
||||
/// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception>
|
||||
public IBeatmap GetPlayableBeatmap(RulesetInfo ruleset)
|
||||
{
|
||||
var rulesetInstance = ruleset.CreateInstance();
|
||||
|
||||
IBeatmapConverter converter = rulesetInstance.CreateBeatmapConverter(Beatmap);
|
||||
|
||||
// Check if the beatmap can be converted
|
||||
if (!converter.CanConvert)
|
||||
throw new BeatmapInvalidForRulesetException($"{nameof(Beatmaps.Beatmap)} can not be converted for the ruleset (ruleset: {ruleset.InstantiationInfo}, converter: {converter}).");
|
||||
|
||||
// Apply conversion mods
|
||||
foreach (var mod in Mods.Value.OfType<IApplicableToBeatmapConverter>())
|
||||
mod.ApplyToBeatmapConverter(converter);
|
||||
|
||||
// Convert
|
||||
IBeatmap converted = converter.Convert();
|
||||
|
||||
// Apply difficulty mods
|
||||
foreach (var mod in Mods.Value.OfType<IApplicableToDifficulty>())
|
||||
mod.ApplyToDifficulty(converted.BeatmapInfo.BaseDifficulty);
|
||||
|
||||
// Post-process
|
||||
rulesetInstance.CreateBeatmapProcessor(converted)?.PostProcess();
|
||||
|
||||
// Compute default values for hitobjects, including creating nested hitobjects in-case they're needed
|
||||
foreach (var obj in converted.HitObjects)
|
||||
obj.ApplyDefaults(converted.ControlPointInfo, converted.BeatmapInfo.BaseDifficulty);
|
||||
|
||||
foreach (var mod in Mods.Value.OfType<IApplicableToHitObject>())
|
||||
foreach (var obj in converted.HitObjects)
|
||||
mod.ApplyToHitObject(obj);
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
public bool BackgroundLoaded => background.IsResultAvailable;
|
||||
public Texture Background => background.Value.Result;
|
||||
public async Task<Texture> GetBackgroundAsync() => await background.Value;
|
||||
|
@ -125,7 +125,7 @@ namespace osu.Game.Rulesets.Edit
|
||||
|
||||
private void setCompositionTool(ICompositionTool tool) => CurrentTool = tool;
|
||||
|
||||
protected virtual RulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => ruleset.CreateRulesetContainerWith(beatmap, true);
|
||||
protected virtual RulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) => ruleset.CreateRulesetContainerWith(beatmap);
|
||||
|
||||
protected abstract IReadOnlyList<ICompositionTool> CompositionTools { get; }
|
||||
|
||||
|
@ -10,13 +10,12 @@ namespace osu.Game.Rulesets.Mods
|
||||
/// Interface for a <see cref="Mod"/> that applies changes to a <see cref="BeatmapConverter{TObject}"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TObject">The type of converted <see cref="HitObject"/>.</typeparam>
|
||||
public interface IApplicableToBeatmapConverter<TObject> : IApplicableMod
|
||||
where TObject : HitObject
|
||||
public interface IApplicableToBeatmapConverter : IApplicableMod
|
||||
{
|
||||
/// <summary>
|
||||
/// Applies this <see cref="Mod"/> to a <see cref="BeatmapConverter{TObject}"/>.
|
||||
/// </summary>
|
||||
/// <param name="beatmapConverter">The <see cref="BeatmapConverter{TObject}"/> to apply to.</param>
|
||||
void ApplyToBeatmapConverter(BeatmapConverter<TObject> beatmapConverter);
|
||||
void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter);
|
||||
}
|
||||
}
|
||||
|
@ -8,13 +8,12 @@ namespace osu.Game.Rulesets.Mods
|
||||
/// <summary>
|
||||
/// An interface for <see cref="Mod"/>s that can be applied to <see cref="HitObject"/>s.
|
||||
/// </summary>
|
||||
public interface IApplicableToHitObject<in TObject> : IApplicableMod
|
||||
where TObject : HitObject
|
||||
public interface IApplicableToHitObject : IApplicableMod
|
||||
{
|
||||
/// <summary>
|
||||
/// Applies this <see cref="IApplicableToHitObject{TObject}"/> to a <see cref="HitObject"/>.
|
||||
/// </summary>
|
||||
/// <param name="hitObject">The <see cref="HitObject"/> to apply to.</param>
|
||||
void ApplyToHitObject(TObject hitObject);
|
||||
void ApplyToHitObject(HitObject hitObject);
|
||||
}
|
||||
}
|
||||
|
@ -52,10 +52,13 @@ namespace osu.Game.Rulesets
|
||||
/// Attempt to create a hit renderer for a beatmap
|
||||
/// </summary>
|
||||
/// <param name="beatmap">The beatmap to create the hit renderer for.</param>
|
||||
/// <param name="isForCurrentRuleset">Whether the hit renderer should assume the beatmap is for the current ruleset.</param>
|
||||
/// <exception cref="BeatmapInvalidForRulesetException">Unable to successfully load the beatmap to be usable with this ruleset.</exception>
|
||||
/// <returns></returns>
|
||||
public abstract RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset);
|
||||
public abstract RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap);
|
||||
|
||||
public abstract IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap);
|
||||
|
||||
public virtual IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => null;
|
||||
|
||||
public abstract DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null);
|
||||
|
||||
@ -114,7 +117,8 @@ namespace osu.Game.Rulesets
|
||||
Name = Description,
|
||||
ShortName = ShortName,
|
||||
InstantiationInfo = GetType().AssemblyQualifiedName,
|
||||
ID = LegacyID
|
||||
ID = LegacyID,
|
||||
Available = true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -2,42 +2,28 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Rulesets.Scoring
|
||||
{
|
||||
public abstract class PerformanceCalculator
|
||||
{
|
||||
public abstract double Calculate(Dictionary<string, double> categoryDifficulty = null);
|
||||
}
|
||||
|
||||
public abstract class PerformanceCalculator<TObject> : PerformanceCalculator
|
||||
where TObject : HitObject
|
||||
{
|
||||
private readonly Dictionary<string, double> attributes = new Dictionary<string, double>();
|
||||
protected IDictionary<string, double> Attributes => attributes;
|
||||
|
||||
protected readonly Beatmap<TObject> Beatmap;
|
||||
protected readonly IBeatmap Beatmap;
|
||||
protected readonly Score Score;
|
||||
|
||||
protected PerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score)
|
||||
{
|
||||
Score = score;
|
||||
|
||||
var converter = CreateBeatmapConverter();
|
||||
|
||||
foreach (var mod in score.Mods.OfType<IApplicableToBeatmapConverter<TObject>>())
|
||||
mod.ApplyToBeatmapConverter(converter);
|
||||
|
||||
Beatmap = converter.Convert(beatmap);
|
||||
Beatmap = beatmap;
|
||||
|
||||
var diffCalc = ruleset.CreateDifficultyCalculator(beatmap, score.Mods);
|
||||
diffCalc.Calculate(attributes);
|
||||
}
|
||||
|
||||
protected abstract BeatmapConverter<TObject> CreateBeatmapConverter();
|
||||
public abstract double Calculate(Dictionary<string, double> categoryDifficulty = null);
|
||||
}
|
||||
}
|
||||
|
@ -190,11 +190,6 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
protected readonly WorkingBeatmap WorkingBeatmap;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the specified beatmap is assumed to be specific to the current ruleset.
|
||||
/// </summary>
|
||||
public readonly bool IsForCurrentRuleset;
|
||||
|
||||
public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor<TObject>(this);
|
||||
|
||||
protected override Container<Drawable> Content => content;
|
||||
@ -206,43 +201,18 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
/// <param name="ruleset">The ruleset being repesented.</param>
|
||||
/// <param name="workingBeatmap">The beatmap to create the hit renderer for.</param>
|
||||
/// <param name="isForCurrentRuleset">Whether to assume the beatmap is for the current ruleset.</param>
|
||||
protected RulesetContainer(Ruleset ruleset, WorkingBeatmap workingBeatmap, bool isForCurrentRuleset)
|
||||
protected RulesetContainer(Ruleset ruleset, WorkingBeatmap workingBeatmap)
|
||||
: base(ruleset)
|
||||
{
|
||||
Debug.Assert(workingBeatmap != null, "RulesetContainer initialized with a null beatmap.");
|
||||
|
||||
WorkingBeatmap = workingBeatmap;
|
||||
IsForCurrentRuleset = isForCurrentRuleset;
|
||||
// ReSharper disable once PossibleNullReferenceException
|
||||
Mods = workingBeatmap.Mods.Value;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
BeatmapConverter<TObject> converter = CreateBeatmapConverter();
|
||||
BeatmapProcessor<TObject> processor = CreateBeatmapProcessor();
|
||||
|
||||
// Check if the beatmap can be converted
|
||||
if (!converter.CanConvert(workingBeatmap.Beatmap))
|
||||
throw new BeatmapInvalidForRulesetException($"{nameof(Beatmap)} can not be converted for the current ruleset (converter: {converter}).");
|
||||
|
||||
// Apply conversion adjustments before converting
|
||||
foreach (var mod in Mods.OfType<IApplicableToBeatmapConverter<TObject>>())
|
||||
mod.ApplyToBeatmapConverter(converter);
|
||||
|
||||
// Convert the beatmap
|
||||
Beatmap = converter.Convert(workingBeatmap.Beatmap);
|
||||
|
||||
// Apply difficulty adjustments from mods before using Difficulty.
|
||||
foreach (var mod in Mods.OfType<IApplicableToDifficulty>())
|
||||
mod.ApplyToDifficulty(Beatmap.BeatmapInfo.BaseDifficulty);
|
||||
|
||||
// Post-process the beatmap
|
||||
processor.PostProcess(Beatmap);
|
||||
|
||||
// Apply defaults
|
||||
foreach (var h in Beatmap.HitObjects)
|
||||
h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty);
|
||||
Beatmap = (Beatmap<TObject>)workingBeatmap.GetPlayableBeatmap(ruleset.RulesetInfo);
|
||||
|
||||
KeyBindingInputManager = CreateInputManager();
|
||||
KeyBindingInputManager.RelativeSizeAxes = Axes.Both;
|
||||
@ -277,10 +247,6 @@ namespace osu.Game.Rulesets.UI
|
||||
if (mods == null)
|
||||
return;
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToHitObject<TObject>>())
|
||||
foreach (var obj in Beatmap.HitObjects)
|
||||
mod.ApplyToHitObject(obj);
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToRulesetContainer<TObject>>())
|
||||
mod.ApplyToRulesetContainer(this);
|
||||
}
|
||||
@ -324,13 +290,6 @@ namespace osu.Game.Rulesets.UI
|
||||
Playfield.Size = GetAspectAdjustedSize() * PlayfieldArea;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a processor to perform post-processing operations
|
||||
/// on HitObjects in converted Beatmaps.
|
||||
/// </summary>
|
||||
/// <returns>The Beatmap processor.</returns>
|
||||
protected virtual BeatmapProcessor<TObject> CreateBeatmapProcessor() => new BeatmapProcessor<TObject>();
|
||||
|
||||
/// <summary>
|
||||
/// Computes the size of the <see cref="Playfield"/> in relative coordinate space after aspect adjustments.
|
||||
/// </summary>
|
||||
@ -344,12 +303,6 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
protected virtual Vector2 PlayfieldArea => new Vector2(0.75f); // A sane default
|
||||
|
||||
/// <summary>
|
||||
/// Creates a converter to convert Beatmap to a specific mode.
|
||||
/// </summary>
|
||||
/// <returns>The Beatmap converter.</returns>
|
||||
protected abstract BeatmapConverter<TObject> CreateBeatmapConverter();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a DrawableHitObject from a HitObject.
|
||||
/// </summary>
|
||||
@ -377,9 +330,8 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
/// <param name="ruleset">The ruleset being repesented.</param>
|
||||
/// <param name="beatmap">The beatmap to create the hit renderer for.</param>
|
||||
/// <param name="isForCurrentRuleset">Whether to assume the beatmap is for the current ruleset.</param>
|
||||
protected RulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(ruleset, beatmap, isForCurrentRuleset)
|
||||
protected RulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
: base(ruleset, beatmap)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +30,8 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
/// <returns></returns>
|
||||
protected readonly SortedList<MultiplierControlPoint> DefaultControlPoints = new SortedList<MultiplierControlPoint>(Comparer<MultiplierControlPoint>.Default);
|
||||
|
||||
protected ScrollingRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
|
||||
: base(ruleset, beatmap, isForCurrentRuleset)
|
||||
protected ScrollingRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
: base(ruleset, beatmap)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
try
|
||||
{
|
||||
RulesetContainer = rulesetInstance.CreateRulesetContainerWith(working, ruleset.ID == beatmap.BeatmapInfo.Ruleset.ID);
|
||||
RulesetContainer = rulesetInstance.CreateRulesetContainerWith(working);
|
||||
}
|
||||
catch (BeatmapInvalidForRulesetException)
|
||||
{
|
||||
@ -115,7 +115,7 @@ namespace osu.Game.Screens.Play
|
||||
// let's try again forcing the beatmap's ruleset.
|
||||
ruleset = beatmap.BeatmapInfo.Ruleset;
|
||||
rulesetInstance = ruleset.CreateInstance();
|
||||
RulesetContainer = rulesetInstance.CreateRulesetContainerWith(Beatmap, true);
|
||||
RulesetContainer = rulesetInstance.CreateRulesetContainerWith(Beatmap);
|
||||
}
|
||||
|
||||
if (!RulesetContainer.Objects.Any())
|
||||
|
@ -10,12 +10,14 @@ using NUnit.Framework;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
namespace osu.Game.Tests.Beatmaps
|
||||
{
|
||||
[TestFixture]
|
||||
public abstract class BeatmapConversionTest<TConvertValue>
|
||||
public abstract class BeatmapConversionTest<TRuleset, TConvertValue>
|
||||
where TRuleset : Ruleset, new()
|
||||
where TConvertValue : IEquatable<TConvertValue>
|
||||
{
|
||||
private const string resource_namespace = "Testing.Beatmaps";
|
||||
@ -79,6 +81,9 @@ namespace osu.Game.Tests.Beatmaps
|
||||
{
|
||||
var beatmap = getBeatmap(name);
|
||||
|
||||
var rulesetInstance = new TRuleset();
|
||||
beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo();
|
||||
|
||||
var result = new ConvertResult();
|
||||
|
||||
var converter = CreateConverter(beatmap);
|
||||
@ -92,7 +97,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
result.Mappings.Add(mapping);
|
||||
};
|
||||
|
||||
converter.Convert(beatmap);
|
||||
converter.Convert();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user