diff --git a/.vscode/launch.json b/.vscode/launch.json
index b981556649..0e07b0a067 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -3,6 +3,9 @@
"configurations": [
{
"name": "Launch VisualTests",
+ "windows": {
+ "type": "clr"
+ },
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Desktop.VisualTests/bin/Debug/osu!.exe",
@@ -11,10 +14,13 @@
"preLaunchTask": "build",
"runtimeExecutable": null,
"env": {},
- "externalConsole": false
+ "console": "internalConsole"
},
{
"name": "Launch Desktop",
+ "windows": {
+ "type": "clr"
+ },
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Desktop/bin/Debug/osu!.exe",
@@ -23,10 +29,15 @@
"preLaunchTask": "build",
"runtimeExecutable": null,
"env": {},
- "externalConsole": false
+ "console": "internalConsole"
},
{
"name": "Attach",
+ "windows": {
+ "type": "clr",
+ "request": "attach",
+ "processName": "osu!"
+ },
"type": "mono",
"request": "attach",
"address": "localhost",
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 0c0e79f7fb..5eaeaa9899 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -2,25 +2,50 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
- "windows": {
- "command": "msbuild"
- },
- "linux": {
- "command": "xbuild"
- },
- "args": [
- // Ask msbuild to generate full paths for file names.
- "/property:GenerateFullPaths=true"
- ],
"taskSelector": "/t:",
- "showOutput": "silent",
"tasks": [
{
"taskName": "build",
- // Show the output window only if unrecognized errors occur.
+ "isShellCommand": true,
"showOutput": "silent",
+ "command": "msbuild",
+ "args": [
+ "/property:GenerateFullPaths=true",
+ "/property:DebugType=portable"
+ ],
+ "windows": {
+ "args": [
+ "/property:GenerateFullPaths=true",
+ "/property:DebugType=portable",
+ "/m" //parallel compiling support. doesn't work well with mono atm
+ ]
+ },
// Use the standard MS compiler pattern to detect errors, warnings and infos
- "problemMatcher": "$msCompile"
+ "problemMatcher": "$msCompile",
+ "isBuildCommand": true
+ },
+ {
+ "taskName": "rebuild",
+ "isShellCommand": true,
+ "showOutput": "silent",
+ "command": "msbuild",
+ "args": [
+ // Ask msbuild to generate full paths for file names.
+ "/property:GenerateFullPaths=true",
+ "/property:DebugType=portable",
+ "/target:Clean,Build"
+ ],
+ "windows": {
+ "args": [
+ "/property:GenerateFullPaths=true",
+ "/property:DebugType=portable",
+ "/target:Clean,Build",
+ "/m" //parallel compiling support. doesn't work well with mono atm
+ ]
+ },
+ // Use the standard MS compiler pattern to detect errors, warnings and infos
+ "problemMatcher": "$msCompile",
+ "isBuildCommand": true
}
]
}
\ No newline at end of file
diff --git a/README.md b/README.md
index 885c7c7722..3306c9ab25 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,4 @@
-# osu! [![Build status](https://ci.appveyor.com/api/projects/status/u2p01nx7l6og8buh?svg=true)](https://ci.appveyor.com/project/peppy/osu)
-
-
+# osu! [![Build status](https://ci.appveyor.com/api/projects/status/u2p01nx7l6og8buh?svg=true)](https://ci.appveyor.com/project/peppy/osu) [![CodeFactor](https://www.codefactor.io/repository/github/ppy/osu/badge)](https://www.codefactor.io/repository/github/ppy/osu)
[osu! on the web](https://osu.ppy.sh) | [dev chat](https://discord.gg/ppy)
@@ -12,14 +10,14 @@ This is still heavily under development and is not intended for end-user use. Th
# Requirements
-- A desktop platform which can compile .NET 4.5.
-- Visual Studio or MonoDevelop is recommended.
+- A desktop platform which can compile .NET 4.5 (tested on macOS, linux and windows). We recommend using [Visual Studio Code](https://code.visualstudio.com/) (all platforms) or [Visual Studio Community Edition](https://www.visualstudio.com/) (windows only), both of which are free.
+- Make sure you initialise and keep submodules up-to-date.
# Contributing
We welcome all contributions, but keep in mind that we already have a lot of the UI designed. If you wish to work on something with the intention on having it included in the official distribution, please open an issue for discussion and we will give you what you need from a design perspective to proceed. If you want to make *changes* to the design, we recommend you open an issue with your intentions before spending too much time, to ensure no effort is wasted.
-Contributions can be made via pull requests to this repository. We hope to credit and reward larger contributions via a [bounty system](https://goo.gl/nFdoyI). If you're unsure of what you can help with, check out the [list](https://github.com/ppy/osu/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3Abounty) of available issues with bounty.
+Contributions can be made via pull requests to this repository. We hope to credit and reward larger contributions via a [bounty system](https://www.bountysource.com/teams/ppy). If you're unsure of what you can help with, check out the [list of open issues](https://github.com/ppy/osu-framework/issues).
Note that while we already have certain standards in place, nothing is set in stone. If you have an issue with the way code is structured; with any libraries we are using; with any processes involved with contributing, *please* bring it up. I welcome all feedback so we can make contributing to this project as pain-free as possible.
diff --git a/osu-framework b/osu-framework
index 45e75163b2..fc93e11439 160000
--- a/osu-framework
+++ b/osu-framework
@@ -1 +1 @@
-Subproject commit 45e75163b272b7aa023afec7801ea079aba4ee69
+Subproject commit fc93e11439b8b391d9e01e208368d96ba85bfa26
diff --git a/osu-resources b/osu-resources
index 0cba3cbc16..b90c4ed490 160000
--- a/osu-resources
+++ b/osu-resources
@@ -1 +1 @@
-Subproject commit 0cba3cbc167cfe94e07fe5b629c925e190be939e
+Subproject commit b90c4ed490f76f2995662b3a8af3a32b8756a012
diff --git a/osu.Desktop.Deploy/App.config b/osu.Desktop.Deploy/App.config
index d1da144f50..45685a74a8 100644
--- a/osu.Desktop.Deploy/App.config
+++ b/osu.Desktop.Deploy/App.config
@@ -21,4 +21,16 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
index 7a3719a25b..1f9726b573 100644
--- a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
+++ b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj
@@ -22,6 +22,7 @@
DEBUG;TRACE
prompt
4
+ 6
AnyCPU
@@ -68,9 +69,8 @@
$(SolutionDir)\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.Rocks.dll
True
-
- $(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
- True
+
+ $(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll
$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\NuGet.Squirrel.dll
@@ -120,7 +120,7 @@
-
-
-
+
+
diff --git a/osu.Desktop.VisualTests/Program.cs b/osu.Desktop.VisualTests/Program.cs
index fe1cdfd7f0..03d1588b78 100644
--- a/osu.Desktop.VisualTests/Program.cs
+++ b/osu.Desktop.VisualTests/Program.cs
@@ -4,11 +4,6 @@
using System;
using osu.Framework.Desktop;
using osu.Framework.Platform;
-using osu.Game.Modes;
-using osu.Game.Modes.Catch;
-using osu.Game.Modes.Mania;
-using osu.Game.Modes.Osu;
-using osu.Game.Modes.Taiko;
namespace osu.Desktop.VisualTests
{
@@ -21,11 +16,6 @@ namespace osu.Desktop.VisualTests
using (GameHost host = Host.GetSuitableHost(@"osu"))
{
- Ruleset.Register(new OsuRuleset());
- Ruleset.Register(new TaikoRuleset());
- Ruleset.Register(new ManiaRuleset());
- Ruleset.Register(new CatchRuleset());
-
if (benchmark)
host.Run(new AutomatedVisualTestGame());
else
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseBeatmapDetails.cs b/osu.Desktop.VisualTests/Tests/TestCaseBeatmapDetails.cs
new file mode 100644
index 0000000000..4a59ad9534
--- /dev/null
+++ b/osu.Desktop.VisualTests/Tests/TestCaseBeatmapDetails.cs
@@ -0,0 +1,65 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Primitives;
+using osu.Framework.Testing;
+using osu.Game.Database;
+using osu.Game.Screens.Select;
+using System.Linq;
+
+namespace osu.Desktop.VisualTests.Tests
+{
+ internal class TestCaseBeatmapDetails : TestCase
+ {
+ public override string Description => "BeatmapDetails tab of BeatmapDetailArea";
+
+ private BeatmapDetails details;
+
+ public override void Reset()
+ {
+ base.Reset();
+
+ Add(details = new BeatmapDetails
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding(150),
+ Beatmap = new BeatmapInfo
+ {
+ Version = "VisualTest",
+ Metadata = new BeatmapMetadata
+ {
+ Source = "Some guy",
+ Tags = "beatmap metadata example with a very very long list of tags and not much creativity",
+ },
+ Difficulty = new BeatmapDifficulty
+ {
+ CircleSize = 7,
+ ApproachRate = 3.5f,
+ OverallDifficulty = 5.7f,
+ DrainRate = 1,
+ },
+ StarDifficulty = 5.3f,
+ Metrics = new BeatmapMetrics
+ {
+ Ratings = Enumerable.Range(0,10),
+ Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6),
+ Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6),
+ },
+ },
+ });
+
+ AddRepeatStep("fail values", newRetryAndFailValues, 10);
+ }
+
+ private int lastRange = 1;
+
+ private void newRetryAndFailValues()
+ {
+ details.Beatmap.Metrics.Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6);
+ details.Beatmap.Metrics.Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6);
+ details.Beatmap = details.Beatmap;
+ lastRange += 100;
+ }
+ }
+}
\ No newline at end of file
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs b/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs
index 3129cade63..cb15558ec3 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs
@@ -9,21 +9,30 @@ using osu.Framework.Testing;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Database;
-using osu.Game.Modes.Catch.UI;
-using osu.Game.Modes.Mania.UI;
-using osu.Game.Modes.Objects;
-using osu.Game.Modes.Osu.Objects;
-using osu.Game.Modes.Osu.UI;
-using osu.Game.Modes.Taiko.UI;
+using osu.Game.Rulesets.Catch.UI;
+using osu.Game.Rulesets.Mania.UI;
+using osu.Game.Rulesets.Objects;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Rulesets.Osu.UI;
+using osu.Game.Rulesets.Taiko.UI;
using System.Collections.Generic;
using osu.Desktop.VisualTests.Beatmaps;
+using osu.Framework.Allocation;
namespace osu.Desktop.VisualTests.Tests
{
internal class TestCaseGamefield : TestCase
{
+ private RulesetDatabase rulesets;
+
public override string Description => @"Showing hitobjects and what not.";
+ [BackgroundDependencyLoader]
+ private void load(RulesetDatabase rulesets)
+ {
+ this.rulesets = rulesets;
+ }
+
public override void Reset()
{
base.Reset();
@@ -36,7 +45,7 @@ namespace osu.Desktop.VisualTests.Tests
objects.Add(new HitCircle
{
StartTime = time,
- Position = new Vector2(RNG.Next(0, 512), RNG.Next(0, 384)),
+ Position = new Vector2(RNG.Next(0, (int)OsuPlayfield.BASE_SIZE.X), RNG.Next(0, (int)OsuPlayfield.BASE_SIZE.Y)),
Scale = RNG.NextSingle(0.5f, 1.0f),
});
@@ -49,6 +58,7 @@ namespace osu.Desktop.VisualTests.Tests
BeatmapInfo = new BeatmapInfo
{
Difficulty = new BeatmapDifficulty(),
+ Ruleset = rulesets.Query().First(),
Metadata = new BeatmapMetadata
{
Artist = @"Unknown",
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseGraph.cs b/osu.Desktop.VisualTests/Tests/TestCaseGraph.cs
new file mode 100644
index 0000000000..7ac795f6f9
--- /dev/null
+++ b/osu.Desktop.VisualTests/Tests/TestCaseGraph.cs
@@ -0,0 +1,42 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+using osu.Framework.Graphics;
+using osu.Framework.Testing;
+using osu.Game.Graphics.UserInterface;
+using System.Linq;
+
+namespace osu.Desktop.VisualTests.Tests
+{
+ internal class TestCaseGraph : TestCase
+ {
+ public override string Description => "graph";
+
+ private BarGraph graph;
+
+ public override void Reset()
+ {
+ base.Reset();
+
+ Children = new[]
+ {
+ graph = new BarGraph
+ {
+ RelativeSizeAxes = Axes.Both,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Size = new Vector2(0.5f),
+ },
+ };
+
+ AddStep("values from 1-10", () => graph.Values = Enumerable.Range(1,10).Select(i => (float)i));
+ AddStep("values from 1-100", () => graph.Values = Enumerable.Range(1, 100).Select(i => (float)i));
+ AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().Select(i => (float)i));
+ AddStep("Bottom to top", () => graph.Direction = BarDirection.BottomToTop);
+ AddStep("Top to bottom", () => graph.Direction = BarDirection.TopToBottom);
+ AddStep("Left to right", () => graph.Direction = BarDirection.LeftToRight);
+ AddStep("Right to left", () => graph.Direction = BarDirection.RightToLeft);
+ }
+ }
+}
\ No newline at end of file
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs
index 99da7d1c73..dceb7a9cff 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseHitObjects.cs
@@ -10,11 +10,10 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Testing;
using osu.Framework.Timing;
-using osu.Game.Modes.Objects;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Osu.Judgements;
-using osu.Game.Modes.Osu.Objects;
-using osu.Game.Modes.Osu.Objects.Drawables;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Judgements;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
using System.Collections.Generic;
namespace osu.Desktop.VisualTests.Tests
@@ -62,15 +61,12 @@ namespace osu.Desktop.VisualTests.Tests
add(new DrawableSlider(new Slider
{
StartTime = framedClock.CurrentTime + 600,
- CurveObject = new CurvedHitObject
+ ControlPoints = new List
{
- ControlPoints = new List
- {
- new Vector2(-200, 0),
- new Vector2(400, 0),
- },
- Distance = 400
+ new Vector2(-200, 0),
+ new Vector2(400, 0),
},
+ Distance = 400,
Position = new Vector2(-200, 0),
Velocity = 1,
TickDistance = 100,
@@ -99,6 +95,7 @@ namespace osu.Desktop.VisualTests.Tests
AddToggleStep(@"auto", state => { auto = state; load(mode); });
+ BasicSliderBar sliderBar;
Add(new Container
{
Anchor = Anchor.TopRight,
@@ -107,16 +104,17 @@ namespace osu.Desktop.VisualTests.Tests
Children = new Drawable[]
{
new SpriteText { Text = "Playback Speed" },
- new BasicSliderBar
+ sliderBar = new BasicSliderBar
{
Width = 150,
Height = 10,
SelectionColor = Color4.Orange,
- Value = playbackSpeed
}
}
});
+ sliderBar.Current.BindTo(playbackSpeed);
+
framedClock.ProcessFrame();
var clockAdjustContainer = new Container
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs b/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs
index 7e7782662b..b1b9ddbcda 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseKeyCounter.cs
@@ -44,6 +44,8 @@ namespace osu.Desktop.VisualTests.Tests
kc.Add(new KeyCounterKeyboard(key));
});
+ TestSliderBar sliderBar;
+
Add(new Container
{
Anchor = Anchor.TopRight,
@@ -52,16 +54,17 @@ namespace osu.Desktop.VisualTests.Tests
Children = new Drawable[]
{
new SpriteText { Text = "FadeTime" },
- new TestSliderBar
+ sliderBar =new TestSliderBar
{
Width = 150,
Height = 10,
SelectionColor = Color4.Orange,
- Value = bindable
}
}
});
+ sliderBar.Current.BindTo(bindable);
+
Add(kc);
}
private class TestSliderBar : SliderBar where T : struct
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseLeaderboard.cs b/osu.Desktop.VisualTests/Tests/TestCaseLeaderboard.cs
index 44e52c237e..39010baf91 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseLeaderboard.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseLeaderboard.cs
@@ -4,9 +4,9 @@
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Testing;
-using osu.Game.Modes.Mods;
-using osu.Game.Modes.Osu.Mods;
-using osu.Game.Modes.Scoring;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Osu.Mods;
+using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Select.Leaderboards;
using osu.Game.Users;
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseModSelectOverlay.cs b/osu.Desktop.VisualTests/Tests/TestCaseModSelectOverlay.cs
index 7677682ac8..d1c137191f 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseModSelectOverlay.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseModSelectOverlay.cs
@@ -1,10 +1,11 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Overlays.Mods;
using osu.Framework.Testing;
-using osu.Game.Modes;
+using osu.Game.Database;
namespace osu.Desktop.VisualTests.Tests
{
@@ -13,6 +14,13 @@ namespace osu.Desktop.VisualTests.Tests
public override string Description => @"Tests the mod select overlay";
private ModSelectOverlay modSelect;
+ private RulesetDatabase rulesets;
+
+ [BackgroundDependencyLoader]
+ private void load(RulesetDatabase rulesets)
+ {
+ this.rulesets = rulesets;
+ }
public override void Reset()
{
@@ -26,10 +34,9 @@ namespace osu.Desktop.VisualTests.Tests
});
AddStep("Toggle", modSelect.ToggleVisibility);
- AddStep("osu!", () => modSelect.PlayMode.Value = PlayMode.Osu);
- AddStep("osu!taiko", () => modSelect.PlayMode.Value = PlayMode.Taiko);
- AddStep("osu!catch", () => modSelect.PlayMode.Value = PlayMode.Catch);
- AddStep("osu!mania", () => modSelect.PlayMode.Value = PlayMode.Mania);
+
+ foreach (var ruleset in rulesets.AllRulesets)
+ AddStep(ruleset.CreateInstance().Description, () => modSelect.Ruleset.Value = ruleset);
}
}
}
diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs b/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs
index 1a43425dda..35eb6d0ff9 100644
--- a/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs
@@ -6,7 +6,6 @@ using osu.Desktop.VisualTests.Platform;
using osu.Framework.Testing;
using osu.Framework.MathUtils;
using osu.Game.Database;
-using osu.Game.Modes;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Filter;
@@ -20,13 +19,19 @@ namespace osu.Desktop.VisualTests.Tests
public override string Description => @"with fake data";
+ private RulesetDatabase rulesets;
+
public override void Reset()
{
base.Reset();
if (db == null)
{
storage = new TestStorage(@"TestCasePlaySongSelect");
- db = new BeatmapDatabase(storage);
+
+ var backingDatabase = storage.GetDatabase(@"client");
+
+ rulesets = new RulesetDatabase(storage, backingDatabase);
+ db = new BeatmapDatabase(storage, backingDatabase, rulesets);
var sets = new List();
@@ -72,7 +77,7 @@ namespace osu.Desktop.VisualTests.Tests
new BeatmapInfo
{
OnlineBeatmapID = 1234 + i,
- Mode = PlayMode.Osu,
+ Ruleset = rulesets.Query().First(),
Path = "normal.osu",
Version = "Normal",
Difficulty = new BeatmapDifficulty
@@ -83,7 +88,7 @@ namespace osu.Desktop.VisualTests.Tests
new BeatmapInfo
{
OnlineBeatmapID = 1235 + i,
- Mode = PlayMode.Osu,
+ Ruleset = rulesets.Query().First(),
Path = "hard.osu",
Version = "Hard",
Difficulty = new BeatmapDifficulty
@@ -94,7 +99,7 @@ namespace osu.Desktop.VisualTests.Tests
new BeatmapInfo
{
OnlineBeatmapID = 1236 + i,
- Mode = PlayMode.Osu,
+ Ruleset = rulesets.Query().First(),
Path = "insane.osu",
Version = "Insane",
Difficulty = new BeatmapDifficulty
diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs
index f36889b02a..f28cdd6a7e 100644
--- a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs
@@ -9,12 +9,12 @@ using osu.Game.Beatmaps;
using OpenTK;
using osu.Framework.Graphics.Sprites;
using osu.Game.Database;
-using osu.Game.Modes;
-using osu.Game.Modes.Objects;
-using osu.Game.Modes.Osu.Objects;
+using osu.Game.Rulesets.Objects;
+using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Play;
using OpenTK.Graphics;
using osu.Desktop.VisualTests.Beatmaps;
+using osu.Game.Rulesets.Osu.UI;
namespace osu.Desktop.VisualTests.Tests
{
@@ -22,12 +22,14 @@ namespace osu.Desktop.VisualTests.Tests
{
protected Player Player;
private BeatmapDatabase db;
+ private RulesetDatabase rulesets;
public override string Description => @"Showing everything to play the game.";
[BackgroundDependencyLoader]
- private void load(BeatmapDatabase db)
+ private void load(BeatmapDatabase db, RulesetDatabase rulesets)
{
+ this.rulesets = rulesets;
this.db = db;
}
@@ -37,7 +39,7 @@ namespace osu.Desktop.VisualTests.Tests
WorkingBeatmap beatmap = null;
- var beatmapInfo = db.Query().FirstOrDefault(b => b.Mode == PlayMode.Osu);
+ var beatmapInfo = db.Query().FirstOrDefault(b => b.RulesetID == 0);
if (beatmapInfo != null)
beatmap = db.GetWorkingBeatmap(beatmapInfo);
@@ -51,8 +53,8 @@ namespace osu.Desktop.VisualTests.Tests
objects.Add(new HitCircle
{
StartTime = time,
- Position = new Vector2(i % 4 == 0 || i % 4 == 2 ? 0 : 512,
- i % 4 < 2 ? 0 : 384),
+ Position = new Vector2(i % 4 == 0 || i % 4 == 2 ? 0 : OsuPlayfield.BASE_SIZE.X,
+ i % 4 < 2 ? 0 : OsuPlayfield.BASE_SIZE.Y),
NewCombo = i % 4 == 0
});
@@ -65,6 +67,7 @@ namespace osu.Desktop.VisualTests.Tests
BeatmapInfo = new BeatmapInfo
{
Difficulty = new BeatmapDifficulty(),
+ Ruleset = rulesets.Query().First(),
Metadata = new BeatmapMetadata
{
Artist = @"Unknown",
@@ -83,10 +86,7 @@ namespace osu.Desktop.VisualTests.Tests
Colour = Color4.Black,
});
- Add(new PlayerLoader(Player = CreatePlayer(beatmap))
- {
- Beatmap = beatmap
- });
+ Add(Player = CreatePlayer(beatmap));
}
protected virtual Player CreatePlayer(WorkingBeatmap beatmap)
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseReplay.cs b/osu.Desktop.VisualTests/Tests/TestCaseReplay.cs
index ffdca25bb3..e00a912278 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseReplay.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseReplay.cs
@@ -2,8 +2,8 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
-using osu.Game.Modes.Mods;
-using osu.Game.Modes.Osu.Mods;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.Play;
namespace osu.Desktop.VisualTests.Tests
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseResults.cs b/osu.Desktop.VisualTests/Tests/TestCaseResults.cs
new file mode 100644
index 0000000000..aa3a117667
--- /dev/null
+++ b/osu.Desktop.VisualTests/Tests/TestCaseResults.cs
@@ -0,0 +1,68 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using osu.Framework.Allocation;
+using osu.Framework.Testing;
+using osu.Game.Beatmaps;
+using osu.Game.Database;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Screens.Ranking;
+using osu.Game.Users;
+
+namespace osu.Desktop.VisualTests.Tests
+{
+ internal class TestCaseResults : TestCase
+ {
+ private BeatmapDatabase db;
+
+ public override string Description => @"Results after playing.";
+
+ [BackgroundDependencyLoader]
+ private void load(BeatmapDatabase db)
+ {
+ this.db = db;
+ }
+
+ private WorkingBeatmap beatmap;
+
+ public override void Reset()
+ {
+ base.Reset();
+
+ if (beatmap == null)
+ {
+ var beatmapInfo = db.Query().FirstOrDefault(b => b.RulesetID == 0);
+ if (beatmapInfo != null)
+ beatmap = db.GetWorkingBeatmap(beatmapInfo);
+ }
+
+ base.Reset();
+
+ Add(new Results(new Score
+ {
+ TotalScore = 2845370,
+ Accuracy = 0.98,
+ MaxCombo = 123,
+ Rank = ScoreRank.A,
+ Date = DateTime.Now,
+ Statistics = new Dictionary()
+ {
+ { "300", 50 },
+ { "100", 20 },
+ { "50", 50 },
+ { "x", 1 }
+ },
+ User = new User
+ {
+ Username = "peppy",
+ }
+ })
+ {
+ Beatmap = beatmap
+ });
+ }
+ }
+}
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseScoreCounter.cs b/osu.Desktop.VisualTests/Tests/TestCaseScoreCounter.cs
index f3cca16678..d8dac63980 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseScoreCounter.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseScoreCounter.cs
@@ -8,7 +8,7 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.MathUtils;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.UI;
namespace osu.Desktop.VisualTests.Tests
{
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseSongProgress.cs b/osu.Desktop.VisualTests/Tests/TestCaseSongProgress.cs
new file mode 100644
index 0000000000..6d8aac1d09
--- /dev/null
+++ b/osu.Desktop.VisualTests/Tests/TestCaseSongProgress.cs
@@ -0,0 +1,60 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System.Collections.Generic;
+using osu.Framework.Graphics;
+using osu.Framework.MathUtils;
+using osu.Framework.Testing;
+using osu.Framework.Timing;
+using osu.Game.Rulesets.Objects;
+using osu.Game.Screens.Play;
+
+namespace osu.Desktop.VisualTests.Tests
+{
+ internal class TestCaseSongProgress : TestCase
+ {
+ public override string Description => @"With fake data";
+
+ private SongProgress progress;
+ private SongProgressGraph graph;
+
+ public override void Reset()
+ {
+ base.Reset();
+
+ Add(progress = new SongProgress
+ {
+ RelativeSizeAxes = Axes.X,
+ AudioClock = new StopwatchClock(true),
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ });
+
+ Add(graph = new SongProgressGraph
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = 200,
+ Anchor = Anchor.TopLeft,
+ Origin = Anchor.TopLeft,
+ });
+
+ AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking);
+ AddWaitStep(5);
+ AddStep("Toggle Bar", () => progress.AllowSeeking = !progress.AllowSeeking);
+ AddWaitStep(2);
+ AddRepeatStep("New Values", displayNewValues, 5);
+
+ displayNewValues();
+ }
+
+ private void displayNewValues()
+ {
+ List objects = new List();
+ for (double i = 0; i < 5000; i += RNG.NextDouble() * 10 + i / 1000)
+ objects.Add(new HitObject { StartTime = i });
+
+ progress.Objects = objects;
+ graph.Objects = objects;
+ }
+ }
+}
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTabControl.cs b/osu.Desktop.VisualTests/Tests/TestCaseTabControl.cs
index 2d3969b822..b72abd1992 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseTabControl.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseTabControl.cs
@@ -36,7 +36,7 @@ namespace osu.Desktop.VisualTests.Tests
filter.PinItem(GroupMode.All);
filter.PinItem(GroupMode.RecentlyPlayed);
- filter.SelectedItem.ValueChanged += newFilter =>
+ filter.Current.ValueChanged += newFilter =>
{
text.Text = "Currently Selected: " + newFilter.ToString();
};
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs b/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs
index b3cb8c3457..d769071bd9 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseTaikoHitObjects.cs
@@ -6,7 +6,7 @@ using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
-using osu.Game.Modes.Taiko.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
namespace osu.Desktop.VisualTests.Tests
{
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
index 88a037afee..259d0267db 100644
--- a/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
+++ b/osu.Desktop.VisualTests/Tests/TestCaseTaikoPlayfield.cs
@@ -1,30 +1,33 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using osu.Framework.Testing;
using osu.Framework.Timing;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Taiko.Judgements;
-using osu.Game.Modes.Taiko.Objects;
-using osu.Game.Modes.Taiko.Objects.Drawables;
-using osu.Game.Modes.Taiko.UI;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.Judgements;
+using osu.Game.Rulesets.Taiko.Objects;
+using osu.Game.Rulesets.Taiko.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.UI;
+using System;
namespace osu.Desktop.VisualTests.Tests
{
internal class TestCaseTaikoPlayfield : TestCase
{
- public override string Description => "Taiko playfield";
+ private const double default_duration = 300;
+ private const float scroll_time = 1000;
- private TaikoPlayfield playfield;
+ public override string Description => "Taiko playfield";
protected override double TimePerAction => default_duration * 2;
- private const double default_duration = 300;
-
- private const float scroll_time = 1000;
+ private readonly Random rng = new Random(1337);
+ private TaikoPlayfield playfield;
+ private Container playfieldContainer;
public override void Reset()
{
@@ -41,15 +44,22 @@ namespace osu.Desktop.VisualTests.Tests
AddStep("Strong Rim", () => addRimHit(true));
AddStep("Add bar line", () => addBarLine(false));
AddStep("Add major bar line", () => addBarLine(true));
-
+ AddStep("Height test 1", () => changePlayfieldSize(1));
+ AddStep("Height test 2", () => changePlayfieldSize(2));
+ AddStep("Height test 3", () => changePlayfieldSize(3));
+ AddStep("Height test 4", () => changePlayfieldSize(4));
+ AddStep("Height test 5", () => changePlayfieldSize(5));
+ AddStep("Reset height", () => changePlayfieldSize(6));
var rateAdjustClock = new StopwatchClock(true) { Rate = 1 };
- Add(new Container
+ Add(playfieldContainer = new Container
{
- Clock = new FramedClock(rateAdjustClock),
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
- Y = 200,
+ Height = TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT,
+ Clock = new FramedClock(rateAdjustClock),
Children = new[]
{
playfield = new TaikoPlayfield()
@@ -57,21 +67,63 @@ namespace osu.Desktop.VisualTests.Tests
});
}
+ private void changePlayfieldSize(int step)
+ {
+ // Add new hits
+ switch (step)
+ {
+ case 1:
+ addCentreHit(false);
+ break;
+ case 2:
+ addCentreHit(true);
+ break;
+ case 3:
+ addDrumRoll(false);
+ break;
+ case 4:
+ addDrumRoll(true);
+ break;
+ case 5:
+ addSwell(1000);
+ playfieldContainer.Delay(scroll_time - 100);
+ break;
+ }
+
+ // Tween playfield height
+ switch (step)
+ {
+ default:
+ playfieldContainer.ResizeTo(new Vector2(1, rng.Next(25, 400)), 500);
+ break;
+ case 6:
+ playfieldContainer.ResizeTo(new Vector2(1, TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT), 500);
+ break;
+ }
+ }
+
private void addHitJudgement()
{
TaikoHitResult hitResult = RNG.Next(2) == 0 ? TaikoHitResult.Good : TaikoHitResult.Great;
- playfield.OnJudgement(new DrawableTestHit(new Hit())
+ var h = new DrawableTestHit(new Hit())
{
X = RNG.NextSingle(hitResult == TaikoHitResult.Good ? -0.1f : -0.05f, hitResult == TaikoHitResult.Good ? 0.1f : 0.05f),
Judgement = new TaikoJudgement
{
Result = HitResult.Hit,
TaikoResult = hitResult,
- TimeOffset = 0,
- SecondHit = RNG.Next(10) == 0
+ TimeOffset = 0
}
- });
+ };
+
+ playfield.OnJudgement(h);
+
+ if (RNG.Next(10) == 0)
+ {
+ h.Judgement.SecondHit = true;
+ playfield.OnJudgement(h);
+ }
}
private void addMissJudgement()
diff --git a/osu.Desktop.VisualTests/Tests/TestCaseTooltip.cs b/osu.Desktop.VisualTests/Tests/TestCaseTooltip.cs
new file mode 100644
index 0000000000..c536672314
--- /dev/null
+++ b/osu.Desktop.VisualTests/Tests/TestCaseTooltip.cs
@@ -0,0 +1,92 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Testing;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Graphics.UserInterface;
+using osu.Framework.Configuration;
+using OpenTK;
+using osu.Game.Graphics;
+
+namespace osu.Desktop.VisualTests.Tests
+{
+ internal class TestCaseTooltip : TestCase
+ {
+ public override string Description => "tests tooltips on various elements";
+
+ public override void Reset()
+ {
+ base.Reset();
+ OsuSliderBar slider;
+ OsuSliderBar sliderDouble;
+
+ const float width = 400;
+
+ Children = new Drawable[]
+ {
+ new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ Direction = FillDirection.Vertical,
+ Spacing = new Vector2(0, 10),
+ Children = new Drawable[]
+ {
+ new TooltipTextContainer("text with a tooltip"),
+ new TooltipTextContainer("more text with another tooltip"),
+ new TooltipTextbox
+ {
+ Text = "a textbox with a tooltip",
+ Size = new Vector2(width,30),
+ },
+ slider = new OsuSliderBar
+ {
+ Width = width,
+ },
+ sliderDouble = new OsuSliderBar
+ {
+ Width = width,
+ },
+ },
+ },
+ };
+
+ slider.Current.BindTo(new BindableInt(5)
+ {
+ MaxValue = 10,
+ MinValue = 0
+ });
+
+ sliderDouble.Current.BindTo(new BindableDouble(0.5)
+ {
+ MaxValue = 1,
+ MinValue = 0
+ });
+ }
+
+ private class TooltipTextContainer : Container, IHasTooltip
+ {
+ private readonly OsuSpriteText text;
+
+ public string TooltipText => text.Text;
+
+ public TooltipTextContainer(string tooltipText)
+ {
+ AutoSizeAxes = Axes.Both;
+ Children = new[]
+ {
+ text = new OsuSpriteText
+ {
+ Text = tooltipText,
+ }
+ };
+ }
+ }
+
+ private class TooltipTextbox : OsuTextBox, IHasTooltip
+ {
+ public string TooltipText => Text;
+ }
+ }
+}
diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
index da068c5557..135e4596c7 100644
--- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
+++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj
@@ -61,6 +61,7 @@
false
false
false
+ 6
none
@@ -83,22 +84,20 @@
-
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+
+ $(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll
-
- ..\packages\SharpCompress.0.15.1\lib\net45\SharpCompress.dll
- True
+
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
+
+
+ $(SolutionDir)\packages\SharpCompress.0.15.2\lib\net45\SharpCompress.dll
False
$(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll
-
- $(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
-
$(SolutionDir)\packages\SQLiteNetExtensions.1.3.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\SQLiteNetExtensions.dll
@@ -162,21 +161,21 @@
{d9a367c9-4c1a-489f-9b05-a0cea2b53b58}
osu.Game.Resources
-
+
{c92a607b-1fdd-4954-9f92-03ff547d9080}
- osu.Game.Modes.Osu
+ osu.Game.Rulesets.Osu
-
+
{58f6c80c-1253-4a0e-a465-b8c85ebeadf3}
- osu.Game.Modes.Catch
+ osu.Game.Rulesets.Catch
-
+
{48f4582b-7687-4621-9cbe-5c24197cb536}
- osu.Game.Modes.Mania
+ osu.Game.Rulesets.Mania
-
+
{f167e17a-7de6-4af5-b920-a5112296c695}
- osu.Game.Modes.Taiko
+ osu.Game.Rulesets.Taiko
{0d3fbf8a-7464-4cf7-8c90-3e7886df2d4d}
@@ -187,8 +186,10 @@
+
+
@@ -197,16 +198,19 @@
+
+
+
diff --git a/osu.Desktop.VisualTests/packages.config b/osu.Desktop.VisualTests/packages.config
index 5a30c50600..cad2ffff0d 100644
--- a/osu.Desktop.VisualTests/packages.config
+++ b/osu.Desktop.VisualTests/packages.config
@@ -4,9 +4,9 @@ Copyright (c) 2007-2017 ppy Pty Ltd .
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
-
-
-
+
+
+
diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs
index 70925f6cf4..9532652bfe 100644
--- a/osu.Desktop/Overlays/VersionManager.cs
+++ b/osu.Desktop/Overlays/VersionManager.cs
@@ -189,19 +189,24 @@ namespace osu.Desktop.Overlays
private class UpdateProgressNotification : ProgressNotification
{
+ private OsuGame game;
+
protected override Notification CreateCompletionNotification() => new ProgressCompletionNotification()
{
Text = @"Update ready to install. Click to restart!",
Activated = () =>
{
- UpdateManager.RestartApp();
+ UpdateManager.RestartAppWhenExited();
+ game.GracefullyExit();
return true;
}
};
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OsuColour colours, OsuGame game)
{
+ this.game = game;
+
IconContent.Add(new Drawable[]
{
new Box
diff --git a/osu.Desktop/Program.cs b/osu.Desktop/Program.cs
index ddf58ac363..210f780078 100644
--- a/osu.Desktop/Program.cs
+++ b/osu.Desktop/Program.cs
@@ -7,11 +7,6 @@ using osu.Desktop.Beatmaps.IO;
using osu.Framework.Desktop;
using osu.Framework.Desktop.Platform;
using osu.Game.IPC;
-using osu.Game.Modes;
-using osu.Game.Modes.Catch;
-using osu.Game.Modes.Mania;
-using osu.Game.Modes.Osu;
-using osu.Game.Modes.Taiko;
namespace osu.Desktop
{
@@ -41,11 +36,6 @@ namespace osu.Desktop
}
else
{
- Ruleset.Register(new OsuRuleset());
- Ruleset.Register(new TaikoRuleset());
- Ruleset.Register(new ManiaRuleset());
- Ruleset.Register(new CatchRuleset());
-
host.Run(new OsuGameDesktop(args));
}
return 0;
diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj
index fbc342d695..4f66dfd3eb 100644
--- a/osu.Desktop/osu.Desktop.csproj
+++ b/osu.Desktop/osu.Desktop.csproj
@@ -63,6 +63,7 @@
false
+ 6
none
@@ -124,8 +125,7 @@
True
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
$(SolutionDir)\packages\Splat.2.0.0\lib\Net45\Splat.dll
@@ -198,21 +198,21 @@
{d9a367c9-4c1a-489f-9b05-a0cea2b53b58}
osu.Game.Resources
-
+
{c92a607b-1fdd-4954-9f92-03ff547d9080}
- osu.Game.Modes.Osu
+ osu.Game.Rulesets.Osu
-
+
{58f6c80c-1253-4a0e-a465-b8c85ebeadf3}
- osu.Game.Modes.Catch
+ osu.Game.Rulesets.Catch
-
+
{48f4582b-7687-4621-9cbe-5c24197cb536}
- osu.Game.Modes.Mania
+ osu.Game.Rulesets.Mania
-
+
{f167e17a-7de6-4af5-b920-a5112296c695}
- osu.Game.Modes.Taiko
+ osu.Game.Rulesets.Taiko
{0d3fbf8a-7464-4cf7-8c90-3e7886df2d4d}
diff --git a/osu.Desktop/packages.config b/osu.Desktop/packages.config
index be9b65f0c6..60e8182c82 100644
--- a/osu.Desktop/packages.config
+++ b/osu.Desktop/packages.config
@@ -7,7 +7,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
-
+
\ No newline at end of file
diff --git a/osu.Game.Modes.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Modes.Catch/Beatmaps/CatchBeatmapConverter.cs
deleted file mode 100644
index 9791554f02..0000000000
--- a/osu.Game.Modes.Catch/Beatmaps/CatchBeatmapConverter.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Beatmaps;
-using osu.Game.Modes.Catch.Objects;
-using System.Collections.Generic;
-
-namespace osu.Game.Modes.Catch.Beatmaps
-{
- internal class CatchBeatmapConverter : IBeatmapConverter
- {
- public Beatmap Convert(Beatmap original)
- {
- return new Beatmap(original)
- {
- HitObjects = new List() // Todo: Convert HitObjects
- };
- }
- }
-}
diff --git a/osu.Game.Modes.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Modes.Catch/Beatmaps/CatchBeatmapProcessor.cs
deleted file mode 100644
index ef585e2675..0000000000
--- a/osu.Game.Modes.Catch/Beatmaps/CatchBeatmapProcessor.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Beatmaps;
-using osu.Game.Modes.Catch.Objects;
-
-namespace osu.Game.Modes.Catch.Beatmaps
-{
- internal class CatchBeatmapProcessor : IBeatmapProcessor
- {
- public void SetDefaults(CatchBaseHit hitObject, Beatmap beatmap)
- {
- }
-
- public void PostProcess(Beatmap beatmap)
- {
- }
- }
-}
diff --git a/osu.Game.Modes.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Modes.Mania/Beatmaps/ManiaBeatmapConverter.cs
deleted file mode 100644
index 3ff210c1cc..0000000000
--- a/osu.Game.Modes.Mania/Beatmaps/ManiaBeatmapConverter.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Beatmaps;
-using osu.Game.Modes.Mania.Objects;
-using System.Collections.Generic;
-
-namespace osu.Game.Modes.Mania.Beatmaps
-{
- internal class ManiaBeatmapConverter : IBeatmapConverter
- {
- public Beatmap Convert(Beatmap original)
- {
- return new Beatmap(original)
- {
- HitObjects = new List() // Todo: Implement
- };
- }
- }
-}
diff --git a/osu.Game.Modes.Mania/Beatmaps/ManiaBeatmapProcessor.cs b/osu.Game.Modes.Mania/Beatmaps/ManiaBeatmapProcessor.cs
deleted file mode 100644
index 5e85a8f864..0000000000
--- a/osu.Game.Modes.Mania/Beatmaps/ManiaBeatmapProcessor.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Beatmaps;
-using osu.Game.Modes.Mania.Objects;
-
-namespace osu.Game.Modes.Mania.Beatmaps
-{
- internal class ManiaBeatmapProcessor : IBeatmapProcessor
- {
- public void SetDefaults(ManiaBaseHit hitObject, Beatmap beatmap)
- {
- }
-
- public void PostProcess(Beatmap beatmap)
- {
- }
- }
-}
diff --git a/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapProcessor.cs
deleted file mode 100644
index 08c9d94141..0000000000
--- a/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapProcessor.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Beatmaps;
-using osu.Game.Modes.Osu.Objects;
-
-namespace osu.Game.Modes.Osu.Beatmaps
-{
- internal class OsuBeatmapProcessor : IBeatmapProcessor
- {
- public void PostProcess(Beatmap beatmap)
- {
- if (beatmap.ComboColors.Count == 0)
- return;
-
- int comboIndex = 0;
- int colourIndex = 0;
-
- foreach (var obj in beatmap.HitObjects)
- {
- if (obj.NewCombo)
- {
- comboIndex = 0;
- colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count;
- }
-
- obj.ComboIndex = comboIndex++;
- obj.ComboColour = beatmap.ComboColors[colourIndex];
- }
- }
- }
-}
diff --git a/osu.Game.Modes.Osu/Scoring/OsuScore.cs b/osu.Game.Modes.Osu/Scoring/OsuScore.cs
deleted file mode 100644
index a0a639a59e..0000000000
--- a/osu.Game.Modes.Osu/Scoring/OsuScore.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Modes.Scoring;
-
-namespace osu.Game.Modes.Osu.Scoring
-{
- internal class OsuScore : Score
- {
- }
-}
diff --git a/osu.Game.Modes.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Modes.Osu/Scoring/OsuScoreProcessor.cs
deleted file mode 100644
index 0bd587e8ea..0000000000
--- a/osu.Game.Modes.Osu/Scoring/OsuScoreProcessor.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Osu.Judgements;
-using osu.Game.Modes.Osu.Objects;
-using osu.Game.Modes.Scoring;
-using osu.Game.Modes.UI;
-
-namespace osu.Game.Modes.Osu.Scoring
-{
- internal class OsuScoreProcessor : ScoreProcessor
- {
- public OsuScoreProcessor()
- {
- }
-
- public OsuScoreProcessor(HitRenderer hitRenderer)
- : base(hitRenderer)
- {
- }
-
- protected override void Reset()
- {
- base.Reset();
-
- Health.Value = 1;
- Accuracy.Value = 1;
- }
-
- protected override void OnNewJudgement(OsuJudgement judgement)
- {
- if (judgement != null)
- {
- switch (judgement.Result)
- {
- case HitResult.Hit:
- Combo.Value++;
- Health.Value += 0.1f;
- break;
- case HitResult.Miss:
- Combo.Value = 0;
- Health.Value -= 0.2f;
- break;
- }
- }
-
- int score = 0;
- int maxScore = 0;
-
- foreach (var j in Judgements)
- {
- score += j.ScoreValue;
- maxScore += j.MaxScoreValue;
- }
-
- TotalScore.Value = score;
- Accuracy.Value = (double)score / maxScore;
- }
- }
-}
diff --git a/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapProcessor.cs b/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapProcessor.cs
deleted file mode 100644
index 84bc470e55..0000000000
--- a/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapProcessor.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Beatmaps;
-using osu.Game.Modes.Taiko.Objects;
-
-namespace osu.Game.Modes.Taiko.Beatmaps
-{
- internal class TaikoBeatmapProcessor : IBeatmapProcessor
- {
- public void SetDefaults(TaikoHitObject hitObject, Beatmap beatmap)
- {
- }
-
- public void PostProcess(Beatmap beatmap)
- {
- }
- }
-}
diff --git a/osu.Game.Modes.Taiko/TaikoDifficultyCalculator.cs b/osu.Game.Modes.Taiko/TaikoDifficultyCalculator.cs
deleted file mode 100644
index 93dfc3d651..0000000000
--- a/osu.Game.Modes.Taiko/TaikoDifficultyCalculator.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Beatmaps;
-using osu.Game.Modes.Taiko.Beatmaps;
-using osu.Game.Modes.Taiko.Objects;
-using System.Collections.Generic;
-
-namespace osu.Game.Modes.Taiko
-{
- public class TaikoDifficultyCalculator : DifficultyCalculator
- {
- public TaikoDifficultyCalculator(Beatmap beatmap) : base(beatmap)
- {
- }
-
- protected override double CalculateInternal(Dictionary categoryDifficulty)
- {
- return 0;
- }
-
- protected override IBeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter();
- }
-}
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Modes.Taiko/UI/TaikoPlayfield.cs
deleted file mode 100644
index 9e7eb571a1..0000000000
--- a/osu.Game.Modes.Taiko/UI/TaikoPlayfield.cs
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Framework.Allocation;
-using osu.Framework.Graphics;
-using osu.Framework.Graphics.Sprites;
-using osu.Game.Modes.Taiko.Objects;
-using osu.Game.Modes.UI;
-using OpenTK;
-using OpenTK.Graphics;
-using osu.Game.Modes.Taiko.Judgements;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Graphics;
-using osu.Framework.Graphics.Containers;
-using osu.Framework.Extensions.Color4Extensions;
-using osu.Framework.Graphics.Primitives;
-using System.Linq;
-using osu.Game.Modes.Taiko.Objects.Drawables;
-
-namespace osu.Game.Modes.Taiko.UI
-{
- public class TaikoPlayfield : Playfield
- {
- ///
- /// The play field height. This is relative to the size of hit objects
- /// such that the playfield is just a bit larger than strong hits.
- ///
- public const float PLAYFIELD_HEIGHT = TaikoHitObject.CIRCLE_RADIUS * 2 * 2;
-
- ///
- /// The offset from which the center of the hit target lies at.
- ///
- private const float hit_target_offset = TaikoHitObject.CIRCLE_RADIUS * 1.5f + 40;
-
- ///
- /// The size of the left area of the playfield. This area contains the input drum.
- ///
- private const float left_area_size = 240;
-
- protected override Container Content => hitObjectContainer;
-
- private readonly Container hitExplosionContainer;
- private readonly Container barLineContainer;
- private readonly Container judgementContainer;
-
- private readonly Container hitObjectContainer;
- private readonly Container topLevelHitContainer;
- private readonly Container leftBackgroundContainer;
- private readonly Container rightBackgroundContainer;
- private readonly Box leftBackground;
- private readonly Box rightBackground;
-
- public TaikoPlayfield()
- {
- RelativeSizeAxes = Axes.X;
- Height = PLAYFIELD_HEIGHT;
-
- AddInternal(new Drawable[]
- {
- rightBackgroundContainer = new Container
- {
- RelativeSizeAxes = Axes.Both,
- BorderThickness = 2,
- Masking = true,
- EdgeEffect = new EdgeEffect
- {
- Type = EdgeEffectType.Shadow,
- Colour = Color4.Black.Opacity(0.2f),
- Radius = 5,
- },
- Children = new Drawable[]
- {
- rightBackground = new Box
- {
- RelativeSizeAxes = Axes.Both,
- Alpha = 0.6f
- },
- }
- },
- new Container
- {
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding { Left = left_area_size },
- Children = new Drawable[]
- {
- new Container
- {
- X = hit_target_offset,
- RelativeSizeAxes = Axes.Both,
- Children = new Drawable[]
- {
- hitExplosionContainer = new Container
- {
- Anchor = Anchor.CentreLeft,
- Origin = Anchor.Centre,
- Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2),
- BlendingMode = BlendingMode.Additive
- },
- barLineContainer = new Container
- {
- RelativeSizeAxes = Axes.Both,
- },
- new HitTarget
- {
- Anchor = Anchor.CentreLeft,
- Origin = Anchor.Centre,
- },
- hitObjectContainer = new Container
- {
- RelativeSizeAxes = Axes.Both,
- },
- judgementContainer = new Container
- {
- RelativeSizeAxes = Axes.Both,
- BlendingMode = BlendingMode.Additive
- },
- },
- },
- }
- },
- leftBackgroundContainer = new Container
- {
- Size = new Vector2(left_area_size, PLAYFIELD_HEIGHT),
- BorderThickness = 1,
- Children = new Drawable[]
- {
- leftBackground = new Box
- {
- RelativeSizeAxes = Axes.Both,
- },
- new InputDrum
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativePositionAxes = Axes.X,
- Position = new Vector2(0.10f, 0),
- Scale = new Vector2(0.9f)
- },
- new Box
- {
- Anchor = Anchor.TopRight,
- RelativeSizeAxes = Axes.Y,
- Width = 10,
- ColourInfo = Framework.Graphics.Colour.ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.6f), Color4.Black.Opacity(0)),
- },
- }
- },
- topLevelHitContainer = new Container
- {
- RelativeSizeAxes = Axes.Both,
- }
- });
- }
-
- [BackgroundDependencyLoader]
- private void load(OsuColour colours)
- {
- leftBackgroundContainer.BorderColour = colours.Gray0;
- leftBackground.Colour = colours.Gray1;
-
- rightBackgroundContainer.BorderColour = colours.Gray1;
- rightBackground.Colour = colours.Gray0;
- }
-
- public override void Add(DrawableHitObject h)
- {
- h.Depth = (float)h.HitObject.StartTime;
-
- base.Add(h);
-
- // Swells should be moved at the very top of the playfield when they reach the hit target
- var swell = h as DrawableSwell;
- if (swell != null)
- swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy());
- }
-
- public void AddBarLine(DrawableBarLine barLine)
- {
- barLineContainer.Add(barLine);
- }
-
- public override void OnJudgement(DrawableHitObject judgedObject)
- {
- bool wasHit = judgedObject.Judgement.Result == HitResult.Hit;
- bool secondHit = judgedObject.Judgement.SecondHit;
-
- judgementContainer.Add(new DrawableTaikoJudgement(judgedObject.Judgement)
- {
- Anchor = wasHit ? Anchor.TopLeft : Anchor.CentreLeft,
- Origin = wasHit ? Anchor.BottomCentre : Anchor.Centre,
- RelativePositionAxes = Axes.X,
- X = wasHit ? judgedObject.Position.X : 0,
- });
-
- if (!wasHit)
- return;
-
- if (!secondHit)
- {
- if (judgedObject.X >= -0.05f && !(judgedObject is DrawableSwell))
- {
- // If we're far enough away from the left stage, we should bring outselves in front of it
- topLevelHitContainer.Add(judgedObject.CreateProxy());
- }
-
- hitExplosionContainer.Add(new HitExplosion(judgedObject.Judgement));
- }
- else
- hitExplosionContainer.Children.FirstOrDefault(e => e.Judgement == judgedObject.Judgement)?.VisualiseSecondHit();
- }
- }
-}
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs
new file mode 100644
index 0000000000..f9859cd244
--- /dev/null
+++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs
@@ -0,0 +1,23 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Catch.Objects;
+using System.Collections.Generic;
+using System;
+using osu.Game.Rulesets.Objects.Types;
+using osu.Game.Rulesets.Beatmaps;
+using osu.Game.Rulesets.Objects;
+
+namespace osu.Game.Rulesets.Catch.Beatmaps
+{
+ internal class CatchBeatmapConverter : BeatmapConverter
+ {
+ protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
+
+ protected override IEnumerable ConvertHitObject(HitObject original, Beatmap beatmap)
+ {
+ yield return null;
+ }
+ }
+}
diff --git a/osu.Game.Modes.Catch/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs
similarity index 65%
rename from osu.Game.Modes.Catch/CatchDifficultyCalculator.cs
rename to osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs
index 53c6f5c2ce..a865299cff 100644
--- a/osu.Game.Modes.Catch/CatchDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Catch/CatchDifficultyCalculator.cs
@@ -2,11 +2,12 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
-using osu.Game.Modes.Catch.Beatmaps;
-using osu.Game.Modes.Catch.Objects;
+using osu.Game.Rulesets.Beatmaps;
+using osu.Game.Rulesets.Catch.Beatmaps;
+using osu.Game.Rulesets.Catch.Objects;
using System.Collections.Generic;
-namespace osu.Game.Modes.Catch
+namespace osu.Game.Rulesets.Catch
{
public class CatchDifficultyCalculator : DifficultyCalculator
{
@@ -19,6 +20,6 @@ namespace osu.Game.Modes.Catch
return 0;
}
- protected override IBeatmapConverter CreateBeatmapConverter() => new CatchBeatmapConverter();
+ protected override BeatmapConverter CreateBeatmapConverter() => new CatchBeatmapConverter();
}
}
\ No newline at end of file
diff --git a/osu.Game.Modes.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs
similarity index 88%
rename from osu.Game.Modes.Catch/CatchRuleset.cs
rename to osu.Game.Rulesets.Catch/CatchRuleset.cs
index 09d8bdb9e5..a6faf13d51 100644
--- a/osu.Game.Modes.Catch/CatchRuleset.cs
+++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs
@@ -4,16 +4,16 @@
using OpenTK.Input;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
-using osu.Game.Modes.Catch.Mods;
-using osu.Game.Modes.Catch.UI;
-using osu.Game.Modes.Mods;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Catch.Mods;
+using osu.Game.Rulesets.Catch.UI;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using System.Collections.Generic;
-using osu.Game.Modes.Catch.Scoring;
-using osu.Game.Modes.Scoring;
+using osu.Game.Rulesets.Catch.Scoring;
+using osu.Game.Rulesets.Scoring;
-namespace osu.Game.Modes.Catch
+namespace osu.Game.Rulesets.Catch
{
public class CatchRuleset : Ruleset
{
@@ -76,8 +76,6 @@ namespace osu.Game.Modes.Catch
}
}
- protected override PlayMode PlayMode => PlayMode.Catch;
-
public override string Description => "osu!catch";
public override FontAwesome Icon => FontAwesome.fa_osu_fruits_o;
@@ -92,5 +90,7 @@ namespace osu.Game.Modes.Catch
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new CatchDifficultyCalculator(beatmap);
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor();
+
+ public override int LegacyID => 2;
}
}
diff --git a/osu.Game.Modes.Catch/Judgements/CatchJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs
similarity index 78%
rename from osu.Game.Modes.Catch/Judgements/CatchJudgement.cs
rename to osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs
index eaacedd7e0..f0125b4c3a 100644
--- a/osu.Game.Modes.Catch/Judgements/CatchJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Judgements;
+using osu.Game.Rulesets.Judgements;
-namespace osu.Game.Modes.Catch.Judgements
+namespace osu.Game.Rulesets.Catch.Judgements
{
public class CatchJudgement : Judgement
{
diff --git a/osu.Game.Modes.Catch/Mods/CatchMod.cs b/osu.Game.Rulesets.Catch/Mods/CatchMod.cs
similarity index 91%
rename from osu.Game.Modes.Catch/Mods/CatchMod.cs
rename to osu.Game.Rulesets.Catch/Mods/CatchMod.cs
index 97e4e58a5d..64a0c51b72 100644
--- a/osu.Game.Modes.Catch/Mods/CatchMod.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchMod.cs
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Mods;
+using osu.Game.Rulesets.Mods;
-namespace osu.Game.Modes.Catch.Mods
+namespace osu.Game.Rulesets.Catch.Mods
{
public class CatchModNoFail : ModNoFail
{
diff --git a/osu.Game.Modes.Catch/Objects/CatchBaseHit.cs b/osu.Game.Rulesets.Catch/Objects/CatchBaseHit.cs
similarity index 75%
rename from osu.Game.Modes.Catch/Objects/CatchBaseHit.cs
rename to osu.Game.Rulesets.Catch/Objects/CatchBaseHit.cs
index ee66894d31..de0547580f 100644
--- a/osu.Game.Modes.Catch/Objects/CatchBaseHit.cs
+++ b/osu.Game.Rulesets.Catch/Objects/CatchBaseHit.cs
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Objects;
+using osu.Game.Rulesets.Objects;
-namespace osu.Game.Modes.Catch.Objects
+namespace osu.Game.Rulesets.Catch.Objects
{
public abstract class CatchBaseHit : HitObject
{
diff --git a/osu.Game.Modes.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs
similarity index 93%
rename from osu.Game.Modes.Catch/Objects/Drawable/DrawableFruit.cs
rename to osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs
index 885048b938..ae6585bdb2 100644
--- a/osu.Game.Modes.Catch/Objects/Drawable/DrawableFruit.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs
@@ -8,7 +8,7 @@ using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.Transforms;
using OpenTK;
-namespace osu.Game.Modes.Catch.Objects.Drawable
+namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
internal class DrawableFruit : Sprite
{
diff --git a/osu.Game.Modes.Catch/Objects/Droplet.cs b/osu.Game.Rulesets.Catch/Objects/Droplet.cs
similarity index 80%
rename from osu.Game.Modes.Catch/Objects/Droplet.cs
rename to osu.Game.Rulesets.Catch/Objects/Droplet.cs
index dd58fec7e8..b1206e0d75 100644
--- a/osu.Game.Modes.Catch/Objects/Droplet.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Droplet.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-namespace osu.Game.Modes.Catch.Objects
+namespace osu.Game.Rulesets.Catch.Objects
{
public class Droplet : CatchBaseHit
{
diff --git a/osu.Game.Modes.Catch/Objects/Fruit.cs b/osu.Game.Rulesets.Catch/Objects/Fruit.cs
similarity index 80%
rename from osu.Game.Modes.Catch/Objects/Fruit.cs
rename to osu.Game.Rulesets.Catch/Objects/Fruit.cs
index 15363a7031..fc55f83969 100644
--- a/osu.Game.Modes.Catch/Objects/Fruit.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Fruit.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-namespace osu.Game.Modes.Catch.Objects
+namespace osu.Game.Rulesets.Catch.Objects
{
public class Fruit : CatchBaseHit
{
diff --git a/osu.Game.Modes.Catch/OpenTK.dll.config b/osu.Game.Rulesets.Catch/OpenTK.dll.config
similarity index 100%
rename from osu.Game.Modes.Catch/OpenTK.dll.config
rename to osu.Game.Rulesets.Catch/OpenTK.dll.config
diff --git a/osu.Game.Modes.Catch/Properties/AssemblyInfo.cs b/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs
similarity index 90%
rename from osu.Game.Modes.Catch/Properties/AssemblyInfo.cs
rename to osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs
index 1d25411e73..42fbc7e082 100644
--- a/osu.Game.Modes.Catch/Properties/AssemblyInfo.cs
+++ b/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs
@@ -7,11 +7,11 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("osu.Game.Modes.Catch")]
+[assembly: AssemblyTitle("osu.Game.Rulesets.Catch")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("osu.Game.Modes.Catch")]
+[assembly: AssemblyProduct("osu.Game.Rulesets.Catch")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
diff --git a/osu.Game.Modes.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs
similarity index 72%
rename from osu.Game.Modes.Catch/Scoring/CatchScoreProcessor.cs
rename to osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs
index 1b9bedf7fb..3f29547e46 100644
--- a/osu.Game.Modes.Catch/Scoring/CatchScoreProcessor.cs
+++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs
@@ -1,12 +1,12 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Catch.Judgements;
-using osu.Game.Modes.Catch.Objects;
-using osu.Game.Modes.Scoring;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Catch.Judgements;
+using osu.Game.Rulesets.Catch.Objects;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Rulesets.UI;
-namespace osu.Game.Modes.Catch.Scoring
+namespace osu.Game.Rulesets.Catch.Scoring
{
internal class CatchScoreProcessor : ScoreProcessor
{
diff --git a/osu.Game.Modes.Catch/UI/CatchHitRenderer.cs b/osu.Game.Rulesets.Catch/UI/CatchHitRenderer.cs
similarity index 56%
rename from osu.Game.Modes.Catch/UI/CatchHitRenderer.cs
rename to osu.Game.Rulesets.Catch/UI/CatchHitRenderer.cs
index 90bd61a39f..f34585be55 100644
--- a/osu.Game.Modes.Catch/UI/CatchHitRenderer.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatchHitRenderer.cs
@@ -2,15 +2,16 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
-using osu.Game.Modes.Catch.Beatmaps;
-using osu.Game.Modes.Catch.Judgements;
-using osu.Game.Modes.Catch.Objects;
-using osu.Game.Modes.Catch.Scoring;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Scoring;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Beatmaps;
+using osu.Game.Rulesets.Catch.Beatmaps;
+using osu.Game.Rulesets.Catch.Judgements;
+using osu.Game.Rulesets.Catch.Objects;
+using osu.Game.Rulesets.Catch.Scoring;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Rulesets.UI;
-namespace osu.Game.Modes.Catch.UI
+namespace osu.Game.Rulesets.Catch.UI
{
public class CatchHitRenderer : HitRenderer
{
@@ -21,9 +22,7 @@ namespace osu.Game.Modes.Catch.UI
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this);
- protected override IBeatmapConverter CreateBeatmapConverter() => new CatchBeatmapConverter();
-
- protected override IBeatmapProcessor CreateBeatmapProcessor() => new CatchBeatmapProcessor();
+ protected override BeatmapConverter CreateBeatmapConverter() => new CatchBeatmapConverter();
protected override Playfield CreatePlayfield() => new CatchPlayfield();
diff --git a/osu.Game.Modes.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
similarity index 68%
rename from osu.Game.Modes.Catch/UI/CatchPlayfield.cs
rename to osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
index cf1a665470..4b1e6e93cd 100644
--- a/osu.Game.Modes.Catch/UI/CatchPlayfield.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
@@ -3,19 +3,18 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
-using osu.Game.Modes.Catch.Objects;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Catch.Objects;
+using osu.Game.Rulesets.UI;
using OpenTK;
-using osu.Game.Modes.Catch.Judgements;
+using osu.Game.Rulesets.Catch.Judgements;
-namespace osu.Game.Modes.Catch.UI
+namespace osu.Game.Rulesets.Catch.UI
{
public class CatchPlayfield : Playfield
{
public CatchPlayfield()
{
- RelativeSizeAxes = Axes.Y;
- Size = new Vector2(512, 0.9f);
+ Size = new Vector2(1, 0.9f);
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
diff --git a/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj
similarity index 88%
rename from osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj
rename to osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj
index 593d8db4f6..281d2b5a79 100644
--- a/osu.Game.Modes.Catch/osu.Game.Modes.Catch.csproj
+++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj
@@ -7,8 +7,8 @@
{58F6C80C-1253-4A0E-A465-B8C85EBEADF3}
Library
Properties
- osu.Game.Modes.Catch
- osu.Game.Modes.Catch
+ osu.Game.Rulesets.Catch
+ osu.Game.Rulesets.Catch
v4.5
512
@@ -21,6 +21,7 @@
prompt
4
false
+ 6
pdbonly
@@ -33,8 +34,7 @@
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
@@ -48,7 +48,6 @@
-
@@ -74,9 +73,9 @@
{C76BF5B3-985E-4D39-95FE-97C9C879B83A}
osu.Framework
-
+
{C92A607B-1FDD-4954-9F92-03FF547D9080}
- osu.Game.Modes.Osu
+ osu.Game.Rulesets.Osu
{0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D}
@@ -84,7 +83,7 @@
-
-
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
new file mode 100644
index 0000000000..847af965cc
--- /dev/null
+++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
@@ -0,0 +1,23 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Mania.Objects;
+using System.Collections.Generic;
+using System;
+using osu.Game.Rulesets.Objects.Types;
+using osu.Game.Rulesets.Beatmaps;
+using osu.Game.Rulesets.Objects;
+
+namespace osu.Game.Rulesets.Mania.Beatmaps
+{
+ internal class ManiaBeatmapConverter : BeatmapConverter
+ {
+ protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
+
+ protected override IEnumerable ConvertHitObject(HitObject original, Beatmap beatmap)
+ {
+ yield return null;
+ }
+ }
+}
diff --git a/osu.Game.Modes.Mania/Judgements/ManiaJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs
similarity index 78%
rename from osu.Game.Modes.Mania/Judgements/ManiaJudgement.cs
rename to osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs
index 3ef5b0f29b..8dafbd01a5 100644
--- a/osu.Game.Modes.Mania/Judgements/ManiaJudgement.cs
+++ b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Judgements;
+using osu.Game.Rulesets.Judgements;
-namespace osu.Game.Modes.Mania.Judgements
+namespace osu.Game.Rulesets.Mania.Judgements
{
public class ManiaJudgement : Judgement
{
diff --git a/osu.Game.Modes.Mania/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs
similarity index 65%
rename from osu.Game.Modes.Mania/ManiaDifficultyCalculator.cs
rename to osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs
index 02a5a3acdc..e9bcc60d2c 100644
--- a/osu.Game.Modes.Mania/ManiaDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Mania/ManiaDifficultyCalculator.cs
@@ -2,11 +2,12 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
-using osu.Game.Modes.Mania.Beatmaps;
-using osu.Game.Modes.Mania.Objects;
+using osu.Game.Rulesets.Beatmaps;
+using osu.Game.Rulesets.Mania.Beatmaps;
+using osu.Game.Rulesets.Mania.Objects;
using System.Collections.Generic;
-namespace osu.Game.Modes.Mania
+namespace osu.Game.Rulesets.Mania
{
public class ManiaDifficultyCalculator : DifficultyCalculator
{
@@ -20,6 +21,6 @@ namespace osu.Game.Modes.Mania
return 0;
}
- protected override IBeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter();
+ protected override BeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter();
}
}
\ No newline at end of file
diff --git a/osu.Game.Modes.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs
similarity index 90%
rename from osu.Game.Modes.Mania/ManiaRuleset.cs
rename to osu.Game.Rulesets.Mania/ManiaRuleset.cs
index bd995d87d6..26614075b1 100644
--- a/osu.Game.Modes.Mania/ManiaRuleset.cs
+++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs
@@ -3,16 +3,16 @@
using osu.Game.Beatmaps;
using osu.Game.Graphics;
-using osu.Game.Modes.Mania.Mods;
-using osu.Game.Modes.Mania.UI;
-using osu.Game.Modes.Mods;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Mania.Mods;
+using osu.Game.Rulesets.Mania.UI;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using System.Collections.Generic;
-using osu.Game.Modes.Mania.Scoring;
-using osu.Game.Modes.Scoring;
+using osu.Game.Rulesets.Mania.Scoring;
+using osu.Game.Rulesets.Scoring;
-namespace osu.Game.Modes.Mania
+namespace osu.Game.Rulesets.Mania
{
public class ManiaRuleset : Ruleset
{
@@ -96,8 +96,6 @@ namespace osu.Game.Modes.Mania
}
}
- protected override PlayMode PlayMode => PlayMode.Mania;
-
public override string Description => "osu!mania";
public override FontAwesome Icon => FontAwesome.fa_osu_mania_o;
@@ -107,5 +105,7 @@ namespace osu.Game.Modes.Mania
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new ManiaDifficultyCalculator(beatmap);
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor();
+
+ public override int LegacyID => 3;
}
}
diff --git a/osu.Game.Modes.Mania/Mods/ManiaMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs
similarity index 94%
rename from osu.Game.Modes.Mania/Mods/ManiaMod.cs
rename to osu.Game.Rulesets.Mania/Mods/ManiaMod.cs
index b330680550..68458caeac 100644
--- a/osu.Game.Modes.Mania/Mods/ManiaMod.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs
@@ -2,10 +2,10 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Graphics;
-using osu.Game.Modes.Mods;
+using osu.Game.Rulesets.Mods;
using System;
-namespace osu.Game.Modes.Mania.Mods
+namespace osu.Game.Rulesets.Mania.Mods
{
public class ManiaModNoFail : ModNoFail
{
diff --git a/osu.Game.Modes.Mania/Objects/Drawable/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawable/DrawableNote.cs
similarity index 93%
rename from osu.Game.Modes.Mania/Objects/Drawable/DrawableNote.cs
rename to osu.Game.Rulesets.Mania/Objects/Drawable/DrawableNote.cs
index 76999cef21..07a27b1643 100644
--- a/osu.Game.Modes.Mania/Objects/Drawable/DrawableNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawable/DrawableNote.cs
@@ -8,7 +8,7 @@ using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics;
using OpenTK;
-namespace osu.Game.Modes.Mania.Objects.Drawable
+namespace osu.Game.Rulesets.Mania.Objects.Drawable
{
public class DrawableNote : Sprite
{
diff --git a/osu.Game.Modes.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
similarity index 79%
rename from osu.Game.Modes.Mania/Objects/HoldNote.cs
rename to osu.Game.Rulesets.Mania/Objects/HoldNote.cs
index 3d95e11118..e8ce1da77f 100644
--- a/osu.Game.Modes.Mania/Objects/HoldNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-namespace osu.Game.Modes.Mania.Objects
+namespace osu.Game.Rulesets.Mania.Objects
{
public class HoldNote : Note
{
diff --git a/osu.Game.Modes.Mania/Objects/ManiaBaseHit.cs b/osu.Game.Rulesets.Mania/Objects/ManiaBaseHit.cs
similarity index 74%
rename from osu.Game.Modes.Mania/Objects/ManiaBaseHit.cs
rename to osu.Game.Rulesets.Mania/Objects/ManiaBaseHit.cs
index 8b3afc82d9..4c15b69eb7 100644
--- a/osu.Game.Modes.Mania/Objects/ManiaBaseHit.cs
+++ b/osu.Game.Rulesets.Mania/Objects/ManiaBaseHit.cs
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Objects;
+using osu.Game.Rulesets.Objects;
-namespace osu.Game.Modes.Mania.Objects
+namespace osu.Game.Rulesets.Mania.Objects
{
public abstract class ManiaBaseHit : HitObject
{
diff --git a/osu.Game.Modes.Mania/Objects/Note.cs b/osu.Game.Rulesets.Mania/Objects/Note.cs
similarity index 80%
rename from osu.Game.Modes.Mania/Objects/Note.cs
rename to osu.Game.Rulesets.Mania/Objects/Note.cs
index c36ed8cf7e..5a6d6003db 100644
--- a/osu.Game.Modes.Mania/Objects/Note.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Note.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-namespace osu.Game.Modes.Mania.Objects
+namespace osu.Game.Rulesets.Mania.Objects
{
public class Note : ManiaBaseHit
{
diff --git a/osu.Game.Modes.Mania/OpenTK.dll.config b/osu.Game.Rulesets.Mania/OpenTK.dll.config
similarity index 100%
rename from osu.Game.Modes.Mania/OpenTK.dll.config
rename to osu.Game.Rulesets.Mania/OpenTK.dll.config
diff --git a/osu.Game.Modes.Mania/Properties/AssemblyInfo.cs b/osu.Game.Rulesets.Mania/Properties/AssemblyInfo.cs
similarity index 90%
rename from osu.Game.Modes.Mania/Properties/AssemblyInfo.cs
rename to osu.Game.Rulesets.Mania/Properties/AssemblyInfo.cs
index 11c8290f1b..790002acd7 100644
--- a/osu.Game.Modes.Mania/Properties/AssemblyInfo.cs
+++ b/osu.Game.Rulesets.Mania/Properties/AssemblyInfo.cs
@@ -7,11 +7,11 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("osu.Game.Modes.Mania")]
+[assembly: AssemblyTitle("osu.Game.Rulesets.Mania")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("osu.Game.Modes.Mania")]
+[assembly: AssemblyProduct("osu.Game.Rulesets.Mania")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
diff --git a/osu.Game.Modes.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs
similarity index 72%
rename from osu.Game.Modes.Mania/Scoring/ManiaScoreProcessor.cs
rename to osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs
index 0f87030e25..ba0304a44a 100644
--- a/osu.Game.Modes.Mania/Scoring/ManiaScoreProcessor.cs
+++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs
@@ -1,12 +1,12 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Mania.Judgements;
-using osu.Game.Modes.Mania.Objects;
-using osu.Game.Modes.Scoring;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Mania.Judgements;
+using osu.Game.Rulesets.Mania.Objects;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Rulesets.UI;
-namespace osu.Game.Modes.Mania.Scoring
+namespace osu.Game.Rulesets.Mania.Scoring
{
internal class ManiaScoreProcessor : ScoreProcessor
{
diff --git a/osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs b/osu.Game.Rulesets.Mania/UI/ManiaHitRenderer.cs
similarity index 59%
rename from osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs
rename to osu.Game.Rulesets.Mania/UI/ManiaHitRenderer.cs
index 0415bc961a..7fb8f95b4c 100644
--- a/osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaHitRenderer.cs
@@ -2,15 +2,16 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
-using osu.Game.Modes.Mania.Beatmaps;
-using osu.Game.Modes.Mania.Judgements;
-using osu.Game.Modes.Mania.Objects;
-using osu.Game.Modes.Mania.Scoring;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Scoring;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Beatmaps;
+using osu.Game.Rulesets.Mania.Beatmaps;
+using osu.Game.Rulesets.Mania.Judgements;
+using osu.Game.Rulesets.Mania.Objects;
+using osu.Game.Rulesets.Mania.Scoring;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Rulesets.UI;
-namespace osu.Game.Modes.Mania.UI
+namespace osu.Game.Rulesets.Mania.UI
{
public class ManiaHitRenderer : HitRenderer
{
@@ -24,9 +25,7 @@ namespace osu.Game.Modes.Mania.UI
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this);
- protected override IBeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter();
-
- protected override IBeatmapProcessor CreateBeatmapProcessor() => new ManiaBeatmapProcessor();
+ protected override BeatmapConverter CreateBeatmapConverter() => new ManiaBeatmapConverter();
protected override Playfield CreatePlayfield() => new ManiaPlayfield(columns);
diff --git a/osu.Game.Modes.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
similarity index 78%
rename from osu.Game.Modes.Mania/UI/ManiaPlayfield.cs
rename to osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
index 670d18f71f..5eea3d70c0 100644
--- a/osu.Game.Modes.Mania/UI/ManiaPlayfield.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
@@ -3,20 +3,19 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
-using osu.Game.Modes.Mania.Objects;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Mania.Objects;
+using osu.Game.Rulesets.UI;
using OpenTK;
using OpenTK.Graphics;
-using osu.Game.Modes.Mania.Judgements;
+using osu.Game.Rulesets.Mania.Judgements;
-namespace osu.Game.Modes.Mania.UI
+namespace osu.Game.Rulesets.Mania.UI
{
public class ManiaPlayfield : Playfield
{
public ManiaPlayfield(int columns)
{
- RelativeSizeAxes = Axes.Both;
- Size = new Vector2(columns / 20f, 1f);
+ Size = new Vector2(0.8f, 1f);
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
diff --git a/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj
similarity index 86%
rename from osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj
rename to osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj
index cc925d417a..facffa757c 100644
--- a/osu.Game.Modes.Mania/osu.Game.Modes.Mania.csproj
+++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj
@@ -7,8 +7,8 @@
{48F4582B-7687-4621-9CBE-5C24197CB536}
Library
Properties
- osu.Game.Modes.Mania
- osu.Game.Modes.Mania
+ osu.Game.Rulesets.Mania
+ osu.Game.Rulesets.Mania
v4.5
512
@@ -21,6 +21,7 @@
prompt
4
false
+ 6
pdbonly
@@ -33,8 +34,7 @@
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
@@ -48,7 +48,6 @@
-
@@ -67,13 +66,13 @@
{C76BF5B3-985E-4D39-95FE-97C9C879B83A}
osu.Framework
-
+
{C92A607B-1FDD-4954-9F92-03FF547D9080}
- osu.Game.Modes.Osu
+ osu.Game.Rulesets.Osu
-
+
{F167E17A-7DE6-4AF5-B920-A5112296C695}
- osu.Game.Modes.Taiko
+ osu.Game.Rulesets.Taiko
{0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D}
@@ -89,7 +88,7 @@
-
-
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs
new file mode 100644
index 0000000000..7f6f524a7a
--- /dev/null
+++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs
@@ -0,0 +1,65 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Objects;
+using osu.Game.Rulesets.Osu.Objects;
+using System.Collections.Generic;
+using osu.Game.Rulesets.Objects.Types;
+using System;
+using osu.Game.Rulesets.Osu.UI;
+using osu.Game.Rulesets.Beatmaps;
+
+namespace osu.Game.Rulesets.Osu.Beatmaps
+{
+ internal class OsuBeatmapConverter : BeatmapConverter
+ {
+ protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(IHasPosition) };
+
+ protected override IEnumerable ConvertHitObject(HitObject original, Beatmap beatmap)
+ {
+ var curveData = original as IHasCurve;
+ var endTimeData = original as IHasEndTime;
+ var positionData = original as IHasPosition;
+ var comboData = original as IHasCombo;
+
+ if (curveData != null)
+ {
+ yield return new Slider
+ {
+ StartTime = original.StartTime,
+ Samples = original.Samples,
+ ControlPoints = curveData.ControlPoints,
+ CurveType = curveData.CurveType,
+ Distance = curveData.Distance,
+ RepeatSamples = curveData.RepeatSamples,
+ RepeatCount = curveData.RepeatCount,
+ Position = positionData?.Position ?? Vector2.Zero,
+ NewCombo = comboData?.NewCombo ?? false
+ };
+ }
+ else if (endTimeData != null)
+ {
+ yield return new Spinner
+ {
+ StartTime = original.StartTime,
+ Samples = original.Samples,
+ EndTime = endTimeData.EndTime,
+
+ Position = positionData?.Position ?? OsuPlayfield.BASE_SIZE / 2,
+ };
+ }
+ else
+ {
+ yield return new HitCircle
+ {
+ StartTime = original.StartTime,
+ Samples = original.Samples,
+ Position = positionData?.Position ?? Vector2.Zero,
+ NewCombo = comboData?.NewCombo ?? false
+ };
+ }
+ }
+ }
+}
diff --git a/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs
similarity index 64%
rename from osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs
rename to osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs
index bae12a98e3..fce0188cda 100644
--- a/osu.Game.Modes.Osu/Beatmaps/OsuBeatmapConverter.cs
+++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs
@@ -3,96 +3,58 @@
using OpenTK;
using osu.Game.Beatmaps;
-using osu.Game.Modes.Objects;
-using osu.Game.Modes.Osu.Objects;
-using osu.Game.Modes.Osu.Objects.Drawables;
-using System.Collections.Generic;
-using osu.Game.Modes.Objects.Types;
-using System.Linq;
+using osu.Game.Rulesets.Beatmaps;
+using osu.Game.Rulesets.Objects.Types;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
-namespace osu.Game.Modes.Osu.Beatmaps
+namespace osu.Game.Rulesets.Osu.Beatmaps
{
- internal class OsuBeatmapConverter : IBeatmapConverter
+ internal class OsuBeatmapProcessor : BeatmapProcessor
{
- public Beatmap Convert(Beatmap original)
+ public override void PostProcess(Beatmap beatmap)
{
- return new Beatmap(original)
+ applyStacking(beatmap);
+
+ if (beatmap.ComboColors.Count == 0)
+ return;
+
+ int comboIndex = 0;
+ int colourIndex = 0;
+
+ foreach (var obj in beatmap.HitObjects)
{
- HitObjects = convertHitObjects(original.HitObjects, original.BeatmapInfo?.StackLeniency ?? 0.7f)
- };
- }
-
- private List convertHitObjects(List hitObjects, float stackLeniency)
- {
- List converted = hitObjects.Select(convertHitObject).ToList();
-
- updateStacking(converted, stackLeniency);
-
- return converted;
- }
-
- private OsuHitObject convertHitObject(HitObject original)
- {
- IHasCurve curveData = original as IHasCurve;
- IHasEndTime endTimeData = original as IHasEndTime;
- IHasPosition positionData = original as IHasPosition;
- IHasCombo comboData = original as IHasCombo;
-
- if (curveData != null)
- {
- return new Slider
+ if (obj.NewCombo)
{
- StartTime = original.StartTime,
- Samples = original.Samples,
- CurveObject = curveData,
- Position = positionData?.Position ?? Vector2.Zero,
- NewCombo = comboData?.NewCombo ?? false
- };
- }
+ comboIndex = 0;
+ colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count;
+ }
- if (endTimeData != null)
- {
- return new Spinner
- {
- StartTime = original.StartTime,
- Samples = original.Samples,
- Position = new Vector2(512, 384) / 2,
- EndTime = endTimeData.EndTime
- };
+ obj.ComboIndex = comboIndex++;
+ obj.ComboColour = beatmap.ComboColors[colourIndex];
}
-
- return new HitCircle
- {
- StartTime = original.StartTime,
- Samples = original.Samples,
- Position = positionData?.Position ?? Vector2.Zero,
- NewCombo = comboData?.NewCombo ?? false
- };
}
- private void updateStacking(List hitObjects, float stackLeniency, int startIndex = 0, int endIndex = -1)
+ private void applyStacking(Beatmap beatmap)
{
- if (endIndex == -1)
- endIndex = hitObjects.Count - 1;
-
const int stack_distance = 3;
- float stackThreshold = DrawableOsuHitObject.TIME_PREEMPT * stackLeniency;
+ float stackThreshold = DrawableOsuHitObject.TIME_PREEMPT * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f;
- // Reset stacking inside the update range
- for (int i = startIndex; i <= endIndex; i++)
- hitObjects[i].StackHeight = 0;
+ // Reset stacking
+ for (int i = 0; i <= beatmap.HitObjects.Count - 1; i++)
+ beatmap.HitObjects[i].StackHeight = 0;
// Extend the end index to include objects they are stacked on
- int extendedEndIndex = endIndex;
- for (int i = endIndex; i >= startIndex; i--)
+ int extendedEndIndex = beatmap.HitObjects.Count - 1;
+ for (int i = beatmap.HitObjects.Count - 1; i >= 0; i--)
{
int stackBaseIndex = i;
- for (int n = stackBaseIndex + 1; n < hitObjects.Count; n++)
+ for (int n = stackBaseIndex + 1; n < beatmap.HitObjects.Count; n++)
{
- OsuHitObject stackBaseObject = hitObjects[stackBaseIndex];
+ OsuHitObject stackBaseObject = beatmap.HitObjects[stackBaseIndex];
if (stackBaseObject is Spinner) break;
- OsuHitObject objectN = hitObjects[n];
+ OsuHitObject objectN = beatmap.HitObjects[n];
if (objectN is Spinner)
continue;
@@ -115,14 +77,14 @@ namespace osu.Game.Modes.Osu.Beatmaps
if (stackBaseIndex > extendedEndIndex)
{
extendedEndIndex = stackBaseIndex;
- if (extendedEndIndex == hitObjects.Count - 1)
+ if (extendedEndIndex == beatmap.HitObjects.Count - 1)
break;
}
}
//Reverse pass for stack calculation.
- int extendedStartIndex = startIndex;
- for (int i = extendedEndIndex; i > startIndex; i--)
+ int extendedStartIndex = 0;
+ for (int i = extendedEndIndex; i > 0; i--)
{
int n = i;
/* We should check every note which has not yet got a stack.
@@ -136,7 +98,7 @@ namespace osu.Game.Modes.Osu.Beatmaps
* 2 and 1 will be ignored in the i loop because they already have a stack value.
*/
- OsuHitObject objectI = hitObjects[i];
+ OsuHitObject objectI = beatmap.HitObjects[i];
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
/* If this object is a hitcircle, then we enter this "special" case.
@@ -147,7 +109,7 @@ namespace osu.Game.Modes.Osu.Beatmaps
{
while (--n >= 0)
{
- OsuHitObject objectN = hitObjects[n];
+ OsuHitObject objectN = beatmap.HitObjects[n];
if (objectN is Spinner) continue;
double endTime = (objectN as IHasEndTime)?.EndTime ?? objectN.StartTime;
@@ -174,7 +136,7 @@ namespace osu.Game.Modes.Osu.Beatmaps
for (int j = n + 1; j <= i; j++)
{
//For each object which was declared under this slider, we will offset it to appear *below* the slider end (rather than above).
- OsuHitObject objectJ = hitObjects[j];
+ OsuHitObject objectJ = beatmap.HitObjects[j];
if (Vector2.Distance(objectN.EndPosition, objectJ.Position) < stack_distance)
objectJ.StackHeight -= offset;
}
@@ -199,9 +161,9 @@ namespace osu.Game.Modes.Osu.Beatmaps
/* We have hit the first slider in a possible stack.
* From this point on, we ALWAYS stack positive regardless.
*/
- while (--n >= startIndex)
+ while (--n >= 0)
{
- OsuHitObject objectN = hitObjects[n];
+ OsuHitObject objectN = beatmap.HitObjects[n];
if (objectN is Spinner) continue;
if (objectI.StartTime - objectN.StartTime > stackThreshold)
diff --git a/osu.Game.Modes.Osu/Judgements/OsuJudgement.cs b/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs
similarity index 89%
rename from osu.Game.Modes.Osu/Judgements/OsuJudgement.cs
rename to osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs
index e65d3dde3a..d61e179002 100644
--- a/osu.Game.Modes.Osu/Judgements/OsuJudgement.cs
+++ b/osu.Game.Rulesets.Osu/Judgements/OsuJudgement.cs
@@ -2,11 +2,11 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
-using osu.Game.Modes.Judgements;
-using osu.Game.Modes.Osu.Objects.Drawables;
+using osu.Game.Rulesets.Judgements;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Framework.Extensions;
-namespace osu.Game.Modes.Osu.Judgements
+namespace osu.Game.Rulesets.Osu.Judgements
{
public class OsuJudgement : Judgement
{
diff --git a/osu.Game.Modes.Osu/Mods/OsuMod.cs b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs
similarity index 93%
rename from osu.Game.Modes.Osu/Mods/OsuMod.cs
rename to osu.Game.Rulesets.Osu/Mods/OsuMod.cs
index db2ee26b7a..bdb5f386d0 100644
--- a/osu.Game.Modes.Osu/Mods/OsuMod.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs
@@ -3,13 +3,13 @@
using osu.Game.Beatmaps;
using osu.Game.Graphics;
-using osu.Game.Modes.Mods;
-using osu.Game.Modes.Osu.Objects;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Osu.Objects;
using System;
using System.Linq;
-using osu.Game.Modes.Scoring;
+using osu.Game.Rulesets.Scoring;
-namespace osu.Game.Modes.Osu.Mods
+namespace osu.Game.Rulesets.Osu.Mods
{
public class OsuModNoFail : ModNoFail
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Connections/ConnectionRenderer.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/ConnectionRenderer.cs
similarity index 83%
rename from osu.Game.Modes.Osu/Objects/Drawables/Connections/ConnectionRenderer.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Connections/ConnectionRenderer.cs
index a680c847ac..192ab0536e 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Connections/ConnectionRenderer.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/ConnectionRenderer.cs
@@ -2,10 +2,10 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Containers;
-using osu.Game.Modes.Objects;
+using osu.Game.Rulesets.Objects;
using System.Collections.Generic;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Connections
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
{
///
/// Connects hit objects visually, for example with follow points.
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs
similarity index 59%
rename from osu.Game.Modes.Osu/Objects/Drawables/Connections/FollowPoint.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs
index 7815e3ba41..9f8ff17853 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Connections/FollowPoint.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs
@@ -8,20 +8,15 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Connections
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
{
public class FollowPoint : Container
{
- public double StartTime;
- public double EndTime;
- public Vector2 EndPosition;
-
private const float width = 8;
public FollowPoint()
{
Origin = Anchor.Centre;
- Alpha = 0;
Masking = true;
AutoSizeAxes = Axes.Both;
@@ -45,22 +40,5 @@ namespace osu.Game.Modes.Osu.Objects.Drawables.Connections
},
};
}
-
- protected override void LoadComplete()
- {
- base.LoadComplete();
-
- Delay(StartTime);
- FadeIn(DrawableOsuHitObject.TIME_FADEIN);
- ScaleTo(1.5f);
- ScaleTo(1, DrawableOsuHitObject.TIME_FADEIN, EasingTypes.Out);
- MoveTo(EndPosition, DrawableOsuHitObject.TIME_FADEIN, EasingTypes.Out);
-
- Delay(EndTime - StartTime);
- FadeOut(DrawableOsuHitObject.TIME_FADEIN);
-
- Delay(DrawableOsuHitObject.TIME_FADEIN);
- Expire(true);
- }
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs
similarity index 76%
rename from osu.Game.Modes.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs
index f45e4226dd..925767b851 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs
@@ -4,9 +4,10 @@
using System;
using System.Collections.Generic;
using OpenTK;
-using osu.Game.Modes.Objects.Types;
+using osu.Framework.Graphics;
+using osu.Game.Rulesets.Objects.Types;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Connections
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
{
public class FollowPointRenderer : ConnectionRenderer
{
@@ -80,14 +81,28 @@ namespace osu.Game.Modes.Osu.Objects.Drawables.Connections
double fadeOutTime = startTime + fraction * duration;
double fadeInTime = fadeOutTime - PreEmpt;
- Add(new FollowPoint
+ FollowPoint fp;
+
+ Add(fp = new FollowPoint
{
- StartTime = fadeInTime,
- EndTime = fadeOutTime,
Position = pointStartPosition,
- EndPosition = pointEndPosition,
Rotation = rotation,
+ Alpha = 0,
+ Scale = new Vector2(1.5f),
});
+
+ using (fp.BeginAbsoluteSequence(fadeInTime))
+ {
+ fp.FadeIn(DrawableOsuHitObject.TIME_FADEIN);
+ fp.ScaleTo(1, DrawableOsuHitObject.TIME_FADEIN, EasingTypes.Out);
+
+ fp.MoveTo(pointEndPosition, DrawableOsuHitObject.TIME_FADEIN, EasingTypes.Out);
+
+ fp.Delay(fadeOutTime - fadeInTime);
+ fp.FadeOut(DrawableOsuHitObject.TIME_FADEIN);
+ }
+
+ fp.Expire(true);
}
}
prevHitObject = currHitObject;
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs
similarity index 91%
rename from osu.Game.Modes.Osu/Objects/Drawables/DrawableHitCircle.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs
index 68c5ec0a45..09bfffeefe 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableHitCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs
@@ -3,12 +3,12 @@
using System;
using osu.Framework.Graphics;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Osu.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
using OpenTK;
-using osu.Game.Modes.Objects.Types;
+using osu.Game.Rulesets.Objects.Types;
-namespace osu.Game.Modes.Osu.Objects.Drawables
+namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public class DrawableHitCircle : DrawableOsuHitObject, IDrawableHitObjectWithProxiedApproach
{
@@ -104,10 +104,8 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
ApproachCircle.ScaleTo(1.1f, TIME_PREEMPT);
}
- protected override void UpdateState(ArmedState state)
+ protected override void UpdateCurrentState(ArmedState state)
{
- base.UpdateState(state);
-
ApproachCircle.FadeOut();
double endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime;
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
similarity index 68%
rename from osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
index 816faa0d98..57a9804330 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuHitObject.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
@@ -2,10 +2,10 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.ComponentModel;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Osu.Judgements;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Judgements;
-namespace osu.Game.Modes.Osu.Objects.Drawables
+namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public class DrawableOsuHitObject : DrawableHitObject
{
@@ -21,17 +21,23 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
protected override OsuJudgement CreateJudgement() => new OsuJudgement { MaxScore = OsuScoreResult.Hit300 };
- protected override void UpdateState(ArmedState state)
+ protected sealed override void UpdateState(ArmedState state)
{
Flush();
UpdateInitialState();
- Delay(HitObject.StartTime - Time.Current - TIME_PREEMPT + Judgement.TimeOffset, true);
+ using (BeginAbsoluteSequence(HitObject.StartTime - TIME_PREEMPT, true))
+ {
+ UpdatePreemptState();
- UpdatePreemptState();
+ using (BeginDelayedSequence(TIME_PREEMPT + Judgement.TimeOffset, true))
+ UpdateCurrentState(state);
+ }
+ }
- Delay(TIME_PREEMPT, true);
+ protected virtual void UpdateCurrentState(ArmedState state)
+ {
}
protected virtual void UpdatePreemptState()
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuJudgement.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs
similarity index 76%
rename from osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuJudgement.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs
index 647c8faef8..eaa0bb7d27 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableOsuJudgement.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs
@@ -2,12 +2,12 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Osu.Judgements;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Judgements;
using OpenTK;
-using osu.Game.Modes.Judgements;
+using osu.Game.Rulesets.Judgements;
-namespace osu.Game.Modes.Osu.Objects.Drawables
+namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public class DrawableOsuJudgement : DrawableJudgement
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
similarity index 93%
rename from osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
index be326751ba..b80f1d7178 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSlider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
@@ -3,13 +3,13 @@
using OpenTK;
using osu.Framework.Graphics;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Osu.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics.Containers;
-namespace osu.Game.Modes.Osu.Objects.Drawables
+namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public class DrawableSlider : DrawableOsuHitObject, IDrawableHitObjectWithProxiedApproach
{
@@ -158,10 +158,8 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
ball.Alpha = 0;
}
- protected override void UpdateState(ArmedState state)
+ protected override void UpdateCurrentState(ArmedState state)
{
- base.UpdateState(state);
-
ball.FadeIn();
Delay(slider.Duration, true);
@@ -181,4 +179,4 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
{
void UpdateProgress(double progress, int repeat);
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs
similarity index 88%
rename from osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs
index 188306c857..6b4d40e080 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSliderTick.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs
@@ -4,12 +4,12 @@
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Osu.Judgements;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Judgements;
using OpenTK;
using OpenTK.Graphics;
-namespace osu.Game.Modes.Osu.Objects.Drawables
+namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public class DrawableSliderTick : DrawableOsuHitObject
{
@@ -72,10 +72,8 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
Delay(-animIn);
}
- protected override void UpdateState(ArmedState state)
+ protected override void UpdateCurrentState(ArmedState state)
{
- base.UpdateState(state);
-
switch (state)
{
case ArmedState.Idle:
@@ -93,4 +91,4 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
}
}
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs
similarity index 91%
rename from osu.Game.Modes.Osu/Objects/Drawables/DrawableSpinner.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs
index d0136f717c..90a6d432c4 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/DrawableSpinner.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs
@@ -5,12 +5,13 @@ using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Osu.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
using OpenTK;
using OpenTK.Graphics;
+using osu.Game.Rulesets.Osu.UI;
-namespace osu.Game.Modes.Osu.Objects.Drawables
+namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public class DrawableSpinner : DrawableOsuHitObject
{
@@ -29,7 +30,7 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
Position = s.Position;
//take up full playfield.
- Size = new Vector2(512);
+ Size = new Vector2(OsuPlayfield.BASE_SIZE.X);
spinner = s;
@@ -131,10 +132,8 @@ namespace osu.Game.Modes.Osu.Objects.Drawables
disc.FadeIn(200);
}
- protected override void UpdateState(ArmedState state)
+ protected override void UpdateCurrentState(ArmedState state)
{
- base.UpdateState(state);
-
Delay(spinner.Duration, true);
FadeOut(160);
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/ApproachCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ApproachCircle.cs
similarity index 90%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/ApproachCircle.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ApproachCircle.cs
index fd4ef64350..323f5fb297 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/ApproachCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ApproachCircle.cs
@@ -7,7 +7,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class ApproachCircle : Container
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs
similarity index 93%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/CirclePiece.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs
index 704a6b7490..9a90c07517 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/CirclePiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/CirclePiece.cs
@@ -10,7 +10,7 @@ using osu.Framework.Graphics.Textures;
using osu.Framework.Input;
using OpenTK;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class CirclePiece : Container
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/ExplodePiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs
similarity index 90%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/ExplodePiece.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs
index 97228f610f..e5cf10b88a 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/ExplodePiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/ExplodePiece.cs
@@ -5,7 +5,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using OpenTK;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class ExplodePiece : Container
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/FlashPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs
similarity index 89%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/FlashPiece.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs
index cb60977dab..68ffb756d4 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/FlashPiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/FlashPiece.cs
@@ -6,7 +6,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using OpenTK;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class FlashPiece : Container
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/GlowPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs
similarity index 91%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/GlowPiece.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs
index 6cffa370cf..8a7b353da1 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/GlowPiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/GlowPiece.cs
@@ -7,7 +7,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class GlowPiece : Container
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/NumberPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs
similarity index 93%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/NumberPiece.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs
index 0ebd274246..07b21657a5 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/NumberPiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/NumberPiece.cs
@@ -8,7 +8,7 @@ using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.Sprites;
using OpenTK.Graphics;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class NumberPiece : Container
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/RingPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/RingPiece.cs
similarity index 90%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/RingPiece.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/RingPiece.cs
index 3e172cdc09..a04d3e7a0a 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/RingPiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/RingPiece.cs
@@ -7,7 +7,7 @@ using osu.Framework.Graphics.Sprites;
using OpenTK;
using OpenTK.Graphics;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class RingPiece : Container
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs
similarity index 95%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBall.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs
index becbebf0c7..4cffc1def3 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBall.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs
@@ -7,7 +7,7 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Input;
using OpenTK.Graphics;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class SliderBall : CircularContainer, ISliderProgress
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs
similarity index 96%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBody.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs
index e7837471ee..b23fdde4e8 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBody.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs
@@ -15,7 +15,7 @@ using OpenTK;
using OpenTK.Graphics.ES30;
using OpenTK.Graphics;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class SliderBody : Container, ISliderProgress
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBouncer.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs
similarity index 93%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBouncer.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs
index 196b9fb521..65679dd7d3 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SliderBouncer.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBouncer.cs
@@ -5,7 +5,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class SliderBouncer : Container, ISliderProgress
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs
similarity index 80%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs
index 50dab933b0..72024bbe99 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerBackground.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class SpinnerBackground : SpinnerDisc
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs
similarity index 95%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs
index a4fce3deb5..71adba74c7 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SpinnerDisc.cs
@@ -15,7 +15,7 @@ using osu.Game.Graphics;
using OpenTK;
using OpenTK.Graphics;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class SpinnerDisc : CircularContainer
{
diff --git a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/TrianglesPiece.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/TrianglesPiece.cs
similarity index 89%
rename from osu.Game.Modes.Osu/Objects/Drawables/Pieces/TrianglesPiece.cs
rename to osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/TrianglesPiece.cs
index 26d44f3865..ea3ddb5051 100644
--- a/osu.Game.Modes.Osu/Objects/Drawables/Pieces/TrianglesPiece.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/TrianglesPiece.cs
@@ -3,7 +3,7 @@
using osu.Game.Graphics.Backgrounds;
-namespace osu.Game.Modes.Osu.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class TrianglesPiece : Triangles
{
diff --git a/osu.Game.Modes.Osu/Objects/HitCircle.cs b/osu.Game.Rulesets.Osu/Objects/HitCircle.cs
similarity index 81%
rename from osu.Game.Modes.Osu/Objects/HitCircle.cs
rename to osu.Game.Rulesets.Osu/Objects/HitCircle.cs
index aa45ac7fb9..be969f1e18 100644
--- a/osu.Game.Modes.Osu/Objects/HitCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/HitCircle.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-namespace osu.Game.Modes.Osu.Objects
+namespace osu.Game.Rulesets.Osu.Objects
{
public class HitCircle : OsuHitObject
{
diff --git a/osu.Game.Modes.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs
similarity index 88%
rename from osu.Game.Modes.Osu/Objects/OsuHitObject.cs
rename to osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs
index fa422834db..723a37ed7b 100644
--- a/osu.Game.Modes.Osu/Objects/OsuHitObject.cs
+++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs
@@ -1,15 +1,15 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Objects;
+using osu.Game.Rulesets.Objects;
using OpenTK;
-using osu.Game.Modes.Osu.Objects.Drawables;
-using osu.Game.Modes.Objects.Types;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
+using osu.Game.Rulesets.Objects.Types;
using OpenTK.Graphics;
using osu.Game.Beatmaps.Timing;
using osu.Game.Database;
-namespace osu.Game.Modes.Osu.Objects
+namespace osu.Game.Rulesets.Osu.Objects
{
public abstract class OsuHitObject : HitObject, IHasCombo, IHasPosition
{
@@ -21,6 +21,8 @@ namespace osu.Game.Modes.Osu.Objects
private const double hit_window_300 = 30;
public Vector2 Position { get; set; }
+ public float X => Position.X;
+ public float Y => Position.Y;
public Vector2 StackedPosition => Position + StackOffset;
diff --git a/osu.Game.Modes.Osu/Objects/OsuHitObjectDifficulty.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObjectDifficulty.cs
similarity index 97%
rename from osu.Game.Modes.Osu/Objects/OsuHitObjectDifficulty.cs
rename to osu.Game.Rulesets.Osu/Objects/OsuHitObjectDifficulty.cs
index 322f6b077a..1786771dca 100644
--- a/osu.Game.Modes.Osu/Objects/OsuHitObjectDifficulty.cs
+++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObjectDifficulty.cs
@@ -6,7 +6,7 @@ using System;
using System.Diagnostics;
using System.Linq;
-namespace osu.Game.Modes.Osu.Objects
+namespace osu.Game.Rulesets.Osu.Objects
{
internal class OsuHitObjectDifficulty
{
diff --git a/osu.Game.Modes.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs
similarity index 69%
rename from osu.Game.Modes.Osu/Objects/Slider.cs
rename to osu.Game.Rulesets.Osu/Objects/Slider.cs
index a01c517cb2..6c0147a3de 100644
--- a/osu.Game.Modes.Osu/Objects/Slider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs
@@ -3,15 +3,15 @@
using OpenTK;
using osu.Game.Beatmaps.Timing;
-using osu.Game.Modes.Objects.Types;
+using osu.Game.Rulesets.Objects.Types;
using System;
using System.Collections.Generic;
-using osu.Game.Modes.Objects;
+using osu.Game.Rulesets.Objects;
using osu.Game.Database;
using System.Linq;
using osu.Game.Audio;
-namespace osu.Game.Modes.Osu.Objects
+namespace osu.Game.Rulesets.Osu.Objects
{
public class Slider : OsuHitObject, IHasCurve
{
@@ -20,24 +20,33 @@ namespace osu.Game.Modes.Osu.Objects
///
private const float base_scoring_distance = 100;
- public IHasCurve CurveObject { get; set; }
-
- public SliderCurve Curve => CurveObject.Curve;
+ public readonly SliderCurve Curve = new SliderCurve();
public double EndTime => StartTime + RepeatCount * Curve.Distance / Velocity;
public double Duration => EndTime - StartTime;
public override Vector2 EndPosition => PositionAt(1);
- public Vector2 PositionAt(double progress) => CurveObject.PositionAt(progress);
- public double ProgressAt(double progress) => CurveObject.ProgressAt(progress);
- public int RepeatAt(double progress) => CurveObject.RepeatAt(progress);
+ public List ControlPoints
+ {
+ get { return Curve.ControlPoints; }
+ set { Curve.ControlPoints = value; }
+ }
- public List ControlPoints => CurveObject.ControlPoints;
- public CurveType CurveType => CurveObject.CurveType;
- public double Distance => CurveObject.Distance;
+ public CurveType CurveType
+ {
+ get { return Curve.CurveType; }
+ set { Curve.CurveType = value; }
+ }
- public int RepeatCount => CurveObject.RepeatCount;
+ public double Distance
+ {
+ get { return Curve.Distance; }
+ set { Curve.Distance = value; }
+ }
+
+ public List RepeatSamples { get; set; } = new List();
+ public int RepeatCount { get; set; } = 1;
private int stackHeight;
public override int StackHeight
@@ -63,6 +72,18 @@ namespace osu.Game.Modes.Osu.Objects
TickDistance = scoringDistance / difficulty.SliderTickRate;
}
+ public Vector2 PositionAt(double progress) => Curve.PositionAt(ProgressAt(progress));
+
+ public double ProgressAt(double progress)
+ {
+ double p = progress * RepeatCount % 1;
+ if (RepeatAt(progress) % 2 == 1)
+ p = 1 - p;
+ return p;
+ }
+
+ public int RepeatAt(double progress) => (int)(progress * RepeatCount);
+
public IEnumerable Ticks
{
get
@@ -96,12 +117,12 @@ namespace osu.Game.Modes.Osu.Objects
StackHeight = StackHeight,
Scale = Scale,
ComboColour = ComboColour,
- Samples = Samples.Select(s => new SampleInfo
+ Samples = new SampleInfoList(Samples.Select(s => new SampleInfo
{
Bank = s.Bank,
Name = @"slidertick",
Volume = s.Volume
- }).ToList()
+ }))
};
}
}
diff --git a/osu.Game.Modes.Osu/Objects/SliderTick.cs b/osu.Game.Rulesets.Osu/Objects/SliderTick.cs
similarity index 83%
rename from osu.Game.Modes.Osu/Objects/SliderTick.cs
rename to osu.Game.Rulesets.Osu/Objects/SliderTick.cs
index 67f393b126..7112a39f97 100644
--- a/osu.Game.Modes.Osu/Objects/SliderTick.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SliderTick.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-namespace osu.Game.Modes.Osu.Objects
+namespace osu.Game.Rulesets.Osu.Objects
{
public class SliderTick : OsuHitObject
{
diff --git a/osu.Game.Modes.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs
similarity index 79%
rename from osu.Game.Modes.Osu/Objects/Spinner.cs
rename to osu.Game.Rulesets.Osu/Objects/Spinner.cs
index dd9a6c386a..0a2c05833a 100644
--- a/osu.Game.Modes.Osu/Objects/Spinner.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Spinner.cs
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Objects.Types;
+using osu.Game.Rulesets.Objects.Types;
-namespace osu.Game.Modes.Osu.Objects
+namespace osu.Game.Rulesets.Osu.Objects
{
public class Spinner : OsuHitObject, IHasEndTime
{
diff --git a/osu.Game.Modes.Osu/OpenTK.dll.config b/osu.Game.Rulesets.Osu/OpenTK.dll.config
similarity index 100%
rename from osu.Game.Modes.Osu/OpenTK.dll.config
rename to osu.Game.Rulesets.Osu/OpenTK.dll.config
diff --git a/osu.Game.Modes.Osu/OsuAutoReplay.cs b/osu.Game.Rulesets.Osu/OsuAutoReplay.cs
similarity index 94%
rename from osu.Game.Modes.Osu/OsuAutoReplay.cs
rename to osu.Game.Rulesets.Osu/OsuAutoReplay.cs
index ae85bd72d8..da30cf4efb 100644
--- a/osu.Game.Modes.Osu/OsuAutoReplay.cs
+++ b/osu.Game.Rulesets.Osu/OsuAutoReplay.cs
@@ -4,16 +4,17 @@
using OpenTK;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
-using osu.Game.Modes.Osu.Objects;
-using osu.Game.Modes.Osu.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using osu.Framework.Graphics;
-using osu.Game.Modes.Objects.Types;
-using osu.Game.Modes.Replays;
+using osu.Game.Rulesets.Objects.Types;
+using osu.Game.Rulesets.Replays;
+using osu.Game.Users;
-namespace osu.Game.Modes.Osu
+namespace osu.Game.Rulesets.Osu
{
public class OsuAutoReplay : Replay
{
@@ -27,6 +28,11 @@ namespace osu.Game.Modes.Osu
{
this.beatmap = beatmap;
+ User = new User
+ {
+ Username = @"Autoplay",
+ };
+
createAutoReplay();
}
@@ -132,8 +138,7 @@ namespace osu.Game.Modes.Osu
if (h is Spinner)
{
- targetPosition.X = Frames[Frames.Count - 1].MouseX;
- targetPosition.Y = Frames[Frames.Count - 1].MouseY;
+ targetPosition = Frames[Frames.Count - 1].Position;
Vector2 difference = spinner_centre - targetPosition;
@@ -187,7 +192,7 @@ namespace osu.Game.Modes.Osu
addFrameToReplay(lastFrame);
}
- Vector2 lastPosition = new Vector2(lastFrame.MouseX, lastFrame.MouseY);
+ Vector2 lastPosition = lastFrame.Position;
double timeDifference = applyModsToTime(h.StartTime - lastFrame.Time);
@@ -213,7 +218,7 @@ namespace osu.Game.Modes.Osu
ReplayButtonState button = buttonIndex % 2 == 0 ? ReplayButtonState.Left1 : ReplayButtonState.Right1;
- double hEndTime = (h as IHasEndTime)?.EndTime ?? h.StartTime;
+ double hEndTime = ((h as IHasEndTime)?.EndTime ?? h.StartTime) + KEY_UP_DELAY;
ReplayFrame newFrame = new ReplayFrame(h.StartTime, targetPosition.X, targetPosition.Y, button);
ReplayFrame endFrame = new ReplayFrame(hEndTime + endDelay, h.EndPosition.X, h.EndPosition.Y, ReplayButtonState.None);
diff --git a/osu.Game.Modes.Osu/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/OsuDifficultyCalculator.cs
similarity index 94%
rename from osu.Game.Modes.Osu/OsuDifficultyCalculator.cs
rename to osu.Game.Rulesets.Osu/OsuDifficultyCalculator.cs
index 7696638082..5669993e67 100644
--- a/osu.Game.Modes.Osu/OsuDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Osu/OsuDifficultyCalculator.cs
@@ -2,13 +2,13 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
-using osu.Game.Modes.Objects.Types;
-using osu.Game.Modes.Osu.Beatmaps;
-using osu.Game.Modes.Osu.Objects;
+using osu.Game.Rulesets.Beatmaps;
+using osu.Game.Rulesets.Osu.Beatmaps;
+using osu.Game.Rulesets.Osu.Objects;
using System;
using System.Collections.Generic;
-namespace osu.Game.Modes.Osu
+namespace osu.Game.Rulesets.Osu
{
public class OsuDifficultyCalculator : DifficultyCalculator
{
@@ -27,7 +27,7 @@ namespace osu.Game.Modes.Osu
protected override void PreprocessHitObjects()
{
foreach (var h in Objects)
- (h as IHasCurve)?.Curve?.Calculate();
+ (h as Slider)?.Curve?.Calculate();
}
protected override double CalculateInternal(Dictionary categoryDifficulty)
@@ -180,7 +180,7 @@ namespace osu.Game.Modes.Osu
return difficulty;
}
- protected override IBeatmapConverter CreateBeatmapConverter() => new OsuBeatmapConverter();
+ protected override BeatmapConverter CreateBeatmapConverter() => new OsuBeatmapConverter();
// Those values are used as array indices. Be careful when changing them!
public enum DifficultyType
@@ -189,4 +189,4 @@ namespace osu.Game.Modes.Osu
Aim,
};
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game.Modes.Osu/OsuKeyConversionInputManager.cs b/osu.Game.Rulesets.Osu/OsuKeyConversionInputManager.cs
similarity index 58%
rename from osu.Game.Modes.Osu/OsuKeyConversionInputManager.cs
rename to osu.Game.Rulesets.Osu/OsuKeyConversionInputManager.cs
index 986240b37f..d60aab90fb 100644
--- a/osu.Game.Modes.Osu/OsuKeyConversionInputManager.cs
+++ b/osu.Game.Rulesets.Osu/OsuKeyConversionInputManager.cs
@@ -2,28 +2,18 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
-using osu.Framework.Allocation;
-using osu.Framework.Configuration;
using osu.Framework.Input;
-using osu.Game.Configuration;
using osu.Game.Screens.Play;
using OpenTK.Input;
using KeyboardState = osu.Framework.Input.KeyboardState;
using MouseState = osu.Framework.Input.MouseState;
-namespace osu.Game.Modes.Osu
+namespace osu.Game.Rulesets.Osu
{
public class OsuKeyConversionInputManager : KeyConversionInputManager
{
private bool leftViaKeyboard;
private bool rightViaKeyboard;
- private Bindable mouseDisabled;
-
- [BackgroundDependencyLoader]
- private void load(OsuConfigManager config)
- {
- mouseDisabled = config.GetBindable(OsuConfig.MouseDisableButtons);
- }
protected override void TransformState(InputState state)
{
@@ -40,16 +30,10 @@ namespace osu.Game.Modes.Osu
if (mouse != null)
{
- if (mouseDisabled.Value)
- {
- mouse.PressedButtons.Remove(MouseButton.Left);
- mouse.PressedButtons.Remove(MouseButton.Right);
- }
-
if (leftViaKeyboard)
- mouse.PressedButtons.Add(MouseButton.Left);
+ mouse.SetPressed(MouseButton.Left, true);
if (rightViaKeyboard)
- mouse.PressedButtons.Add(MouseButton.Right);
+ mouse.SetPressed(MouseButton.Right, true);
}
}
}
diff --git a/osu.Game.Modes.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs
similarity index 89%
rename from osu.Game.Modes.Osu/OsuRuleset.cs
rename to osu.Game.Rulesets.Osu/OsuRuleset.cs
index 12df7d3f3c..39e911651a 100644
--- a/osu.Game.Modes.Osu/OsuRuleset.cs
+++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs
@@ -4,18 +4,18 @@
using OpenTK.Input;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
-using osu.Game.Modes.Mods;
-using osu.Game.Modes.Osu.Mods;
-using osu.Game.Modes.Osu.Objects;
-using osu.Game.Modes.Osu.UI;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Osu.Mods;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Rulesets.Osu.UI;
+using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using System.Collections.Generic;
using System.Linq;
-using osu.Game.Modes.Osu.Scoring;
-using osu.Game.Modes.Scoring;
+using osu.Game.Rulesets.Osu.Scoring;
+using osu.Game.Rulesets.Scoring;
-namespace osu.Game.Modes.Osu
+namespace osu.Game.Rulesets.Osu
{
public class OsuRuleset : Ruleset
{
@@ -99,8 +99,6 @@ namespace osu.Game.Modes.Osu
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new OsuDifficultyCalculator(beatmap);
- protected override PlayMode PlayMode => PlayMode.Osu;
-
public override string Description => "osu!";
public override IEnumerable CreateGameplayKeys() => new KeyCounter[]
@@ -112,5 +110,7 @@ namespace osu.Game.Modes.Osu
};
public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor();
+
+ public override int LegacyID => 0;
}
}
diff --git a/osu.Game.Modes.Osu/Properties/AssemblyInfo.cs b/osu.Game.Rulesets.Osu/Properties/AssemblyInfo.cs
similarity index 100%
rename from osu.Game.Modes.Osu/Properties/AssemblyInfo.cs
rename to osu.Game.Rulesets.Osu/Properties/AssemblyInfo.cs
diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs
new file mode 100644
index 0000000000..079ee928af
--- /dev/null
+++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs
@@ -0,0 +1,84 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System.Collections.Generic;
+using osu.Framework.Extensions;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Judgements;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Rulesets.UI;
+
+namespace osu.Game.Rulesets.Osu.Scoring
+{
+ internal class OsuScoreProcessor : ScoreProcessor
+ {
+ public OsuScoreProcessor()
+ {
+ }
+
+ public OsuScoreProcessor(HitRenderer hitRenderer)
+ : base(hitRenderer)
+ {
+ }
+
+ protected override void Reset()
+ {
+ base.Reset();
+
+ Health.Value = 1;
+ Accuracy.Value = 1;
+
+ scoreResultCounts.Clear();
+ comboResultCounts.Clear();
+ }
+
+ private readonly Dictionary scoreResultCounts = new Dictionary();
+ private readonly Dictionary comboResultCounts = new Dictionary();
+
+ public override void PopulateScore(Score score)
+ {
+ base.PopulateScore(score);
+
+ score.Statistics[@"300"] = scoreResultCounts.GetOrDefault(OsuScoreResult.Hit300);
+ score.Statistics[@"100"] = scoreResultCounts.GetOrDefault(OsuScoreResult.Hit100);
+ score.Statistics[@"50"] = scoreResultCounts.GetOrDefault(OsuScoreResult.Hit50);
+ score.Statistics[@"x"] = scoreResultCounts.GetOrDefault(OsuScoreResult.Miss);
+ }
+
+ protected override void OnNewJudgement(OsuJudgement judgement)
+ {
+ if (judgement != null)
+ {
+ if (judgement.Result != HitResult.None)
+ {
+ scoreResultCounts[judgement.Score] = scoreResultCounts.GetOrDefault(judgement.Score) + 1;
+ comboResultCounts[judgement.Combo] = comboResultCounts.GetOrDefault(judgement.Combo) + 1;
+ }
+
+ switch (judgement.Result)
+ {
+ case HitResult.Hit:
+ Health.Value += 0.1f;
+ break;
+ case HitResult.Miss:
+ Health.Value -= 0.2f;
+ break;
+ }
+ }
+
+ int score = 0;
+ int maxScore = 0;
+
+ foreach (var j in Judgements)
+ {
+ score += j.ScoreValue;
+ maxScore += j.MaxScoreValue;
+ }
+
+ TotalScore.Value = score;
+ Accuracy.Value = (double)score / maxScore;
+ }
+ }
+}
diff --git a/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs b/osu.Game.Rulesets.Osu/UI/OsuHitRenderer.cs
similarity index 62%
rename from osu.Game.Modes.Osu/UI/OsuHitRenderer.cs
rename to osu.Game.Rulesets.Osu/UI/OsuHitRenderer.cs
index ca9ff6fc61..687518e6d5 100644
--- a/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs
+++ b/osu.Game.Rulesets.Osu/UI/OsuHitRenderer.cs
@@ -1,18 +1,20 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using OpenTK;
using osu.Game.Beatmaps;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Osu.Beatmaps;
-using osu.Game.Modes.Osu.Judgements;
-using osu.Game.Modes.Osu.Objects;
-using osu.Game.Modes.Osu.Objects.Drawables;
-using osu.Game.Modes.Osu.Scoring;
-using osu.Game.Modes.Scoring;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Beatmaps;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Beatmaps;
+using osu.Game.Rulesets.Osu.Judgements;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Scoring;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
-namespace osu.Game.Modes.Osu.UI
+namespace osu.Game.Rulesets.Osu.UI
{
public class OsuHitRenderer : HitRenderer
{
@@ -23,9 +25,9 @@ namespace osu.Game.Modes.Osu.UI
public override ScoreProcessor CreateScoreProcessor() => new OsuScoreProcessor(this);
- protected override IBeatmapConverter CreateBeatmapConverter() => new OsuBeatmapConverter();
+ protected override BeatmapConverter CreateBeatmapConverter() => new OsuBeatmapConverter();
- protected override IBeatmapProcessor CreateBeatmapProcessor() => new OsuBeatmapProcessor();
+ protected override BeatmapProcessor CreateBeatmapProcessor() => new OsuBeatmapProcessor();
protected override Playfield CreatePlayfield() => new OsuPlayfield();
@@ -46,5 +48,7 @@ namespace osu.Game.Modes.Osu.UI
return new DrawableSpinner(spinner);
return null;
}
+
+ protected override Vector2 GetPlayfieldAspectAdjust() => new Vector2(0.75f);
}
}
diff --git a/osu.Game.Modes.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
similarity index 84%
rename from osu.Game.Modes.Osu/UI/OsuPlayfield.cs
rename to osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
index d89bbfd131..53eedea073 100644
--- a/osu.Game.Modes.Osu/UI/OsuPlayfield.cs
+++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs
@@ -4,16 +4,16 @@
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Osu.Objects;
-using osu.Game.Modes.Osu.Objects.Drawables;
-using osu.Game.Modes.Osu.Objects.Drawables.Connections;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Objects.Drawables.Connections;
+using osu.Game.Rulesets.UI;
using System.Linq;
using osu.Game.Graphics.Cursor;
-using osu.Game.Modes.Osu.Judgements;
+using osu.Game.Rulesets.Osu.Judgements;
-namespace osu.Game.Modes.Osu.UI
+namespace osu.Game.Rulesets.Osu.UI
{
public class OsuPlayfield : Playfield
{
@@ -23,6 +23,8 @@ namespace osu.Game.Modes.Osu.UI
public override bool ProvidingUserCursor => true;
+ public static readonly Vector2 BASE_SIZE = new Vector2(512, 384);
+
public override Vector2 Size
{
get
@@ -34,12 +36,10 @@ namespace osu.Game.Modes.Osu.UI
}
}
- public OsuPlayfield() : base(512)
+ public OsuPlayfield() : base(BASE_SIZE.X)
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
- RelativeSizeAxes = Axes.Both;
- Size = new Vector2(0.75f);
Add(new Drawable[]
{
@@ -96,4 +96,4 @@ namespace osu.Game.Modes.Osu.UI
judgementLayer.Add(explosion);
}
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
similarity index 93%
rename from osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj
rename to osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
index 55322e855e..fcad0061e4 100644
--- a/osu.Game.Modes.Osu/osu.Game.Modes.Osu.csproj
+++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
@@ -7,8 +7,8 @@
{C92A607B-1FDD-4954-9F92-03FF547D9080}
Library
Properties
- osu.Game.Modes.Osu
- osu.Game.Modes.Osu
+ osu.Game.Rulesets.Osu
+ osu.Game.Rulesets.Osu
v4.5
512
@@ -22,6 +22,7 @@
prompt
4
false
+ 6
pdbonly
@@ -34,8 +35,7 @@
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
@@ -72,7 +72,6 @@
-
@@ -104,7 +103,7 @@
-
-
+
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs
similarity index 67%
rename from osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapConverter.cs
rename to osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs
index aee06ad796..0784c94059 100644
--- a/osu.Game.Modes.Taiko/Beatmaps/TaikoBeatmapConverter.cs
+++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs
@@ -2,19 +2,20 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
-using osu.Game.Modes.Objects;
-using osu.Game.Modes.Objects.Types;
-using osu.Game.Modes.Taiko.Objects;
+using osu.Game.Rulesets.Objects;
+using osu.Game.Rulesets.Objects.Types;
+using osu.Game.Rulesets.Taiko.Objects;
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Database;
using osu.Game.IO.Serialization;
using osu.Game.Audio;
+using osu.Game.Rulesets.Beatmaps;
-namespace osu.Game.Modes.Taiko.Beatmaps
+namespace osu.Game.Rulesets.Taiko.Beatmaps
{
- internal class TaikoBeatmapConverter : IBeatmapConverter
+ internal class TaikoBeatmapConverter : BeatmapConverter
{
///
/// osu! is generally slower than taiko, so a factor is added to increase
@@ -38,31 +39,37 @@ namespace osu.Game.Modes.Taiko.Beatmaps
///
private const float taiko_base_distance = 100;
- public Beatmap Convert(Beatmap original)
+ protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(HitObject) };
+
+ protected override Beatmap ConvertBeatmap(Beatmap original)
{
+ // Rewrite the beatmap info to add the slider velocity multiplier
BeatmapInfo info = original.BeatmapInfo.DeepClone();
info.Difficulty.SliderMultiplier *= legacy_velocity_multiplier;
- return new Beatmap(original)
+ Beatmap converted = base.ConvertBeatmap(original);
+
+ // Post processing step to transform hit objects with the same start time into strong hits
+ converted.HitObjects = converted.HitObjects.GroupBy(t => t.StartTime).Select(x =>
{
- BeatmapInfo = info,
- HitObjects = original.HitObjects.SelectMany(h => convertHitObject(h, original)).ToList()
- };
+ TaikoHitObject first = x.First();
+ if (x.Skip(1).Any())
+ first.IsStrong = true;
+ return first;
+ }).ToList();
+
+ return converted;
}
- private IEnumerable convertHitObject(HitObject obj, Beatmap beatmap)
+ protected override IEnumerable ConvertHitObject(HitObject obj, Beatmap beatmap)
{
- // Check if this HitObject is already a TaikoHitObject, and return it if so
- var originalTaiko = obj as TaikoHitObject;
- if (originalTaiko != null)
- yield return originalTaiko;
-
var distanceData = obj as IHasDistance;
var repeatsData = obj as IHasRepeats;
var endTimeData = obj as IHasEndTime;
+ var curveData = obj as IHasCurve;
// Old osu! used hit sounding to determine various hit type information
- List samples = obj.Samples;
+ SampleInfoList samples = obj.Samples;
bool strong = samples.Any(s => s.Name == SampleInfo.HIT_FINISH);
@@ -92,20 +99,39 @@ namespace osu.Game.Modes.Taiko.Beatmaps
double osuDuration = distance / osuVelocity;
// If the drum roll is to be split into hit circles, assume the ticks are 1/8 spaced within the duration of one beat
- double tickSpacing = Math.Min(speedAdjustedBeatLength / beatmap.BeatmapInfo.Difficulty.SliderTickRate, taikoDuration / repeats) / 8;
+ double tickSpacing = Math.Min(speedAdjustedBeatLength / beatmap.BeatmapInfo.Difficulty.SliderTickRate, taikoDuration / repeats);
if (tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength)
{
- for (double j = obj.StartTime; j <= distanceData.EndTime + tickSpacing; j += tickSpacing)
+ List allSamples = curveData != null ? curveData.RepeatSamples : new List(new[] { samples });
+
+ int i = 0;
+ for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing)
{
- // Todo: This should generate different type of hits (including strongs)
- // depending on hitobject sound additions (not implemented fully yet)
- yield return new CentreHit
+ SampleInfoList currentSamples = allSamples[i];
+ bool isRim = currentSamples.Any(s => s.Name == SampleInfo.HIT_CLAP || s.Name == SampleInfo.HIT_WHISTLE);
+ strong = currentSamples.Any(s => s.Name == SampleInfo.HIT_FINISH);
+
+ if (isRim)
{
- StartTime = j,
- Samples = obj.Samples,
- IsStrong = strong,
- };
+ yield return new RimHit
+ {
+ StartTime = j,
+ Samples = currentSamples,
+ IsStrong = strong
+ };
+ }
+ else
+ {
+ yield return new CentreHit
+ {
+ StartTime = j,
+ Samples = currentSamples,
+ IsStrong = strong,
+ };
+ }
+
+ i = (i + 1) % allSamples.Count;
}
}
else
diff --git a/osu.Game.Modes.Taiko/Judgements/TaikoDrumRollTickJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs
similarity index 92%
rename from osu.Game.Modes.Taiko/Judgements/TaikoDrumRollTickJudgement.cs
rename to osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs
index 6ae476b265..78a5b29d36 100644
--- a/osu.Game.Modes.Taiko/Judgements/TaikoDrumRollTickJudgement.cs
+++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-namespace osu.Game.Modes.Taiko.Judgements
+namespace osu.Game.Rulesets.Taiko.Judgements
{
public class TaikoDrumRollTickJudgement : TaikoJudgement
{
diff --git a/osu.Game.Modes.Taiko/Judgements/TaikoHitResult.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoHitResult.cs
similarity index 84%
rename from osu.Game.Modes.Taiko/Judgements/TaikoHitResult.cs
rename to osu.Game.Rulesets.Taiko/Judgements/TaikoHitResult.cs
index cbc3919c4f..5fd850d6b0 100644
--- a/osu.Game.Modes.Taiko/Judgements/TaikoHitResult.cs
+++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoHitResult.cs
@@ -3,7 +3,7 @@
using System.ComponentModel;
-namespace osu.Game.Modes.Taiko.Judgements
+namespace osu.Game.Rulesets.Taiko.Judgements
{
public enum TaikoHitResult
{
diff --git a/osu.Game.Modes.Taiko/Judgements/TaikoJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs
similarity index 93%
rename from osu.Game.Modes.Taiko/Judgements/TaikoJudgement.cs
rename to osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs
index 7676ef8c29..7bca59bf11 100644
--- a/osu.Game.Modes.Taiko/Judgements/TaikoJudgement.cs
+++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs
@@ -1,11 +1,11 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Judgements;
+using osu.Game.Rulesets.Judgements;
using osu.Framework.Extensions;
-using osu.Game.Modes.Objects.Drawables;
+using osu.Game.Rulesets.Objects.Drawables;
-namespace osu.Game.Modes.Taiko.Judgements
+namespace osu.Game.Rulesets.Taiko.Judgements
{
public class TaikoJudgement : Judgement
{
diff --git a/osu.Game.Modes.Taiko/Judgements/TaikoStrongHitJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs
similarity index 84%
rename from osu.Game.Modes.Taiko/Judgements/TaikoStrongHitJudgement.cs
rename to osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs
index ee978d0026..4996cac39e 100644
--- a/osu.Game.Modes.Taiko/Judgements/TaikoStrongHitJudgement.cs
+++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongHitJudgement.cs
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Judgements;
+using osu.Game.Rulesets.Judgements;
-namespace osu.Game.Modes.Taiko.Judgements
+namespace osu.Game.Rulesets.Taiko.Judgements
{
public class TaikoStrongHitJudgement : TaikoJudgement, IPartialJudgement
{
diff --git a/osu.Game.Modes.Taiko/Mods/TaikoMod.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoMod.cs
similarity index 87%
rename from osu.Game.Modes.Taiko/Mods/TaikoMod.cs
rename to osu.Game.Rulesets.Taiko/Mods/TaikoMod.cs
index 422f0ec250..0b8492ef8c 100644
--- a/osu.Game.Modes.Taiko/Mods/TaikoMod.cs
+++ b/osu.Game.Rulesets.Taiko/Mods/TaikoMod.cs
@@ -2,13 +2,13 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
-using osu.Game.Modes.Mods;
-using osu.Game.Modes.Scoring;
-using osu.Game.Modes.Taiko.Objects;
-using osu.Game.Modes.Taiko.Replays;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Rulesets.Taiko.Objects;
+using osu.Game.Rulesets.Taiko.Replays;
using osu.Game.Users;
-namespace osu.Game.Modes.Taiko.Mods
+namespace osu.Game.Rulesets.Taiko.Mods
{
public class TaikoModNoFail : ModNoFail
{
diff --git a/osu.Game.Modes.Taiko/Objects/BarLine.cs b/osu.Game.Rulesets.Taiko/Objects/BarLine.cs
similarity index 80%
rename from osu.Game.Modes.Taiko/Objects/BarLine.cs
rename to osu.Game.Rulesets.Taiko/Objects/BarLine.cs
index ae3c03de5e..0e6ff9f758 100644
--- a/osu.Game.Modes.Taiko/Objects/BarLine.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/BarLine.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-namespace osu.Game.Modes.Taiko.Objects
+namespace osu.Game.Rulesets.Taiko.Objects
{
public class BarLine : TaikoHitObject
{
diff --git a/osu.Game.Modes.Taiko/Objects/CentreHit.cs b/osu.Game.Rulesets.Taiko/Objects/CentreHit.cs
similarity index 79%
rename from osu.Game.Modes.Taiko/Objects/CentreHit.cs
rename to osu.Game.Rulesets.Taiko/Objects/CentreHit.cs
index 258112f045..f82058fe01 100644
--- a/osu.Game.Modes.Taiko/Objects/CentreHit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/CentreHit.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-namespace osu.Game.Modes.Taiko.Objects
+namespace osu.Game.Rulesets.Taiko.Objects
{
public class CentreHit : Hit
{
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs
similarity index 94%
rename from osu.Game.Modes.Taiko/Objects/Drawables/DrawableBarLine.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs
index 59f8aca867..4c83e08bab 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableBarLine.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs
@@ -6,7 +6,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using OpenTK;
-namespace osu.Game.Modes.Taiko.Objects.Drawables
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
///
/// A line that scrolls alongside hit objects in the playfield and visualises control points.
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableBarLineMajor.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLineMajor.cs
similarity index 94%
rename from osu.Game.Modes.Taiko/Objects/Drawables/DrawableBarLineMajor.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLineMajor.cs
index 73565e6948..e64682a1e4 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableBarLineMajor.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLineMajor.cs
@@ -6,7 +6,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using OpenTK;
-namespace osu.Game.Modes.Taiko.Objects.Drawables
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableBarLineMajor : DrawableBarLine
{
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableCentreHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHit.cs
similarity index 83%
rename from osu.Game.Modes.Taiko/Objects/Drawables/DrawableCentreHit.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHit.cs
index ff5ac859b4..8bb78669ca 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableCentreHit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHit.cs
@@ -3,10 +3,10 @@
using osu.Framework.Allocation;
using osu.Game.Graphics;
-using osu.Game.Modes.Taiko.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK.Input;
-namespace osu.Game.Modes.Taiko.Objects.Drawables
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableCentreHit : DrawableHit
{
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs
similarity index 83%
rename from osu.Game.Modes.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs
index bc24e2aa65..434fb9377f 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs
@@ -3,10 +3,10 @@
using osu.Framework.Allocation;
using osu.Game.Graphics;
-using osu.Game.Modes.Taiko.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK.Input;
-namespace osu.Game.Modes.Taiko.Objects.Drawables
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableCentreHitStrong : DrawableHitStrong
{
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
similarity index 92%
rename from osu.Game.Modes.Taiko/Objects/Drawables/DrawableDrumRoll.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
index 0a0098dd34..4562501ed1 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableDrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
@@ -5,13 +5,13 @@ using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.MathUtils;
using osu.Game.Graphics;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Taiko.Judgements;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.Judgements;
using OpenTK;
using OpenTK.Graphics;
-using osu.Game.Modes.Taiko.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
-namespace osu.Game.Modes.Taiko.Objects.Drawables
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableDrumRoll : DrawableTaikoHitObject
{
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
similarity index 80%
rename from osu.Game.Modes.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
index 296affedaf..56a747467e 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
@@ -3,12 +3,12 @@
using System;
using osu.Framework.Graphics;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Taiko.Judgements;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.Judgements;
using OpenTK.Input;
-using osu.Game.Modes.Taiko.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
-namespace osu.Game.Modes.Taiko.Objects.Drawables
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableDrumRollTick : DrawableTaikoHitObject
{
@@ -27,11 +27,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables
protected override void CheckJudgement(bool userTriggered)
{
if (!userTriggered)
- {
- if (Judgement.TimeOffset > HitObject.HitWindow)
- Judgement.Result = HitResult.Miss;
return;
- }
if (Math.Abs(Judgement.TimeOffset) < HitObject.HitWindow)
{
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
similarity index 91%
rename from osu.Game.Modes.Taiko/Objects/Drawables/DrawableHit.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
index 167fbebd7b..a4a46e3b48 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableHit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
@@ -4,12 +4,12 @@
using System;
using System.Linq;
using osu.Framework.Graphics;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Taiko.Judgements;
-using osu.Game.Modes.Taiko.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.Judgements;
+using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK.Input;
-namespace osu.Game.Modes.Taiko.Objects.Drawables
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public abstract class DrawableHit : DrawableTaikoHitObject
{
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs
similarity index 90%
rename from osu.Game.Modes.Taiko/Objects/Drawables/DrawableHitStrong.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs
index 4ab029acb3..1c6b12ea43 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableHitStrong.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs
@@ -4,12 +4,12 @@
using System;
using System.Linq;
using osu.Framework.Input;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Taiko.Judgements;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.Judgements;
using OpenTK.Input;
-using osu.Game.Modes.Taiko.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
-namespace osu.Game.Modes.Taiko.Objects.Drawables
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public abstract class DrawableHitStrong : DrawableHit
{
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableRimHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHit.cs
similarity index 83%
rename from osu.Game.Modes.Taiko/Objects/Drawables/DrawableRimHit.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHit.cs
index 5a311d51ef..20e8d36105 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableRimHit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHit.cs
@@ -3,10 +3,10 @@
using osu.Framework.Allocation;
using osu.Game.Graphics;
-using osu.Game.Modes.Taiko.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK.Input;
-namespace osu.Game.Modes.Taiko.Objects.Drawables
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableRimHit : DrawableHit
{
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableRimHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHitStrong.cs
similarity index 83%
rename from osu.Game.Modes.Taiko/Objects/Drawables/DrawableRimHitStrong.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHitStrong.cs
index 5789dfb140..4b1bb62bab 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableRimHitStrong.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHitStrong.cs
@@ -3,10 +3,10 @@
using osu.Framework.Allocation;
using osu.Game.Graphics;
-using osu.Game.Modes.Taiko.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK.Input;
-namespace osu.Game.Modes.Taiko.Objects.Drawables
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableRimHitStrong : DrawableHitStrong
{
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
similarity index 91%
rename from osu.Game.Modes.Taiko/Objects/Drawables/DrawableSwell.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
index e1a590a025..37efd8aba4 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableSwell.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
@@ -9,14 +9,14 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Taiko.Judgements;
-using osu.Game.Modes.Taiko.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.Judgements;
+using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
-namespace osu.Game.Modes.Taiko.Objects.Drawables
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableSwell : DrawableTaikoHitObject
{
@@ -65,7 +65,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Alpha = 0,
- Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2),
+ Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER),
BlendingMode = BlendingMode.Additive,
Masking = true,
Children = new []
@@ -82,7 +82,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables
Name = "Target ring (thick border)",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2),
+ Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER),
Masking = true,
BorderThickness = target_ring_thick_border,
BlendingMode = BlendingMode.Additive,
@@ -148,9 +148,8 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables
var completion = (float)userHits / HitObject.RequiredHits;
expandingRing.FadeTo(expandingRing.Alpha + MathHelper.Clamp(completion / 16, 0.1f, 0.6f), 50);
- expandingRing.Delay(50);
- expandingRing.FadeTo(completion / 8, 2000, EasingTypes.OutQuint);
- expandingRing.DelayReset();
+ using (expandingRing.BeginDelayedSequence(50))
+ expandingRing.FadeTo(completion / 8, 2000, EasingTypes.OutQuint);
symbol.RotateTo((float)(completion * HitObject.Duration / 8), 4000, EasingTypes.OutQuint);
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
similarity index 91%
rename from osu.Game.Modes.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
index f15f2bd152..24aa366944 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
@@ -5,13 +5,13 @@ using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Taiko.Judgements;
-using osu.Game.Modes.Taiko.Objects.Drawables.Pieces;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.Judgements;
+using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK;
using OpenTK.Input;
-namespace osu.Game.Modes.Taiko.Objects.Drawables
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public abstract class DrawableTaikoHitObject : DrawableHitObject
where TaikoHitType : TaikoHitObject
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs
similarity index 90%
rename from osu.Game.Modes.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs
index 0cf4e97b41..ddf1492ecc 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CentreHitSymbolPiece.cs
@@ -6,7 +6,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using OpenTK;
-namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
///
/// The symbol used for centre hit pieces.
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
similarity index 89%
rename from osu.Game.Modes.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
index f921511e22..9f91488fe3 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/CirclePiece.cs
@@ -8,7 +8,7 @@ using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.Backgrounds;
using OpenTK.Graphics;
-namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
///
/// A circle piece which is used uniformly through osu!taiko to visualise hitobjects.
@@ -19,15 +19,10 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
///
public class CirclePiece : TaikoPiece
{
- public const float SYMBOL_SIZE = TaikoHitObject.CIRCLE_RADIUS * 2f * 0.45f;
+ public const float SYMBOL_SIZE = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER * 0.45f;
public const float SYMBOL_BORDER = 8;
public const float SYMBOL_INNER_SIZE = SYMBOL_SIZE - 2 * SYMBOL_BORDER;
- ///
- /// The amount to scale up the base circle to show it as a "strong" piece.
- ///
- private const float strong_scale = 1.5f;
-
///
/// The colour of the inner circle and outer glows.
///
@@ -129,10 +124,10 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
if (isStrong)
{
- Size *= strong_scale;
+ Size *= TaikoHitObject.STRONG_CIRCLE_DIAMETER_SCALE;
//default for symbols etc.
- Content.Scale *= strong_scale;
+ Content.Scale *= TaikoHitObject.STRONG_CIRCLE_DIAMETER_SCALE;
}
}
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs
similarity index 88%
rename from osu.Game.Modes.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs
index 5431507614..bed54d358e 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/ElongatedCirclePiece.cs
@@ -3,14 +3,13 @@
using System;
using osu.Framework.Graphics.Primitives;
-using osu.Game.Modes.Taiko.UI;
-namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
public class ElongatedCirclePiece : CirclePiece
{
///
- /// As we are being used to define the absolute size of hits, we need to be given a relative reference of our containing .
+ /// As we are being used to define the absolute size of hits, we need to be given a relative reference of our containing playfield container.
///
public Func PlayfieldLengthReference;
@@ -38,4 +37,4 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
Width = (PlayfieldLengthReference?.Invoke() ?? 0) * Length + DrawHeight;
}
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs
similarity index 91%
rename from osu.Game.Modes.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs
index 6e19497978..4146edbdf7 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/RimHitSymbolPiece.cs
@@ -7,7 +7,7 @@ using osu.Framework.Graphics.Sprites;
using OpenTK;
using OpenTK.Graphics;
-namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
///
/// The symbol used for rim hit pieces.
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
similarity index 88%
rename from osu.Game.Modes.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
index e491793902..0f703837a9 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/SwellSymbolPiece.cs
@@ -4,7 +4,7 @@
using osu.Framework.Graphics;
using osu.Game.Graphics;
-namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
///
/// The symbol used for swell pieces.
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
similarity index 85%
rename from osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
index a0c8865c59..83b2e59e44 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TaikoPiece.cs
@@ -6,7 +6,7 @@ using osu.Game.Graphics;
using OpenTK;
using OpenTK.Graphics;
-namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
public class TaikoPiece : Container, IHasAccentColour
{
@@ -39,7 +39,7 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
public TaikoPiece()
{
//just a default
- Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2);
+ Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER);
}
}
}
diff --git a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TickPiece.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TickPiece.cs
similarity index 84%
rename from osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TickPiece.cs
rename to osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TickPiece.cs
index 697102eb22..1a0d0156e8 100644
--- a/osu.Game.Modes.Taiko/Objects/Drawables/Pieces/TickPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/Pieces/TickPiece.cs
@@ -7,7 +7,7 @@ using osu.Framework.Graphics.Sprites;
using OpenTK;
using OpenTK.Graphics;
-namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
+namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
public class TickPiece : TaikoPiece
{
@@ -15,12 +15,12 @@ namespace osu.Game.Modes.Taiko.Objects.Drawables.Pieces
/// Any tick that is not the first for a drumroll is not filled, but is instead displayed
/// as a hollow circle. This is what controls the border width of that circle.
///
- private const float tick_border_width = TaikoHitObject.CIRCLE_RADIUS / 2 / 4;
+ private const float tick_border_width = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER / 16;
///
/// The size of a tick.
///
- private const float tick_size = TaikoHitObject.CIRCLE_RADIUS / 2;
+ private const float tick_size = TaikoHitObject.DEFAULT_CIRCLE_DIAMETER / 6;
private bool filled;
public bool Filled
diff --git a/osu.Game.Modes.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
similarity index 91%
rename from osu.Game.Modes.Taiko/Objects/DrumRoll.cs
rename to osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
index 4f26ffd3a1..f79c01b643 100644
--- a/osu.Game.Modes.Taiko/Objects/DrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Objects.Types;
+using osu.Game.Rulesets.Objects.Types;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -9,7 +9,7 @@ using osu.Game.Beatmaps.Timing;
using osu.Game.Database;
using osu.Game.Audio;
-namespace osu.Game.Modes.Taiko.Objects
+namespace osu.Game.Rulesets.Taiko.Objects
{
public class DrumRoll : TaikoHitObject, IHasEndTime
{
@@ -82,12 +82,12 @@ namespace osu.Game.Modes.Taiko.Objects
TickSpacing = tickSpacing,
StartTime = t,
IsStrong = IsStrong,
- Samples = Samples.Select(s => new SampleInfo
+ Samples = new SampleInfoList(Samples.Select(s => new SampleInfo
{
Bank = s.Bank,
Name = @"slidertick",
Volume = s.Volume
- }).ToList()
+ }))
});
first = false;
diff --git a/osu.Game.Modes.Taiko/Objects/DrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs
similarity index 91%
rename from osu.Game.Modes.Taiko/Objects/DrumRollTick.cs
rename to osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs
index 32e8851b66..01f9caf215 100644
--- a/osu.Game.Modes.Taiko/Objects/DrumRollTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-namespace osu.Game.Modes.Taiko.Objects
+namespace osu.Game.Rulesets.Taiko.Objects
{
public class DrumRollTick : TaikoHitObject
{
diff --git a/osu.Game.Modes.Taiko/Objects/Hit.cs b/osu.Game.Rulesets.Taiko/Objects/Hit.cs
similarity index 93%
rename from osu.Game.Modes.Taiko/Objects/Hit.cs
rename to osu.Game.Rulesets.Taiko/Objects/Hit.cs
index ad8d07d901..136e89124c 100644
--- a/osu.Game.Modes.Taiko/Objects/Hit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Hit.cs
@@ -4,7 +4,7 @@
using osu.Game.Beatmaps.Timing;
using osu.Game.Database;
-namespace osu.Game.Modes.Taiko.Objects
+namespace osu.Game.Rulesets.Taiko.Objects
{
public class Hit : TaikoHitObject
{
diff --git a/osu.Game.Modes.Taiko/Objects/RimHit.cs b/osu.Game.Rulesets.Taiko/Objects/RimHit.cs
similarity index 79%
rename from osu.Game.Modes.Taiko/Objects/RimHit.cs
rename to osu.Game.Rulesets.Taiko/Objects/RimHit.cs
index aae93ec10d..8e09842294 100644
--- a/osu.Game.Modes.Taiko/Objects/RimHit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/RimHit.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-namespace osu.Game.Modes.Taiko.Objects
+namespace osu.Game.Rulesets.Taiko.Objects
{
public class RimHit : Hit
{
diff --git a/osu.Game.Modes.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs
similarity index 82%
rename from osu.Game.Modes.Taiko/Objects/Swell.cs
rename to osu.Game.Rulesets.Taiko/Objects/Swell.cs
index 97101ea797..f74a543ca9 100644
--- a/osu.Game.Modes.Taiko/Objects/Swell.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs
@@ -1,9 +1,9 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Objects.Types;
+using osu.Game.Rulesets.Objects.Types;
-namespace osu.Game.Modes.Taiko.Objects
+namespace osu.Game.Rulesets.Taiko.Objects
{
public class Swell : TaikoHitObject, IHasEndTime
{
diff --git a/osu.Game.Modes.Taiko/Objects/TaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
similarity index 65%
rename from osu.Game.Modes.Taiko/Objects/TaikoHitObject.cs
rename to osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
index 54ab8c5300..6a6353fde2 100644
--- a/osu.Game.Modes.Taiko/Objects/TaikoHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
@@ -3,16 +3,32 @@
using osu.Game.Beatmaps.Timing;
using osu.Game.Database;
-using osu.Game.Modes.Objects;
+using osu.Game.Rulesets.Objects;
+using osu.Game.Rulesets.Taiko.UI;
-namespace osu.Game.Modes.Taiko.Objects
+namespace osu.Game.Rulesets.Taiko.Objects
{
public abstract class TaikoHitObject : HitObject
{
///
- /// HitCircle radius.
+ /// Diameter of a circle relative to the size of the .
///
- public const float CIRCLE_RADIUS = 42f;
+ public const float PLAYFIELD_RELATIVE_DIAMETER = 0.5f;
+
+ ///
+ /// Scale multiplier for a strong circle.
+ ///
+ public const float STRONG_CIRCLE_DIAMETER_SCALE = 1.5f;
+
+ ///
+ /// Default circle diameter.
+ ///
+ public const float DEFAULT_CIRCLE_DIAMETER = TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT * PLAYFIELD_RELATIVE_DIAMETER;
+
+ ///
+ /// Default strong circle diameter.
+ ///
+ public const float DEFAULT_STRONG_CIRCLE_DIAMETER = DEFAULT_CIRCLE_DIAMETER * STRONG_CIRCLE_DIAMETER_SCALE;
///
/// The time taken from the initial (off-screen) spawn position to the centre of the hit target for a of 1000ms.
diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObjectDifficulty.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObjectDifficulty.cs
new file mode 100644
index 0000000000..c8bb73abbb
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObjectDifficulty.cs
@@ -0,0 +1,127 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System;
+
+namespace osu.Game.Rulesets.Taiko.Objects
+{
+ internal class TaikoHitObjectDifficulty
+ {
+ ///
+ /// Factor by how much individual / overall strain decays per second.
+ ///
+ ///
+ /// These values are results of tweaking a lot and taking into account general feedback.
+ ///
+ internal const double DECAY_BASE = 0.30;
+
+ private const double type_change_bonus = 0.75;
+ private const double rhythm_change_bonus = 1.0;
+ private const double rhythm_change_base_threshold = 0.2;
+ private const double rhythm_change_base = 2.0;
+
+ internal TaikoHitObject BaseHitObject;
+
+ ///
+ /// Measures note density in a way
+ ///
+ internal double Strain = 1;
+
+ private double timeElapsed;
+ private int sameTypeSince = 1;
+
+ private bool isRim => BaseHitObject is RimHit;
+
+ public TaikoHitObjectDifficulty(TaikoHitObject baseHitObject)
+ {
+ BaseHitObject = baseHitObject;
+ }
+
+ internal void CalculateStrains(TaikoHitObjectDifficulty previousHitObject, double timeRate)
+ {
+ // Rather simple, but more specialized things are inherently inaccurate due to the big difference playstyles and opinions make.
+ // See Taiko feedback thread.
+ timeElapsed = (BaseHitObject.StartTime - previousHitObject.BaseHitObject.StartTime) / timeRate;
+ double decay = Math.Pow(DECAY_BASE, timeElapsed / 1000);
+
+ double addition = 1;
+
+ // Only if we are no slider or spinner we get an extra addition
+ if (previousHitObject.BaseHitObject is Hit && BaseHitObject is Hit
+ && BaseHitObject.StartTime - previousHitObject.BaseHitObject.StartTime < 1000) // And we only want to check out hitobjects which aren't so far in the past
+ {
+ addition += typeChangeAddition(previousHitObject);
+ addition += rhythmChangeAddition(previousHitObject);
+ }
+
+ double additionFactor = 1.0;
+ // Scale AdditionFactor linearly from 0.4 to 1 for TimeElapsed from 0 to 50
+ if (timeElapsed < 50.0)
+ additionFactor = 0.4 + 0.6 * timeElapsed / 50.0;
+
+ Strain = previousHitObject.Strain * decay + addition * additionFactor;
+ }
+
+ private TypeSwitch lastTypeSwitchEven = TypeSwitch.None;
+ private double typeChangeAddition(TaikoHitObjectDifficulty previousHitObject)
+ {
+ // If we don't have the same hit type, trigger a type change!
+ if (previousHitObject.isRim != isRim)
+ {
+ lastTypeSwitchEven = previousHitObject.sameTypeSince % 2 == 0 ? TypeSwitch.Even : TypeSwitch.Odd;
+
+ // We only want a bonus if the parity of the type switch changes!
+ switch (previousHitObject.lastTypeSwitchEven)
+ {
+ case TypeSwitch.Even:
+ if (lastTypeSwitchEven == TypeSwitch.Odd)
+ return type_change_bonus;
+ break;
+ case TypeSwitch.Odd:
+ if (lastTypeSwitchEven == TypeSwitch.Even)
+ return type_change_bonus;
+ break;
+ }
+ }
+ // No type change? Increment counter and keep track of last type switch
+ else
+ {
+ lastTypeSwitchEven = previousHitObject.lastTypeSwitchEven;
+ sameTypeSince = previousHitObject.sameTypeSince + 1;
+ }
+
+ return 0;
+ }
+
+ private double rhythmChangeAddition(TaikoHitObjectDifficulty previousHitObject)
+ {
+ // We don't want a division by zero if some random mapper decides to put 2 HitObjects at the same time.
+ if (timeElapsed == 0 || previousHitObject.timeElapsed == 0)
+ return 0;
+
+ double timeElapsedRatio = Math.Max(previousHitObject.timeElapsed / timeElapsed, timeElapsed / previousHitObject.timeElapsed);
+
+ if (timeElapsedRatio >= 8)
+ return 0;
+
+ double difference = Math.Log(timeElapsedRatio, rhythm_change_base) % 1.0;
+
+ if (isWithinChangeThreshold(difference))
+ return rhythm_change_bonus;
+
+ return 0;
+ }
+
+ private bool isWithinChangeThreshold(double value)
+ {
+ return value > rhythm_change_base_threshold && value < 1 - rhythm_change_base_threshold;
+ }
+
+ private enum TypeSwitch
+ {
+ None,
+ Even,
+ Odd
+ }
+ }
+}
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/OpenTK.dll.config b/osu.Game.Rulesets.Taiko/OpenTK.dll.config
similarity index 100%
rename from osu.Game.Modes.Taiko/OpenTK.dll.config
rename to osu.Game.Rulesets.Taiko/OpenTK.dll.config
diff --git a/osu.Game.Modes.Taiko/Properties/AssemblyInfo.cs b/osu.Game.Rulesets.Taiko/Properties/AssemblyInfo.cs
similarity index 90%
rename from osu.Game.Modes.Taiko/Properties/AssemblyInfo.cs
rename to osu.Game.Rulesets.Taiko/Properties/AssemblyInfo.cs
index 94ec895707..89c07517ca 100644
--- a/osu.Game.Modes.Taiko/Properties/AssemblyInfo.cs
+++ b/osu.Game.Rulesets.Taiko/Properties/AssemblyInfo.cs
@@ -7,11 +7,11 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("osu.Game.Modes.Taiko")]
+[assembly: AssemblyTitle("osu.Game.Rulesets.Taiko")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("osu.Game.Modes.Taiko")]
+[assembly: AssemblyProduct("osu.Game.Rulesets.Taiko")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
diff --git a/osu.Game.Modes.Taiko/Replays/TaikoAutoReplay.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoReplay.cs
similarity index 76%
rename from osu.Game.Modes.Taiko/Replays/TaikoAutoReplay.cs
rename to osu.Game.Rulesets.Taiko/Replays/TaikoAutoReplay.cs
index 89d974baf9..d78e8af589 100644
--- a/osu.Game.Modes.Taiko/Replays/TaikoAutoReplay.cs
+++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoReplay.cs
@@ -3,14 +3,16 @@
using System;
using osu.Game.Beatmaps;
-using osu.Game.Modes.Objects.Types;
-using osu.Game.Modes.Taiko.Objects;
-using osu.Game.Modes.Replays;
+using osu.Game.Rulesets.Objects.Types;
+using osu.Game.Rulesets.Taiko.Objects;
+using osu.Game.Rulesets.Replays;
-namespace osu.Game.Modes.Taiko.Replays
+namespace osu.Game.Rulesets.Taiko.Replays
{
public class TaikoAutoReplay : Replay
{
+ private const double swell_hit_speed = 50;
+
private readonly Beatmap beatmap;
public TaikoAutoReplay(Beatmap beatmap)
@@ -24,8 +26,8 @@ namespace osu.Game.Modes.Taiko.Replays
{
bool hitButton = true;
- Frames.Add(new ReplayFrame(-100000, 320, 240, ReplayButtonState.None));
- Frames.Add(new ReplayFrame(beatmap.HitObjects[0].StartTime - 1000, 320, 240, ReplayButtonState.None));
+ Frames.Add(new ReplayFrame(-100000, null, null, ReplayButtonState.None));
+ Frames.Add(new ReplayFrame(beatmap.HitObjects[0].StartTime - 1000, null, null, ReplayButtonState.None));
for (int i = 0; i < beatmap.HitObjects.Count; i++)
{
@@ -45,12 +47,13 @@ namespace osu.Game.Modes.Taiko.Replays
int d = 0;
int count = 0;
int req = swell.RequiredHits;
- double hitRate = swell.Duration / req;
+ double hitRate = Math.Min(swell_hit_speed, swell.Duration / req);
for (double j = h.StartTime; j < endTime; j += hitRate)
{
switch (d)
{
default:
+ case 0:
button = ReplayButtonState.Left1;
break;
case 1:
@@ -64,9 +67,9 @@ namespace osu.Game.Modes.Taiko.Replays
break;
}
- Frames.Add(new ReplayFrame(j, 0, 0, button));
+ Frames.Add(new ReplayFrame(j, null, null, button));
d = (d + 1) % 4;
- if (++count > req)
+ if (++count == req)
break;
}
}
@@ -74,7 +77,7 @@ namespace osu.Game.Modes.Taiko.Replays
{
foreach (var tick in drumRoll.Ticks)
{
- Frames.Add(new ReplayFrame(tick.StartTime, 0, 0, hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2));
+ Frames.Add(new ReplayFrame(tick.StartTime, null, null, hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2));
hitButton = !hitButton;
}
}
@@ -95,22 +98,22 @@ namespace osu.Game.Modes.Taiko.Replays
button = hitButton ? ReplayButtonState.Left1 : ReplayButtonState.Left2;
}
- Frames.Add(new ReplayFrame(h.StartTime, 0, 0, button));
+ Frames.Add(new ReplayFrame(h.StartTime, null, null, button));
}
else
throw new Exception("Unknown hit object type.");
- Frames.Add(new ReplayFrame(endTime + 1, 0, 0, ReplayButtonState.None));
+ Frames.Add(new ReplayFrame(endTime + KEY_UP_DELAY, null, null, ReplayButtonState.None));
if (i < beatmap.HitObjects.Count - 1)
{
double waitTime = beatmap.HitObjects[i + 1].StartTime - 1000;
if (waitTime > endTime)
- Frames.Add(new ReplayFrame(waitTime, 0, 0, ReplayButtonState.None));
+ Frames.Add(new ReplayFrame(waitTime, null, null, ReplayButtonState.None));
}
hitButton = !hitButton;
}
}
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game.Modes.Taiko/Replays/TaikoFramedReplayInputHandler.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs
similarity index 90%
rename from osu.Game.Modes.Taiko/Replays/TaikoFramedReplayInputHandler.cs
rename to osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs
index 44fca4abe7..f6425dd66f 100644
--- a/osu.Game.Modes.Taiko/Replays/TaikoFramedReplayInputHandler.cs
+++ b/osu.Game.Rulesets.Taiko/Replays/TaikoFramedReplayInputHandler.cs
@@ -1,12 +1,12 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Replays;
+using osu.Game.Rulesets.Replays;
using System.Collections.Generic;
using osu.Framework.Input;
using OpenTK.Input;
-namespace osu.Game.Modes.Taiko.Replays
+namespace osu.Game.Rulesets.Taiko.Replays
{
internal class TaikoFramedReplayInputHandler : FramedReplayInputHandler
{
diff --git a/osu.Game.Modes.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs
similarity index 95%
rename from osu.Game.Modes.Taiko/Scoring/TaikoScoreProcessor.cs
rename to osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs
index 987c3181a4..f5e2094cbf 100644
--- a/osu.Game.Modes.Taiko/Scoring/TaikoScoreProcessor.cs
+++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs
@@ -4,14 +4,14 @@
using System;
using osu.Game.Beatmaps;
using osu.Game.Database;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Scoring;
-using osu.Game.Modes.Taiko.Judgements;
-using osu.Game.Modes.Taiko.Objects;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Rulesets.Taiko.Judgements;
+using osu.Game.Rulesets.Taiko.Objects;
+using osu.Game.Rulesets.UI;
using OpenTK;
-namespace osu.Game.Modes.Taiko.Scoring
+namespace osu.Game.Rulesets.Taiko.Scoring
{
internal class TaikoScoreProcessor : ScoreProcessor
{
diff --git a/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs
new file mode 100644
index 0000000000..33e9510f1c
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko/TaikoDifficultyCalculator.cs
@@ -0,0 +1,140 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Beatmaps;
+using osu.Game.Rulesets.Taiko.Beatmaps;
+using osu.Game.Rulesets.Taiko.Objects;
+using System.Collections.Generic;
+using System.Globalization;
+using System;
+
+namespace osu.Game.Rulesets.Taiko
+{
+ internal class TaikoDifficultyCalculator : DifficultyCalculator
+ {
+ private const double star_scaling_factor = 0.04125;
+
+ ///
+ /// In milliseconds. For difficulty calculation we will only look at the highest strain value in each time interval of size STRAIN_STEP.
+ /// This is to eliminate higher influence of stream over aim by simply having more HitObjects with high strain.
+ /// The higher this value, the less strains there will be, indirectly giving long beatmaps an advantage.
+ ///
+ private const double strain_step = 400;
+
+ ///
+ /// The weighting of each strain value decays to this number * it's previous value
+ ///
+ private const double decay_weight = 0.9;
+
+ ///
+ /// HitObjects are stored as a member variable.
+ ///
+ private readonly List difficultyHitObjects = new List();
+
+ public TaikoDifficultyCalculator(Beatmap beatmap)
+ : base(beatmap)
+ {
+ }
+
+ protected override double CalculateInternal(Dictionary categoryDifficulty)
+ {
+ // Fill our custom DifficultyHitObject class, that carries additional information
+ difficultyHitObjects.Clear();
+
+ foreach (var hitObject in Objects)
+ difficultyHitObjects.Add(new TaikoHitObjectDifficulty(hitObject));
+
+ // Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure.
+ difficultyHitObjects.Sort((a, b) => a.BaseHitObject.StartTime.CompareTo(b.BaseHitObject.StartTime));
+
+ if (!calculateStrainValues()) return 0;
+
+ double starRating = calculateDifficulty() * star_scaling_factor;
+
+ if (categoryDifficulty != null)
+ {
+ categoryDifficulty.Add("Strain", starRating.ToString("0.00", CultureInfo.InvariantCulture));
+ categoryDifficulty.Add("Hit window 300", (35 /*HitObjectManager.HitWindow300*/ / TimeRate).ToString("0.00", CultureInfo.InvariantCulture));
+ }
+
+ return starRating;
+ }
+
+ private bool calculateStrainValues()
+ {
+ // Traverse hitObjects in pairs to calculate the strain value of NextHitObject from the strain value of CurrentHitObject and environment.
+ using (List.Enumerator hitObjectsEnumerator = difficultyHitObjects.GetEnumerator())
+ {
+ if (!hitObjectsEnumerator.MoveNext()) return false;
+
+ TaikoHitObjectDifficulty current = hitObjectsEnumerator.Current;
+
+ // First hitObject starts at strain 1. 1 is the default for strain values, so we don't need to set it here. See DifficultyHitObject.
+ while (hitObjectsEnumerator.MoveNext())
+ {
+ var next = hitObjectsEnumerator.Current;
+ next?.CalculateStrains(current, TimeRate);
+ current = next;
+ }
+
+ return true;
+ }
+ }
+
+ private double calculateDifficulty()
+ {
+ double actualStrainStep = strain_step * TimeRate;
+
+ // Find the highest strain value within each strain step
+ List highestStrains = new List();
+ double intervalEndTime = actualStrainStep;
+ double maximumStrain = 0; // We need to keep track of the maximum strain in the current interval
+
+ TaikoHitObjectDifficulty previousHitObject = null;
+ foreach (var hitObject in difficultyHitObjects)
+ {
+ // While we are beyond the current interval push the currently available maximum to our strain list
+ while (hitObject.BaseHitObject.StartTime > intervalEndTime)
+ {
+ highestStrains.Add(maximumStrain);
+
+ // The maximum strain of the next interval is not zero by default! We need to take the last hitObject we encountered, take its strain and apply the decay
+ // until the beginning of the next interval.
+ if (previousHitObject == null)
+ {
+ maximumStrain = 0;
+ }
+ else
+ {
+ double decay = Math.Pow(TaikoHitObjectDifficulty.DECAY_BASE, (intervalEndTime - previousHitObject.BaseHitObject.StartTime) / 1000);
+ maximumStrain = previousHitObject.Strain * decay;
+ }
+
+ // Go to the next time interval
+ intervalEndTime += actualStrainStep;
+ }
+
+ // Obtain maximum strain
+ maximumStrain = Math.Max(hitObject.Strain, maximumStrain);
+
+ previousHitObject = hitObject;
+ }
+
+ // Build the weighted sum over the highest strains for each interval
+ double difficulty = 0;
+ double weight = 1;
+ highestStrains.Sort((a, b) => b.CompareTo(a)); // Sort from highest to lowest strain.
+
+ foreach (double strain in highestStrains)
+ {
+ difficulty += weight * strain;
+ weight *= decay_weight;
+ }
+
+ return difficulty;
+ }
+
+ protected override BeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter();
+ }
+}
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
similarity index 88%
rename from osu.Game.Modes.Taiko/TaikoRuleset.cs
rename to osu.Game.Rulesets.Taiko/TaikoRuleset.cs
index 1b3c3fc0eb..3fb2cf6c28 100644
--- a/osu.Game.Modes.Taiko/TaikoRuleset.cs
+++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
@@ -4,16 +4,16 @@
using OpenTK.Input;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
-using osu.Game.Modes.Mods;
-using osu.Game.Modes.Taiko.Mods;
-using osu.Game.Modes.Taiko.UI;
-using osu.Game.Modes.UI;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Taiko.Mods;
+using osu.Game.Rulesets.Taiko.UI;
+using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using System.Collections.Generic;
-using osu.Game.Modes.Scoring;
-using osu.Game.Modes.Taiko.Scoring;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Rulesets.Taiko.Scoring;
-namespace osu.Game.Modes.Taiko
+namespace osu.Game.Rulesets.Taiko
{
public class TaikoRuleset : Ruleset
{
@@ -76,8 +76,6 @@ namespace osu.Game.Modes.Taiko
}
}
- protected override PlayMode PlayMode => PlayMode.Taiko;
-
public override string Description => "osu!taiko";
public override FontAwesome Icon => FontAwesome.fa_osu_taiko_o;
@@ -93,5 +91,7 @@ namespace osu.Game.Modes.Taiko
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new TaikoDifficultyCalculator(beatmap);
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor();
+
+ public override int LegacyID => 1;
}
}
diff --git a/osu.Game.Modes.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs
similarity index 87%
rename from osu.Game.Modes.Taiko/UI/DrawableTaikoJudgement.cs
rename to osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs
index 78c9657b40..08fd8dbecc 100644
--- a/osu.Game.Modes.Taiko/UI/DrawableTaikoJudgement.cs
+++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs
@@ -1,13 +1,13 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Taiko.Judgements;
-using osu.Game.Modes.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.Judgements;
+using osu.Game.Rulesets.Objects.Drawables;
using osu.Framework.Allocation;
using osu.Game.Graphics;
-using osu.Game.Modes.Judgements;
+using osu.Game.Rulesets.Judgements;
-namespace osu.Game.Modes.Taiko.UI
+namespace osu.Game.Rulesets.Taiko.UI
{
///
/// Text that is shown as judgement when a hit object is hit or missed.
diff --git a/osu.Game.Modes.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs
similarity index 79%
rename from osu.Game.Modes.Taiko/UI/HitExplosion.cs
rename to osu.Game.Rulesets.Taiko/UI/HitExplosion.cs
index eb43c1a5d0..2ebdeaa5b0 100644
--- a/osu.Game.Modes.Taiko/UI/HitExplosion.cs
+++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs
@@ -8,21 +8,16 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
-using osu.Game.Modes.Taiko.Judgements;
-using osu.Game.Modes.Taiko.Objects;
+using osu.Game.Rulesets.Taiko.Judgements;
+using osu.Game.Rulesets.Taiko.Objects;
-namespace osu.Game.Modes.Taiko.UI
+namespace osu.Game.Rulesets.Taiko.UI
{
///
/// A circle explodes from the hit target to indicate a hitobject has been hit.
///
internal class HitExplosion : CircularContainer
{
- ///
- /// The size multiplier of a hit explosion if a hit object has been hit with the second key.
- ///
- private const float secondhit_size_multiplier = 1.5f;
-
///
/// The judgement this hit explosion visualises.
///
@@ -34,7 +29,7 @@ namespace osu.Game.Modes.Taiko.UI
{
Judgement = judgement;
- Size = new Vector2(TaikoHitObject.CIRCLE_RADIUS * 2);
+ Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER);
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
@@ -85,7 +80,7 @@ namespace osu.Game.Modes.Taiko.UI
///
public void VisualiseSecondHit()
{
- ResizeTo(Size * secondhit_size_multiplier, 50);
+ ResizeTo(Size * TaikoHitObject.STRONG_CIRCLE_DIAMETER_SCALE, 50);
}
}
}
diff --git a/osu.Game.Modes.Taiko/UI/HitTarget.cs b/osu.Game.Rulesets.Taiko/UI/HitTarget.cs
similarity index 78%
rename from osu.Game.Modes.Taiko/UI/HitTarget.cs
rename to osu.Game.Rulesets.Taiko/UI/HitTarget.cs
index a17480628d..fde2623246 100644
--- a/osu.Game.Modes.Taiko/UI/HitTarget.cs
+++ b/osu.Game.Rulesets.Taiko/UI/HitTarget.cs
@@ -6,25 +6,15 @@ using OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
-using osu.Game.Modes.Taiko.Objects;
+using osu.Game.Rulesets.Taiko.Objects;
-namespace osu.Game.Modes.Taiko.UI
+namespace osu.Game.Rulesets.Taiko.UI
{
///
/// A component that is displayed at the hit position in the taiko playfield.
///
internal class HitTarget : Container
{
- ///
- /// Diameter of normal hit object circles.
- ///
- private const float normal_diameter = TaikoHitObject.CIRCLE_RADIUS * 2;
-
- ///
- /// Diameter of strong hit object circles.
- ///
- private const float strong_hit_diameter = normal_diameter * 1.5f;
-
///
/// The 1px inner border of the taiko playfield.
///
@@ -37,7 +27,7 @@ namespace osu.Game.Modes.Taiko.UI
public HitTarget()
{
- RelativeSizeAxes = Axes.Y;
+ Size = new Vector2(TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT);
Children = new Drawable[]
{
@@ -47,7 +37,7 @@ namespace osu.Game.Modes.Taiko.UI
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Y = border_offset,
- Size = new Vector2(border_thickness, (TaikoPlayfield.PLAYFIELD_HEIGHT - strong_hit_diameter) / 2f - border_offset),
+ Size = new Vector2(border_thickness, (TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT - TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER) / 2f - border_offset),
Alpha = 0.1f
},
new CircularContainer
@@ -55,7 +45,7 @@ namespace osu.Game.Modes.Taiko.UI
Name = "Strong Hit Ring",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Size = new Vector2(strong_hit_diameter),
+ Size = new Vector2(TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER),
Masking = true,
BorderColour = Color4.White,
BorderThickness = border_thickness,
@@ -75,7 +65,7 @@ namespace osu.Game.Modes.Taiko.UI
Name = "Normal Hit Ring",
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Size = new Vector2(normal_diameter),
+ Size = new Vector2(TaikoHitObject.DEFAULT_CIRCLE_DIAMETER),
Masking = true,
BorderColour = Color4.White,
BorderThickness = border_thickness,
@@ -96,7 +86,7 @@ namespace osu.Game.Modes.Taiko.UI
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
Y = -border_offset,
- Size = new Vector2(border_thickness, (TaikoPlayfield.PLAYFIELD_HEIGHT - strong_hit_diameter) / 2f - border_offset),
+ Size = new Vector2(border_thickness, (TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT - TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER) / 2f - border_offset),
Alpha = 0.1f
},
};
diff --git a/osu.Game.Modes.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
similarity index 95%
rename from osu.Game.Modes.Taiko/UI/InputDrum.cs
rename to osu.Game.Rulesets.Taiko/UI/InputDrum.cs
index 0c1e1105cb..999d76ab0b 100644
--- a/osu.Game.Modes.Taiko/UI/InputDrum.cs
+++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
@@ -12,7 +12,7 @@ using osu.Framework.Graphics.Textures;
using osu.Framework.Input;
using osu.Game.Graphics;
-namespace osu.Game.Modes.Taiko.UI
+namespace osu.Game.Rulesets.Taiko.UI
{
///
/// A component of the playfield that captures input and displays input as a drum.
@@ -21,7 +21,7 @@ namespace osu.Game.Modes.Taiko.UI
{
public InputDrum()
{
- Size = new Vector2(TaikoPlayfield.PLAYFIELD_HEIGHT);
+ Size = new Vector2(TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT);
const float middle_split = 10;
diff --git a/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoHitRenderer.cs
similarity index 54%
rename from osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs
rename to osu.Game.Rulesets.Taiko/UI/TaikoHitRenderer.cs
index 29fa693d58..db15193ce5 100644
--- a/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoHitRenderer.cs
@@ -2,23 +2,23 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
-using osu.Framework.MathUtils;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
-using osu.Game.Beatmaps.Timing;
-using osu.Game.Modes.Objects.Drawables;
-using osu.Game.Modes.Objects.Types;
-using osu.Game.Modes.Replays;
-using osu.Game.Modes.Scoring;
-using osu.Game.Modes.Taiko.Beatmaps;
-using osu.Game.Modes.Taiko.Judgements;
-using osu.Game.Modes.Taiko.Objects;
-using osu.Game.Modes.Taiko.Objects.Drawables;
-using osu.Game.Modes.Taiko.Scoring;
-using osu.Game.Modes.UI;
-using osu.Game.Modes.Taiko.Replays;
+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.Judgements;
+using osu.Game.Rulesets.Taiko.Objects;
+using osu.Game.Rulesets.Taiko.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.Scoring;
+using osu.Game.Rulesets.UI;
+using osu.Game.Rulesets.Taiko.Replays;
+using OpenTK;
+using osu.Game.Rulesets.Beatmaps;
-namespace osu.Game.Modes.Taiko.UI
+namespace osu.Game.Rulesets.Taiko.UI
{
public class TaikoHitRenderer : HitRenderer
{
@@ -49,62 +49,53 @@ namespace osu.Game.Modes.Taiko.UI
return;
int currentIndex = 0;
-
- while (currentIndex < timingPoints.Count && Precision.AlmostEquals(timingPoints[currentIndex].BeatLength, 0))
- currentIndex++;
-
- double time = timingPoints[currentIndex].Time;
- double measureLength = timingPoints[currentIndex].BeatLength * (int)timingPoints[currentIndex].TimeSignature;
-
- // Find the bar line time closest to 0
- time -= measureLength * (int)(time / measureLength);
-
- // Always start barlines from a positive time
- while (time < 0)
- time += measureLength;
-
int currentBeat = 0;
+ double time = timingPoints[currentIndex].Time;
while (time <= lastHitTime)
{
- ControlPoint current = timingPoints[currentIndex];
-
- if (time > current.Time || current.OmitFirstBarLine)
+ int nextIndex = currentIndex + 1;
+ if (nextIndex < timingPoints.Count && time > timingPoints[nextIndex].Time)
{
- bool isMajor = currentBeat % (int)current.TimeSignature == 0;
-
- var barLine = new BarLine
- {
- StartTime = time,
- };
-
- barLine.ApplyDefaults(Beatmap.TimingInfo, Beatmap.BeatmapInfo.Difficulty);
-
- taikoPlayfield.AddBarLine(isMajor ? new DrawableBarLineMajor(barLine) : new DrawableBarLine(barLine));
-
- currentBeat++;
+ currentIndex = nextIndex;
+ time = timingPoints[currentIndex].Time;
+ currentBeat = 0;
}
- double bl = current.BeatLength;
+ var currentPoint = timingPoints[currentIndex];
+ var barLine = new BarLine
+ {
+ StartTime = time,
+ };
+
+ barLine.ApplyDefaults(Beatmap.TimingInfo, Beatmap.BeatmapInfo.Difficulty);
+
+ bool isMajor = currentBeat % (int)currentPoint.TimeSignature == 0;
+ taikoPlayfield.AddBarLine(isMajor ? new DrawableBarLineMajor(barLine) : new DrawableBarLine(barLine));
+
+ double bl = currentPoint.BeatLength;
if (bl < 800)
- bl *= (int)current.TimeSignature;
+ bl *= (int)currentPoint.TimeSignature;
time += bl;
-
- if (currentIndex + 1 >= timingPoints.Count || time < timingPoints[currentIndex + 1].Time)
- continue;
-
- currentBeat = 0;
- currentIndex++;
- time = timingPoints[currentIndex].Time;
+ currentBeat++;
}
}
+ protected override Vector2 GetPlayfieldAspectAdjust()
+ {
+ const float default_relative_height = TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT / 768;
+ const float default_aspect = 16f / 9f;
+
+ float aspectAdjust = MathHelper.Clamp(DrawWidth / DrawHeight, 0.4f, 4) / default_aspect;
+
+ return new Vector2(1, default_relative_height * aspectAdjust);
+ }
+
+
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this);
- protected override IBeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter();
-
- protected override IBeatmapProcessor CreateBeatmapProcessor() => new TaikoBeatmapProcessor();
+ protected override BeatmapConverter CreateBeatmapConverter() => new TaikoBeatmapConverter();
protected override Playfield CreatePlayfield() => new TaikoPlayfield
{
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
new file mode 100644
index 0000000000..8e6f1c8556
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
@@ -0,0 +1,273 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Sprites;
+using osu.Game.Rulesets.Taiko.Objects;
+using osu.Game.Rulesets.UI;
+using OpenTK;
+using OpenTK.Graphics;
+using osu.Game.Rulesets.Taiko.Judgements;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Extensions.Color4Extensions;
+using osu.Framework.Graphics.Primitives;
+using System.Linq;
+using osu.Game.Rulesets.Taiko.Objects.Drawables;
+using System;
+
+namespace osu.Game.Rulesets.Taiko.UI
+{
+ public class TaikoPlayfield : Playfield
+ {
+ ///
+ /// The default play field height.
+ ///
+ public const float DEFAULT_PLAYFIELD_HEIGHT = 168f;
+
+ ///
+ /// The offset from which the center of the hit target lies at.
+ ///
+ private const float hit_target_offset = TaikoHitObject.DEFAULT_STRONG_CIRCLE_DIAMETER / 2f + 40;
+
+ ///
+ /// The size of the left area of the playfield. This area contains the input drum.
+ ///
+ private const float left_area_size = 240;
+
+ protected override Container Content => hitObjectContainer;
+
+ private readonly Container hitExplosionContainer;
+ private readonly Container barLineContainer;
+ private readonly Container judgementContainer;
+
+ private readonly Container hitObjectContainer;
+ private readonly Container topLevelHitContainer;
+ private readonly Container leftBackgroundContainer;
+ private readonly Container rightBackgroundContainer;
+ private readonly Box leftBackground;
+ private readonly Box rightBackground;
+
+ public TaikoPlayfield()
+ {
+ AddInternal(new Drawable[]
+ {
+ rightBackgroundContainer = new Container
+ {
+ Name = "Transparent playfield background",
+ RelativeSizeAxes = Axes.Both,
+ BorderThickness = 2,
+ Masking = true,
+ EdgeEffect = new EdgeEffect
+ {
+ Type = EdgeEffectType.Shadow,
+ Colour = Color4.Black.Opacity(0.2f),
+ Radius = 5,
+ },
+ Children = new Drawable[]
+ {
+ rightBackground = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Alpha = 0.6f
+ },
+ }
+ },
+ new ScaleFixContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = DEFAULT_PLAYFIELD_HEIGHT,
+ Children = new[]
+ {
+ new Container
+ {
+ Name = "Transparent playfield elements",
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Left = left_area_size },
+ Children = new Drawable[]
+ {
+ new Container
+ {
+ Name = "Hit target container",
+ X = hit_target_offset,
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ hitExplosionContainer = new Container
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Y,
+ BlendingMode = BlendingMode.Additive
+ },
+ barLineContainer = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ new HitTarget
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.Centre,
+ },
+ hitObjectContainer = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ judgementContainer = new Container
+ {
+ RelativeSizeAxes = Axes.Y,
+ BlendingMode = BlendingMode.Additive
+ },
+ },
+ },
+ }
+ },
+ leftBackgroundContainer = new Container
+ {
+ Name = "Left overlay",
+ Size = new Vector2(left_area_size, DEFAULT_PLAYFIELD_HEIGHT),
+ BorderThickness = 1,
+ Children = new Drawable[]
+ {
+ leftBackground = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ new InputDrum
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativePositionAxes = Axes.X,
+ Position = new Vector2(0.10f, 0),
+ Scale = new Vector2(0.9f)
+ },
+ new Box
+ {
+ Anchor = Anchor.TopRight,
+ RelativeSizeAxes = Axes.Y,
+ Width = 10,
+ ColourInfo = Framework.Graphics.Colour.ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.6f), Color4.Black.Opacity(0)),
+ },
+ }
+ },
+ }
+ },
+ topLevelHitContainer = new Container
+ {
+ Name = "Top level hit objects",
+ RelativeSizeAxes = Axes.Both,
+ }
+ });
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ leftBackgroundContainer.BorderColour = colours.Gray0;
+ leftBackground.Colour = colours.Gray1;
+
+ rightBackgroundContainer.BorderColour = colours.Gray1;
+ rightBackground.Colour = colours.Gray0;
+ }
+
+ public override void Add(DrawableHitObject h)
+ {
+ h.Depth = (float)h.HitObject.StartTime;
+
+ base.Add(h);
+
+ // Swells should be moved at the very top of the playfield when they reach the hit target
+ var swell = h as DrawableSwell;
+ if (swell != null)
+ swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy());
+ }
+
+ public void AddBarLine(DrawableBarLine barLine)
+ {
+ barLineContainer.Add(barLine);
+ }
+
+ public override void OnJudgement(DrawableHitObject judgedObject)
+ {
+ bool wasHit = judgedObject.Judgement.Result == HitResult.Hit;
+ bool secondHit = judgedObject.Judgement.SecondHit;
+
+ judgementContainer.Add(new DrawableTaikoJudgement(judgedObject.Judgement)
+ {
+ Anchor = wasHit ? Anchor.TopLeft : Anchor.CentreLeft,
+ Origin = wasHit ? Anchor.BottomCentre : Anchor.Centre,
+ RelativePositionAxes = Axes.X,
+ X = wasHit ? judgedObject.Position.X : 0,
+ });
+
+ if (!wasHit)
+ return;
+
+ if (!secondHit)
+ {
+ if (judgedObject.X >= -0.05f && !(judgedObject is DrawableSwell))
+ {
+ // If we're far enough away from the left stage, we should bring outselves in front of it
+ topLevelHitContainer.Add(judgedObject.CreateProxy());
+ }
+
+ hitExplosionContainer.Add(new HitExplosion(judgedObject.Judgement));
+ }
+ else
+ hitExplosionContainer.Children.FirstOrDefault(e => e.Judgement == judgedObject.Judgement)?.VisualiseSecondHit();
+ }
+
+ ///
+ /// This is a very special type of container. It serves a similar purpose to , however unlike ,
+ /// this will only adjust the scale relative to the height of its parent and will maintain the original width relative to its parent.
+ ///
+ ///
+ /// By adjusting the scale relative to the height of its parent, the aspect ratio of this container's children is maintained, however this is undesirable
+ /// in the case where the hit object container should not have its width adjusted by scale. To counteract this, another container is nested inside this
+ /// container which takes care of reversing the width adjustment while appearing transparent to the user.
+ ///
+ ///
+ private class ScaleFixContainer : Container
+ {
+ protected override Container Content => widthAdjustmentContainer;
+ private readonly WidthAdjustmentContainer widthAdjustmentContainer;
+
+ ///
+ /// We only want to apply DrawScale in the Y-axis to preserve aspect ratio and doesn't care about having its width adjusted.
+ ///
+ protected override Vector2 DrawScale => Scale * RelativeToAbsoluteFactor.Y / DrawHeight;
+
+ public ScaleFixContainer()
+ {
+ AddInternal(widthAdjustmentContainer = new WidthAdjustmentContainer { ParentDrawScaleReference = () => DrawScale.X });
+ }
+
+ ///
+ /// The container type that reverses the width adjustment.
+ ///
+ private class WidthAdjustmentContainer : Container
+ {
+ ///
+ /// This container needs to know its parent's so it can reverse the width adjustment caused by .
+ ///
+ public Func ParentDrawScaleReference;
+
+ public WidthAdjustmentContainer()
+ {
+ // This container doesn't care about height, it should always fill its parent
+ RelativeSizeAxes = Axes.Y;
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+
+ // Reverse the DrawScale adjustment
+ Width = Parent.DrawSize.X / ParentDrawScaleReference();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj
similarity index 93%
rename from osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj
rename to osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj
index d0981c2500..f890e32f90 100644
--- a/osu.Game.Modes.Taiko/osu.Game.Modes.Taiko.csproj
+++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj
@@ -7,8 +7,8 @@
{F167E17A-7DE6-4AF5-B920-A5112296C695}
Library
Properties
- osu.Game.Modes.Taiko
- osu.Game.Modes.Taiko
+ osu.Game.Rulesets.Taiko
+ osu.Game.Rulesets.Taiko
v4.5
512
@@ -21,6 +21,7 @@
prompt
4
false
+ 6
pdbonly
@@ -33,8 +34,7 @@
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
@@ -48,7 +48,6 @@
-
@@ -82,6 +81,7 @@
+
@@ -112,7 +112,7 @@
-
-
+
\ No newline at end of file
diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs
index 8183bc952e..4814af984e 100644
--- a/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs
+++ b/osu.Game.Tests/Beatmaps/Formats/OsuLegacyDecoderTest.cs
@@ -6,12 +6,10 @@ using NUnit.Framework;
using OpenTK;
using OpenTK.Graphics;
using osu.Game.Beatmaps.Formats;
-using osu.Game.Modes;
using osu.Game.Tests.Resources;
-using osu.Game.Modes.Osu;
-using osu.Game.Modes.Objects.Legacy;
using System.Linq;
using osu.Game.Audio;
+using osu.Game.Rulesets.Objects.Types;
namespace osu.Game.Tests.Beatmaps.Formats
{
@@ -22,7 +20,6 @@ namespace osu.Game.Tests.Beatmaps.Formats
public void SetUp()
{
OsuLegacyDecoder.Register();
- Ruleset.Register(new OsuRuleset());
}
[Test]
@@ -58,7 +55,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.AreEqual(false, beatmapInfo.Countdown);
Assert.AreEqual(0.7f, beatmapInfo.StackLeniency);
Assert.AreEqual(false, beatmapInfo.SpecialStyle);
- Assert.AreEqual(PlayMode.Osu, beatmapInfo.Mode);
+ Assert.IsTrue(beatmapInfo.RulesetID == 0);
Assert.AreEqual(false, beatmapInfo.LetterboxInBreaks);
Assert.AreEqual(false, beatmapInfo.WidescreenStoryboard);
}
@@ -133,16 +130,22 @@ namespace osu.Game.Tests.Beatmaps.Formats
using (var stream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
{
var beatmap = decoder.Decode(new StreamReader(stream));
- var slider = beatmap.HitObjects[0] as LegacySlider;
- Assert.IsNotNull(slider);
- Assert.AreEqual(new Vector2(192, 168), slider.Position);
- Assert.AreEqual(956, slider.StartTime);
- Assert.IsTrue(slider.Samples.Any(s => s.Name == SampleInfo.HIT_NORMAL));
- var hit = beatmap.HitObjects[1] as LegacyHit;
- Assert.IsNotNull(hit);
- Assert.AreEqual(new Vector2(304, 56), hit.Position);
- Assert.AreEqual(1285, hit.StartTime);
- Assert.IsTrue(hit.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP));
+
+ var curveData = beatmap.HitObjects[0] as IHasCurve;
+ var positionData = beatmap.HitObjects[0] as IHasPosition;
+
+ Assert.IsNotNull(positionData);
+ Assert.IsNotNull(curveData);
+ Assert.AreEqual(new Vector2(192, 168), positionData.Position);
+ Assert.AreEqual(956, beatmap.HitObjects[0].StartTime);
+ Assert.IsTrue(beatmap.HitObjects[0].Samples.Any(s => s.Name == SampleInfo.HIT_NORMAL));
+
+ positionData = beatmap.HitObjects[1] as IHasPosition;
+
+ Assert.IsNotNull(positionData);
+ Assert.AreEqual(new Vector2(304, 56), positionData.Position);
+ Assert.AreEqual(1285, beatmap.HitObjects[1].StartTime);
+ Assert.IsTrue(beatmap.HitObjects[1].Samples.Any(s => s.Name == SampleInfo.HIT_CLAP));
}
}
}
diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
index 5d15b43761..b35f5901be 100644
--- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
+++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs
@@ -12,11 +12,6 @@ using osu.Framework.Desktop.Platform;
using osu.Framework.Platform;
using osu.Game.Database;
using osu.Game.IPC;
-using osu.Game.Modes;
-using osu.Game.Modes.Catch;
-using osu.Game.Modes.Mania;
-using osu.Game.Modes.Osu;
-using osu.Game.Modes.Taiko;
namespace osu.Game.Tests.Beatmaps.IO
{
@@ -25,15 +20,6 @@ namespace osu.Game.Tests.Beatmaps.IO
{
private const string osz_path = @"../../../osu-resources/osu.Game.Resources/Beatmaps/241526 Soleily - Renatus.osz";
- [OneTimeSetUp]
- public void SetUp()
- {
- Ruleset.Register(new OsuRuleset());
- Ruleset.Register(new TaikoRuleset());
- Ruleset.Register(new ManiaRuleset());
- Ruleset.Register(new CatchRuleset());
- }
-
[Test]
public void TestImportWhenClosed()
{
@@ -119,6 +105,7 @@ namespace osu.Game.Tests.Beatmaps.IO
Thread.Sleep(1);
//reset beatmap database (sqlite and storage backing)
+ osu.Dependencies.Get().Reset();
osu.Dependencies.Get().Reset();
return osu;
@@ -166,8 +153,16 @@ namespace osu.Game.Tests.Beatmaps.IO
Assert.IsTrue(set.Beatmaps.Count > 0);
- var beatmap = osu.Dependencies.Get().GetWorkingBeatmap(set.Beatmaps.First(b => b.Mode == PlayMode.Osu))?.Beatmap;
+ var beatmap = osu.Dependencies.Get().GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 0))?.Beatmap;
+ Assert.IsTrue(beatmap?.HitObjects.Count > 0);
+ beatmap = osu.Dependencies.Get().GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 1))?.Beatmap;
+ Assert.IsTrue(beatmap?.HitObjects.Count > 0);
+
+ beatmap = osu.Dependencies.Get().GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 2))?.Beatmap;
+ Assert.IsTrue(beatmap?.HitObjects.Count > 0);
+
+ beatmap = osu.Dependencies.Get().GetWorkingBeatmap(set.Beatmaps.First(b => b.RulesetID == 3))?.Beatmap;
Assert.IsTrue(beatmap?.HitObjects.Count > 0);
}
}
diff --git a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs
index b9c4cf780a..03d09e24e0 100644
--- a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs
+++ b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs
@@ -4,8 +4,6 @@
using System.IO;
using NUnit.Framework;
using osu.Game.Beatmaps.IO;
-using osu.Game.Modes;
-using osu.Game.Modes.Osu;
using osu.Game.Tests.Resources;
using osu.Game.Beatmaps.Formats;
using osu.Game.Database;
@@ -19,7 +17,6 @@ namespace osu.Game.Tests.Beatmaps.IO
public void SetUp()
{
OszArchiveReader.Register();
- Ruleset.Register(new OsuRuleset());
}
[Test]
diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj
index d01aa77e02..b8fcb80aaf 100644
--- a/osu.Game.Tests/osu.Game.Tests.csproj
+++ b/osu.Game.Tests/osu.Game.Tests.csproj
@@ -19,6 +19,7 @@
4
false
false
+ 6
true
@@ -29,13 +30,11 @@
false
-
- $(SolutionDir)\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll
- True
+
+ $(SolutionDir)\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll
- $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1340\lib\net45\OpenTK.dll
- True
+ $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll
@@ -64,21 +63,21 @@
{c76bf5b3-985e-4d39-95fe-97c9c879b83a}
osu.Framework
-
+
{c92a607b-1fdd-4954-9f92-03ff547d9080}
- osu.Game.Modes.Osu
+ osu.Game.Rulesets.Osu
-
+
{58f6c80c-1253-4a0e-a465-b8c85ebeadf3}
- osu.Game.Modes.Catch
+ osu.Game.Rulesets.Catch
-
+
{48f4582b-7687-4621-9cbe-5c24197cb536}
- osu.Game.Modes.Mania
+ osu.Game.Rulesets.Mania
-
+
{f167e17a-7de6-4af5-b920-a5112296c695}
- osu.Game.Modes.Taiko
+ osu.Game.Rulesets.Taiko
{0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D}
diff --git a/osu.Game.Tests/packages.config b/osu.Game.Tests/packages.config
index ca53ef08b0..9972fb41a1 100644
--- a/osu.Game.Tests/packages.config
+++ b/osu.Game.Tests/packages.config
@@ -1,12 +1,11 @@

-
-
-
+
+
\ No newline at end of file
diff --git a/osu.Game/Audio/SampleInfoList.cs b/osu.Game/Audio/SampleInfoList.cs
new file mode 100644
index 0000000000..594341bbb1
--- /dev/null
+++ b/osu.Game/Audio/SampleInfoList.cs
@@ -0,0 +1,19 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System.Collections.Generic;
+
+namespace osu.Game.Audio
+{
+ public class SampleInfoList : List
+ {
+ public SampleInfoList()
+ {
+ }
+
+ public SampleInfoList(IEnumerable elements)
+ {
+ AddRange(elements);
+ }
+ }
+}
\ No newline at end of file
diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs
index 5709bdc8c5..3964fd25a7 100644
--- a/osu.Game/Beatmaps/Beatmap.cs
+++ b/osu.Game/Beatmaps/Beatmap.cs
@@ -4,8 +4,7 @@
using OpenTK.Graphics;
using osu.Game.Beatmaps.Timing;
using osu.Game.Database;
-using osu.Game.Modes;
-using osu.Game.Modes.Objects;
+using osu.Game.Rulesets.Objects;
using System.Collections.Generic;
namespace osu.Game.Beatmaps
@@ -50,12 +49,6 @@ namespace osu.Game.Beatmaps
///
public class Beatmap : Beatmap
{
- ///
- /// Calculates the star difficulty for this Beatmap.
- ///
- /// The star difficulty.
- public double CalculateStarDifficulty() => Ruleset.GetRuleset(BeatmapInfo.Mode).CreateDifficultyCalculator(this).Calculate();
-
///
/// Constructs a new beatmap.
///
@@ -63,6 +56,7 @@ namespace osu.Game.Beatmaps
public Beatmap(Beatmap original = null)
: base(original)
{
+ HitObjects = original?.HitObjects;
}
}
}
diff --git a/osu.Game/Beatmaps/DifficultyCalculator.cs b/osu.Game/Beatmaps/DifficultyCalculator.cs
index a9da5c589c..8e9266b644 100644
--- a/osu.Game/Beatmaps/DifficultyCalculator.cs
+++ b/osu.Game/Beatmaps/DifficultyCalculator.cs
@@ -1,7 +1,8 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using osu.Game.Modes.Objects;
+using osu.Game.Rulesets.Beatmaps;
+using osu.Game.Rulesets.Objects;
using System.Collections.Generic;
namespace osu.Game.Beatmaps
@@ -34,6 +35,10 @@ namespace osu.Game.Beatmaps
protected DifficultyCalculator(Beatmap beatmap)
{
Objects = CreateBeatmapConverter().Convert(beatmap).HitObjects;
+
+ foreach (var h in Objects)
+ h.ApplyDefaults(beatmap.TimingInfo, beatmap.BeatmapInfo.Difficulty);
+
PreprocessHitObjects();
}
@@ -41,6 +46,6 @@ namespace osu.Game.Beatmaps
{
}
- protected abstract IBeatmapConverter CreateBeatmapConverter();
+ protected abstract BeatmapConverter CreateBeatmapConverter();
}
}
diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs
index 534578337f..db14a48af1 100644
--- a/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs
+++ b/osu.Game/Beatmaps/Drawables/BeatmapSetHeader.cs
@@ -1,19 +1,18 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
+using OpenTK;
+using OpenTK.Graphics;
using osu.Framework.Allocation;
-using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
-using osu.Game.Configuration;
+using osu.Framework.Localisation;
using osu.Game.Graphics.Sprites;
-using OpenTK;
-using OpenTK.Graphics;
namespace osu.Game.Beatmaps.Drawables
{
@@ -23,8 +22,6 @@ namespace osu.Game.Beatmaps.Drawables
private readonly SpriteText title;
private readonly SpriteText artist;
- private Bindable preferUnicode;
-
private readonly WorkingBeatmap beatmap;
private readonly FillFlowContainer difficultyIcons;
@@ -82,15 +79,10 @@ namespace osu.Game.Beatmaps.Drawables
}
[BackgroundDependencyLoader]
- private void load(OsuConfigManager config)
+ private void load(LocalisationEngine localisation)
{
- preferUnicode = config.GetBindable(OsuConfig.ShowUnicode);
- preferUnicode.ValueChanged += unicode =>
- {
- title.Text = unicode ? beatmap.BeatmapSetInfo.Metadata.TitleUnicode : beatmap.BeatmapSetInfo.Metadata.Title;
- artist.Text = unicode ? beatmap.BeatmapSetInfo.Metadata.ArtistUnicode : beatmap.BeatmapSetInfo.Metadata.Artist;
- };
- preferUnicode.TriggerChange();
+ title.Current = localisation.GetUnicodePreference(beatmap.BeatmapSetInfo.Metadata.TitleUnicode, beatmap.BeatmapSetInfo.Metadata.Title);
+ artist.Current = localisation.GetUnicodePreference(beatmap.BeatmapSetInfo.Metadata.ArtistUnicode, beatmap.BeatmapSetInfo.Metadata.Artist);
}
private class PanelBackground : BufferedContainer
@@ -112,7 +104,7 @@ namespace osu.Game.Beatmaps.Drawables
Depth = -1,
Direction = FillDirection.Horizontal,
RelativeSizeAxes = Axes.Both,
- // This makes the gradient not be perfectly horizontal, but diagonal at a ~40° angle
+ // This makes the gradient not be perfectly horizontal, but diagonal at a ~40° angle
Shear = new Vector2(0.8f, 0),
Alpha = 0.5f,
Children = new[]
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs b/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs
new file mode 100644
index 0000000000..7c0aa49d2a
--- /dev/null
+++ b/osu.Game/Beatmaps/Drawables/DifficultyColouredContainer.cs
@@ -0,0 +1,69 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Database;
+using osu.Game.Graphics;
+using OpenTK.Graphics;
+
+namespace osu.Game.Beatmaps.Drawables
+{
+ internal class DifficultyColouredContainer : Container, IHasAccentColour
+ {
+ public Color4 AccentColour { get; set; }
+
+ private readonly BeatmapInfo beatmap;
+ private OsuColour palette;
+
+ public DifficultyColouredContainer(BeatmapInfo beatmap)
+ {
+ this.beatmap = beatmap;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour palette)
+ {
+ this.palette = palette;
+ AccentColour = getColour(beatmap);
+ }
+
+ private enum DifficultyRating
+ {
+ Easy,
+ Normal,
+ Hard,
+ Insane,
+ Expert
+ }
+
+ private DifficultyRating getDifficultyRating(BeatmapInfo beatmap)
+ {
+ var rating = beatmap.StarDifficulty;
+
+ if (rating < 1.5) return DifficultyRating.Easy;
+ if (rating < 2.25) return DifficultyRating.Normal;
+ if (rating < 3.75) return DifficultyRating.Hard;
+ if (rating < 5.25) return DifficultyRating.Insane;
+ return DifficultyRating.Expert;
+ }
+
+ private Color4 getColour(BeatmapInfo beatmap)
+ {
+ switch (getDifficultyRating(beatmap))
+ {
+ case DifficultyRating.Easy:
+ return palette.Green;
+ default:
+ case DifficultyRating.Normal:
+ return palette.Yellow;
+ case DifficultyRating.Hard:
+ return palette.Pink;
+ case DifficultyRating.Insane:
+ return palette.Purple;
+ case DifficultyRating.Expert:
+ return palette.Gray0;
+ }
+ }
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
index 47ae4d7985..a8b63c2502 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
@@ -3,32 +3,27 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
using osu.Game.Database;
using osu.Game.Graphics;
-using osu.Game.Modes;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Beatmaps.Drawables
{
- internal class DifficultyIcon : Container
+
+ internal class DifficultyIcon : DifficultyColouredContainer
{
private readonly BeatmapInfo beatmap;
- private OsuColour palette;
- public DifficultyIcon(BeatmapInfo beatmap)
+ public DifficultyIcon(BeatmapInfo beatmap) : base(beatmap)
{
this.beatmap = beatmap;
- const float size = 20;
- Size = new Vector2(size);
+ Size = new Vector2(20);
}
[BackgroundDependencyLoader]
- private void load(OsuColour palette)
+ private void load()
{
- this.palette = palette;
-
Children = new[]
{
new TextAwesome
@@ -36,7 +31,7 @@ namespace osu.Game.Beatmaps.Drawables
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
TextSize = Size.X,
- Colour = getColour(beatmap),
+ Colour = AccentColour,
Icon = FontAwesome.fa_circle
},
new TextAwesome
@@ -45,47 +40,9 @@ namespace osu.Game.Beatmaps.Drawables
Origin = Anchor.Centre,
TextSize = Size.X,
Colour = Color4.White,
- Icon = Ruleset.GetRuleset(beatmap.Mode).Icon
+ Icon = beatmap.Ruleset.CreateInstance().Icon
}
};
}
-
- private enum DifficultyRating
- {
- Easy,
- Normal,
- Hard,
- Insane,
- Expert
- }
-
- private DifficultyRating getDifficultyRating(BeatmapInfo beatmap)
- {
- var rating = beatmap.StarDifficulty;
-
- if (rating < 1.5) return DifficultyRating.Easy;
- if (rating < 2.25) return DifficultyRating.Normal;
- if (rating < 3.75) return DifficultyRating.Hard;
- if (rating < 5.25) return DifficultyRating.Insane;
- return DifficultyRating.Expert;
- }
-
- private Color4 getColour(BeatmapInfo beatmap)
- {
- switch (getDifficultyRating(beatmap))
- {
- case DifficultyRating.Easy:
- return palette.Green;
- default:
- case DifficultyRating.Normal:
- return palette.Yellow;
- case DifficultyRating.Hard:
- return palette.Pink;
- case DifficultyRating.Insane:
- return palette.Purple;
- case DifficultyRating.Expert:
- return palette.Gray0;
- }
- }
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs
index 452bd595c7..cc9d367a59 100644
--- a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs
@@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
-using osu.Game.Modes.Objects;
+using osu.Game.Rulesets.Objects;
using osu.Game.Database;
namespace osu.Game.Beatmaps.Formats
diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs
index 35d81311d2..95213417ed 100644
--- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs
@@ -7,9 +7,8 @@ using System.IO;
using OpenTK.Graphics;
using osu.Game.Beatmaps.Events;
using osu.Game.Beatmaps.Timing;
-using osu.Game.Modes;
-using osu.Game.Modes.Objects;
using osu.Game.Beatmaps.Legacy;
+using osu.Game.Rulesets.Objects.Legacy;
namespace osu.Game.Beatmaps.Formats
{
@@ -30,6 +29,8 @@ namespace osu.Game.Beatmaps.Formats
// TODO: Not sure how far back to go, or differences between versions
}
+ private ConvertHitObjectParser parser;
+
private LegacySampleBank defaultSampleBank;
private int defaultSampleVolume = 100;
@@ -84,7 +85,23 @@ namespace osu.Game.Beatmaps.Formats
beatmap.BeatmapInfo.StackLeniency = float.Parse(val, NumberFormatInfo.InvariantInfo);
break;
case @"Mode":
- beatmap.BeatmapInfo.Mode = (PlayMode)int.Parse(val);
+ beatmap.BeatmapInfo.RulesetID = int.Parse(val);
+
+ switch (beatmap.BeatmapInfo.RulesetID)
+ {
+ case 0:
+ parser = new Rulesets.Objects.Legacy.Osu.ConvertHitObjectParser();
+ break;
+ case 1:
+ parser = new Rulesets.Objects.Legacy.Taiko.ConvertHitObjectParser();
+ break;
+ case 2:
+ parser = new Rulesets.Objects.Legacy.Catch.ConvertHitObjectParser();
+ break;
+ case 3:
+ parser = new Rulesets.Objects.Legacy.Mania.ConvertHitObjectParser();
+ break;
+ }
break;
case @"LetterboxInBreaks":
beatmap.BeatmapInfo.LetterboxInBreaks = int.Parse(val) == 1;
@@ -304,8 +321,6 @@ namespace osu.Game.Beatmaps.Formats
{
beatmap.BeatmapInfo.BeatmapVersion = beatmapVersion;
- HitObjectParser parser = new LegacyHitObjectParser();
-
Section section = Section.None;
bool hasCustomColours = false;
diff --git a/osu.Game/Beatmaps/IBeatmapConverter.cs b/osu.Game/Beatmaps/IBeatmapConverter.cs
deleted file mode 100644
index 72b248cfba..0000000000
--- a/osu.Game/Beatmaps/IBeatmapConverter.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Modes.Objects;
-
-namespace osu.Game.Beatmaps
-{
- ///
- /// Converts a Beatmap for another mode.
- ///
- /// The type of HitObject stored in the Beatmap.
- public interface IBeatmapConverter where T : HitObject
- {
- ///
- /// Converts a Beatmap to another mode.
- ///
- /// The original Beatmap.
- /// The converted Beatmap.
- Beatmap Convert(Beatmap original);
- }
-}
diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs
index 5bea1d0986..616128dab5 100644
--- a/osu.Game/Beatmaps/WorkingBeatmap.cs
+++ b/osu.Game/Beatmaps/WorkingBeatmap.cs
@@ -5,10 +5,10 @@ using osu.Framework.Audio.Track;
using osu.Framework.Configuration;
using osu.Framework.Graphics.Textures;
using osu.Game.Database;
-using osu.Game.Modes;
-using osu.Game.Modes.Mods;
+using osu.Game.Rulesets.Mods;
using System;
using System.Collections.Generic;
+using System.Linq;
namespace osu.Game.Beatmaps
{
@@ -18,15 +18,7 @@ namespace osu.Game.Beatmaps
public readonly BeatmapSetInfo BeatmapSetInfo;
- ///
- /// A play mode that is preferred for this beatmap. PlayMode will become this mode where conversion is feasible,
- /// or otherwise to the beatmap's default.
- ///
- public PlayMode? PreferredPlayMode;
-
- public PlayMode PlayMode => Beatmap?.BeatmapInfo?.Mode > PlayMode.Osu ? Beatmap.BeatmapInfo.Mode : PreferredPlayMode ?? PlayMode.Osu;
-
- public readonly Bindable> Mods = new Bindable>();
+ public readonly Bindable> Mods = new Bindable>(new Mod[] { });
public readonly bool WithStoryboard;
@@ -35,6 +27,18 @@ namespace osu.Game.Beatmaps
BeatmapInfo = beatmapInfo;
BeatmapSetInfo = beatmapSetInfo;
WithStoryboard = withStoryboard;
+
+ Mods.ValueChanged += mods => applyRateAdjustments();
+ }
+
+ private void applyRateAdjustments()
+ {
+ var t = track;
+ if (t == null) return;
+
+ t.ResetSpeedAdjustments();
+ foreach (var mod in Mods.Value.OfType())
+ mod.ApplyToClock(t);
}
protected abstract Beatmap GetBeatmap();
@@ -75,7 +79,11 @@ namespace osu.Game.Beatmaps
{
lock (trackLock)
{
- return track ?? (track = GetTrack());
+ if (track != null) return track;
+
+ track = GetTrack();
+ applyRateAdjustments();
+ return track;
}
}
}
diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs
index 7d7c61b69a..30cd31c113 100644
--- a/osu.Game/Configuration/OsuConfigManager.cs
+++ b/osu.Game/Configuration/OsuConfigManager.cs
@@ -4,7 +4,7 @@
using System;
using osu.Framework.Configuration;
using osu.Framework.Platform;
-using osu.Game.Modes;
+using osu.Game.Screens.Select;
namespace osu.Game.Configuration
{
@@ -17,7 +17,7 @@ namespace osu.Game.Configuration
Set(OsuConfig.Username, string.Empty);
Set(OsuConfig.Token, string.Empty);
- Set(OsuConfig.PlayMode, PlayMode.Osu);
+ Set(OsuConfig.Ruleset, 0, 0, int.MaxValue);
Set(OsuConfig.AudioDevice, string.Empty);
Set(OsuConfig.SavePassword, false);
@@ -25,7 +25,7 @@ namespace osu.Game.Configuration
Set(OsuConfig.MenuCursorSize, 1.0, 0.5f, 2);
Set(OsuConfig.GameplayCursorSize, 1.0, 0.5f, 2);
- Set(OsuConfig.DimLevel, 30, 0, 100);
+ Set(OsuConfig.DimLevel, 0.3, 0, 1);
Set(OsuConfig.MouseDisableButtons, false);
Set(OsuConfig.MouseDisableWheel, false);
@@ -35,9 +35,16 @@ namespace osu.Game.Configuration
Set(OsuConfig.MenuParallax, true);
+ Set(OsuConfig.MenuVoice, true);
+ Set(OsuConfig.MenuMusic, true);
+
+ Set(OsuConfig.BeatmapDetailTab, BeatmapDetailTab.Details);
+
Set(OsuConfig.ShowInterface, true);
Set(OsuConfig.KeyOverlay, false);
+
//todo: implement all settings below this line (remove the Disabled set when doing so).
+ Set(OsuConfig.AudioOffset, 0, -500.0, 500.0);
Set(OsuConfig.MouseSpeed, 1.0).Disabled = true;
Set(OsuConfig.BeatmapDirectory, @"Songs").Disabled = true; // TODO: use thi.Disabled = trues
@@ -46,6 +53,7 @@ namespace osu.Game.Configuration
Set(OsuConfig.AutomaticDownload, true).Disabled = true;
Set(OsuConfig.AutomaticDownloadNoVideo, false).Disabled = true;
Set(OsuConfig.BlockNonFriendPM, false).Disabled = true;
+ Set(OsuConfig.Bloom, false).Disabled = true;
Set(OsuConfig.BloomSoftening, false).Disabled = true;
Set(OsuConfig.BossKeyFirstActivation, true).Disabled = true;
Set(OsuConfig.ChatAudibleHighlight, true).Disabled = true;
@@ -84,7 +92,6 @@ namespace osu.Game.Configuration
Set(OsuConfig.IgnoreBeatmapSamples, false).Disabled = true;
Set(OsuConfig.IgnoreBeatmapSkins, false).Disabled = true;
Set(OsuConfig.IgnoreList, string.Empty).Disabled = true;
- Set(OsuConfig.Language, @"unknown").Disabled = true;
Set(OsuConfig.AllowNowPlayingHighlights, false).Disabled = true;
Set(OsuConfig.LastVersion, string.Empty).Disabled = true;
Set(OsuConfig.LastVersionPermissionsFailed, string.Empty).Disabled = true;
@@ -103,7 +110,6 @@ namespace osu.Game.Configuration
Set(OsuConfig.ManiaSpeedBPMScale, true).Disabled = true;
Set(OsuConfig.MenuTip, 0).Disabled = true;
Set(OsuConfig.MouseSpeed, 1, 0.4, 6).Disabled = true;
- Set(OsuConfig.Offset, 0, -300, 300).Disabled = true;
Set(OsuConfig.ScoreMeterScale, 1, 0.5, 2).Disabled = true;
//Set(OsuConfig.ScoreMeterScale, 1, 0.5, OsuGame.Tournament ? 10 : 2).Disabled = true;
Set(OsuConfig.DistanceSpacing, 0.8, 0.1, 6).Disabled = true;
@@ -144,8 +150,6 @@ namespace osu.Game.Configuration
Set(OsuConfig.YahooIntegration, false).Disabled = true;
Set(OsuConfig.ForceFrameFlush, false).Disabled = true;
Set(OsuConfig.DetectPerformanceIssues, true).Disabled = true;
- Set(OsuConfig.MenuMusic, true).Disabled = true;
- Set(OsuConfig.MenuVoice, true).Disabled = true;
Set(OsuConfig.RawInput, false).Disabled = true;
Set(OsuConfig.AbsoluteToOsuWindow, Get(OsuConfig.RawInput)).Disabled = true;
Set(OsuConfig.ShowMenuTips, true).Disabled = true;
@@ -158,16 +162,6 @@ namespace osu.Game.Configuration
Set(OsuConfig.UpdateFailCount, 0).Disabled = true;
//Set(OsuConfig.TreeSortMode, TreeGroupMode.Show_All).Disabled = true;
//Set(OsuConfig.TreeSortMode2, TreeSortMode.Title).Disabled = true;
- bool unicodeDefault = false;
- switch (Get(OsuConfig.Language))
- {
- case @"zh":
- case @"ja":
- case @"ko":
- unicodeDefault = true;
- break;
- }
- Set(OsuConfig.ShowUnicode, unicodeDefault);
Set(OsuConfig.PermanentSongInfo, false).Disabled = true;
Set(OsuConfig.Ticker, false).Disabled = true;
Set(OsuConfig.CompatibilityContext, false).Disabled = true;
@@ -175,7 +169,6 @@ namespace osu.Game.Configuration
Set(OsuConfig.ConfineMouse, Get(OsuConfig.ConfineMouseToFullscreen) ?
ConfineMouseMode.Fullscreen : ConfineMouseMode.Never).Disabled = true;
-
GetOriginalBindable(OsuConfig.SavePassword).ValueChanged += delegate
{
if (Get(OsuConfig.SavePassword)) Set(OsuConfig.SaveUsername, true);
@@ -195,7 +188,7 @@ namespace osu.Game.Configuration
public enum OsuConfig
{
// New osu:
- PlayMode,
+ Ruleset,
Token,
// Imported from old osu:
BeatmapDirectory,
@@ -270,7 +263,7 @@ namespace osu.Game.Configuration
MouseDisableButtons,
MouseDisableWheel,
MouseSpeed,
- Offset,
+ AudioOffset,
ScoreMeterScale,
DistanceSpacing,
EditorBeatDivisor,
@@ -315,6 +308,7 @@ namespace osu.Game.Configuration
MenuMusic,
MenuVoice,
MenuParallax,
+ BeatmapDetailTab,
RawInput,
AbsoluteToOsuWindow,
ConfineMouse,
@@ -334,11 +328,9 @@ namespace osu.Game.Configuration
SaveUsername,
TreeSortMode,
TreeSortMode2,
- ShowUnicode,
PermanentSongInfo,
Ticker,
CompatibilityContext,
CanForceOptimusCompatibility,
-
}
}
diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs
index 41ddd8df39..0e814dea82 100644
--- a/osu.Game/Database/BeatmapDatabase.cs
+++ b/osu.Game/Database/BeatmapDatabase.cs
@@ -5,7 +5,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using System.Linq.Expressions;
using osu.Framework.Extensions;
using osu.Framework.Logging;
using osu.Framework.Platform;
@@ -18,37 +17,21 @@ using SQLiteNetExtensions.Extensions;
namespace osu.Game.Database
{
- public class BeatmapDatabase
+ public class BeatmapDatabase : Database
{
- private SQLiteConnection connection { get; }
- private readonly Storage storage;
+ private readonly RulesetDatabase rulesets;
+
public event Action BeatmapSetAdded;
public event Action BeatmapSetRemoved;
// ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised)
private BeatmapIPCChannel ipc;
- public BeatmapDatabase(Storage storage, IIpcHost importHost = null)
+ public BeatmapDatabase(Storage storage, SQLiteConnection connection, RulesetDatabase rulesets, IIpcHost importHost = null) : base(storage, connection)
{
- this.storage = storage;
-
+ this.rulesets = rulesets;
if (importHost != null)
ipc = new BeatmapIPCChannel(importHost, this);
-
- if (connection == null)
- {
- try
- {
- connection = prepareConnection();
- deletePending();
- }
- catch (Exception e)
- {
- Logger.Error(e, @"Failed to initialise the beatmap database! Trying again with a clean database...");
- storage.DeleteDatabase(@"beatmaps");
- connection = prepareConnection();
- }
- }
}
private void deletePending()
@@ -57,20 +40,20 @@ namespace osu.Game.Database
{
try
{
- storage.Delete(b.Path);
+ Storage.Delete(b.Path);
GetChildren(b, true);
foreach (var i in b.Beatmaps)
{
- if (i.Metadata != null) connection.Delete(i.Metadata);
- if (i.Difficulty != null) connection.Delete(i.Difficulty);
+ if (i.Metadata != null) Connection.Delete(i.Metadata);
+ if (i.Difficulty != null) Connection.Delete(i.Difficulty);
- connection.Delete(i);
+ Connection.Delete(i);
}
- if (b.Metadata != null) connection.Delete(b.Metadata);
- connection.Delete(b);
+ if (b.Metadata != null) Connection.Delete(b.Metadata);
+ Connection.Delete(b);
}
catch (Exception e)
{
@@ -80,42 +63,41 @@ namespace osu.Game.Database
//this is required because sqlite migrations don't work, initially inserting nulls into this field.
//see https://github.com/praeclarum/sqlite-net/issues/326
- connection.Query("UPDATE BeatmapSetInfo SET DeletePending = 0 WHERE DeletePending IS NULL");
+ Connection.Query("UPDATE BeatmapSetInfo SET DeletePending = 0 WHERE DeletePending IS NULL");
}
- private SQLiteConnection prepareConnection()
+ protected override void Prepare(bool reset = false)
{
- var conn = storage.GetDatabase(@"beatmaps");
+ Connection.CreateTable();
+ Connection.CreateTable();
+ Connection.CreateTable();
+ Connection.CreateTable();
- try
+ if (reset)
{
- conn.CreateTable();
- conn.CreateTable();
- conn.CreateTable();
- conn.CreateTable();
- }
- catch
- {
- conn.Close();
- throw;
+ Storage.DeleteDatabase(@"beatmaps");
+
+ foreach (var setInfo in Query())
+ {
+ if (Storage.Exists(setInfo.Path))
+ Storage.Delete(setInfo.Path);
+ }
+
+ Connection.DeleteAll();
+ Connection.DeleteAll();
+ Connection.DeleteAll();
+ Connection.DeleteAll();
}
- return conn;
+ deletePending();
}
- public void Reset()
- {
- foreach (var setInfo in Query())
- {
- if (storage.Exists(setInfo.Path))
- storage.Delete(setInfo.Path);
- }
-
- connection.DeleteAll();
- connection.DeleteAll();
- connection.DeleteAll();
- connection.DeleteAll();
- }
+ protected override Type[] ValidTypes => new[] {
+ typeof(BeatmapSetInfo),
+ typeof(BeatmapInfo),
+ typeof(BeatmapMetadata),
+ typeof(BeatmapDifficulty),
+ };
///
/// Import multiple from .
@@ -174,7 +156,7 @@ namespace osu.Game.Database
BeatmapMetadata metadata;
- using (var reader = ArchiveReader.GetReader(storage, path))
+ using (var reader = ArchiveReader.GetReader(Storage, path))
{
using (var stream = new StreamReader(reader.GetStream(reader.BeatmapFilenames[0])))
metadata = BeatmapDecoder.GetDecoder(stream).Decode(stream).Metadata;
@@ -182,18 +164,18 @@ namespace osu.Game.Database
if (File.Exists(path)) // Not always the case, i.e. for LegacyFilesystemReader
{
- using (var input = storage.GetStream(path))
+ using (var input = Storage.GetStream(path))
{
hash = input.GetMd5Hash();
input.Seek(0, SeekOrigin.Begin);
path = Path.Combine(@"beatmaps", hash.Remove(1), hash.Remove(2), hash);
- if (!storage.Exists(path))
- using (var output = storage.GetStream(path, FileAccess.Write))
+ if (!Storage.Exists(path))
+ using (var output = Storage.GetStream(path, FileAccess.Write))
input.CopyTo(output);
}
}
- var existing = connection.Table().FirstOrDefault(b => b.Hash == hash);
+ var existing = Connection.Table().FirstOrDefault(b => b.Hash == hash);
if (existing != null)
{
@@ -216,7 +198,7 @@ namespace osu.Game.Database
Metadata = metadata
};
- using (var archive = ArchiveReader.GetReader(storage, path))
+ using (var archive = ArchiveReader.GetReader(Storage, path))
{
string[] mapNames = archive.BeatmapFilenames;
foreach (var name in mapNames)
@@ -236,7 +218,9 @@ namespace osu.Game.Database
// TODO: Diff beatmap metadata with set metadata and leave it here if necessary
beatmap.BeatmapInfo.Metadata = null;
- beatmap.BeatmapInfo.StarDifficulty = beatmap.CalculateStarDifficulty();
+ // TODO: this should be done in a better place once we actually need to dynamically update it.
+ beatmap.BeatmapInfo.Ruleset = rulesets.Query().FirstOrDefault(r => r.ID == beatmap.BeatmapInfo.RulesetID);
+ beatmap.BeatmapInfo.StarDifficulty = rulesets.Query().FirstOrDefault(r => r.ID == beatmap.BeatmapInfo.RulesetID)?.CreateInstance()?.CreateDifficultyCalculator(beatmap).Calculate() ?? 0;
beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo);
}
@@ -248,17 +232,17 @@ namespace osu.Game.Database
public void Import(IEnumerable beatmapSets)
{
- lock (connection)
+ lock (Connection)
{
- connection.BeginTransaction();
+ Connection.BeginTransaction();
foreach (var s in beatmapSets)
{
- connection.InsertWithChildren(s, true);
+ Connection.InsertOrReplaceWithChildren(s, true);
BeatmapSetAdded?.Invoke(s);
}
- connection.Commit();
+ Connection.Commit();
}
}
@@ -275,7 +259,7 @@ namespace osu.Game.Database
if (string.IsNullOrEmpty(beatmapSet.Path))
return null;
- return ArchiveReader.GetReader(storage, beatmapSet.Path);
+ return ArchiveReader.GetReader(Storage, beatmapSet.Path);
}
public BeatmapSetInfo GetBeatmapSet(int id)
@@ -287,12 +271,14 @@ namespace osu.Game.Database
{
var beatmapSetInfo = Query().FirstOrDefault(s => s.ID == beatmapInfo.BeatmapSetInfoID);
- //we need metadata
- GetChildren(beatmapSetInfo);
-
if (beatmapSetInfo == null)
throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetInfoID} is not in the local database.");
+ //we need metadata
+ GetChildren(beatmapSetInfo);
+ //we also need a ruleset
+ GetChildren(beatmapInfo);
+
if (beatmapInfo.Metadata == null)
beatmapInfo.Metadata = beatmapSetInfo.Metadata;
@@ -303,47 +289,6 @@ namespace osu.Game.Database
return working;
}
- public TableQuery Query() where T : class
- {
- return connection.Table();
- }
-
- public T GetWithChildren(object id) where T : class
- {
- return connection.GetWithChildren(id);
- }
-
- public List GetAllWithChildren(Expression> filter = null, bool recursive = true)
- where T : class
- {
- return connection.GetAllWithChildren(filter, recursive);
- }
-
- public T GetChildren(T item, bool recursive = false)
- {
- if (item == null) return default(T);
-
- connection.GetChildren(item, recursive);
- return item;
- }
-
- private readonly Type[] validTypes = {
- typeof(BeatmapSetInfo),
- typeof(BeatmapInfo),
- typeof(BeatmapMetadata),
- typeof(BeatmapDifficulty),
- };
-
- public void Update(T record, bool cascade = true) where T : class
- {
- if (validTypes.All(t => t != typeof(T)))
- throw new ArgumentException("Must be a type managed by BeatmapDatabase", nameof(T));
- if (cascade)
- connection.UpdateWithChildren(record);
- else
- connection.Update(record);
- }
-
- public bool Exists(BeatmapSetInfo beatmapSet) => storage.Exists(beatmapSet.Path);
+ public bool Exists(BeatmapSetInfo beatmapSet) => Storage.Exists(beatmapSet.Path);
}
}
diff --git a/osu.Game/Database/BeatmapInfo.cs b/osu.Game/Database/BeatmapInfo.cs
index bc6e077633..5097622deb 100644
--- a/osu.Game/Database/BeatmapInfo.cs
+++ b/osu.Game/Database/BeatmapInfo.cs
@@ -3,7 +3,6 @@
using Newtonsoft.Json;
using osu.Game.IO.Serialization;
-using osu.Game.Modes;
using SQLite.Net.Attributes;
using SQLiteNetExtensions.Attributes;
using System;
@@ -41,8 +40,12 @@ namespace osu.Game.Database
[OneToOne(CascadeOperations = CascadeOperation.All)]
public BeatmapDifficulty Difficulty { get; set; }
+ [Ignore]
+ public BeatmapMetrics Metrics { get; set; }
+
public string Path { get; set; }
+ [JsonProperty("file_md5")]
public string Hash { get; set; }
// General
@@ -50,7 +53,13 @@ namespace osu.Game.Database
public bool Countdown { get; set; }
public float StackLeniency { get; set; }
public bool SpecialStyle { get; set; }
- public PlayMode Mode { get; set; }
+
+ [ForeignKey(typeof(RulesetInfo))]
+ public int RulesetID { get; set; }
+
+ [OneToOne(CascadeOperations = CascadeOperation.All)]
+ public RulesetInfo Ruleset { get; set; }
+
public bool LetterboxInBreaks { get; set; }
public bool WidescreenStoryboard { get; set; }
diff --git a/osu.Game/Database/BeatmapMetrics.cs b/osu.Game/Database/BeatmapMetrics.cs
new file mode 100644
index 0000000000..25de0f0a8d
--- /dev/null
+++ b/osu.Game/Database/BeatmapMetrics.cs
@@ -0,0 +1,31 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace osu.Game.Database
+{
+ ///
+ /// Beatmap metrics based on acculumated online data from community plays.
+ ///
+ public class BeatmapMetrics
+ {
+ ///
+ /// Total vote counts of user ratings on a scale of 0..length.
+ ///
+ public IEnumerable Ratings { get; set; }
+
+ ///
+ /// Points of failure on a relative time scale (usually 0..100).
+ ///
+ [JsonProperty(@"fail")]
+ public IEnumerable Fails { get; set; }
+
+ ///
+ /// Points of retry on a relative time scale (usually 0..100).
+ ///
+ [JsonProperty(@"exit")]
+ public IEnumerable Retries { get; set; }
+ }
+}
diff --git a/osu.Game/Database/BeatmapSetInfo.cs b/osu.Game/Database/BeatmapSetInfo.cs
index 0ef0ba4c63..0875d3c01f 100644
--- a/osu.Game/Database/BeatmapSetInfo.cs
+++ b/osu.Game/Database/BeatmapSetInfo.cs
@@ -26,6 +26,7 @@ namespace osu.Game.Database
public double MaxStarDifficulty => Beatmaps.Max(b => b.StarDifficulty);
+ [Indexed]
public bool DeletePending { get; set; }
public string Hash { get; set; }
diff --git a/osu.Game/Database/Database.cs b/osu.Game/Database/Database.cs
new file mode 100644
index 0000000000..23851b3b2e
--- /dev/null
+++ b/osu.Game/Database/Database.cs
@@ -0,0 +1,82 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using osu.Framework.Logging;
+using osu.Framework.Platform;
+using SQLite.Net;
+using SQLiteNetExtensions.Extensions;
+
+namespace osu.Game.Database
+{
+ public abstract class Database
+ {
+ protected SQLiteConnection Connection { get; }
+ protected Storage Storage { get; }
+
+ protected Database(Storage storage, SQLiteConnection connection)
+ {
+ Storage = storage;
+ Connection = connection;
+
+ try
+ {
+ Prepare();
+ }
+ catch (Exception e)
+ {
+ Logger.Error(e, $@"Failed to initialise the {GetType()}! Trying again with a clean database...");
+ Prepare(true);
+ }
+ }
+
+ ///
+ /// Prepare this database for use.
+ ///
+ protected abstract void Prepare(bool reset = false);
+
+ ///
+ /// Reset this database to a default state. Undo all changes to database and storage backings.
+ ///
+ public void Reset() => Prepare(true);
+
+ public TableQuery Query() where T : class
+ {
+ return Connection.Table();
+ }
+
+ public T GetWithChildren(object id) where T : class
+ {
+ return Connection.GetWithChildren(id);
+ }
+
+ public List GetAllWithChildren(Expression> filter = null, bool recursive = true)
+ where T : class
+ {
+ return Connection.GetAllWithChildren(filter, recursive);
+ }
+
+ public T GetChildren(T item, bool recursive = false)
+ {
+ if (item == null) return default(T);
+
+ Connection.GetChildren(item, recursive);
+ return item;
+ }
+
+ protected abstract Type[] ValidTypes { get; }
+
+ public void Update(T record, bool cascade = true) where T : class
+ {
+ if (ValidTypes.All(t => t != typeof(T)))
+ throw new ArgumentException("Must be a type managed by BeatmapDatabase", nameof(T));
+ if (cascade)
+ Connection.UpdateWithChildren(record);
+ else
+ Connection.Update(record);
+ }
+ }
+}
\ No newline at end of file
diff --git a/osu.Game/Database/RulesetDatabase.cs b/osu.Game/Database/RulesetDatabase.cs
new file mode 100644
index 0000000000..b78ca5ffc6
--- /dev/null
+++ b/osu.Game/Database/RulesetDatabase.cs
@@ -0,0 +1,103 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using osu.Framework.Platform;
+using osu.Game.Rulesets;
+using SQLite.Net;
+
+namespace osu.Game.Database
+{
+ ///
+ /// Todo: All of this needs to be moved to a RulesetDatabase.
+ ///
+ public class RulesetDatabase : Database
+ {
+ public IEnumerable AllRulesets => Query().Where(r => r.Available);
+
+ public RulesetDatabase(Storage storage, SQLiteConnection connection)
+ : base(storage, connection)
+ {
+ }
+
+ protected override void Prepare(bool reset = false)
+ {
+ Connection.CreateTable();
+
+ if (reset)
+ {
+ Connection.DeleteAll();
+ }
+
+ List instances = new List();
+
+ foreach (string file in Directory.GetFiles(Environment.CurrentDirectory, @"osu.Game.Rulesets.*.dll"))
+ {
+ try
+ {
+ var assembly = Assembly.LoadFile(file);
+ var rulesets = assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(Ruleset)));
+
+ if (rulesets.Count() != 1)
+ continue;
+
+ foreach (Type rulesetType in rulesets)
+ instances.Add((Ruleset)Activator.CreateInstance(rulesetType));
+ }
+ catch (Exception) { }
+ }
+
+ Connection.BeginTransaction();
+
+ //add all legacy modes in correct order
+ foreach (var r in instances.Where(r => r.LegacyID >= 0).OrderBy(r => r.LegacyID))
+ {
+ Connection.InsertOrReplace(createRulesetInfo(r));
+ }
+
+ //add any other modes
+ foreach (var r in instances.Where(r => r.LegacyID < 0))
+ {
+ var us = createRulesetInfo(r);
+
+ var existing = Query().FirstOrDefault(ri => ri.InstantiationInfo == us.InstantiationInfo);
+
+ if (existing == null)
+ Connection.Insert(us);
+ }
+
+ //perform a consistency check
+ foreach (var r in Query())
+ {
+ try
+ {
+ r.CreateInstance();
+ r.Available = true;
+ }
+ catch
+ {
+ r.Available = false;
+ }
+
+ Connection.Update(r);
+ }
+
+ Connection.Commit();
+ }
+
+ private RulesetInfo createRulesetInfo(Ruleset ruleset) => new RulesetInfo
+ {
+ Name = ruleset.Description,
+ InstantiationInfo = ruleset.GetType().AssemblyQualifiedName,
+ ID = ruleset.LegacyID
+ };
+
+ protected override Type[] ValidTypes => new[] { typeof(RulesetInfo) };
+
+ public RulesetInfo GetRuleset(int id) => Query().First(r => r.ID == id);
+ }
+}
diff --git a/osu.Game/Database/RulesetInfo.cs b/osu.Game/Database/RulesetInfo.cs
new file mode 100644
index 0000000000..322cb10c33
--- /dev/null
+++ b/osu.Game/Database/RulesetInfo.cs
@@ -0,0 +1,26 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System;
+using osu.Game.Rulesets;
+using SQLite.Net.Attributes;
+
+namespace osu.Game.Database
+{
+ public class RulesetInfo
+ {
+ [PrimaryKey, AutoIncrement]
+ public int? ID { get; set; }
+
+ [Indexed(Unique = true)]
+ public string Name { get; set; }
+
+ [Indexed(Unique = true)]
+ public string InstantiationInfo { get; set; }
+
+ [Indexed]
+ public bool Available { get; set; }
+
+ public Ruleset CreateInstance() => (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo));
+ }
+}
\ No newline at end of file
diff --git a/osu.Game/Database/ScoreDatabase.cs b/osu.Game/Database/ScoreDatabase.cs
index 642bb4aff6..8ea836aceb 100644
--- a/osu.Game/Database/ScoreDatabase.cs
+++ b/osu.Game/Database/ScoreDatabase.cs
@@ -2,31 +2,36 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using osu.Framework.Platform;
using osu.Game.IO.Legacy;
using osu.Game.IPC;
-using osu.Game.Modes;
-using osu.Game.Modes.Scoring;
+using osu.Game.Rulesets.Replays;
+using osu.Game.Rulesets.Scoring;
using SharpCompress.Compressors.LZMA;
+using SQLite.Net;
namespace osu.Game.Database
{
- public class ScoreDatabase
+ public class ScoreDatabase : Database
{
private readonly Storage storage;
+
private readonly BeatmapDatabase beatmaps;
+ private readonly RulesetDatabase rulesets;
private const string replay_folder = @"replays";
// ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised)
private ScoreIPCChannel ipc;
- public ScoreDatabase(Storage storage, IIpcHost importHost = null, BeatmapDatabase beatmaps = null)
+ public ScoreDatabase(Storage storage, SQLiteConnection connection, IIpcHost importHost = null, BeatmapDatabase beatmaps = null, RulesetDatabase rulesets = null) : base(storage, connection)
{
this.storage = storage;
this.beatmaps = beatmaps;
+ this.rulesets = rulesets;
if (importHost != null)
ipc = new ScoreIPCChannel(importHost, this);
@@ -39,8 +44,10 @@ namespace osu.Game.Database
using (Stream s = storage.GetStream(Path.Combine(replay_folder, replayFilename)))
using (SerializationReader sr = new SerializationReader(s))
{
- var ruleset = Ruleset.GetRuleset((PlayMode)sr.ReadByte());
- score = ruleset.CreateScoreProcessor().CreateScore();
+ score = new Score
+ {
+ Ruleset = rulesets.GetRuleset(sr.ReadByte())
+ };
/* score.Pass = true;*/
var version = sr.ReadInt32();
@@ -101,11 +108,47 @@ namespace osu.Game.Database
using (var lzma = new LzmaStream(properties, replayInStream, compressedSize, outSize))
using (var reader = new StreamReader(lzma))
- score.Replay = score.CreateReplay(reader);
+ score.Replay = createLegacyReplay(reader);
}
}
return score;
}
+
+ ///
+ /// Creates a legacy replay which is read from a stream.
+ ///
+ /// The stream reader.
+ /// The legacy replay.
+ private Replay createLegacyReplay(StreamReader reader)
+ {
+ var frames = new List();
+
+ float lastTime = 0;
+
+ foreach (var l in reader.ReadToEnd().Split(','))
+ {
+ var split = l.Split('|');
+
+ if (split.Length < 4 || float.Parse(split[0]) < 0) continue;
+
+ lastTime += float.Parse(split[0]);
+
+ frames.Add(new ReplayFrame(
+ lastTime,
+ float.Parse(split[1]),
+ 384 - float.Parse(split[2]),
+ (ReplayButtonState)int.Parse(split[3])
+ ));
+ }
+
+ return new Replay { Frames = frames };
+ }
+
+ protected override void Prepare(bool reset = false)
+ {
+ }
+
+ protected override Type[] ValidTypes => new[] { typeof(Score) };
}
}
diff --git a/osu.Game/Graphics/Cursor/CursorTrail.cs b/osu.Game/Graphics/Cursor/CursorTrail.cs
index 4b5610e840..09d1b99d13 100644
--- a/osu.Game/Graphics/Cursor/CursorTrail.cs
+++ b/osu.Game/Graphics/Cursor/CursorTrail.cs
@@ -13,6 +13,7 @@ using osu.Framework.Graphics.OpenGL.Buffers;
using OpenTK.Graphics.ES30;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Colour;
+using osu.Framework.Timing;
namespace osu.Game.Graphics.Cursor
{
@@ -58,6 +59,9 @@ namespace osu.Game.Graphics.Cursor
public CursorTrail()
{
+ // as we are currently very dependent on having a running clock, let's make our own clock for the time being.
+ Clock = new FramedClock();
+
AlwaysReceiveInput = true;
RelativeSizeAxes = Axes.Both;
@@ -231,4 +235,4 @@ namespace osu.Game.Graphics.Cursor
}
}
}
-}
\ No newline at end of file
+}
diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs
index 0fb7f59212..8d5f95aad5 100644
--- a/osu.Game/Graphics/Cursor/MenuCursor.cs
+++ b/osu.Game/Graphics/Cursor/MenuCursor.cs
@@ -80,14 +80,12 @@ namespace osu.Game.Graphics.Cursor
protected override void PopIn()
{
ActiveCursor.FadeTo(1, 250, EasingTypes.OutQuint);
- ActiveCursor.ScaleTo(1, 1000, EasingTypes.OutElastic);
+ ActiveCursor.ScaleTo(1, 400, EasingTypes.OutQuint);
}
protected override void PopOut()
{
- ActiveCursor.FadeTo(0, 1400, EasingTypes.OutQuint);
- ActiveCursor.ScaleTo(1.1f, 100, EasingTypes.Out);
- ActiveCursor.Delay(100);
+ ActiveCursor.FadeTo(0, 900, EasingTypes.OutQuint);
ActiveCursor.ScaleTo(0, 500, EasingTypes.In);
}
@@ -100,7 +98,7 @@ namespace osu.Game.Graphics.Cursor
public Cursor()
{
- Size = new Vector2(42);
+ AutoSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
diff --git a/osu.Game/Graphics/Cursor/TooltipContainer.cs b/osu.Game/Graphics/Cursor/TooltipContainer.cs
new file mode 100644
index 0000000000..5f0743746a
--- /dev/null
+++ b/osu.Game/Graphics/Cursor/TooltipContainer.cs
@@ -0,0 +1,158 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+using OpenTK.Graphics;
+using osu.Framework.Allocation;
+using osu.Framework.Extensions.Color4Extensions;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Cursor;
+using osu.Framework.Graphics.Primitives;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Input;
+using osu.Framework.Threading;
+using osu.Game.Graphics.Sprites;
+using System.Linq;
+
+namespace osu.Game.Graphics.Cursor
+{
+ public class TooltipContainer : Container
+ {
+ private readonly CursorContainer cursor;
+ private readonly Tooltip tooltip;
+
+ private ScheduledDelegate findTooltipTask;
+ private UserInputManager inputManager;
+
+ private const int default_appear_delay = 220;
+
+ private IHasTooltip currentlyDisplayed;
+
+ public TooltipContainer(CursorContainer cursor)
+ {
+ this.cursor = cursor;
+ AlwaysPresent = true;
+ RelativeSizeAxes = Axes.Both;
+ Add(tooltip = new Tooltip { Alpha = 0 });
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(UserInputManager input)
+ {
+ inputManager = input;
+ }
+
+ protected override void Update()
+ {
+ if (tooltip.IsPresent)
+ {
+ if (currentlyDisplayed != null)
+ tooltip.TooltipText = currentlyDisplayed.TooltipText;
+
+ //update the position of the displayed tooltip.
+ tooltip.Position = ToLocalSpace(cursor.ActiveCursor.ScreenSpaceDrawQuad.Centre) + new Vector2(10);
+ }
+ }
+
+ protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
+ {
+ updateTooltipState(state);
+ return base.OnMouseUp(state, args);
+ }
+
+ protected override bool OnMouseMove(InputState state)
+ {
+ updateTooltipState(state);
+ return base.OnMouseMove(state);
+ }
+
+ private void updateTooltipState(InputState state)
+ {
+ if (currentlyDisplayed?.Hovering != true)
+ {
+ if (currentlyDisplayed != null && !state.Mouse.HasMainButtonPressed)
+ {
+ tooltip.Delay(150);
+ tooltip.FadeOut(500, EasingTypes.OutQuint);
+ currentlyDisplayed = null;
+ }
+
+ findTooltipTask?.Cancel();
+ findTooltipTask = Scheduler.AddDelayed(delegate
+ {
+ var tooltipTarget = inputManager.HoveredDrawables.OfType().FirstOrDefault();
+
+ if (tooltipTarget == null) return;
+
+ tooltip.TooltipText = tooltipTarget.TooltipText;
+ tooltip.FadeIn(500, EasingTypes.OutQuint);
+
+ currentlyDisplayed = tooltipTarget;
+ }, (1 - tooltip.Alpha) * default_appear_delay);
+ }
+ }
+
+ public class Tooltip : Container
+ {
+ private readonly Box background;
+ private readonly OsuSpriteText text;
+
+ public string TooltipText
+ {
+ set
+ {
+ if (value == text.Text) return;
+
+ text.Text = value;
+ if (Alpha > 0)
+ {
+ AutoSizeDuration = 250;
+ background.FlashColour(OsuColour.Gray(0.4f), 1000, EasingTypes.OutQuint);
+ }
+ else
+ AutoSizeDuration = 0;
+ }
+ }
+
+ public override bool HandleInput => false;
+
+ private const float text_size = 16;
+
+ public Tooltip()
+ {
+ AutoSizeEasing = EasingTypes.OutQuint;
+ AutoSizeAxes = Axes.Both;
+
+ CornerRadius = 5;
+ Masking = true;
+ EdgeEffect = new EdgeEffect
+ {
+ Type = EdgeEffectType.Shadow,
+ Colour = Color4.Black.Opacity(40),
+ Radius = 5,
+ };
+ Children = new Drawable[]
+ {
+ background = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Alpha = 0.9f,
+ },
+ text = new OsuSpriteText
+ {
+ TextSize = text_size,
+ Padding = new MarginPadding(5),
+ Font = @"Exo2.0-Regular",
+ }
+ };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colour)
+ {
+ background.Colour = colour.Gray3;
+ }
+ }
+ }
+}
diff --git a/osu.Game/Graphics/IHasAccentColour.cs b/osu.Game/Graphics/IHasAccentColour.cs
index f959bc8760..e4647f22fd 100644
--- a/osu.Game/Graphics/IHasAccentColour.cs
+++ b/osu.Game/Graphics/IHasAccentColour.cs
@@ -28,7 +28,7 @@ namespace osu.Game.Graphics
/// The tween easing.
public static void FadeAccent(this IHasAccentColour accentedDrawable, Color4 newColour, double duration = 0, EasingTypes easing = EasingTypes.None)
{
- accentedDrawable.TransformTo(accentedDrawable.AccentColour, newColour, duration, easing, new TransformAccent());
+ accentedDrawable.TransformTo(() => accentedDrawable.AccentColour, newColour, duration, easing, new TransformAccent());
}
}
}
diff --git a/osu.Game/Graphics/IHasTooltip.cs b/osu.Game/Graphics/IHasTooltip.cs
new file mode 100644
index 0000000000..dd51d68c41
--- /dev/null
+++ b/osu.Game/Graphics/IHasTooltip.cs
@@ -0,0 +1,15 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Framework.Graphics;
+
+namespace osu.Game.Graphics
+{
+ public interface IHasTooltip : IDrawable
+ {
+ ///
+ /// Tooltip that shows when hovering the drawable
+ ///
+ string TooltipText { get; }
+ }
+}
diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs
index d8de4f6346..cd719431e7 100644
--- a/osu.Game/Graphics/OsuColour.cs
+++ b/osu.Game/Graphics/OsuColour.cs
@@ -80,6 +80,10 @@ namespace osu.Game.Graphics
public Color4 GrayE = FromHex(@"eee");
public Color4 GrayF = FromHex(@"fff");
- public Color4 Red = FromHex(@"fc4549");
+ public Color4 RedLighter = FromHex(@"ffeded");
+ public Color4 RedLight = FromHex(@"ed7787");
+ public Color4 Red = FromHex(@"ed1121");
+ public Color4 RedDark = FromHex(@"ba0011");
+ public Color4 RedDarker = FromHex(@"870000");
}
}
diff --git a/osu.Game/Graphics/TextAwesome.cs b/osu.Game/Graphics/TextAwesome.cs
index 1bae165e45..69b0217444 100644
--- a/osu.Game/Graphics/TextAwesome.cs
+++ b/osu.Game/Graphics/TextAwesome.cs
@@ -817,13 +817,13 @@ namespace osu.Game.Graphics
fa_youtube_play = 0xf16a,
fa_youtube_square = 0xf166,
- // gamemode icons in circles
+ // ruleset icons in circles
fa_osu_osu_o = 0xe000,
fa_osu_mania_o = 0xe001,
fa_osu_fruits_o = 0xe002,
fa_osu_taiko_o = 0xe003,
- // gamemode icons without circles
+ // ruleset icons without circles
fa_osu_filled_circle = 0xe004,
fa_osu_cross_o = 0xe005,
fa_osu_logo = 0xe006,
diff --git a/osu.Game/Graphics/UserInterface/Bar.cs b/osu.Game/Graphics/UserInterface/Bar.cs
new file mode 100644
index 0000000000..76b75f1084
--- /dev/null
+++ b/osu.Game/Graphics/UserInterface/Bar.cs
@@ -0,0 +1,137 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+using OpenTK.Graphics;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using System;
+
+namespace osu.Game.Graphics.UserInterface
+{
+ public class Bar : Container, IHasAccentColour
+ {
+ private readonly Box background;
+ private readonly Box bar;
+
+ private const int resize_duration = 250;
+
+ private const EasingTypes easing = EasingTypes.InOutCubic;
+
+ private float length;
+ ///
+ /// Length of the bar, ranges from 0 to 1
+ ///
+ public float Length
+ {
+ get
+ {
+ return length;
+ }
+ set
+ {
+ length = MathHelper.Clamp(value, 0, 1);
+ updateBarLength();
+ }
+ }
+
+ public Color4 BackgroundColour
+ {
+ get
+ {
+ return background.Colour;
+ }
+ set
+ {
+ background.Colour = value;
+ }
+ }
+
+ public Color4 AccentColour
+ {
+ get
+ {
+ return bar.Colour;
+ }
+ set
+ {
+ bar.Colour = value;
+ }
+ }
+
+ private BarDirection direction = BarDirection.LeftToRight;
+ public BarDirection Direction
+ {
+ get
+ {
+ return direction;
+ }
+ set
+ {
+ direction = value;
+ updateBarLength();
+ }
+ }
+
+ public Bar()
+ {
+ Children = new[]
+ {
+ background = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = new Color4(0,0,0,0)
+ },
+ bar = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Width = 0,
+ },
+ };
+ }
+
+ private void updateBarLength()
+ {
+ switch (direction)
+ {
+ case BarDirection.LeftToRight:
+ case BarDirection.RightToLeft:
+ bar.ResizeTo(new Vector2(length, 1), resize_duration, easing);
+ break;
+
+ case BarDirection.TopToBottom:
+ case BarDirection.BottomToTop:
+ bar.ResizeTo(new Vector2(1, length), resize_duration, easing);
+ break;
+ }
+
+ switch (direction)
+ {
+ case BarDirection.LeftToRight:
+ case BarDirection.TopToBottom:
+ bar.Anchor = Anchor.TopLeft;
+ bar.Origin = Anchor.TopLeft;
+ break;
+
+ case BarDirection.RightToLeft:
+ case BarDirection.BottomToTop:
+ bar.Anchor = Anchor.BottomRight;
+ bar.Origin = Anchor.BottomRight;
+ break;
+ }
+ }
+ }
+
+ [Flags]
+ public enum BarDirection
+ {
+ LeftToRight = 1 << 0,
+ RightToLeft = 1 << 1,
+ TopToBottom = 1 << 2,
+ BottomToTop = 1 << 3,
+
+ Vertical = TopToBottom | BottomToTop,
+ Horizontal = LeftToRight | RightToLeft,
+ }
+}
\ No newline at end of file
diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs
new file mode 100644
index 0000000000..d0965a1861
--- /dev/null
+++ b/osu.Game/Graphics/UserInterface/BarGraph.cs
@@ -0,0 +1,65 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using OpenTK;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace osu.Game.Graphics.UserInterface
+{
+ public class BarGraph : FillFlowContainer
+ {
+ ///
+ /// Manually sets the max value, if null is instead used
+ ///
+ public float? MaxValue { get; set; }
+
+ private BarDirection direction = BarDirection.BottomToTop;
+ public new BarDirection Direction
+ {
+ get
+ {
+ return direction;
+ }
+ set
+ {
+ direction = value;
+ base.Direction = (direction & BarDirection.Horizontal) > 0 ? FillDirection.Vertical : FillDirection.Horizontal;
+ foreach (var bar in Children)
+ {
+ bar.Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, 1.0f / Children.Count()) : new Vector2(1.0f / Children.Count(), 1);
+ bar.Direction = direction;
+ }
+ }
+ }
+
+ ///
+ /// A list of floats that defines the length of each
+ ///
+ public IEnumerable Values
+ {
+ set
+ {
+ List bars = Children.ToList();
+ foreach (var bar in value.Select((length, index) => new { Value = length, Bar = bars.Count > index ? bars[index] : null }))
+ if (bar.Bar != null)
+ {
+ bar.Bar.Length = bar.Value / (MaxValue ?? value.Max());
+ bar.Bar.Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, 1.0f / value.Count()) : new Vector2(1.0f / value.Count(), 1);
+ }
+ else
+ Add(new Bar
+ {
+ RelativeSizeAxes = Axes.Both,
+ Size = (direction & BarDirection.Horizontal) > 0 ? new Vector2(1, 1.0f / value.Count()) : new Vector2(1.0f / value.Count(), 1),
+ Length = bar.Value / (MaxValue ?? value.Max()),
+ Direction = Direction,
+ });
+ //I'm using ToList() here because Where() returns an Enumerable which can change it's elements afterwards
+ Remove(Children.Where((bar, index) => index >= value.Count()).ToList());
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/osu.Game/Graphics/UserInterface/Nub.cs b/osu.Game/Graphics/UserInterface/Nub.cs
index e150c7dc07..82ede8f079 100644
--- a/osu.Game/Graphics/UserInterface/Nub.cs
+++ b/osu.Game/Graphics/UserInterface/Nub.cs
@@ -3,8 +3,8 @@
using OpenTK;
using OpenTK.Graphics;
-using osu.Framework;
using osu.Framework.Allocation;
+using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@@ -12,18 +12,18 @@ using osu.Framework.Graphics.UserInterface;
namespace osu.Game.Graphics.UserInterface
{
- public class Nub : CircularContainer, IStateful
+ public class Nub : CircularContainer, IHasCurrentValue
{
public const float COLLAPSED_SIZE = 20;
public const float EXPANDED_SIZE = 40;
- private readonly Box fill;
-
private const float border_width = 3;
private Color4 glowingColour, idleColour;
public Nub()
{
+ Box fill;
+
Size = new Vector2(COLLAPSED_SIZE, 12);
BorderColour = Color4.White;
@@ -40,6 +40,14 @@ namespace osu.Game.Graphics.UserInterface
AlwaysPresent = true,
},
};
+
+ Current.ValueChanged += newValue =>
+ {
+ if (newValue)
+ fill.FadeIn(200, EasingTypes.OutQuint);
+ else
+ fill.FadeTo(0.01f, 200, EasingTypes.OutQuint); //todo: remove once we figure why containers aren't drawing at all times
+ };
}
[BackgroundDependencyLoader]
@@ -84,28 +92,6 @@ namespace osu.Game.Graphics.UserInterface
}
}
- private CheckboxState state;
-
- public CheckboxState State
- {
- get
- {
- return state;
- }
- set
- {
- state = value;
-
- switch (state)
- {
- case CheckboxState.Checked:
- fill.FadeIn(200, EasingTypes.OutQuint);
- break;
- case CheckboxState.Unchecked:
- fill.FadeTo(0.01f, 200, EasingTypes.OutQuint); //todo: remove once we figure why containers aren't drawing at all times
- break;
- }
- }
- }
+ public Bindable Current { get; } = new Bindable();
}
}
diff --git a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs
index 6a5151b90c..e81db4954e 100644
--- a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs
+++ b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs
@@ -23,19 +23,8 @@ namespace osu.Game.Graphics.UserInterface
{
set
{
- if (bindable != null)
- bindable.ValueChanged -= bindableValueChanged;
bindable = value;
- if (bindable != null)
- {
- bool state = State == CheckboxState.Checked;
- if (state != bindable.Value)
- State = bindable.Value ? CheckboxState.Checked : CheckboxState.Unchecked;
- bindable.ValueChanged += bindableValueChanged;
- }
-
- if (bindable?.Disabled ?? true)
- Alpha = 0.3f;
+ Current.BindTo(bindable);
}
}
@@ -83,18 +72,21 @@ namespace osu.Game.Graphics.UserInterface
Margin = new MarginPadding { Right = 5 },
}
};
- }
- private void bindableValueChanged(bool isChecked)
- {
- State = isChecked ? CheckboxState.Checked : CheckboxState.Unchecked;
- }
+ nub.Current.BindTo(Current);
- protected override void Dispose(bool isDisposing)
- {
- if (bindable != null)
- bindable.ValueChanged -= bindableValueChanged;
- base.Dispose(isDisposing);
+ Current.ValueChanged += newValue =>
+ {
+ if (newValue)
+ sampleChecked?.Play();
+ else
+ sampleUnchecked?.Play();
+ };
+
+ Current.DisabledChanged += disabled =>
+ {
+ Alpha = disabled ? 0.3f : 1;
+ };
}
protected override bool OnHover(InputState state)
@@ -117,23 +109,5 @@ namespace osu.Game.Graphics.UserInterface
sampleChecked = audio.Sample.Get(@"Checkbox/check-on");
sampleUnchecked = audio.Sample.Get(@"Checkbox/check-off");
}
-
- protected override void OnChecked()
- {
- sampleChecked?.Play();
- nub.State = CheckboxState.Checked;
-
- if (bindable != null)
- bindable.Value = true;
- }
-
- protected override void OnUnchecked()
- {
- sampleUnchecked?.Play();
- nub.State = CheckboxState.Unchecked;
-
- if (bindable != null)
- bindable.Value = false;
- }
}
}
diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs
index fcc05822f0..59bee8baad 100644
--- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs
+++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs
@@ -45,7 +45,7 @@ namespace osu.Game.Graphics.UserInterface
private class OsuDropdownMenuItem : DropdownMenuItem
{
- public OsuDropdownMenuItem(string text, T value) : base(text, value)
+ public OsuDropdownMenuItem(string text, T current) : base(text, current)
{
Foreground.Padding = new MarginPadding(2);
diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs
index 078c8564d7..027473921f 100644
--- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs
+++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs
@@ -2,10 +2,10 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
-using OpenTK.Input;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
+using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
@@ -13,15 +13,36 @@ using osu.Framework.Input;
namespace osu.Game.Graphics.UserInterface
{
- public class OsuSliderBar : SliderBar where U : struct
+ public class OsuSliderBar : SliderBar, IHasTooltip where T : struct
{
private SampleChannel sample;
private double lastSampleTime;
+ private T lastSampleValue;
private readonly Nub nub;
private readonly Box leftBox;
private readonly Box rightBox;
+ public virtual string TooltipText
+ {
+ get
+ {
+ var bindableDouble = CurrentNumber as BindableNumber;
+ if (bindableDouble != null)
+ {
+ if (bindableDouble.MaxValue == 1 && (bindableDouble.MinValue == 0 || bindableDouble.MinValue == -1))
+ return bindableDouble.Value.ToString(@"P0");
+ return bindableDouble.Value.ToString(@"n1");
+ }
+
+ var bindableInt = CurrentNumber as BindableNumber;
+ if (bindableInt != null)
+ return bindableInt.Value.ToString(@"n0");
+
+ return Current.Value.ToString();
+ }
+ }
+
public OsuSliderBar()
{
Height = 12;
@@ -50,10 +71,14 @@ namespace osu.Game.Graphics.UserInterface
nub = new Nub
{
Origin = Anchor.TopCentre,
- State = CheckboxState.Unchecked,
Expanded = true,
}
};
+
+ Current.DisabledChanged += disabled =>
+ {
+ Alpha = disabled ? 0.3f : 1;
+ };
}
[BackgroundDependencyLoader]
@@ -64,15 +89,6 @@ namespace osu.Game.Graphics.UserInterface
rightBox.Colour = colours.Pink;
}
- private void playSample()
- {
- if (Clock == null || Clock.CurrentTime - lastSampleTime <= 50)
- return;
- lastSampleTime = Clock.CurrentTime;
- sample.Frequency.Value = 1 + NormalizedValue * 0.2f;
- sample.Play();
- }
-
protected override bool OnHover(InputState state)
{
nub.Glowing = true;
@@ -85,37 +101,45 @@ namespace osu.Game.Graphics.UserInterface
base.OnHoverLost(state);
}
- protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
+ protected override void OnUserChange()
{
- if (args.Key == Key.Left || args.Key == Key.Right)
- playSample();
- return base.OnKeyDown(state, args);
+ base.OnUserChange();
+ playSample();
+ }
+
+ private void playSample()
+ {
+ if (Clock == null || Clock.CurrentTime - lastSampleTime <= 50)
+ return;
+
+ if (Current.Value.Equals(lastSampleValue))
+ return;
+
+ lastSampleValue = Current.Value;
+
+ lastSampleTime = Clock.CurrentTime;
+ sample.Frequency.Value = 1 + NormalizedValue * 0.2f;
+
+ if (NormalizedValue == 0)
+ sample.Frequency.Value -= 0.4f;
+ else if (NormalizedValue == 1)
+ sample.Frequency.Value += 0.4f;
+
+ sample.Play();
}
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
{
- nub.State = CheckboxState.Checked;
+ nub.Current.Value = true;
return base.OnMouseDown(state, args);
}
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
{
- nub.State = CheckboxState.Unchecked;
+ nub.Current.Value = false;
return base.OnMouseUp(state, args);
}
- protected override bool OnClick(InputState state)
- {
- playSample();
- return base.OnClick(state);
- }
-
- protected override bool OnDrag(InputState state)
- {
- playSample();
- return base.OnDrag(state);
- }
-
protected override void UpdateAfterChildren()
{
base.UpdateAfterChildren();
diff --git a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs
index 5914d0ba4c..f732916889 100644
--- a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs
+++ b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs
@@ -1,7 +1,6 @@
// Copyright (c) 2007-2017 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-using System;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
@@ -24,8 +23,6 @@ namespace osu.Game.Graphics.UserInterface
private readonly SpriteText text;
private readonly TextAwesome icon;
- public event EventHandler Action;
-
private Color4? accentColour;
public Color4 AccentColour
{
@@ -34,7 +31,7 @@ namespace osu.Game.Graphics.UserInterface
{
accentColour = value;
- if (State != CheckboxState.Checked)
+ if (Current)
{
text.Colour = AccentColour;
icon.Colour = AccentColour;
@@ -48,20 +45,6 @@ namespace osu.Game.Graphics.UserInterface
set { text.Text = value; }
}
- protected override void OnChecked()
- {
- fadeIn();
- icon.Icon = FontAwesome.fa_check_circle_o;
- Action?.Invoke(this, State);
- }
-
- protected override void OnUnchecked()
- {
- fadeOut();
- icon.Icon = FontAwesome.fa_circle_o;
- Action?.Invoke(this, State);
- }
-
private const float transition_length = 500;
private void fadeIn()
@@ -84,7 +67,7 @@ namespace osu.Game.Graphics.UserInterface
protected override void OnHoverLost(InputState state)
{
- if (State == CheckboxState.Unchecked)
+ if (!Current)
fadeOut();
base.OnHoverLost(state);
@@ -134,6 +117,20 @@ namespace osu.Game.Graphics.UserInterface
Anchor = Anchor.BottomLeft,
}
};
+
+ Current.ValueChanged += v =>
+ {
+ if (v)
+ {
+ fadeIn();
+ icon.Icon = FontAwesome.fa_check_circle_o;
+ }
+ else
+ {
+ fadeOut();
+ icon.Icon = FontAwesome.fa_circle_o;
+ }
+ };
}
}
}
diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs
index a54b122615..62b10b96ef 100644
--- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs
+++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs
@@ -33,6 +33,11 @@ namespace osu.Game.Graphics.UserInterface
Height = 40;
TextContainer.Height = 0.5f;
CornerRadius = 5;
+
+ Current.DisabledChanged += disabled =>
+ {
+ Alpha = disabled ? 0.3f : 1;
+ };
}
[BackgroundDependencyLoader]
diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs
index 12eeb771dd..e98867277a 100644
--- a/osu.Game/Graphics/UserInterface/RollingCounter.cs
+++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs
@@ -10,10 +10,11 @@ using osu.Game.Graphics.Sprites;
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using OpenTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
- public abstract class RollingCounter : Container
+ public abstract class RollingCounter : Container, IHasAccentColour
{
///
/// The current value.
@@ -80,6 +81,12 @@ namespace osu.Game.Graphics.UserInterface
}
}
+ public Color4 AccentColour
+ {
+ get { return DisplayedCountSpriteText.Colour; }
+ set { DisplayedCountSpriteText.Colour = value; }
+ }
+
///
/// Skeleton of a numeric counter which value rolls over time.
///
@@ -108,11 +115,7 @@ namespace osu.Game.Graphics.UserInterface
{
base.LoadComplete();
- Flush(false, TransformType);
-
DisplayedCountSpriteText.Text = FormatCount(Current);
- DisplayedCountSpriteText.Anchor = Anchor;
- DisplayedCountSpriteText.Origin = Origin;
}
///
@@ -205,8 +208,8 @@ namespace osu.Game.Graphics.UserInterface
? GetProportionalDuration(currentValue, newValue)
: RollingDuration;
- transform.StartTime = Time.Current;
- transform.EndTime = Time.Current + rollingTotalDuration;
+ transform.StartTime = TransformStartTime;
+ transform.EndTime = TransformStartTime + rollingTotalDuration;
transform.StartValue = currentValue;
transform.EndValue = newValue;
transform.Easing = RollingEasing;
diff --git a/osu.Game/Graphics/UserInterface/ScoreCounter.cs b/osu.Game/Graphics/UserInterface/ScoreCounter.cs
index c2b1b026b6..3e01b9e4f4 100644
--- a/osu.Game/Graphics/UserInterface/ScoreCounter.cs
+++ b/osu.Game/Graphics/UserInterface/ScoreCounter.cs
@@ -15,6 +15,8 @@ namespace osu.Game.Graphics.UserInterface
protected override double RollingDuration => 1000;
protected override EasingTypes RollingEasing => EasingTypes.Out;
+ public bool UseCommaSeparator;
+
///
/// How many leading zeroes the counter has.
///
@@ -41,7 +43,12 @@ namespace osu.Game.Graphics.UserInterface
protected override string FormatCount(double count)
{
- return ((long)count).ToString("D" + LeadingZeroes);
+ string format = new string('0', (int)LeadingZeroes);
+ if (UseCommaSeparator)
+ for (int i = format.Length - 3; i > 0; i -= 3)
+ format = format.Insert(i, @",");
+
+ return ((long)count).ToString(format);
}
public override void Increment(double amount)
diff --git a/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs b/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs
new file mode 100644
index 0000000000..8537e80f63
--- /dev/null
+++ b/osu.Game/Graphics/UserInterface/SimpleComboCounter.cs
@@ -0,0 +1,61 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using System;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Transforms;
+using osu.Framework.MathUtils;
+
+namespace osu.Game.Graphics.UserInterface
+{
+ ///
+ /// Used as an accuracy counter. Represented visually as a percentage.
+ ///
+ public class SimpleComboCounter : RollingCounter
+ {
+ protected override Type TransformType => typeof(TransformCounterCount);
+
+ protected override double RollingDuration => 750;
+
+ public SimpleComboCounter()
+ {
+ Current.Value = DisplayedCount = 0;
+ }
+
+ protected override string FormatCount(int count)
+ {
+ return $@"{count}x";
+ }
+
+ protected override double GetProportionalDuration(int currentValue, int newValue)
+ {
+ return Math.Abs(currentValue - newValue) * RollingDuration * 100.0f;
+ }
+
+ public override void Increment(int amount)
+ {
+ Current.Value = Current + amount;
+ }
+
+ private class TransformCounterCount : Transform
+ {
+ public override int CurrentValue
+ {
+ get
+ {
+ double time = Time?.Current ?? 0;
+ if (time < StartTime) return StartValue;
+ if (time >= EndTime) return EndValue;
+
+ return (int)Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing);
+ }
+ }
+
+ public override void Apply(Drawable d)
+ {
+ base.Apply(d);
+ ((SimpleComboCounter)d).DisplayedCount = CurrentValue;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/osu.Game/Graphics/UserInterface/StarCounter.cs b/osu.Game/Graphics/UserInterface/StarCounter.cs
index c046749dad..295cdac81d 100644
--- a/osu.Game/Graphics/UserInterface/StarCounter.cs
+++ b/osu.Game/Graphics/UserInterface/StarCounter.cs
@@ -131,14 +131,14 @@ namespace osu.Game.Graphics.UserInterface
foreach (var star in stars.Children)
{
star.ClearTransforms(true);
- if (count <= newValue)
- star.Delay(Math.Max(i - count, 0) * animationDelay, true);
- else
- star.Delay(Math.Max(count - 1 - i, 0) * animationDelay, true);
- star.FadeTo(i < newValue ? 1.0f : minStarAlpha, fadingDuration);
- star.Icon.ScaleTo(getStarScale(i, newValue), scalingDuration, scalingEasing);
- star.DelayReset();
+ var delay = (count <= newValue ? Math.Max(i - count, 0) : Math.Max(count - 1 - i, 0)) * animationDelay;
+
+ using (BeginDelayedSequence(delay, true))
+ {
+ star.FadeTo(i < newValue ? 1.0f : minStarAlpha, fadingDuration);
+ star.Icon.ScaleTo(getStarScale(i, newValue), scalingDuration, scalingEasing);
+ }
i++;
}
diff --git a/osu.Game/Modes/Mods/Mod.cs b/osu.Game/Modes/Mods/Mod.cs
deleted file mode 100644
index b6f09b8506..0000000000
--- a/osu.Game/Modes/Mods/Mod.cs
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Beatmaps;
-using osu.Game.Graphics;
-using osu.Game.Modes.Objects;
-using osu.Game.Modes.UI;
-using System;
-using osu.Game.Modes.Scoring;
-
-namespace osu.Game.Modes.Mods
-{
- ///
- /// The base class for gameplay modifiers.
- ///
- public abstract class Mod
- {
- ///
- /// The name of this mod.
- ///
- public abstract string Name { get; }
-
- ///
- /// The icon of this mod.
- ///
- public virtual FontAwesome Icon => FontAwesome.fa_question;
-
- ///
- /// The user readable description of this mod.
- ///
- public virtual string Description => string.Empty;
-
- ///
- /// The score multiplier of this mod.
- ///
- public abstract double ScoreMultiplier { get; }
-
- ///
- /// Returns if this mod is ranked.
- ///
- public virtual bool Ranked => false;
-
- ///
- /// The mods this mod cannot be enabled with.
- ///
- public virtual Type[] IncompatibleMods => new Type[] { };
- }
-
- public class MultiMod : Mod
- {
- public override string Name => string.Empty;
- public override string Description => string.Empty;
- public override double ScoreMultiplier => 0.0;
-
- public Mod[] Mods;
- }
-
- public abstract class ModNoFail : Mod
- {
- public override string Name => "NoFail";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail;
- public override string Description => "You can't fail, no matter what.";
- public override double ScoreMultiplier => 0.5;
- public override bool Ranked => true;
- public override Type[] IncompatibleMods => new[] { typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModAutoplay) };
- }
-
- public abstract class ModEasy : Mod
- {
- public override string Name => "Easy";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_easy;
- public override string Description => "Reduces overall difficulty - larger circles, more forgiving HP drain, less accuracy required.";
- public override double ScoreMultiplier => 0.5;
- public override bool Ranked => true;
- public override Type[] IncompatibleMods => new[] { typeof(ModHardRock) };
- }
-
- public abstract class ModHidden : Mod
- {
- public override string Name => "Hidden";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden;
- public override bool Ranked => true;
- }
-
- public abstract class ModHardRock : Mod
- {
- public override string Name => "Hard Rock";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_hardrock;
- public override string Description => "Everything just got a bit harder...";
- public override Type[] IncompatibleMods => new[] { typeof(ModEasy) };
- }
-
- public abstract class ModSuddenDeath : Mod
- {
- public override string Name => "Sudden Death";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_suddendeath;
- public override string Description => "Miss a note and fail.";
- public override double ScoreMultiplier => 1;
- public override bool Ranked => true;
- public override Type[] IncompatibleMods => new[] { typeof(ModNoFail), typeof(ModRelax), typeof(ModAutoplay) };
- }
-
- public abstract class ModDoubleTime : Mod
- {
- public override string Name => "Double Time";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_doubletime;
- public override string Description => "Zoooooooooom";
- public override bool Ranked => true;
- public override Type[] IncompatibleMods => new[] { typeof(ModHalfTime) };
- }
-
- public abstract class ModRelax : Mod
- {
- public override string Name => "Relax";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_relax;
- public override double ScoreMultiplier => 0;
- public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModNoFail), typeof(ModSuddenDeath) };
- }
-
- public abstract class ModHalfTime : Mod
- {
- public override string Name => "Half Time";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_halftime;
- public override string Description => "Less zoom";
- public override bool Ranked => true;
- public override Type[] IncompatibleMods => new[] { typeof(ModDoubleTime) };
- }
-
- public abstract class ModNightcore : ModDoubleTime
- {
- public override string Name => "Nightcore";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_nightcore;
- public override string Description => "uguuuuuuuu";
- }
-
- public abstract class ModFlashlight : Mod
- {
- public override string Name => "Flashlight";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_flashlight;
- public override string Description => "Restricted view area.";
- public override bool Ranked => true;
- }
-
- public class ModAutoplay : Mod
- {
- public override string Name => "Autoplay";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_auto;
- public override string Description => "Watch a perfect automated play through the song";
- public override double ScoreMultiplier => 0;
- public override Type[] IncompatibleMods => new[] { typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail) };
- }
-
- public abstract class ModAutoplay : ModAutoplay, IApplicableMod
- where T : HitObject
- {
- protected abstract Score CreateReplayScore(Beatmap beatmap);
-
- public void Apply(HitRenderer hitRenderer)
- {
- hitRenderer.SetReplay(CreateReplayScore(hitRenderer.Beatmap)?.Replay);
- }
- }
-
- public abstract class ModPerfect : ModSuddenDeath
- {
- public override string Name => "Perfect";
- public override string Description => "SS or quit.";
- }
-
- public class ModCinema : ModAutoplay
- {
- public override string Name => "Cinema";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_cinema;
- }
-}
diff --git a/osu.Game/Modes/Objects/CurvedHitObject.cs b/osu.Game/Modes/Objects/CurvedHitObject.cs
deleted file mode 100644
index ccb3d2497d..0000000000
--- a/osu.Game/Modes/Objects/CurvedHitObject.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using OpenTK;
-using osu.Game.Modes.Objects.Types;
-using System.Collections.Generic;
-
-namespace osu.Game.Modes.Objects
-{
- public class CurvedHitObject : HitObject, IHasCurve
- {
- public SliderCurve Curve { get; } = new SliderCurve();
-
- public int RepeatCount { get; set; } = 1;
-
- public double EndTime => 0;
- public double Duration => 0;
-
- public List ControlPoints
- {
- get { return Curve.ControlPoints; }
- set { Curve.ControlPoints = value; }
- }
-
- public CurveType CurveType
- {
- get { return Curve.CurveType; }
- set { Curve.CurveType = value; }
- }
-
- public double Distance
- {
- get { return Curve.Distance; }
- set { Curve.Distance = value; }
- }
-
- public Vector2 PositionAt(double progress) => Curve.PositionAt(ProgressAt(progress));
-
- public double ProgressAt(double progress)
- {
- var p = progress * RepeatCount % 1;
- if (RepeatAt(progress) % 2 == 1)
- p = 1 - p;
- return p;
- }
-
- public int RepeatAt(double progress) => (int)(progress * RepeatCount);
- }
-}
diff --git a/osu.Game/Modes/Objects/HitObject.cs b/osu.Game/Modes/Objects/HitObject.cs
deleted file mode 100644
index f362d6de63..0000000000
--- a/osu.Game/Modes/Objects/HitObject.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Audio;
-using osu.Game.Beatmaps.Timing;
-using osu.Game.Database;
-using System.Collections.Generic;
-
-namespace osu.Game.Modes.Objects
-{
- ///
- /// A HitObject describes an object in a Beatmap.
- ///
- /// HitObjects may contain more properties for which you should be checking through the IHas* types.
- ///
- ///
- public class HitObject
- {
- ///
- /// The time at which the HitObject starts.
- ///
- public double StartTime { get; set; }
-
- ///
- /// The samples to be played when this hit object is hit.
- ///
- public List Samples = new List();
-
- ///
- /// Applies default values to this HitObject.
- ///
- /// The difficulty settings to use.
- /// The timing settings to use.
- public virtual void ApplyDefaults(TimingInfo timing, BeatmapDifficulty difficulty)
- {
- ControlPoint overridePoint;
- ControlPoint timingPoint = timing.TimingPointAt(StartTime, out overridePoint);
-
- foreach (var sample in Samples)
- {
- if (sample.Volume == 0)
- sample.Volume = (overridePoint ?? timingPoint)?.SampleVolume ?? 0;
-
- // If the bank is not assigned a name, assign it from the control point
- if (!string.IsNullOrEmpty(sample.Bank))
- continue;
-
- sample.Bank = (overridePoint ?? timingPoint)?.SampleBank ?? @"normal";
- }
- }
- }
-}
diff --git a/osu.Game/Modes/Objects/Legacy/LegacyHit.cs b/osu.Game/Modes/Objects/Legacy/LegacyHit.cs
deleted file mode 100644
index 239c8982da..0000000000
--- a/osu.Game/Modes/Objects/Legacy/LegacyHit.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Modes.Objects.Types;
-using OpenTK;
-
-namespace osu.Game.Modes.Objects.Legacy
-{
- ///
- /// Legacy Hit-type, used for parsing Beatmaps.
- ///
- public sealed class LegacyHit : HitObject, IHasPosition, IHasCombo
- {
- public Vector2 Position { get; set; }
-
- public bool NewCombo { get; set; }
- }
-}
diff --git a/osu.Game/Modes/Objects/Legacy/LegacySlider.cs b/osu.Game/Modes/Objects/Legacy/LegacySlider.cs
deleted file mode 100644
index bdfebb1983..0000000000
--- a/osu.Game/Modes/Objects/Legacy/LegacySlider.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Modes.Objects.Types;
-using OpenTK;
-
-namespace osu.Game.Modes.Objects.Legacy
-{
- ///
- /// Legacy Slider-type, used for parsing Beatmaps.
- ///
- public sealed class LegacySlider : CurvedHitObject, IHasPosition, IHasCombo
- {
- public Vector2 Position { get; set; }
-
- public bool NewCombo { get; set; }
- }
-}
diff --git a/osu.Game/Modes/Objects/LegacyHitObjectParser.cs b/osu.Game/Modes/Objects/LegacyHitObjectParser.cs
deleted file mode 100644
index 2316e5dc5d..0000000000
--- a/osu.Game/Modes/Objects/LegacyHitObjectParser.cs
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using OpenTK;
-using osu.Game.Modes.Objects.Types;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using osu.Game.Modes.Objects.Legacy;
-using osu.Game.Beatmaps.Formats;
-using osu.Game.Audio;
-
-namespace osu.Game.Modes.Objects
-{
- internal class LegacyHitObjectParser : HitObjectParser
- {
- public override HitObject Parse(string text)
- {
- string[] split = text.Split(',');
- var type = (LegacyHitObjectType)int.Parse(split[3]) & ~LegacyHitObjectType.ColourHax;
- bool combo = type.HasFlag(LegacyHitObjectType.NewCombo);
- type &= ~LegacyHitObjectType.NewCombo;
-
- int sampleVolume = 0;
- string normalSampleBank = null;
- string addSampleBank = null;
-
- HitObject result;
-
- if ((type & LegacyHitObjectType.Circle) > 0)
- {
- result = new LegacyHit
- {
- Position = new Vector2(int.Parse(split[0]), int.Parse(split[1])),
- NewCombo = combo
- };
-
- if (split.Length > 5)
- readCustomSampleBanks(split[5], ref normalSampleBank, ref addSampleBank, ref sampleVolume);
- }
- else if ((type & LegacyHitObjectType.Slider) > 0)
- {
- CurveType curveType = CurveType.Catmull;
- double length = 0;
- List points = new List { new Vector2(int.Parse(split[0]), int.Parse(split[1])) };
-
- string[] pointsplit = split[5].Split('|');
- foreach (string t in pointsplit)
- {
- if (t.Length == 1)
- {
- switch (t)
- {
- case @"C":
- curveType = CurveType.Catmull;
- break;
- case @"B":
- curveType = CurveType.Bezier;
- break;
- case @"L":
- curveType = CurveType.Linear;
- break;
- case @"P":
- curveType = CurveType.PerfectCurve;
- break;
- }
- continue;
- }
-
- string[] temp = t.Split(':');
- Vector2 v = new Vector2(
- (int)Convert.ToDouble(temp[0], CultureInfo.InvariantCulture),
- (int)Convert.ToDouble(temp[1], CultureInfo.InvariantCulture)
- );
- points.Add(v);
- }
-
- int repeatCount = Convert.ToInt32(split[6], CultureInfo.InvariantCulture);
-
- if (repeatCount > 9000)
- throw new ArgumentOutOfRangeException(nameof(repeatCount), @"Repeat count is way too high");
-
- if (split.Length > 7)
- length = Convert.ToDouble(split[7], CultureInfo.InvariantCulture);
-
- result = new LegacySlider
- {
- ControlPoints = points,
- Distance = length,
- CurveType = curveType,
- RepeatCount = repeatCount,
- Position = new Vector2(int.Parse(split[0]), int.Parse(split[1])),
- NewCombo = combo
- };
-
- if (split.Length > 10)
- readCustomSampleBanks(split[10], ref normalSampleBank, ref addSampleBank, ref sampleVolume);
- }
- else if ((type & LegacyHitObjectType.Spinner) > 0)
- {
- result = new LegacySpinner
- {
- EndTime = Convert.ToDouble(split[5], CultureInfo.InvariantCulture)
- };
-
- if (split.Length > 6)
- readCustomSampleBanks(split[6], ref normalSampleBank, ref addSampleBank, ref sampleVolume);
- }
- else if ((type & LegacyHitObjectType.Hold) > 0)
- {
- // Note: Hold is generated by BMS converts
-
- // Todo: Apparently end time is determined by samples??
- // Shouldn't need implementation until mania
-
- result = new LegacyHold
- {
- Position = new Vector2(int.Parse(split[0]), int.Parse(split[1])),
- NewCombo = combo
- };
- }
- else
- throw new InvalidOperationException($@"Unknown hit object type {type}");
-
- result.StartTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture);
-
- var soundType = (LegacySoundType)int.Parse(split[4]);
-
- result.Samples.Add(new SampleInfo
- {
- Bank = normalSampleBank,
- Name = SampleInfo.HIT_NORMAL,
- Volume = sampleVolume
- });
-
- if ((soundType & LegacySoundType.Finish) > 0)
- {
- result.Samples.Add(new SampleInfo
- {
- Bank = addSampleBank,
- Name = SampleInfo.HIT_FINISH,
- Volume = sampleVolume
- });
- }
-
- if ((soundType & LegacySoundType.Whistle) > 0)
- {
- result.Samples.Add(new SampleInfo
- {
- Bank = addSampleBank,
- Name = SampleInfo.HIT_WHISTLE,
- Volume = sampleVolume
- });
- }
-
- if ((soundType & LegacySoundType.Clap) > 0)
- {
- result.Samples.Add(new SampleInfo
- {
- Bank = addSampleBank,
- Name = SampleInfo.HIT_CLAP,
- Volume = sampleVolume
- });
- }
-
- return result;
- }
-
- private void readCustomSampleBanks(string str, ref string normalSampleBank, ref string addSampleBank, ref int sampleVolume)
- {
- if (string.IsNullOrEmpty(str))
- return;
-
- string[] split = str.Split(':');
-
- var bank = (OsuLegacyDecoder.LegacySampleBank)Convert.ToInt32(split[0]);
- var addbank = (OsuLegacyDecoder.LegacySampleBank)Convert.ToInt32(split[1]);
-
- // Let's not implement this for now, because this doesn't fit nicely into the bank structure
- //string sampleFile = split2.Length > 4 ? split2[4] : string.Empty;
-
- string stringBank = bank.ToString().ToLower();
- if (stringBank == @"none")
- stringBank = null;
- string stringAddBank = addbank.ToString().ToLower();
- if (stringAddBank == @"none")
- stringAddBank = null;
-
- normalSampleBank = stringBank;
- addSampleBank = stringAddBank;
- sampleVolume = split.Length > 3 ? int.Parse(split[3]) : 0;
- }
-
- [Flags]
- private enum LegacySoundType
- {
- None = 0,
- Normal = 1,
- Whistle = 2,
- Finish = 4,
- Clap = 8
- }
- }
-}
diff --git a/osu.Game/Modes/PlayMode.cs b/osu.Game/Modes/PlayMode.cs
deleted file mode 100644
index fa6d94a650..0000000000
--- a/osu.Game/Modes/PlayMode.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-namespace osu.Game.Modes
-{
- public enum PlayMode
- {
- Osu = 0,
- Taiko = 1,
- Catch = 2,
- Mania = 3
- }
-}
diff --git a/osu.Game/Modes/Ruleset.cs b/osu.Game/Modes/Ruleset.cs
deleted file mode 100644
index c97420fbe3..0000000000
--- a/osu.Game/Modes/Ruleset.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Beatmaps;
-using osu.Game.Graphics;
-using osu.Game.Modes.Mods;
-using osu.Game.Modes.UI;
-using osu.Game.Screens.Play;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using osu.Game.Modes.Scoring;
-
-namespace osu.Game.Modes
-{
- public class BeatmapStatistic
- {
- public FontAwesome Icon;
- public string Content;
- public string Name;
- }
-
- public abstract class Ruleset
- {
- private static readonly ConcurrentDictionary available_rulesets = new ConcurrentDictionary();
-
- public static IEnumerable PlayModes => available_rulesets.Keys;
-
- public virtual IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { };
-
- public abstract IEnumerable GetModsFor(ModType type);
-
- public abstract HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap);
-
- public abstract DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap);
-
- public abstract ScoreProcessor CreateScoreProcessor();
-
- public static void Register(Ruleset ruleset) => available_rulesets.TryAdd(ruleset.PlayMode, ruleset.GetType());
-
- protected abstract PlayMode PlayMode { get; }
-
- public virtual FontAwesome Icon => FontAwesome.fa_question_circle;
-
- public abstract string Description { get; }
-
- public abstract IEnumerable CreateGameplayKeys();
-
- public static Ruleset GetRuleset(PlayMode mode)
- {
- Type type;
-
- if (!available_rulesets.TryGetValue(mode, out type))
- return null;
-
- return Activator.CreateInstance(type) as Ruleset;
- }
-
- }
-}
diff --git a/osu.Game/Modes/Scoring/Score.cs b/osu.Game/Modes/Scoring/Score.cs
deleted file mode 100644
index c998b11f77..0000000000
--- a/osu.Game/Modes/Scoring/Score.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using System;
-using System.Collections.Generic;
-using Newtonsoft.Json;
-using osu.Game.Database;
-using osu.Game.Modes.Mods;
-using osu.Game.Users;
-using System.IO;
-using osu.Game.Modes.Replays;
-
-namespace osu.Game.Modes.Scoring
-{
- public class Score
- {
- [JsonProperty(@"rank")]
- public ScoreRank Rank { get; set; }
-
- [JsonProperty(@"score")]
- public double TotalScore { get; set; }
- public double Accuracy { get; set; }
- public double Health { get; set; }
-
- [JsonProperty(@"maxcombo")]
- public int MaxCombo { get; set; }
- public int Combo { get; set; }
- public Mod[] Mods { get; set; }
-
- public User User { get; set; }
-
- [JsonProperty(@"replay_data")]
- public Replay Replay;
-
- public BeatmapInfo Beatmap;
-
- [JsonProperty(@"score_id")]
- public long OnlineScoreID;
-
- [JsonProperty(@"username")]
- public string Username;
-
- [JsonProperty(@"user_id")]
- public long UserID;
-
- [JsonProperty(@"date")]
- public DateTime Date;
-
- ///
- /// Creates a replay which is read from a stream.
- ///
- /// The stream reader.
- /// The replay.
- public virtual Replay CreateReplay(StreamReader reader)
- {
- var frames = new List();
-
- float lastTime = 0;
-
- foreach (var l in reader.ReadToEnd().Split(','))
- {
- var split = l.Split('|');
-
- if (split.Length < 4 || float.Parse(split[0]) < 0) continue;
-
- lastTime += float.Parse(split[0]);
-
- frames.Add(new ReplayFrame(
- lastTime,
- float.Parse(split[1]),
- 384 - float.Parse(split[2]),
- (ReplayButtonState)int.Parse(split[3])
- ));
- }
-
- return new Replay { Frames = frames };
- }
-
- // [JsonProperty(@"count50")] 0,
- //[JsonProperty(@"count100")] 0,
- //[JsonProperty(@"count300")] 100,
- //[JsonProperty(@"countmiss")] 0,
- //[JsonProperty(@"countkatu")] 0,
- //[JsonProperty(@"countgeki")] 31,
- //[JsonProperty(@"perfect")] true,
- //[JsonProperty(@"enabled_mods")] [
- // "DT",
- // "FL",
- // "HD",
- // "HR"
- //],
- //[JsonProperty(@"rank")] "XH",
- //[JsonProperty(@"pp")] 26.1816,
- //[JsonProperty(@"replay")] true
- }
-}
diff --git a/osu.Game/Modes/UI/StandardHealthDisplay.cs b/osu.Game/Modes/UI/StandardHealthDisplay.cs
deleted file mode 100644
index d49e32ea8b..0000000000
--- a/osu.Game/Modes/UI/StandardHealthDisplay.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using OpenTK;
-using OpenTK.Graphics;
-using osu.Framework.Allocation;
-using osu.Framework.Extensions.Color4Extensions;
-using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Sprites;
-using osu.Game.Graphics;
-
-namespace osu.Game.Modes.UI
-{
- public class StandardHealthDisplay : HealthDisplay
- {
- private readonly Container fill;
-
- public StandardHealthDisplay()
- {
- Children = new Drawable[]
- {
- new Box
- {
- RelativeSizeAxes = Axes.Both,
- Colour = Color4.Black,
- },
- fill = new Container
- {
- RelativeSizeAxes = Axes.Both,
- Scale = new Vector2(0, 1),
- Masking = true,
- Children = new[]
- {
- new Box
- {
- RelativeSizeAxes = Axes.Both,
- }
- }
- },
- };
- }
-
- [BackgroundDependencyLoader]
- private void load(OsuColour colours)
- {
- fill.Colour = colours.BlueLighter;
- fill.EdgeEffect = new EdgeEffect
- {
- Colour = colours.BlueDarker.Opacity(0.6f),
- Radius = 8,
- Type = EdgeEffectType.Glow
- };
- }
-
- protected override void SetHealth(float value) => fill.ScaleTo(new Vector2(value, 1), 200, EasingTypes.OutQuint);
- }
-}
diff --git a/osu.Game/Modes/UI/StandardHudOverlay.cs b/osu.Game/Modes/UI/StandardHudOverlay.cs
deleted file mode 100644
index f07e421f00..0000000000
--- a/osu.Game/Modes/UI/StandardHudOverlay.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2007-2017 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using OpenTK;
-using osu.Framework.Graphics;
-using osu.Framework.Graphics.Primitives;
-using osu.Game.Graphics.UserInterface;
-using osu.Game.Screens.Play;
-
-namespace osu.Game.Modes.UI
-{
- public class StandardHudOverlay : HudOverlay
- {
- protected override PercentageCounter CreateAccuracyCounter() => new PercentageCounter
- {
- Anchor = Anchor.TopCentre,
- Origin = Anchor.TopCentre,
- Position = new Vector2(0, 65),
- TextSize = 20,
- Margin = new MarginPadding { Right = 5 },
- };
-
- protected override ComboCounter CreateComboCounter() => new StandardComboCounter
- {
- Anchor = Anchor.BottomLeft,
- Origin = Anchor.BottomLeft,
- };
-
- protected override HealthDisplay CreateHealthDisplay() => new StandardHealthDisplay
- {
- Size = new Vector2(1, 5),
- RelativeSizeAxes = Axes.X,
- Margin = new MarginPadding { Top = 20 }
- };
-
- protected override KeyCounterCollection CreateKeyCounter() => new KeyCounterCollection
- {
- IsCounting = true,
- FadeTime = 50,
- Anchor = Anchor.BottomRight,
- Origin = Anchor.BottomRight,
- Margin = new MarginPadding(10),
- Y = - TwoLayerButton.SIZE_RETRACTED.Y,
- };
-
- protected override ScoreCounter CreateScoreCounter() => new ScoreCounter(6)
- {
- Anchor = Anchor.TopCentre,
- Origin = Anchor.TopCentre,
- TextSize = 40,
- Position = new Vector2(0, 30),
- Margin = new MarginPadding { Right = 5 },
- };
- }
-}
diff --git a/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs
new file mode 100644
index 0000000000..43e14e59de
--- /dev/null
+++ b/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs
@@ -0,0 +1,46 @@
+// Copyright (c) 2007-2017 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using Newtonsoft.Json;
+using osu.Game.Database;
+
+namespace osu.Game.Online.API.Requests
+{
+ public class GetBeatmapDetailsRequest : APIRequest