diff --git a/appveyor.yml b/appveyor.yml
index 15484e4c68..69bc762f4c 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -11,7 +11,7 @@ install:
- cmd: git submodule update --init --recursive --depth=5
- cmd: choco install resharper-clt -y
- cmd: choco install nvika -y
- - cmd: appveyor DownloadFile https://github.com/peppy/CodeFileSanity/releases/download/v0.2.4/CodeFileSanity.exe
+ - cmd: appveyor DownloadFile https://github.com/peppy/CodeFileSanity/releases/download/v0.2.5/CodeFileSanity.exe
before_build:
- cmd: CodeFileSanity.exe
- cmd: nuget restore -verbosity quiet
diff --git a/osu-framework b/osu-framework
index 0773d895d9..fac688633b 160000
--- a/osu-framework
+++ b/osu-framework
@@ -1 +1 @@
-Subproject commit 0773d895d9aa0729995cd4a23efc28238e35ceed
+Subproject commit fac688633b8fcf34ae5d0514c26b03e217161eb4
diff --git a/osu.Desktop.Deploy/Program.cs b/osu.Desktop.Deploy/Program.cs
index 16bbf90cd4..a1c2a8aef2 100644
--- a/osu.Desktop.Deploy/Program.cs
+++ b/osu.Desktop.Deploy/Program.cs
@@ -19,7 +19,7 @@ namespace osu.Desktop.Deploy
{
private static string packages => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages");
private static string nugetPath => Path.Combine(packages, @"nuget.commandline\4.5.1\tools\NuGet.exe");
- private static string squirrelPath => Path.Combine(packages, @"squirrel.windows\1.7.8\tools\Squirrel.exe");
+ private static string squirrelPath => Path.Combine(packages, @"squirrel.windows\1.8.0\tools\Squirrel.exe");
private const string msbuild_path = @"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe";
public static string StagingFolder = ConfigurationManager.AppSettings["StagingFolder"];
@@ -115,7 +115,7 @@ namespace osu.Desktop.Deploy
checkReleaseFiles();
write("Running squirrel build...");
- runCommand(squirrelPath, $"--releasify {stagingPath}\\{nupkgFilename(version)} --setupIcon {iconPath} --icon {iconPath} {codeSigningCmd} --no-msi");
+ runCommand(squirrelPath, $"--releasify {stagingPath}\\{nupkgFilename(version)} --framework-version=net471 --setupIcon {iconPath} --icon {iconPath} {codeSigningCmd} --no-msi");
//prune again to clean up before upload.
pruneReleases();
diff --git a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
index a97b8197b4..063fb89918 100644
--- a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
+++ b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj
index 27bc3f7597..3d64cab84e 100644
--- a/osu.Desktop/osu.Desktop.csproj
+++ b/osu.Desktop/osu.Desktop.csproj
@@ -1,4 +1,4 @@
-
+
net471;netcoreapp2.0
@@ -10,8 +10,8 @@
osu!lazer
osu!lazer
lazer.ico
- 0.0.0.0
- 0.0.0.0
+ 0.0.0
+ 0.0.0
$(DefineConstants);NET_FRAMEWORK
@@ -31,9 +31,9 @@
-
+
-
\ No newline at end of file
+
diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs
index bd0cc209b6..d0d623178e 100644
--- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs
+++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs
@@ -14,7 +14,7 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Catch.Tests
{
- public class CatchBeatmapConversionTest : BeatmapConversionTest
+ public class CatchBeatmapConversionTest : BeatmapConversionTest
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Catch";
@@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Catch.Tests
}
}
- protected override IBeatmapConverter CreateConverter(Beatmap beatmap) => new CatchBeatmapConverter();
+ protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap);
}
public struct ConvertValue : IEquatable
@@ -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
+ {
+ }
}
diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs
index bce20520d3..097750d7e0 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Tests
{
}
- protected override Beatmap CreateBeatmap(Ruleset ruleset)
+ protected override IBeatmap CreateBeatmap(Ruleset ruleset)
{
var beatmap = new Beatmap
{
diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseBananaShower.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseBananaShower.cs
index d13a6bb860..b5cf0e3d1d 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestCaseBananaShower.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestCaseBananaShower.cs
@@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Tests
{
}
- protected override Beatmap CreateBeatmap(Ruleset ruleset)
+ protected override IBeatmap CreateBeatmap(Ruleset ruleset)
{
var beatmap = new Beatmap
{
diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseCatchStacker.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseCatchStacker.cs
index 2b58fcc93c..8a90b48180 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestCaseCatchStacker.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestCaseCatchStacker.cs
@@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Tests
{
}
- protected override Beatmap CreateBeatmap(Ruleset ruleset)
+ protected override IBeatmap CreateBeatmap(Ruleset ruleset)
{
var beatmap = new Beatmap
{
diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseHyperdash.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseHyperdash.cs
index e7f936ca2a..896582bf0a 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestCaseHyperdash.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestCaseHyperdash.cs
@@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Tests
{
}
- protected override Beatmap CreateBeatmap(Ruleset ruleset)
+ protected override IBeatmap CreateBeatmap(Ruleset ruleset)
{
var beatmap = new Beatmap { BeatmapInfo = { Ruleset = ruleset.RulesetInfo } };
diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs
new file mode 100644
index 0000000000..5b4af6ea8a
--- /dev/null
+++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs
@@ -0,0 +1,43 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// 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.Graphics;
+using osu.Game.Rulesets.Catch.Objects;
+
+namespace osu.Game.Rulesets.Catch.Beatmaps
+{
+ public class CatchBeatmap : Beatmap
+ {
+ public override IEnumerable GetStatistics()
+ {
+ int fruits = HitObjects.Count(s => s is Fruit);
+ int juiceStreams = HitObjects.Count(s => s is JuiceStream);
+ int bananaShowers = HitObjects.Count(s => s is BananaShower);
+
+ return new[]
+ {
+ new BeatmapStatistic
+ {
+ Name = @"Fruit Count",
+ Content = fruits.ToString(),
+ Icon = FontAwesome.fa_circle_o
+ },
+ new BeatmapStatistic
+ {
+ Name = @"Juice Stream Count",
+ Content = juiceStreams.ToString(),
+ Icon = FontAwesome.fa_circle
+ },
+ new BeatmapStatistic
+ {
+ Name = @"Banana Shower Count",
+ Content = bananaShowers.ToString(),
+ Icon = FontAwesome.fa_circle
+ }
+ };
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs
index 34e5f425fd..f40ef67dfb 100644
--- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs
+++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs
@@ -13,9 +13,14 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
{
public class CatchBeatmapConverter : BeatmapConverter
{
+ public CatchBeatmapConverter(IBeatmap beatmap)
+ : base(beatmap)
+ {
+ }
+
protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
- protected override IEnumerable ConvertHitObject(HitObject obj, Beatmap beatmap)
+ protected override IEnumerable ConvertHitObject(HitObject obj, IBeatmap beatmap)
{
var curveData = obj as IHasCurve;
var positionData = obj as IHasXPosition;
@@ -64,5 +69,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
X = positionData.X / CatchPlayfield.BASE_WIDTH
};
}
+
+ protected override Beatmap CreateBeatmap() => new CatchBeatmap();
}
}
diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs
index dfd10e0df7..e16f5fcb60 100644
--- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs
+++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs
@@ -12,16 +12,21 @@ using OpenTK;
namespace osu.Game.Rulesets.Catch.Beatmaps
{
- public class CatchBeatmapProcessor : BeatmapProcessor
+ public class CatchBeatmapProcessor : BeatmapProcessor
{
- public override void PostProcess(Beatmap beatmap)
+ public CatchBeatmapProcessor(IBeatmap beatmap)
+ : base(beatmap)
{
- initialiseHyperDash(beatmap.HitObjects);
+ }
- base.PostProcess(beatmap);
+ public override void PostProcess()
+ {
+ initialiseHyperDash((List)Beatmap.HitObjects);
+
+ base.PostProcess();
int index = 0;
- foreach (var obj in beatmap.HitObjects)
+ foreach (var obj in Beatmap.HitObjects.OfType())
obj.IndexInBeatmap = index++;
}
diff --git a/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs
index 876b394da0..f47d09fe20 100644
--- a/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs
@@ -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
+ public class CatchDifficultyCalculator : DifficultyCalculator
{
- public CatchDifficultyCalculator(Beatmap beatmap) : base(beatmap)
+ public CatchDifficultyCalculator(IBeatmap beatmap) : base(beatmap)
{
}
public override double Calculate(Dictionary categoryDifficulty = null) => 0;
-
- protected override BeatmapConverter CreateBeatmapConverter(Beatmap beatmap) => new CatchBeatmapConverter();
}
}
diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs
index cfe0fc5cec..15e51fa126 100644
--- a/osu.Game.Rulesets.Catch/CatchRuleset.cs
+++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs
@@ -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 GetDefaultKeyBindings(int variant = 0) => new[]
{
@@ -138,7 +141,7 @@ namespace osu.Game.Rulesets.Catch
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o };
- public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new CatchDifficultyCalculator(beatmap);
+ public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new CatchDifficultyCalculator(beatmap);
public override int? LegacyID => 2;
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs
index df7578799f..8e19c0614a 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs
@@ -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
+ 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;
diff --git a/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs b/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs
index d63d1bd331..d5c5eb844a 100644
--- a/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs
+++ b/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs
@@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.Replays
Dashing = dashing;
}
- public void ConvertFrom(LegacyReplayFrame legacyFrame, Beatmap beatmap)
+ public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap)
{
Position = legacyFrame.Position.X / CatchPlayfield.BASE_WIDTH;
Dashing = legacyFrame.ButtonState == ReplayButtonState.Left1;
diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs
index 022a8a8b43..070dc19a6f 100644
--- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs
@@ -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
{
- 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 CreateBeatmapProcessor() => new CatchBeatmapProcessor();
-
- protected override BeatmapConverter CreateBeatmapConverter() => new CatchBeatmapConverter();
-
protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, GetVisualRepresentation);
public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs
index 81c537e53c..f1ee874b88 100644
--- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs
+++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs
@@ -14,17 +14,14 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Mania.Tests
{
- public class ManiaBeatmapConversionTest : BeatmapConversionTest
+ public class ManiaBeatmapConversionTest : BeatmapConversionTest
{
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(Beatmap beatmap) => new ManiaBeatmapConverter(isForCurrentRuleset, beatmap);
+ protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
}
public struct ConvertValue : IEquatable
@@ -57,4 +54,8 @@ namespace osu.Game.Rulesets.Mania.Tests
&& Precision.AlmostEquals(EndTime, other.EndTime, conversion_lenience)
&& Column == other.Column;
}
+
+ public class TestManiaRuleset : ManiaRuleset
+ {
+ }
}
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs
index 6af3719f83..ad5f8e447d 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
+using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.UI;
@@ -29,5 +30,27 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
{
Stages.Add(defaultStage);
}
+
+ public override IEnumerable GetStatistics()
+ {
+ int notes = HitObjects.Count(s => s is Note);
+ int holdnotes = HitObjects.Count(s => s is HoldNote);
+
+ return new[]
+ {
+ new BeatmapStatistic
+ {
+ Name = @"Note Count",
+ Content = notes.ToString(),
+ Icon = FontAwesome.fa_circle_o
+ },
+ new BeatmapStatistic
+ {
+ Name = @"Hold Note Count",
+ Content = holdnotes.ToString(),
+ Icon = FontAwesome.fa_circle
+ },
+ };
+ }
}
}
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
index 60b92cb7b3..c8a7402904 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
@@ -33,18 +33,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
private ManiaBeatmap beatmap;
- public ManiaBeatmapConverter(bool isForCurrentRuleset, Beatmap 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)
@@ -56,8 +57,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
}
}
- protected override Beatmap ConvertBeatmap(Beatmap original)
+ protected override Beatmap 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);
@@ -68,7 +70,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
protected override Beatmap CreateBeatmap() => beatmap = new ManiaBeatmap(new StageDefinition { Columns = TargetColumns });
- protected override IEnumerable ConvertHitObject(HitObject original, Beatmap beatmap)
+ protected override IEnumerable ConvertHitObject(HitObject original, IBeatmap beatmap)
{
var maniaOriginal = original as ManiaHitObject;
if (maniaOriginal != null)
@@ -112,7 +114,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
/// The original hit object.
/// The original beatmap. This is used to look-up any values dependent on a fully-loaded beatmap.
/// The hit objects generated.
- private IEnumerable generateSpecific(HitObject original, Beatmap originalBeatmap)
+ private IEnumerable generateSpecific(HitObject original, IBeatmap originalBeatmap)
{
var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern, originalBeatmap);
@@ -128,7 +130,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
/// The original hit object.
/// The original beatmap. This is used to look-up any values dependent on a fully-loaded beatmap.
/// The hit objects generated.
- private IEnumerable generateConverted(HitObject original, Beatmap originalBeatmap)
+ private IEnumerable generateConverted(HitObject original, IBeatmap originalBeatmap)
{
var endTimeData = original as IHasEndTime;
var distanceData = original as IHasDistance;
@@ -165,7 +167,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
///
private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator
{
- public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, Beatmap originalBeatmap)
+ public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap)
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
{
}
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs
index 3b5c028bfd..afa9bdbbd7 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
private PatternType convertType;
- public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, Beatmap originalBeatmap)
+ public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap)
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
{
convertType = PatternType.None;
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs
index 743e230cb2..3f34afee85 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
private readonly double endTime;
- public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Beatmap originalBeatmap)
+ public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, IBeatmap originalBeatmap)
: base(random, hitObject, beatmap, new Pattern(), originalBeatmap)
{
var endtimeData = HitObject as IHasEndTime;
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs
index 652c92dd78..cec3e18ad6 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
private readonly PatternType convertType;
- public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair, Beatmap originalBeatmap)
+ public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair, IBeatmap originalBeatmap)
: base(random, hitObject, beatmap, previousPattern, originalBeatmap)
{
if (previousTime > hitObject.StartTime) throw new ArgumentOutOfRangeException(nameof(previousTime));
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs
index 02306846a3..930597c1ad 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs
@@ -28,9 +28,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
///
/// The beatmap which is being converted from.
///
- protected readonly Beatmap OriginalBeatmap;
+ protected readonly IBeatmap OriginalBeatmap;
- protected PatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, Beatmap originalBeatmap)
+ protected PatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap)
: base(hitObject, beatmap, previousPattern)
{
if (random == null) throw new ArgumentNullException(nameof(random));
@@ -113,7 +113,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
drainTime /= 1000;
BeatmapDifficulty difficulty = OriginalBeatmap.BeatmapInfo.BaseDifficulty;
- conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + OriginalBeatmap.HitObjects.Count / drainTime * 9f) / 38f * 5f / 1.15;
+ conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + OriginalBeatmap.HitObjects.Count() / drainTime * 9f) / 38f * 5f / 1.15;
conversionDifficulty = Math.Min(conversionDifficulty.Value, 12);
return conversionDifficulty.Value;
diff --git a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs
index 5eea346836..822ba53eeb 100644
--- a/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs
@@ -10,7 +10,7 @@ using System.Collections.Generic;
namespace osu.Game.Rulesets.Mania
{
- internal class ManiaDifficultyCalculator : DifficultyCalculator
+ internal class ManiaDifficultyCalculator : DifficultyCalculator
{
private const double star_scaling_factor = 0.018;
@@ -31,12 +31,12 @@ namespace osu.Game.Rulesets.Mania
///
private readonly List difficultyHitObjects = new List();
- public ManiaDifficultyCalculator(Beatmap beatmap)
+ public ManiaDifficultyCalculator(IBeatmap beatmap)
: base(beatmap)
{
}
- public ManiaDifficultyCalculator(Beatmap beatmap, Mod[] mods)
+ public ManiaDifficultyCalculator(IBeatmap beatmap, Mod[] mods)
: base(beatmap, mods)
{
}
@@ -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 CreateBeatmapConverter(Beatmap beatmap) => new ManiaBeatmapConverter(true, beatmap);
}
}
diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs
index 0546cbc174..f1d65f855b 100644
--- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs
+++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs
@@ -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 ConvertLegacyMods(LegacyMods mods)
{
@@ -182,7 +184,7 @@ namespace osu.Game.Rulesets.Mania
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o };
- public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new ManiaDifficultyCalculator(beatmap, mods);
+ public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new ManiaDifficultyCalculator(beatmap, mods);
public override int? LegacyID => 3;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs
index dbd30121a8..e02db68a28 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs
@@ -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
+ 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 beatmapConverter)
+ public void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter)
{
var mbc = (ManiaBeatmapConverter)beatmapConverter;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs
index 197b37b3f5..7f3985b26d 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs
@@ -11,19 +11,23 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Mania.Mods
{
- public class ManiaModDualStages : Mod, IPlayfieldTypeMod, IApplicableToBeatmapConverter, IApplicableToRulesetContainer
+ public class ManiaModDualStages : Mod, IPlayfieldTypeMod, IApplicableToBeatmapConverter, IApplicableToRulesetContainer
{
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 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();
diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs b/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs
index 8d86325dd9..bc9fd6e06f 100644
--- a/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs
+++ b/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs
@@ -24,10 +24,10 @@ namespace osu.Game.Rulesets.Mania.Replays
Actions.AddRange(actions);
}
- public void ConvertFrom(LegacyReplayFrame legacyFrame, Beatmap beatmap)
+ 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.
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs
index 76afaf270f..7123aab901 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs
@@ -36,8 +36,8 @@ namespace osu.Game.Rulesets.Mania.UI
public IEnumerable 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 CreateBeatmapConverter() => new ManiaBeatmapConverter(IsForCurrentRuleset, WorkingBeatmap.Beatmap);
-
protected override DrawableHitObject GetVisualRepresentation(ManiaHitObject h)
{
ManiaAction action = Playfield.Columns.ElementAt(h.Column).Action;
diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs
index 6ac3c016a0..aa7de4ed01 100644
--- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs
+++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs
@@ -15,7 +15,7 @@ using OpenTK;
namespace osu.Game.Rulesets.Osu.Tests
{
- public class OsuBeatmapConversionTest : BeatmapConversionTest
+ public class OsuBeatmapConversionTest : BeatmapConversionTest
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Osu";
@@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Osu.Tests
};
}
- protected override IBeatmapConverter CreateConverter(Beatmap beatmap) => new OsuBeatmapConverter();
+ protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap);
}
public struct ConvertValue : IEquatable
@@ -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
+ {
+ }
}
diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs
new file mode 100644
index 0000000000..6d90c2a875
--- /dev/null
+++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmap.cs
@@ -0,0 +1,43 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// 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.Graphics;
+using osu.Game.Rulesets.Osu.Objects;
+
+namespace osu.Game.Rulesets.Osu.Beatmaps
+{
+ public class OsuBeatmap : Beatmap
+ {
+ public override IEnumerable GetStatistics()
+ {
+ int circles = HitObjects.Count(c => c is HitCircle);
+ int sliders = HitObjects.Count(s => s is Slider);
+ int spinners = HitObjects.Count(s => s is Spinner);
+
+ return new[]
+ {
+ new BeatmapStatistic
+ {
+ Name = @"Circle Count",
+ Content = circles.ToString(),
+ Icon = FontAwesome.fa_circle_o
+ },
+ new BeatmapStatistic
+ {
+ Name = @"Slider Count",
+ Content = sliders.ToString(),
+ Icon = FontAwesome.fa_circle
+ },
+ new BeatmapStatistic
+ {
+ Name = @"Spinner Count",
+ Content = spinners.ToString(),
+ Icon = FontAwesome.fa_circle
+ }
+ };
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs
index 1236076f48..5f3a909488 100644
--- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs
+++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs
@@ -14,9 +14,14 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
{
internal class OsuBeatmapConverter : BeatmapConverter
{
+ public OsuBeatmapConverter(IBeatmap beatmap)
+ : base(beatmap)
+ {
+ }
+
protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(IHasPosition) };
- protected override IEnumerable ConvertHitObject(HitObject original, Beatmap beatmap)
+ protected override IEnumerable ConvertHitObject(HitObject original, IBeatmap beatmap)
{
var curveData = original as IHasCurve;
var endTimeData = original as IHasEndTime;
@@ -60,5 +65,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
};
}
}
+
+ protected override Beatmap CreateBeatmap() => new OsuBeatmap();
}
}
diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs
index afa2437bf6..c7c9f4a01a 100644
--- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs
+++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs
@@ -8,12 +8,17 @@ using osu.Game.Rulesets.Osu.Objects;
namespace osu.Game.Rulesets.Osu.Beatmaps
{
- internal class OsuBeatmapProcessor : BeatmapProcessor
+ internal class OsuBeatmapProcessor : BeatmapProcessor
{
- public override void PostProcess(Beatmap beatmap)
+ public OsuBeatmapProcessor(IBeatmap beatmap)
+ : base(beatmap)
{
- applyStacking(beatmap);
- base.PostProcess(beatmap);
+ }
+
+ public override void PostProcess()
+ {
+ applyStacking((Beatmap)Beatmap);
+ base.PostProcess();
}
private void applyStacking(Beatmap beatmap)
diff --git a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs
index 8d4c342740..ea33ec9ae0 100644
--- a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs
+++ b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs
@@ -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)
{
}
diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
index 7bf0651443..dce1fc2851 100644
--- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
+++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
@@ -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 CompositionTools => new ICompositionTool[]
{
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs
index cf71116d47..7a30e6b134 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs
@@ -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
+ 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)
diff --git a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs
index 926a7975f3..4853cd66cd 100644
--- a/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Osu/OsuDifficulty/OsuDifficultyCalculator.cs
@@ -5,36 +5,30 @@ 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
+ public class OsuDifficultyCalculator : DifficultyCalculator
{
private const int section_length = 400;
private const double difficulty_multiplier = 0.0675;
- public OsuDifficultyCalculator(Beatmap beatmap)
+ public OsuDifficultyCalculator(IBeatmap beatmap)
: base(beatmap)
{
}
- public OsuDifficultyCalculator(Beatmap beatmap, Mod[] mods)
+ public OsuDifficultyCalculator(IBeatmap beatmap, Mod[] mods)
: base(beatmap, mods)
{
}
- protected override void PreprocessHitObjects()
- {
- new OsuBeatmapProcessor().PostProcess(Beatmap);
- }
-
public override double Calculate(Dictionary categoryDifficulty = null)
{
- OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap(Beatmap.HitObjects, TimeRate);
+ OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap((List)Beatmap.HitObjects, TimeRate);
Skill[] skills =
{
new Aim(),
@@ -72,7 +66,5 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty
return starRating;
}
-
- protected override BeatmapConverter CreateBeatmapConverter(Beatmap beatmap) => new OsuBeatmapConverter();
}
}
diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs
index e0ecee97a3..69a54fb533 100644
--- a/osu.Game.Rulesets.Osu/OsuRuleset.cs
+++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs
@@ -9,7 +9,6 @@ using osu.Game.Rulesets.Osu.OsuDifficulty;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Rulesets.UI;
using System.Collections.Generic;
-using System.Linq;
using osu.Framework.Graphics;
using osu.Game.Overlays.Settings;
using osu.Framework.Input.Bindings;
@@ -17,17 +16,18 @@ using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Osu.Scoring;
using osu.Game.Rulesets.Osu.Edit;
using osu.Game.Rulesets.Edit;
-using osu.Game.Rulesets.Objects.Types;
-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 GetDefaultKeyBindings(int variant = 0) => new[]
{
@@ -37,36 +37,6 @@ namespace osu.Game.Rulesets.Osu
new KeyBinding(InputKey.MouseRight, OsuAction.RightButton),
};
- public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap)
- {
- IEnumerable hitObjects = beatmap.Beatmap.HitObjects;
- IEnumerable circles = hitObjects.Where(c => !(c is IHasEndTime));
- IEnumerable sliders = hitObjects.Where(s => s is IHasCurve);
- IEnumerable spinners = hitObjects.Where(s => s is IHasEndTime && !(s is IHasCurve));
-
- return new[]
- {
- new BeatmapStatistic
- {
- Name = @"Circle Count",
- Content = circles.Count().ToString(),
- Icon = FontAwesome.fa_circle_o
- },
- new BeatmapStatistic
- {
- Name = @"Slider Count",
- Content = sliders.Count().ToString(),
- Icon = FontAwesome.fa_circle
- },
- new BeatmapStatistic
- {
- Name = @"Spinner Count",
- Content = spinners.Count().ToString(),
- Icon = FontAwesome.fa_circle
- }
- };
- }
-
public override IEnumerable ConvertLegacyMods(LegacyMods mods)
{
if (mods.HasFlag(LegacyMods.Nightcore))
@@ -181,9 +151,9 @@ namespace osu.Game.Rulesets.Osu
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_osu_o };
- public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new OsuDifficultyCalculator(beatmap, mods);
+ public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new OsuDifficultyCalculator(beatmap, mods);
- public override PerformanceCalculator CreatePerformanceCalculator(Beatmap beatmap, Score score) => new OsuPerformanceCalculator(this, beatmap, score);
+ public override PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => new OsuPerformanceCalculator(this, beatmap, score);
public override HitObjectComposer CreateHitObjectComposer() => new OsuHitObjectComposer(this);
diff --git a/osu.Game.Rulesets.Osu/Replays/OsuReplayFrame.cs b/osu.Game.Rulesets.Osu/Replays/OsuReplayFrame.cs
index 6f2512cc33..4412b6efab 100644
--- a/osu.Game.Rulesets.Osu/Replays/OsuReplayFrame.cs
+++ b/osu.Game.Rulesets.Osu/Replays/OsuReplayFrame.cs
@@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Replays
Actions.AddRange(actions);
}
- public void ConvertFrom(LegacyReplayFrame legacyFrame, Beatmap beatmap)
+ public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap)
{
Position = legacyFrame.Position;
if (legacyFrame.MouseLeft) Actions.Add(OsuAction.LeftButton);
diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs
index 8f0feca207..a12bdf7f20 100644
--- a/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Scoring/OsuPerformanceCalculator.cs
@@ -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
+ public class OsuPerformanceCalculator : PerformanceCalculator
{
private readonly int countHitCircles;
private readonly int beatmapMaxCombo;
@@ -27,13 +26,14 @@ namespace osu.Game.Rulesets.Osu.Scoring
private int count50;
private int countMiss;
- public OsuPerformanceCalculator(Ruleset ruleset, Beatmap beatmap, Score score)
+ public OsuPerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score)
: base(ruleset, beatmap, score)
{
countHitCircles = Beatmap.HitObjects.Count(h => h is HitCircle);
- beatmapMaxCombo = Beatmap.HitObjects.Count;
- beatmapMaxCombo += Beatmap.HitObjects.OfType().Sum(s => s.NestedHitObjects.Count) + 1;
+ beatmapMaxCombo = Beatmap.HitObjects.Count();
+ // Add the ticks + tail of the slider. 1 is subtracted because the "headcircle" would be counted twice (once for the slider itself in the line above)
+ beatmapMaxCombo += Beatmap.HitObjects.OfType().Sum(s => s.NestedHitObjects.Count - 1);
}
public override double Calculate(Dictionary categoryRatings = null)
@@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
aimValue *= approachRateFactor;
if (mods.Any(h => h is OsuModHidden))
- aimValue *= 1.18f;
+ aimValue *= 1.03f;
if (mods.Any(h => h is OsuModFlashlight))
{
@@ -153,6 +153,9 @@ namespace osu.Game.Rulesets.Osu.Scoring
if (beatmapMaxCombo > 0)
speedValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8f) / Math.Pow(beatmapMaxCombo, 0.8f), 1.0f);
+ if (mods.Any(m => m is OsuModHidden))
+ speedValue *= 1.18f;
+
// Scale the speed value with accuracy _slightly_
speedValue *= 0.5f + accuracy / 2.0f;
// It is important to also consider accuracy difficulty when doing that
@@ -193,7 +196,5 @@ namespace osu.Game.Rulesets.Osu.Scoring
private double totalHits => count300 + count100 + count50 + countMiss;
private double totalSuccessfulHits => count300 + count100 + count50;
-
- protected override BeatmapConverter CreateBeatmapConverter() => new OsuBeatmapConverter();
}
}
diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs
index 22c7b719cd..ad1052f86a 100644
--- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs
+++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs
@@ -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
{
- 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 CreateBeatmapConverter() => new OsuBeatmapConverter();
-
- protected override BeatmapProcessor CreateBeatmapProcessor() => new OsuBeatmapProcessor();
-
protected override Playfield CreatePlayfield() => new OsuPlayfield();
public override PassThroughInputManager CreateInputManager() => new OsuInputManager(Ruleset.RulesetInfo);
diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs
index aa61f2d60b..33a5e1772e 100644
--- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs
+++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs
@@ -14,18 +14,15 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Rulesets.Taiko.Tests
{
- public class TaikoBeatmapConversionTest : BeatmapConversionTest
+ public class TaikoBeatmapConversionTest : BeatmapConversionTest
{
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(Beatmap beatmap) => new TaikoBeatmapConverter(isForCurrentRuleset);
+ protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap);
}
public struct ConvertValue : IEquatable
@@ -70,4 +67,8 @@ namespace osu.Game.Rulesets.Taiko.Tests
&& IsSwell == other.IsSwell
&& IsStrong == other.IsStrong;
}
+
+ public class TestTaikoRuleset : TaikoRuleset
+ {
+ }
}
diff --git a/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs
index aa7318b863..1bf24a46bc 100644
--- a/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs
+++ b/osu.Game.Rulesets.Taiko.Tests/TestCaseTaikoPlayfield.cs
@@ -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) }
});
}
diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs
new file mode 100644
index 0000000000..36f6df7869
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmap.cs
@@ -0,0 +1,43 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// 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.Graphics;
+using osu.Game.Rulesets.Taiko.Objects;
+
+namespace osu.Game.Rulesets.Taiko.Beatmaps
+{
+ public class TaikoBeatmap : Beatmap
+ {
+ public override IEnumerable GetStatistics()
+ {
+ int hits = HitObjects.Count(s => s is Hit);
+ int drumrolls = HitObjects.Count(s => s is DrumRoll);
+ int swells = HitObjects.Count(s => s is Swell);
+
+ return new[]
+ {
+ new BeatmapStatistic
+ {
+ Name = @"Hit Count",
+ Content = hits.ToString(),
+ Icon = FontAwesome.fa_circle_o
+ },
+ new BeatmapStatistic
+ {
+ Name = @"Drumroll Count",
+ Content = drumrolls.ToString(),
+ Icon = FontAwesome.fa_circle
+ },
+ new BeatmapStatistic
+ {
+ Name = @"Swell Count",
+ Content = swells.ToString(),
+ Icon = FontAwesome.fa_circle
+ }
+ };
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs
index 2f175a9922..d40e8dc643 100644
--- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs
+++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs
@@ -42,12 +42,13 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
protected override IEnumerable 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 ConvertBeatmap(Beatmap original)
+ protected override Beatmap ConvertBeatmap(IBeatmap original)
{
// Rewrite the beatmap info to add the slider velocity multiplier
BeatmapInfo info = original.BeatmapInfo.DeepClone();
@@ -70,7 +71,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
return converted;
}
- protected override IEnumerable ConvertHitObject(HitObject obj, Beatmap beatmap)
+ protected override IEnumerable ConvertHitObject(HitObject obj, IBeatmap beatmap)
{
var distanceData = obj as IHasDistance;
var repeatsData = obj as IHasRepeats;
@@ -196,5 +197,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
}
}
}
+
+ protected override Beatmap CreateBeatmap() => new TaikoBeatmap();
}
}
diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs
index e510b34ad7..2177a3cbdc 100644
--- a/osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs
+++ b/osu.Game.Rulesets.Taiko/Replays/TaikoReplayFrame.cs
@@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko.Replays
Actions.AddRange(actions);
}
- public void ConvertFrom(LegacyReplayFrame legacyFrame, Beatmap beatmap)
+ public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap)
{
if (legacyFrame.MouseRight1) Actions.Add(TaikoAction.LeftRim);
if (legacyFrame.MouseRight2) Actions.Add(TaikoAction.RightRim);
diff --git a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs
index 58661d7881..f14c53f7ae 100644
--- a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs
@@ -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
+ internal class TaikoDifficultyCalculator : DifficultyCalculator
{
private const double star_scaling_factor = 0.04125;
@@ -30,7 +29,7 @@ namespace osu.Game.Rulesets.Taiko
///
private readonly List difficultyHitObjects = new List();
- public TaikoDifficultyCalculator(Beatmap beatmap)
+ public TaikoDifficultyCalculator(IBeatmap beatmap)
: base(beatmap)
{
}
@@ -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 CreateBeatmapConverter(Beatmap beatmap) => new TaikoBeatmapConverter(true);
}
}
diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
index 06a8e44a14..102de5717f 100644
--- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
+++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
@@ -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 GetDefaultKeyBindings(int variant = 0) => new[]
{
@@ -140,7 +142,7 @@ namespace osu.Game.Rulesets.Taiko
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o };
- public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new TaikoDifficultyCalculator(beatmap);
+ public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new TaikoDifficultyCalculator(beatmap);
public override int? LegacyID => 1;
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs
index 3d3c6ab2f3..313c205981 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs
@@ -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
{
- 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 CreateBeatmapConverter() => new TaikoBeatmapConverter(IsForCurrentRuleset);
-
public override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo);
protected override Playfield CreatePlayfield() => new TaikoPlayfield(Beatmap.ControlPointInfo)
diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
index 6453cdbd3e..f60caf2397 100644
--- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
+++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
@@ -275,13 +275,13 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.IsTrue(set.Beatmaps.Any(c => c.OnlineBeatmapID == b.OnlineBeatmapID));
Assert.IsTrue(set.Beatmaps.Count > 0);
var beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 0))?.Beatmap;
- Assert.IsTrue(beatmap?.HitObjects.Count > 0);
+ Assert.IsTrue(beatmap?.HitObjects.Any() == true);
beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 1))?.Beatmap;
- Assert.IsTrue(beatmap?.HitObjects.Count > 0);
+ Assert.IsTrue(beatmap?.HitObjects.Any() == true);
beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 2))?.Beatmap;
- Assert.IsTrue(beatmap?.HitObjects.Count > 0);
+ Assert.IsTrue(beatmap?.HitObjects.Any() == true);
beatmap = store.GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap;
- Assert.IsTrue(beatmap?.HitObjects.Count > 0);
+ Assert.IsTrue(beatmap?.HitObjects.Any() == true);
}
private void waitForOrAssert(Func result, string failureMessage, int timeout = 60000)
diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs
index 886c1120d4..0d3e08154f 100644
--- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs
+++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs
@@ -12,8 +12,12 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets;
+using osu.Game.Rulesets.Catch;
+using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Objects;
+using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu;
+using osu.Game.Rulesets.Taiko;
using osu.Game.Screens.Select;
using osu.Game.Tests.Beatmaps;
@@ -24,7 +28,7 @@ namespace osu.Game.Tests.Visual
{
private RulesetStore rulesets;
private TestBeatmapInfoWedge infoWedge;
- private readonly List beatmaps = new List();
+ private readonly List beatmaps = new List();
private readonly Bindable beatmap = new Bindable();
[BackgroundDependencyLoader]
@@ -72,13 +76,23 @@ namespace osu.Game.Tests.Visual
selectBeatmap(testBeatmap);
+ testBeatmapLabels(ruleset);
+
// TODO: adjust cases once more info is shown for other gamemodes
switch (ruleset)
{
- case OsuRuleset osu:
- testOsuBeatmap(osu);
+ case OsuRuleset _:
testInfoLabels(5);
break;
+ case TaikoRuleset _:
+ testInfoLabels(5);
+ break;
+ case CatchRuleset _:
+ testInfoLabels(5);
+ break;
+ case ManiaRuleset _:
+ testInfoLabels(4);
+ break;
default:
testInfoLabels(2);
break;
@@ -88,7 +102,7 @@ namespace osu.Game.Tests.Visual
testNullBeatmap();
}
- private void testOsuBeatmap(OsuRuleset ruleset)
+ private void testBeatmapLabels(Ruleset ruleset)
{
AddAssert("check version", () => infoWedge.Info.VersionLabel.Text == $"{ruleset.ShortName}Version");
AddAssert("check title", () => infoWedge.Info.TitleLabel.Text == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title");
@@ -112,7 +126,7 @@ namespace osu.Game.Tests.Visual
AddAssert("check no infolabels", () => !infoWedge.Info.InfoLabelContainer.Children.Any());
}
- private void selectBeatmap(Beatmap b)
+ private void selectBeatmap(IBeatmap b)
{
BeatmapInfoWedge.BufferedWedgeInfo infoBefore = null;
@@ -134,11 +148,11 @@ namespace osu.Game.Tests.Visual
});
}
- private Beatmap createTestBeatmap(RulesetInfo ruleset)
+ private IBeatmap createTestBeatmap(RulesetInfo ruleset)
{
List objects = new List();
for (double i = 0; i < 50000; i += 1000)
- objects.Add(new HitObject { StartTime = i });
+ objects.Add(new TestHitObject { StartTime = i });
return new Beatmap
{
@@ -153,7 +167,8 @@ namespace osu.Game.Tests.Visual
},
Ruleset = ruleset,
StarDifficulty = 6,
- Version = $"{ruleset.ShortName}Version"
+ Version = $"{ruleset.ShortName}Version",
+ BaseDifficulty = new BeatmapDifficulty()
},
HitObjects = objects
};
@@ -163,5 +178,12 @@ namespace osu.Game.Tests.Visual
{
public new BufferedWedgeInfo Info => base.Info;
}
+
+ private class TestHitObject : HitObject, IHasPosition
+ {
+ public float X { get; } = 0;
+ public float Y { get; } = 0;
+ public Vector2 Position { get; } = Vector2.Zero;
+ }
}
}
diff --git a/osu.Game.Tests/Visual/TestCaseBreakOverlay.cs b/osu.Game.Tests/Visual/TestCaseBreakOverlay.cs
index a6a6130a8f..442ca1322a 100644
--- a/osu.Game.Tests/Visual/TestCaseBreakOverlay.cs
+++ b/osu.Game.Tests/Visual/TestCaseBreakOverlay.cs
@@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Framework.Timing;
using osu.Game.Beatmaps.Timing;
using System.Collections.Generic;
using NUnit.Framework;
@@ -16,8 +15,6 @@ namespace osu.Game.Tests.Visual
public TestCaseBreakOverlay()
{
- Clock = new FramedClock();
-
Child = breakOverlay = new BreakOverlay(true);
AddStep("2s break", () => startBreak(2000));
diff --git a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs
index 25f8ba06c4..bb5bf93a69 100644
--- a/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs
+++ b/osu.Game.Tests/Visual/TestCaseDrawableRoom.cs
@@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Online.Multiplayer;
using osu.Game.Rulesets;
-using osu.Game.Screens.Multiplayer;
+using osu.Game.Screens.Multi.Components;
using osu.Game.Users;
namespace osu.Game.Tests.Visual
diff --git a/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs b/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs
index 582ab5ecc9..f037d70493 100644
--- a/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs
+++ b/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs
@@ -332,7 +332,7 @@ namespace osu.Game.Tests.Visual
private readonly Drawable tracker;
- public TimingPointVisualiser(Beatmap beatmap, double length)
+ public TimingPointVisualiser(IBeatmap beatmap, double length)
{
this.length = length;
diff --git a/osu.Game.Tests/Visual/TestCaseMods.cs b/osu.Game.Tests/Visual/TestCaseMods.cs
index dad8fb8fed..d3d21509fd 100644
--- a/osu.Game.Tests/Visual/TestCaseMods.cs
+++ b/osu.Game.Tests/Visual/TestCaseMods.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using System;
using System.ComponentModel;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@@ -17,6 +18,7 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Mania.Mods;
+using osu.Game.Rulesets.UI;
using OpenTK.Graphics;
namespace osu.Game.Tests.Visual
@@ -24,6 +26,19 @@ namespace osu.Game.Tests.Visual
[Description("mod select and icon display")]
public class TestCaseMods : OsuTestCase
{
+ public override IReadOnlyList RequiredTypes => new[]
+ {
+ typeof(ModSelectOverlay),
+ typeof(ModDisplay),
+ typeof(ModSection),
+ typeof(ModIcon),
+ typeof(ModButton),
+ typeof(ModButtonEmpty),
+ typeof(DifficultyReductionSection),
+ typeof(DifficultyIncreaseSection),
+ typeof(SpecialSection),
+ };
+
private const string unranked_suffix = " (Unranked)";
private RulesetStore rulesets;
@@ -66,7 +81,8 @@ namespace osu.Game.Tests.Visual
Ruleset ruleset = rulesetInfo.CreateInstance();
AddStep($"switch to {ruleset.Description}", () => modSelect.Ruleset.Value = rulesetInfo);
- switch (ruleset) {
+ switch (ruleset)
+ {
case OsuRuleset or:
testOsuMods(or);
break;
diff --git a/osu.Game.Tests/Visual/TestCaseReplay.cs b/osu.Game.Tests/Visual/TestCaseReplay.cs
index 6ba671c7fc..5bc16fe420 100644
--- a/osu.Game.Tests/Visual/TestCaseReplay.cs
+++ b/osu.Game.Tests/Visual/TestCaseReplay.cs
@@ -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;
diff --git a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs
index 88059d2dcf..cb1425ca69 100644
--- a/osu.Game.Tests/Visual/TestCaseRoomInspector.cs
+++ b/osu.Game.Tests/Visual/TestCaseRoomInspector.cs
@@ -7,7 +7,7 @@ using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Online.Multiplayer;
using osu.Game.Rulesets;
-using osu.Game.Screens.Multiplayer;
+using osu.Game.Screens.Multi.Components;
using osu.Game.Users;
namespace osu.Game.Tests.Visual
diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs
index 12a017f68c..84897853d8 100644
--- a/osu.Game/Beatmaps/Beatmap.cs
+++ b/osu.Game/Beatmaps/Beatmap.cs
@@ -15,21 +15,27 @@ namespace osu.Game.Beatmaps
///
/// A Beatmap containing converted HitObjects.
///
- public class Beatmap : IJsonSerializable
+ public class Beatmap : IBeatmap
where T : HitObject
{
- public BeatmapInfo BeatmapInfo = new BeatmapInfo();
- public ControlPointInfo ControlPointInfo = new ControlPointInfo();
- public List Breaks = new List();
+ public BeatmapInfo BeatmapInfo { get; set; } = new BeatmapInfo
+ {
+ Metadata = new BeatmapMetadata
+ {
+ Artist = @"Unknown",
+ Title = @"Unknown",
+ AuthorString = @"Unknown Creator",
+ },
+ Version = @"Normal",
+ BaseDifficulty = new BeatmapDifficulty()
+ };
[JsonIgnore]
public BeatmapMetadata Metadata => BeatmapInfo?.Metadata ?? BeatmapInfo?.BeatmapSet?.Metadata;
- ///
- /// The HitObjects this Beatmap contains.
- ///
- [JsonConverter(typeof(TypedListConverter))]
- public List HitObjects = new List();
+ public ControlPointInfo ControlPointInfo { get; set; } = new ControlPointInfo();
+
+ public List Breaks { get; set; } = new List();
///
/// Total amount of break time in the beatmap.
@@ -38,51 +44,28 @@ namespace osu.Game.Beatmaps
public double TotalBreakTime => Breaks.Sum(b => b.Duration);
///
- /// Constructs a new beatmap.
+ /// The HitObjects this Beatmap contains.
///
- /// The original beatmap to use the parameters of.
- public Beatmap(Beatmap original = null)
- {
- BeatmapInfo = original?.BeatmapInfo.DeepClone() ?? BeatmapInfo;
- ControlPointInfo = original?.ControlPointInfo ?? ControlPointInfo;
- Breaks = original?.Breaks ?? Breaks;
- HitObjects = original?.HitObjects ?? HitObjects;
+ [JsonConverter(typeof(TypedListConverter))]
+ public List HitObjects = new List();
- if (original == null && Metadata == null)
- {
- // we may have no metadata in cases we weren't sourced from the database.
- // let's fill it (and other related fields) so we don't need to null-check it in future usages.
- BeatmapInfo = new BeatmapInfo
- {
- Metadata = new BeatmapMetadata
- {
- Artist = @"Unknown",
- Title = @"Unknown",
- AuthorString = @"Unknown Creator",
- },
- Version = @"Normal",
- BaseDifficulty = new BeatmapDifficulty()
- };
- }
+ IEnumerable IBeatmap.HitObjects => HitObjects;
+
+ public virtual IEnumerable GetStatistics() => Enumerable.Empty();
+
+ IBeatmap IBeatmap.Clone() => Clone();
+
+ public Beatmap Clone()
+ {
+ var newInstance = (Beatmap)MemberwiseClone();
+ newInstance.BeatmapInfo = BeatmapInfo.DeepClone();
+
+ return newInstance;
}
}
- ///
- /// A Beatmap containing un-converted HitObjects.
- ///
public class Beatmap : Beatmap
{
- ///
- /// Constructs a new beatmap.
- ///
- /// The original beatmap to use the parameters of.
- public Beatmap(Beatmap original)
- : base(original)
- {
- }
-
- public Beatmap()
- {
- }
+ public Beatmap Clone() => (Beatmap)base.Clone();
}
}
diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs
index 153cace187..b7a454460f 100644
--- a/osu.Game/Beatmaps/BeatmapConverter.cs
+++ b/osu.Game/Beatmaps/BeatmapConverter.cs
@@ -22,32 +22,34 @@ namespace osu.Game.Beatmaps
remove => ObjectConverted -= value;
}
- ///
- /// Checks if a Beatmap can be converted using this Beatmap Converter.
- ///
- /// The Beatmap to check.
- /// Whether the Beatmap can be converted using this Beatmap Converter.
- public bool CanConvert(Beatmap beatmap) => ValidConversionTypes.All(t => beatmap.HitObjects.Any(t.IsInstanceOfType));
+ public IBeatmap Beatmap { get; }
- ///
- /// Converts a Beatmap using this Beatmap Converter.
- ///
- /// The un-converted Beatmap.
- /// The converted Beatmap.
- public Beatmap Convert(Beatmap original)
+ protected BeatmapConverter(IBeatmap beatmap)
{
- // We always operate on a clone of the original beatmap, to not modify it game-wide
- return ConvertBeatmap(new Beatmap(original));
+ Beatmap = beatmap;
}
- void IBeatmapConverter.Convert(Beatmap original) => Convert(original);
+ ///
+ /// Whether can be converted by this .
+ ///
+ public bool CanConvert => !Beatmap.HitObjects.Any() || ValidConversionTypes.All(t => Beatmap.HitObjects.Any(t.IsInstanceOfType));
+
+ ///
+ /// Converts .
+ ///
+ /// The converted Beatmap.
+ public IBeatmap Convert()
+ {
+ // We always operate on a clone of the original beatmap, to not modify it game-wide
+ return ConvertBeatmap(Beatmap.Clone());
+ }
///
/// Performs the conversion of a Beatmap using this Beatmap Converter.
///
/// The un-converted Beatmap.
/// The converted Beatmap.
- protected virtual Beatmap ConvertBeatmap(Beatmap original)
+ protected virtual Beatmap ConvertBeatmap(IBeatmap original)
{
var beatmap = CreateBeatmap();
@@ -67,7 +69,7 @@ namespace osu.Game.Beatmaps
/// The hit object to convert.
/// The un-converted Beatmap.
/// The converted hit object.
- private IEnumerable convert(HitObject original, Beatmap beatmap)
+ private IEnumerable convert(HitObject original, IBeatmap beatmap)
{
// Check if the hitobject is already the converted type
T tObject = original as T;
@@ -107,6 +109,6 @@ namespace osu.Game.Beatmaps
/// The hit object to convert.
/// The un-converted Beatmap.
/// The converted hit object.
- protected abstract IEnumerable ConvertHitObject(HitObject original, Beatmap beatmap);
+ protected abstract IEnumerable ConvertHitObject(HitObject original, IBeatmap beatmap);
}
}
diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs
index 645e52a6c6..36fde8a319 100644
--- a/osu.Game/Beatmaps/BeatmapManager.cs
+++ b/osu.Game/Beatmaps/BeatmapManager.cs
@@ -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;
@@ -333,7 +335,7 @@ namespace osu.Game.Beatmaps
ms.Position = 0;
var decoder = Decoder.GetDecoder(sr);
- Beatmap beatmap = decoder.Decode(sr);
+ IBeatmap beatmap = decoder.Decode(sr);
beatmap.BeatmapInfo.Path = name;
beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash();
@@ -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;
}
+
+ ///
+ /// A dummy WorkingBeatmap for the purpose of retrieving a beatmap for star difficulty calculation.
+ ///
+ 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;
+ }
}
}
diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs
index 8e09d66c42..71406c6034 100644
--- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs
+++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs
@@ -30,7 +30,7 @@ namespace osu.Game.Beatmaps
this.audioManager = audioManager;
}
- protected override Beatmap GetBeatmap()
+ protected override IBeatmap GetBeatmap()
{
try
{
diff --git a/osu.Game/Beatmaps/BeatmapProcessor.cs b/osu.Game/Beatmaps/BeatmapProcessor.cs
index 8f5a2a4cab..bf1cd7d4ee 100644
--- a/osu.Game/Beatmaps/BeatmapProcessor.cs
+++ b/osu.Game/Beatmaps/BeatmapProcessor.cs
@@ -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; }
+
+ ///
+ /// Post-processes to add mode-specific components that aren't added during conversion.
+ ///
+ /// An example of such a usage is for combo colours.
+ ///
+ ///
+ void PostProcess();
+ }
+
///
/// Processes a post-converted Beatmap.
///
/// The type of HitObject contained in the Beatmap.
- public class BeatmapProcessor
- where TObject : HitObject
+ public class BeatmapProcessor : IBeatmapProcessor
{
+ public IBeatmap Beatmap { get; }
+
+ public BeatmapProcessor(IBeatmap beatmap)
+ {
+ Beatmap = beatmap;
+ }
+
///
/// Post-processes a Beatmap to add mode-specific components that aren't added during conversion.
///
/// An example of such a usage is for combo colours.
///
///
- /// The Beatmap to process.
- public virtual void PostProcess(Beatmap beatmap)
+ public virtual void PostProcess()
{
IHasComboInformation lastObj = null;
- foreach (var obj in beatmap.HitObjects.OfType())
+ foreach (var obj in Beatmap.HitObjects.OfType())
{
if (obj.NewCombo)
{
diff --git a/osu.Game/Beatmaps/DifficultyCalculator.cs b/osu.Game/Beatmaps/DifficultyCalculator.cs
index 5e2d9afd23..37155c09cd 100644
--- a/osu.Game/Beatmaps/DifficultyCalculator.cs
+++ b/osu.Game/Beatmaps/DifficultyCalculator.cs
@@ -1,7 +1,6 @@
// Copyright (c) 2007-2018 ppy Pty Ltd .
// 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 categoryDifficulty = null);
- }
-
- public abstract class DifficultyCalculator : DifficultyCalculator where T : HitObject
- {
- protected readonly Beatmap Beatmap;
+ protected readonly IBeatmap Beatmap;
protected readonly Mod[] Mods;
- protected DifficultyCalculator(Beatmap beatmap, Mod[] mods = null)
+ 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>())
- 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().ForEach(m => m.ApplyToClock(clock));
TimeRate = clock.Rate;
-
- foreach (var mod in Mods.OfType())
- mod.ApplyToDifficulty(Beatmap.BeatmapInfo.BaseDifficulty);
-
- foreach (var h in Beatmap.HitObjects)
- h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty);
-
- foreach (var mod in mods.OfType>())
- foreach (var obj in Beatmap.HitObjects)
- mod.ApplyToHitObject(obj);
}
protected virtual void PreprocessHitObjects()
{
}
- protected abstract BeatmapConverter CreateBeatmapConverter(Beatmap beatmap);
+ public abstract double Calculate(Dictionary categoryDifficulty = null);
}
}
diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs
index 0424ff84f1..da52dc7284 100644
--- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs
+++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs
@@ -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
@@ -39,7 +40,7 @@ namespace osu.Game.Beatmaps
this.game = game;
}
- protected override Beatmap GetBeatmap() => new Beatmap();
+ protected override IBeatmap GetBeatmap() => new Beatmap();
protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4");
@@ -53,12 +54,14 @@ namespace osu.Game.Beatmaps
{
public override IEnumerable GetModsFor(ModType type) => new Mod[] { };
- public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset)
+ public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap)
{
throw new NotImplementedException();
}
- public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => null;
+ 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> ObjectConverted;
+ public IBeatmap Beatmap { get; set; }
+ public bool CanConvert => true;
+ public IBeatmap Convert() => Beatmap;
+ }
}
}
}
diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
index 366b4f163f..655355913c 100644
--- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
@@ -373,17 +373,18 @@ namespace osu.Game.Beatmaps.Formats
if (parser == null)
parser = new Rulesets.Objects.Legacy.Osu.ConvertHitObjectParser();
- var obj = parser.Parse(line);
+ var obj = parser.Parse(line, getOffsetTime());
if (obj != null)
{
- obj.StartTime = getOffsetTime(obj.StartTime);
beatmap.HitObjects.Add(obj);
}
}
private int getOffsetTime(int time) => time + (ApplyOffsets ? offset : 0);
+ private double getOffsetTime() => ApplyOffsets ? offset : 0;
+
private double getOffsetTime(double time) => time + (ApplyOffsets ? offset : 0);
}
}
diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs
new file mode 100644
index 0000000000..fe20bce98a
--- /dev/null
+++ b/osu.Game/Beatmaps/IBeatmap.cs
@@ -0,0 +1,56 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System.Collections.Generic;
+using osu.Game.Beatmaps.ControlPoints;
+using osu.Game.Beatmaps.Timing;
+using osu.Game.IO.Serialization;
+using osu.Game.Rulesets.Objects;
+
+namespace osu.Game.Beatmaps
+{
+ public interface IBeatmap : IJsonSerializable
+ {
+ ///
+ /// This beatmap's info.
+ ///
+ BeatmapInfo BeatmapInfo { get; set; }
+
+ ///
+ /// This beatmap's metadata.
+ ///
+ BeatmapMetadata Metadata { get; }
+
+ ///
+ /// The control points in this beatmap.
+ ///
+ ControlPointInfo ControlPointInfo { get; }
+
+ ///
+ /// The breaks in this beatmap.
+ ///
+ List Breaks { get; }
+
+ ///
+ /// Total amount of break time in the beatmap.
+ ///
+ double TotalBreakTime { get; }
+
+ ///
+ /// The hitobjects contained by this beatmap.
+ ///
+ IEnumerable HitObjects { get; }
+
+ ///
+ /// Returns statistics for the contained in this beatmap.
+ ///
+ ///
+ IEnumerable GetStatistics();
+
+ ///
+ /// Creates a shallow-clone of this beatmap and returns it.
+ ///
+ /// The shallow-cloned beatmap.
+ IBeatmap Clone();
+ }
+}
diff --git a/osu.Game/Beatmaps/IBeatmapConverter.cs b/osu.Game/Beatmaps/IBeatmapConverter.cs
index 6c25395a56..00566093b8 100644
--- a/osu.Game/Beatmaps/IBeatmapConverter.cs
+++ b/osu.Game/Beatmaps/IBeatmapConverter.cs
@@ -16,10 +16,16 @@ namespace osu.Game.Beatmaps
///
event Action> ObjectConverted;
+ IBeatmap Beatmap { get; }
+
///
- /// Converts a Beatmap using this Beatmap Converter.
+ /// Whether can be converted by this .
///
- /// The un-converted Beatmap.
- void Convert(Beatmap beatmap);
+ bool CanConvert { get; }
+
+ ///
+ /// Converts .
+ ///
+ IBeatmap Convert();
}
}
diff --git a/osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs b/osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs
deleted file mode 100644
index eea82dac6d..0000000000
--- a/osu.Game/Beatmaps/Legacy/LegacyBeatmap.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-namespace osu.Game.Beatmaps.Legacy
-{
- ///
- /// A type of Beatmap loaded from a legacy .osu beatmap file (version <=15).
- ///
- public class LegacyBeatmap : Beatmap
- {
- ///
- /// Constructs a new beatmap.
- ///
- /// The original beatmap to use the parameters of.
- internal LegacyBeatmap(Beatmap original = null)
- : base(original)
- {
- HitObjects = original?.HitObjects;
- }
- }
-}
diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs
index 4080e34e81..9c389bbb8f 100644
--- a/osu.Game/Beatmaps/WorkingBeatmap.cs
+++ b/osu.Game/Beatmaps/WorkingBeatmap.cs
@@ -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
@@ -36,7 +38,7 @@ namespace osu.Game.Beatmaps
Mods.ValueChanged += mods => applyRateAdjustments();
- beatmap = new AsyncLazy(populateBeatmap);
+ beatmap = new AsyncLazy(populateBeatmap);
background = new AsyncLazy(populateBackground, b => b == null || !b.IsDisposed);
track = new AsyncLazy