1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-19 07:42:58 +08:00

Merge branch 'master' of git://github.com/ppy/osu into caps-warning

# Conflicts:
#	osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs
This commit is contained in:
Jorolf 2017-08-22 13:29:42 +02:00
commit 2ccd6c6128
548 changed files with 16933 additions and 7511 deletions

24
.vscode/launch.json vendored
View File

@ -1,34 +1,22 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "VisualTests (debug)",
"configurations": [{
"name": "osu! (VisualTests)",
"windows": {
"type": "clr"
},
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Desktop.VisualTests/bin/Debug/osu!.exe",
"program": "${workspaceRoot}/osu.Desktop/bin/Debug/osu!.exe",
"args": [
"--tests"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Debug)",
"runtimeExecutable": null,
"env": {},
"console": "internalConsole"
},
{
"name": "VisualTests (release)",
"windows": {
"type": "clr"
},
"type": "mono",
"request": "launch",
"program": "${workspaceRoot}/osu.Desktop.VisualTests/bin/Release/osu!.exe",
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)",
"runtimeExecutable": null,
"env": {},
"console": "internalConsole"
},
{
"name": "osu! (debug)",
"windows": {

49
.vscode/tasks.json vendored
View File

@ -2,41 +2,41 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"problemMatcher": "$msCompile",
"isShellCommand": true,
"command": "msbuild",
"type": "shell",
"suppressTaskName": true,
"showOutput": "silent",
"args": [
"/property:GenerateFullPaths=true",
"/property:DebugType=portable"
"/property:DebugType=portable",
"/verbosity:minimal",
"/m" //parallel compiling support.
],
"windows": {
"args": [
"/property:GenerateFullPaths=true",
"/property:DebugType=portable",
"/m" //parallel compiling support. doesn't work well with mono atm
]
},
"tasks": [
{
"tasks": [{
"taskName": "Build (Debug)",
"isBuildCommand": true
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$msCompile"
]
},
{
"taskName": "Build (Release)",
"args": [
"/property:Configuration=Release"
],
"problemMatcher": [
"$msCompile"
]
},
{
"taskName": "Clean All",
"dependsOn": ["Clean (Debug)", "Clean (Release)"]
},
{
"taskName": "Clean (Debug)",
"args": [
"/target:Clean"
],
"problemMatcher": [
"$msCompile"
]
},
{
@ -44,6 +44,19 @@
"args": [
"/target:Clean",
"/property:Configuration=Release"
],
"problemMatcher": [
"$msCompile"
]
},
{
"taskName": "Clean All",
"dependsOn": [
"Clean (Debug)",
"Clean (Release)"
],
"problemMatcher": [
"$msCompile"
]
}
]

View File

@ -20,4 +20,4 @@ build:
verbosity: minimal
after_build:
- cmd: inspectcode /o="inspectcodereport.xml" /caches-home="inspectcode" osu.sln
- cmd: NVika parsereport "inspectcodereport.xml"
- cmd: NVika parsereport "inspectcodereport.xml" --treatwarningsaserrors

@ -1 +1 @@
Subproject commit c76d8b811b93d0c0862f342ebbab70a461006e13
Subproject commit ba70b8eaa9b79d4248873d4399f3b9e918fc3c8f

@ -1 +1 @@
Subproject commit 9f46a456dc3a56dcbff09671a3f588b16a464106
Subproject commit f6042e1cb37cfad6c879d0e1245f7880c7fcd5f5

View File

@ -31,6 +31,10 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="SharpCompress" publicKeyToken="afb0a02973931d96" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-0.17.1.0" newVersion="0.17.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -17,8 +17,8 @@ namespace osu.Desktop.Deploy
{
internal static class Program
{
private const string nuget_path = @"packages\NuGet.CommandLine.3.5.0\tools\NuGet.exe";
private const string squirrel_path = @"packages\squirrel.windows.1.5.2\tools\Squirrel.exe";
private const string nuget_path = @"packages\NuGet.CommandLine.4.1.0\tools\NuGet.exe";
private const string squirrel_path = @"packages\squirrel.windows.1.7.5\tools\Squirrel.exe";
private const string msbuild_path = @"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe";
public static string StagingFolder = ConfigurationManager.AppSettings["StagingFolder"];

View File

@ -49,10 +49,6 @@
<HintPath>$(SolutionDir)\packages\DeltaCompressionDotNet.1.1.0\lib\net20\DeltaCompressionDotNet.PatchApi.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\ICSharpCode.SharpZipLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Mono.Cecil, Version=0.9.6.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Mono.Cecil.0.9.6.4\lib\net45\Mono.Cecil.dll</HintPath>
<Private>True</Private>
@ -73,15 +69,19 @@
<HintPath>$(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NuGet.Squirrel, Version=3.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\NuGet.Squirrel.dll</HintPath>
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.7.5\lib\Net45\NuGet.Squirrel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SharpCompress, Version=0.17.1.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\SharpCompress.0.17.1\lib\net45\SharpCompress.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Splat, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Splat.2.0.0\lib\Net45\Splat.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Squirrel, Version=1.5.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\Squirrel.dll</HintPath>
<Reference Include="Squirrel, Version=1.7.5.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.7.5\lib\Net45\Squirrel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />

View File

@ -7,7 +7,8 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
<package id="DeltaCompressionDotNet" version="1.1.0" targetFramework="net452" />
<package id="Mono.Cecil" version="0.9.6.4" targetFramework="net452" />
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net452" />
<package id="NuGet.CommandLine" version="3.5.0" targetFramework="net452" developmentDependency="true" />
<package id="NuGet.CommandLine" version="4.1.0" targetFramework="net452" developmentDependency="true" />
<package id="SharpCompress" version="0.17.1" targetFramework="net452" />
<package id="Splat" version="2.0.0" targetFramework="net452" />
<package id="squirrel.windows" version="1.5.2" targetFramework="net452" />
<package id="squirrel.windows" version="1.7.5" targetFramework="net452" />
</packages>

View File

@ -5,7 +5,7 @@ using osu.Framework.Audio.Track;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps;
namespace osu.Desktop.VisualTests.Beatmaps
namespace osu.Desktop.Tests.Beatmaps
{
public class TestWorkingBeatmap : WorkingBeatmap
{

View File

@ -8,7 +8,7 @@ using SQLite.Net.Interop;
using SQLite.Net.Platform.Generic;
using SQLite.Net.Platform.Win32;
namespace osu.Desktop.VisualTests.Platform
namespace osu.Desktop.Tests.Platform
{
public class TestStorage : DesktopStorage
{

View File

@ -0,0 +1,37 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using NUnit.Framework;
using osu.Framework.Desktop.Platform;
using osu.Framework.Testing;
using osu.Game;
namespace osu.Desktop.Tests.Visual
{
[TestFixture]
public abstract class OsuTestCase : TestCase
{
[Test]
public override void RunTest()
{
using (var host = new HeadlessGameHost())
host.Run(new OsuTestCaseTestRunner(this));
}
public class OsuTestCaseTestRunner : OsuGameBase
{
private readonly OsuTestCase testCase;
public OsuTestCaseTestRunner(OsuTestCase testCase)
{
this.testCase = testCase;
}
protected override void LoadComplete()
{
base.LoadComplete();
Add(new TestCaseTestRunner.TestRunner(testCase));
}
}
}
}

View File

@ -0,0 +1,205 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Lists;
using osu.Framework.Timing;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
using OpenTK.Graphics;
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseBeatSyncedContainer : OsuTestCase
{
public override string Description => @"Tests beat synced containers.";
private readonly MusicController mc;
public TestCaseBeatSyncedContainer()
{
Clock = new FramedClock();
Clock.ProcessFrame();
Add(new BeatContainer
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
});
Add(mc = new MusicController
{
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,
});
}
protected override void LoadComplete()
{
base.LoadComplete();
mc.ToggleVisibility();
}
private class BeatContainer : BeatSyncedContainer
{
private const int flash_layer_heigth = 150;
private readonly InfoString timingPointCount;
private readonly InfoString currentTimingPoint;
private readonly InfoString beatCount;
private readonly InfoString currentBeat;
private readonly InfoString beatsPerMinute;
private readonly InfoString adjustedBeatLength;
private readonly InfoString timeUntilNextBeat;
private readonly InfoString timeSinceLastBeat;
private readonly Box flashLayer;
public BeatContainer()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Children = new Drawable[]
{
new Container
{
Name = @"Info Layer",
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding { Bottom = flash_layer_heigth },
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black.Opacity(150),
},
new FillFlowContainer
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
timingPointCount = new InfoString(@"Timing points amount"),
currentTimingPoint = new InfoString(@"Current timing point"),
beatCount = new InfoString(@"Beats amount (in the current timing point)"),
currentBeat = new InfoString(@"Current beat"),
beatsPerMinute = new InfoString(@"BPM"),
adjustedBeatLength = new InfoString(@"Adjusted beat length"),
timeUntilNextBeat = new InfoString(@"Time until next beat"),
timeSinceLastBeat = new InfoString(@"Time since last beat"),
}
}
}
},
new Container
{
Name = @"Color indicator",
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
RelativeSizeAxes = Axes.X,
Height = flash_layer_heigth,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
flashLayer = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.White,
Alpha = 0,
}
}
}
};
Beatmap.ValueChanged += delegate
{
timingPointCount.Value = 0;
currentTimingPoint.Value = 0;
beatCount.Value = 0;
currentBeat.Value = 0;
beatsPerMinute.Value = 0;
adjustedBeatLength.Value = 0;
timeUntilNextBeat.Value = 0;
timeSinceLastBeat.Value = 0;
};
}
private SortedList<TimingControlPoint> timingPoints => Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints;
private TimingControlPoint getNextTimingPoint(TimingControlPoint current)
{
if (timingPoints[timingPoints.Count - 1] == current)
return current;
return timingPoints[timingPoints.IndexOf(current) + 1];
}
private int calculateBeatCount(TimingControlPoint current)
{
if (timingPoints.Count == 0) return 0;
if (timingPoints[timingPoints.Count - 1] == current)
return (int)Math.Ceiling((Beatmap.Value.Track.Length - current.Time) / current.BeatLength);
return (int)Math.Ceiling((getNextTimingPoint(current).Time - current.Time) / current.BeatLength);
}
protected override void Update()
{
base.Update();
timeUntilNextBeat.Value = TimeUntilNextBeat;
timeSinceLastBeat.Value = TimeSinceLastBeat;
}
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes)
{
base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes);
timingPointCount.Value = timingPoints.Count;
currentTimingPoint.Value = timingPoints.IndexOf(timingPoint);
beatCount.Value = calculateBeatCount(timingPoint);
currentBeat.Value = beatIndex;
beatsPerMinute.Value = 60000 / timingPoint.BeatLength;
adjustedBeatLength.Value = timingPoint.BeatLength;
flashLayer.FadeOutFromOne(timingPoint.BeatLength);
}
}
private class InfoString : FillFlowContainer
{
private const int text_size = 20;
private const int margin = 7;
private readonly OsuSpriteText valueText;
public double Value
{
set { valueText.Text = $"{value:G}"; }
}
public InfoString(string header)
{
AutoSizeAxes = Axes.Both;
Direction = FillDirection.Horizontal;
Add(new OsuSpriteText { Text = header + @": ", TextSize = text_size });
Add(valueText = new OsuSpriteText { TextSize = text_size });
Margin = new MarginPadding(margin);
}
}
}
}

View File

@ -1,21 +1,20 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Screens.Select;
using OpenTK;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseBeatmapDetailArea : TestCase
[TestFixture]
internal class TestCaseBeatmapDetailArea : OsuTestCase
{
public override string Description => @"Beatmap details in song select";
public override void Reset()
public TestCaseBeatmapDetailArea()
{
base.Reset();
Add(new BeatmapDetailArea
{
Anchor = Anchor.Centre,

View File

@ -1,24 +1,21 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Database;
using osu.Game.Screens.Select;
using System.Linq;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Screens.Select;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseBeatmapDetails : TestCase
internal class TestCaseBeatmapDetails : OsuTestCase
{
public override string Description => "BeatmapDetails tab of BeatmapDetailArea";
private BeatmapDetails details;
private readonly BeatmapDetails details;
public override void Reset()
public TestCaseBeatmapDetails()
{
base.Reset();
Add(details = new BeatmapDetails
{
RelativeSizeAxes = Axes.Both,
@ -41,7 +38,7 @@ namespace osu.Desktop.VisualTests.Tests
StarDifficulty = 5.3f,
Metrics = new BeatmapMetrics
{
Ratings = Enumerable.Range(0,10),
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),
},

View File

@ -1,22 +1,19 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Graphics;
using OpenTK.Input;
using osu.Framework.Testing;
using osu.Game.Graphics;
using osu.Game.Screens.Select.Options;
using OpenTK.Graphics;
using OpenTK.Input;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseBeatmapOptionsOverlay : TestCase
internal class TestCaseBeatmapOptionsOverlay : OsuTestCase
{
public override string Description => @"Beatmap options in song select";
public override void Reset()
public TestCaseBeatmapOptionsOverlay()
{
base.Reset();
var overlay = new BeatmapOptionsOverlay();
overlay.AddButton(@"Remove", @"from unplayed", FontAwesome.fa_times_circle_o, Color4.Purple, null, Key.Number1);

View File

@ -1,20 +1,17 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Framework.Graphics;
using osu.Game.Graphics.UserInterface;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseBreadcrumbs : TestCase
internal class TestCaseBreadcrumbs : OsuTestCase
{
public override string Description => @"breadcrumb > control";
public override void Reset()
public TestCaseBreadcrumbs()
{
base.Reset();
BreadcrumbControl<BreadcrumbTab> c;
Add(c = new BreadcrumbControl<BreadcrumbTab>
{

View File

@ -0,0 +1,35 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Catch.UI;
using OpenTK;
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseCatcher : OsuTestCase
{
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
Children = new Drawable[]
{
new CatchInputManager(rulesets.GetRuleset(2))
{
RelativeSizeAxes = Axes.Both,
Child = new CatcherArea
{
RelativePositionAxes = Axes.Both,
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Size = new Vector2(1, 0.2f),
}
},
};
}
}
}

View File

@ -1,20 +1,17 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Testing;
using osu.Framework.Graphics.Containers;
using osu.Game.Overlays;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseChatDisplay : TestCase
internal class TestCaseChatDisplay : OsuTestCase
{
public override string Description => @"Testing chat api and overlay";
public override void Reset()
public TestCaseChatDisplay()
{
base.Reset();
Add(new ChatOverlay
{
State = Visibility.Visible

View File

@ -0,0 +1,97 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.UserInterface;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseContextMenu : OsuTestCase
{
public override string Description => @"Menu visible on right click";
private const int start_time = 0;
private const int duration = 1000;
private readonly Container container;
public TestCaseContextMenu()
{
Add(container = new MyContextMenuContainer
{
Size = new Vector2(200),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Green,
}
}
});
Add(new AnotherContextMenuContainer
{
Size = new Vector2(200),
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = Color4.Red,
}
}
});
}
protected override void LoadComplete()
{
base.LoadComplete();
// Move box along a square trajectory
container.Loop(c => c
.MoveTo(new Vector2(0, 100), duration).Then()
.MoveTo(new Vector2(100, 100), duration).Then()
.MoveTo(new Vector2(100, 0), duration).Then()
.MoveTo(Vector2.Zero, duration)
);
}
private class MyContextMenuContainer : Container, IHasContextMenu
{
public ContextMenuItem[] ContextMenuItems => new ContextMenuItem[]
{
new OsuContextMenuItem(@"Some option"),
new OsuContextMenuItem(@"Highlighted option", MenuItemType.Highlighted),
new OsuContextMenuItem(@"Another option"),
new OsuContextMenuItem(@"Choose me please"),
new OsuContextMenuItem(@"And me too"),
new OsuContextMenuItem(@"Trying to fill"),
new OsuContextMenuItem(@"Destructive option", MenuItemType.Destructive),
};
}
private class AnotherContextMenuContainer : Container, IHasContextMenu
{
public ContextMenuItem[] ContextMenuItems => new ContextMenuItem[]
{
new OsuContextMenuItem(@"Simple option"),
new OsuContextMenuItem(@"Simple very very long option"),
new OsuContextMenuItem(@"Change width", MenuItemType.Highlighted) { Action = () => this.ResizeWidthTo(Width * 2, 100, Easing.OutQuint) },
new OsuContextMenuItem(@"Change height", MenuItemType.Highlighted) { Action = () => this.ResizeHeightTo(Height * 2, 100, Easing.OutQuint) },
new OsuContextMenuItem(@"Change width back", MenuItemType.Destructive) { Action = () => this.ResizeWidthTo(Width / 2, 100, Easing.OutQuint) },
new OsuContextMenuItem(@"Change height back", MenuItemType.Destructive) { Action = () => this.ResizeHeightTo(Height / 2, 100, Easing.OutQuint) },
};
}
}
}

View File

@ -1,22 +1,19 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Testing;
using osu.Game.Graphics;
using osu.Game.Overlays;
using osu.Game.Overlays.Dialog;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseDialogOverlay : TestCase
internal class TestCaseDialogOverlay : OsuTestCase
{
public override string Description => @"Display dialogs";
private DialogOverlay overlay;
public override void Reset()
public TestCaseDialogOverlay()
{
base.Reset();
DialogOverlay overlay;
Add(overlay = new DialogOverlay());

View File

@ -3,22 +3,22 @@
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Testing;
using osu.Game.Database;
using osu.Game.Beatmaps;
using osu.Game.Overlays;
using osu.Game.Rulesets;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
public class TestCaseDirect : TestCase
public class TestCaseDirect : OsuTestCase
{
public override string Description => @"osu!direct overlay";
private DirectOverlay direct;
private RulesetDatabase rulesets;
private RulesetStore rulesets;
public override void Reset()
protected override void LoadComplete()
{
base.Reset();
base.LoadComplete();
Add(direct = new DirectOverlay());
newBeatmaps();
@ -28,7 +28,7 @@ namespace osu.Desktop.VisualTests.Tests
}
[BackgroundDependencyLoader]
private void load(RulesetDatabase rulesets)
private void load(RulesetStore rulesets)
{
this.rulesets = rulesets;
}
@ -48,6 +48,17 @@ namespace osu.Desktop.VisualTests.Tests
Author = @"RLC",
Source = @"",
},
OnlineInfo = new BeatmapSetOnlineInfo
{
Covers = new BeatmapSetOnlineCovers
{
Card = @"https://assets.ppy.sh/beatmaps/578332/covers/card.jpg?1494591390",
Cover = @"https://assets.ppy.sh/beatmaps/578332/covers/cover.jpg?1494591390",
},
Preview = @"https://b.ppy.sh/preview/578332.mp3",
PlayCount = 97,
FavouriteCount = 72,
},
Beatmaps = new List<BeatmapInfo>
{
new BeatmapInfo
@ -55,13 +66,6 @@ namespace osu.Desktop.VisualTests.Tests
Ruleset = ruleset,
StarDifficulty = 5.35f,
Metadata = new BeatmapMetadata(),
OnlineInfo = new BeatmapOnlineInfo
{
Covers = new[] { @"https://assets.ppy.sh//beatmaps/578332/covers/cover.jpg?1494591390" },
Preview = @"https://b.ppy.sh/preview/578332.mp3",
PlayCount = 97,
FavouriteCount = 72,
},
},
},
},
@ -74,6 +78,17 @@ namespace osu.Desktop.VisualTests.Tests
Author = @"Sotarks",
Source = @"ぎんぎつね",
},
OnlineInfo = new BeatmapSetOnlineInfo
{
Covers = new BeatmapSetOnlineCovers
{
Card = @"https://assets.ppy.sh/beatmaps/599627/covers/card.jpg?1494539318",
Cover = @"https://assets.ppy.sh/beatmaps/599627/covers/cover.jpg?1494539318",
},
Preview = @"https//b.ppy.sh/preview/599627.mp3",
PlayCount = 3082,
FavouriteCount = 14,
},
Beatmaps = new List<BeatmapInfo>
{
new BeatmapInfo
@ -81,13 +96,6 @@ namespace osu.Desktop.VisualTests.Tests
Ruleset = ruleset,
StarDifficulty = 5.81f,
Metadata = new BeatmapMetadata(),
OnlineInfo = new BeatmapOnlineInfo
{
Covers = new[] { @"https://assets.ppy.sh//beatmaps/599627/covers/cover.jpg?1494539318" },
Preview = @"https//b.ppy.sh/preview/599627.mp3",
PlayCount = 3082,
FavouriteCount = 14,
},
},
},
},
@ -100,6 +108,17 @@ namespace osu.Desktop.VisualTests.Tests
Author = @"Cerulean Veyron",
Source = @"",
},
OnlineInfo = new BeatmapSetOnlineInfo
{
Covers = new BeatmapSetOnlineCovers
{
Card = @"https://assets.ppy.sh/beatmaps/513268/covers/card.jpg?1494502863",
Cover = @"https://assets.ppy.sh/beatmaps/513268/covers/cover.jpg?1494502863",
},
Preview = @"https//b.ppy.sh/preview/513268.mp3",
PlayCount = 2762,
FavouriteCount = 15,
},
Beatmaps = new List<BeatmapInfo>
{
new BeatmapInfo
@ -107,13 +126,6 @@ namespace osu.Desktop.VisualTests.Tests
Ruleset = ruleset,
StarDifficulty = 0.9f,
Metadata = new BeatmapMetadata(),
OnlineInfo = new BeatmapOnlineInfo
{
Covers = new[] { @"https://assets.ppy.sh//beatmaps/513268/covers/cover.jpg?1494502863" },
Preview = @"https//b.ppy.sh/preview/513268.mp3",
PlayCount = 2762,
FavouriteCount = 15,
},
},
new BeatmapInfo
{
@ -141,6 +153,17 @@ namespace osu.Desktop.VisualTests.Tests
Author = @"[Kamiya]",
Source = @"小林さんちのメイドラゴン",
},
OnlineInfo = new BeatmapSetOnlineInfo
{
Covers = new BeatmapSetOnlineCovers
{
Card = @"https://assets.ppy.sh/beatmaps/586841/covers/card.jpg?1494052741",
Cover = @"https://assets.ppy.sh/beatmaps/586841/covers/cover.jpg?1494052741",
},
Preview = @"https//b.ppy.sh/preview/586841.mp3",
PlayCount = 62317,
FavouriteCount = 161,
},
Beatmaps = new List<BeatmapInfo>
{
new BeatmapInfo
@ -148,13 +171,6 @@ namespace osu.Desktop.VisualTests.Tests
Ruleset = ruleset,
StarDifficulty = 1.26f,
Metadata = new BeatmapMetadata(),
OnlineInfo = new BeatmapOnlineInfo
{
Covers = new[] { @"https://assets.ppy.sh//beatmaps/586841/covers/cover.jpg?1494052741" },
Preview = @"https//b.ppy.sh/preview/586841.mp3",
PlayCount = 62317,
FavouriteCount = 161,
},
},
new BeatmapInfo
{

View File

@ -0,0 +1,132 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Online.Multiplayer;
using osu.Game.Rulesets;
using osu.Game.Screens.Multiplayer;
using osu.Game.Users;
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseDrawableRoom : OsuTestCase
{
public override string Description => @"Select your favourite room";
private RulesetStore rulesets;
protected override void LoadComplete()
{
base.LoadComplete();
DrawableRoom first;
Add(new FillFlowContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
AutoSizeAxes = Axes.Y,
Width = 580f,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
first = new DrawableRoom(new Room
{
Name = { Value = @"Great Room Right Here" },
Host = { Value = new User { Username = @"Naeferith", Id = 9492835, Country = new Country { FlagName = @"FR" } } },
Status = { Value = new RoomStatusOpen() },
Type = { Value = new GameTypeTeamVersus() },
Beatmap =
{
Value = new BeatmapInfo
{
StarDifficulty = 4.65,
Ruleset = rulesets.GetRuleset(3),
Metadata = new BeatmapMetadata
{
Title = @"Critical Crystal",
Artist = @"Seiryu",
},
BeatmapSet = new BeatmapSetInfo
{
OnlineInfo = new BeatmapSetOnlineInfo
{
Covers = new BeatmapSetOnlineCovers
{
Cover = @"https://assets.ppy.sh//beatmaps/376340/covers/cover.jpg?1456478455",
},
},
},
},
},
Participants =
{
Value = new[]
{
new User { GlobalRank = 1355 },
new User { GlobalRank = 8756 },
},
},
}),
new DrawableRoom(new Room
{
Name = { Value = @"Relax It's The Weekend" },
Host = { Value = new User { Username = @"peppy", Id = 2, Country = new Country { FlagName = @"AU" } } },
Status = { Value = new RoomStatusPlaying() },
Type = { Value = new GameTypeTagTeam() },
Beatmap =
{
Value = new BeatmapInfo
{
StarDifficulty = 1.96,
Ruleset = rulesets.GetRuleset(0),
Metadata = new BeatmapMetadata
{
Title = @"Serendipity",
Artist = @"ZAQ",
},
BeatmapSet = new BeatmapSetInfo
{
OnlineInfo = new BeatmapSetOnlineInfo
{
Covers = new BeatmapSetOnlineCovers
{
Cover = @"https://assets.ppy.sh//beatmaps/526839/covers/cover.jpg?1493815706",
},
},
},
},
},
Participants =
{
Value = new[]
{
new User { GlobalRank = 578975 },
new User { GlobalRank = 24554 },
},
},
}),
}
});
AddStep(@"change title", () => first.Room.Name.Value = @"I Changed Name");
AddStep(@"change host", () => first.Room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } });
AddStep(@"change status", () => first.Room.Status.Value = new RoomStatusPlaying());
AddStep(@"change type", () => first.Room.Type.Value = new GameTypeVersus());
AddStep(@"change beatmap", () => first.Room.Beatmap.Value = null);
AddStep(@"change participants", () => first.Room.Participants.Value = new[]
{
new User { GlobalRank = 1254 },
new User { GlobalRank = 123189 },
});
}
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
this.rulesets = rulesets;
}
}
}

View File

@ -2,20 +2,17 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Framework.Testing;
using osu.Game.Screens.Tournament;
using osu.Game.Screens.Tournament.Teams;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseDrawings : TestCase
internal class TestCaseDrawings : OsuTestCase
{
public override string Description => "Tournament drawings";
public override void Reset()
public TestCaseDrawings()
{
base.Reset();
Add(new Drawings
{
TeamList = new TestTeamList(),

View File

@ -1,42 +1,45 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using System.Collections.Generic;
using osu.Desktop.Tests.Beatmaps;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using osu.Framework.Testing;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Catch;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Rulesets.Taiko;
using osu.Game.Rulesets.Taiko.UI;
using System.Collections.Generic;
using osu.Desktop.VisualTests.Beatmaps;
using osu.Framework.Allocation;
using osu.Game.Beatmaps.ControlPoints;
using OpenTK;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseGamefield : TestCase
internal class TestCaseGamefield : OsuTestCase
{
private RulesetDatabase rulesets;
private RulesetStore rulesets;
public override string Description => @"Showing hitobjects and what not.";
[BackgroundDependencyLoader]
private void load(RulesetDatabase rulesets)
private void load(RulesetStore rulesets)
{
this.rulesets = rulesets;
}
public override void Reset()
protected override void LoadComplete()
{
base.Reset();
base.LoadComplete();
List<HitObject> objects = new List<HitObject>();
@ -76,7 +79,7 @@ namespace osu.Desktop.VisualTests.Tests
ControlPointInfo = controlPointInfo
});
Add(new Drawable[]
AddRange(new Drawable[]
{
new Container
{
@ -85,25 +88,25 @@ namespace osu.Desktop.VisualTests.Tests
Clock = new FramedClock(),
Children = new Drawable[]
{
new OsuHitRenderer(beatmap, false)
new OsuRulesetContainer(new OsuRuleset(new RulesetInfo()), beatmap, false)
{
Scale = new Vector2(0.5f),
Anchor = Anchor.TopLeft,
Origin = Anchor.TopLeft
},
new TaikoHitRenderer(beatmap, false)
new TaikoRulesetContainer(new TaikoRuleset(new RulesetInfo()),beatmap, false)
{
Scale = new Vector2(0.5f),
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight
},
new CatchHitRenderer(beatmap, false)
new CatchRulesetContainer(new CatchRuleset(new RulesetInfo()),beatmap, false)
{
Scale = new Vector2(0.5f),
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft
},
new ManiaHitRenderer(beatmap, false)
new ManiaRulesetContainer(new ManiaRuleset(new RulesetInfo()),beatmap, false)
{
Scale = new Vector2(0.5f),
Anchor = Anchor.BottomRight,

View File

@ -1,23 +1,20 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using System.Linq;
using osu.Framework.Graphics;
using osu.Game.Graphics.UserInterface;
using OpenTK;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseGraph : TestCase
internal class TestCaseGraph : OsuTestCase
{
public override string Description => "graph";
private BarGraph graph;
public override void Reset()
public TestCaseGraph()
{
base.Reset();
BarGraph graph;
Children = new[]
{
@ -30,7 +27,7 @@ namespace osu.Desktop.VisualTests.Tests
},
};
AddStep("values from 1-10", () => graph.Values = Enumerable.Range(1,10).Select(i => (float)i));
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);

View File

@ -1,43 +1,62 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Configuration;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Testing;
using osu.Framework.Timing;
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;
using OpenTK;
using osu.Game.Rulesets.Osu;
using osu.Framework.Allocation;
using osu.Game.Rulesets;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseHitObjects : TestCase
internal class TestCaseHitObjects : OsuTestCase
{
private readonly FramedClock framedClock;
private FramedClock framedClock;
private bool auto;
public TestCaseHitObjects()
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
var rateAdjustClock = new StopwatchClock(true);
framedClock = new FramedClock(rateAdjustClock);
playbackSpeed.ValueChanged += delegate { rateAdjustClock.Rate = playbackSpeed.Value; };
AddStep(@"circles", () => loadHitobjects(HitObjectType.Circle));
AddStep(@"slider", () => loadHitobjects(HitObjectType.Slider));
AddStep(@"spinner", () => loadHitobjects(HitObjectType.Spinner));
AddToggleStep("Auto", state => { auto = state; loadHitobjects(mode); });
AddSliderStep("Playback speed", 0.0, 2.0, 0.5, v => rateAdjustClock.Rate = v);
framedClock.ProcessFrame();
var clockAdjustContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Clock = framedClock,
Children = new[]
{
playfieldContainer = new OsuInputManager(rulesets.GetRuleset(0)) { RelativeSizeAxes = Axes.Both },
approachContainer = new Container { RelativeSizeAxes = Axes.Both }
}
};
Add(clockAdjustContainer);
}
private HitObjectType mode = HitObjectType.Slider;
private readonly BindableNumber<double> playbackSpeed = new BindableDouble(0.5) { MinValue = 0, MaxValue = 1 };
private Container playfieldContainer;
private Container approachContainer;
private void load(HitObjectType mode)
private void loadHitobjects(HitObjectType mode)
{
this.mode = mode;
@ -83,54 +102,6 @@ namespace osu.Desktop.VisualTests.Tests
}
}
public override void Reset()
{
base.Reset();
playbackSpeed.TriggerChange();
AddStep(@"circles", () => load(HitObjectType.Circle));
AddStep(@"slider", () => load(HitObjectType.Slider));
AddStep(@"spinner", () => load(HitObjectType.Spinner));
AddToggleStep(@"auto", state => { auto = state; load(mode); });
BasicSliderBar<double> sliderBar;
Add(new Container
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new SpriteText { Text = "Playback Speed" },
sliderBar = new BasicSliderBar<double>
{
Width = 150,
Height = 10,
SelectionColor = Color4.Orange,
}
}
});
sliderBar.Current.BindTo(playbackSpeed);
framedClock.ProcessFrame();
var clockAdjustContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Clock = framedClock,
Children = new[]
{
playfieldContainer = new Container { RelativeSizeAxes = Axes.Both },
approachContainer = new Container { RelativeSizeAxes = Axes.Both }
}
};
Add(clockAdjustContainer);
}
private int depth;
private void add(DrawableOsuHitObject h)

View File

@ -0,0 +1,25 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Overlays;
namespace osu.Desktop.Tests.Visual
{
public class TestCaseKeyConfiguration : OsuTestCase
{
private readonly KeyBindingOverlay overlay;
public override string Description => @"Key configuration";
public TestCaseKeyConfiguration()
{
Child = overlay = new KeyBindingOverlay();
}
protected override void LoadComplete()
{
base.LoadComplete();
overlay.Show();
}
}
}

View File

@ -0,0 +1,41 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Framework.MathUtils;
using osu.Game.Screens.Play;
using OpenTK.Input;
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseKeyCounter : OsuTestCase
{
public override string Description => @"Tests key counter";
public TestCaseKeyCounter()
{
KeyCounterCollection kc = new KeyCounterCollection
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
IsCounting = true,
Children = new KeyCounter[]
{
new KeyCounterKeyboard(Key.Z),
new KeyCounterKeyboard(Key.X),
new KeyCounterMouse(MouseButton.Left),
new KeyCounterMouse(MouseButton.Right),
},
};
AddStep("Add random", () =>
{
Key key = (Key)((int)Key.A + RNG.Next(26));
kc.Add(new KeyCounterKeyboard(key));
});
AddSliderStep("Fade time", 0, 200, 50, v => kc.FadeTime = v);
Add(kc);
}
}
}

View File

@ -1,22 +1,21 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Testing;
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;
using OpenTK;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseLeaderboard : TestCase
internal class TestCaseLeaderboard : OsuTestCase
{
public override string Description => @"From song select";
private Leaderboard leaderboard;
private readonly Leaderboard leaderboard;
private void newScores()
{
@ -207,10 +206,8 @@ namespace osu.Desktop.VisualTests.Tests
leaderboard.Scores = scores;
}
public override void Reset()
public TestCaseLeaderboard()
{
base.Reset();
Add(leaderboard = new Leaderboard
{
Origin = Anchor.Centre,

View File

@ -3,20 +3,17 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using OpenTK.Graphics;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseManiaHitObjects : TestCase
internal class TestCaseManiaHitObjects : OsuTestCase
{
public override void Reset()
public TestCaseManiaHitObjects()
{
base.Reset();
Add(new FillFlowContainer
{
Anchor = Anchor.Centre,
@ -40,7 +37,7 @@ namespace osu.Desktop.VisualTests.Tests
{
Name = "Timing section",
RelativeSizeAxes = Axes.Both,
RelativeCoordinateSpace = new Vector2(1, 10000),
RelativeChildSize = new Vector2(1, 10000),
Children = new[]
{
new DrawableNote(new Note { StartTime = 5000 }) { AccentColour = Color4.Red },
@ -62,7 +59,7 @@ namespace osu.Desktop.VisualTests.Tests
{
Name = "Timing section",
RelativeSizeAxes = Axes.Both,
RelativeCoordinateSpace = new Vector2(1, 10000),
RelativeChildSize = new Vector2(1, 10000),
Children = new[]
{
new DrawableHoldNote(new HoldNote

View File

@ -1,36 +1,35 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Input;
using osu.Framework.Testing;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.UI;
using System;
using System.Collections.Generic;
using OpenTK;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Timing;
using System.Linq;
using osu.Framework.Configuration;
using OpenTK.Input;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Timing;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.Timing;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Timing;
using OpenTK;
using OpenTK.Input;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseManiaPlayfield : TestCase
internal class TestCaseManiaPlayfield : OsuTestCase
{
public override string Description => @"Mania playfield";
protected override double TimePerAction => 200;
public override void Reset()
public TestCaseManiaPlayfield()
{
base.Reset();
Action<int, SpecialColumnPosition> createPlayfield = (cols, pos) =>
{
Clear();
Add(new ManiaPlayfield(cols, new List<TimingChange>())
Add(new ManiaPlayfield(cols)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@ -39,37 +38,22 @@ namespace osu.Desktop.VisualTests.Tests
});
};
Action<int, SpecialColumnPosition> createPlayfieldWithNotes = (cols, pos) =>
const double start_time = 500;
const double duration = 500;
Func<double, bool, SpeedAdjustmentContainer> createTimingChange = (time, gravity) => new ManiaSpeedAdjustmentContainer(new MultiplierControlPoint(time)
{
TimingPoint = { BeatLength = 1000 }
}, gravity ? ScrollingAlgorithm.Gravity : ScrollingAlgorithm.Basic);
Action<bool> createPlayfieldWithNotes = gravity =>
{
Clear();
ManiaPlayfield playField;
Add(playField = new ManiaPlayfield(cols, new List<TimingChange> { new TimingChange { BeatLength = 200 } })
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
SpecialColumnPosition = pos,
Scale = new Vector2(1, -1)
});
for (int i = 0; i < cols; i++)
{
playField.Add(new DrawableNote(new Note
{
StartTime = Time.Current + 1000,
Column = i
}));
}
};
Action createPlayfieldWithNotesAcceptingInput = () =>
{
Clear();
var rateAdjustClock = new StopwatchClock(true) { Rate = 0.5 };
var rateAdjustClock = new StopwatchClock(true) { Rate = 1 };
ManiaPlayfield playField;
Add(playField = new ManiaPlayfield(4, new List<TimingChange> { new TimingChange { BeatLength = 200 } })
Add(playField = new ManiaPlayfield(4)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@ -77,14 +61,23 @@ namespace osu.Desktop.VisualTests.Tests
Clock = new FramedClock(rateAdjustClock)
});
for (int t = 1000; t <= 2000; t += 100)
if (!gravity)
playField.Columns.ForEach(c => c.Add(createTimingChange(0, false)));
for (double t = start_time; t <= start_time + duration; t += 100)
{
if (gravity)
playField.Columns.ElementAt(0).Add(createTimingChange(t, true));
playField.Add(new DrawableNote(new Note
{
StartTime = t,
Column = 0
}, new Bindable<Key>(Key.D)));
if (gravity)
playField.Columns.ElementAt(3).Add(createTimingChange(t, true));
playField.Add(new DrawableNote(new Note
{
StartTime = t,
@ -92,17 +85,23 @@ namespace osu.Desktop.VisualTests.Tests
}, new Bindable<Key>(Key.K)));
}
playField.Add(new DrawableHoldNote(new HoldNote
{
StartTime = 1000,
Duration = 1000,
Column = 1
}, new Bindable<Key>(Key.F)));
if (gravity)
playField.Columns.ElementAt(1).Add(createTimingChange(start_time, true));
playField.Add(new DrawableHoldNote(new HoldNote
{
StartTime = 1000,
Duration = 1000,
StartTime = start_time,
Duration = duration,
Column = 1
}, new Bindable<Key>(Key.F)));
if (gravity)
playField.Columns.ElementAt(2).Add(createTimingChange(start_time, true));
playField.Add(new DrawableHoldNote(new HoldNote
{
StartTime = start_time,
Duration = duration,
Column = 2
}, new Bindable<Key>(Key.J)));
};
@ -116,16 +115,11 @@ namespace osu.Desktop.VisualTests.Tests
AddStep("Left special style", () => createPlayfield(8, SpecialColumnPosition.Left));
AddStep("Right special style", () => createPlayfield(8, SpecialColumnPosition.Right));
AddStep("Normal special style", () => createPlayfield(4, SpecialColumnPosition.Normal));
AddStep("Notes with input", () => createPlayfieldWithNotes(false));
AddWaitStep((int)Math.Ceiling((start_time + duration) / TimePerAction));
AddStep("Notes", () => createPlayfieldWithNotes(4, SpecialColumnPosition.Normal));
AddWaitStep(10);
AddStep("Left special style", () => createPlayfieldWithNotes(4, SpecialColumnPosition.Left));
AddWaitStep(10);
AddStep("Right special style", () => createPlayfieldWithNotes(4, SpecialColumnPosition.Right));
AddWaitStep(10);
AddStep("Notes with input", () => createPlayfieldWithNotesAcceptingInput());
AddStep("Notes with gravity", () => createPlayfieldWithNotes(true));
AddWaitStep((int)Math.Ceiling((start_time + duration) / TimePerAction));
}
private void triggerKeyDown(Column column)

View File

@ -0,0 +1,26 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Overlays;
using osu.Game.Users;
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseMedalOverlay : OsuTestCase
{
public override string Description => @"medal get!";
public TestCaseMedalOverlay()
{
AddStep(@"display", () =>
{
LoadComponentAsync(new MedalOverlay(new Medal
{
Name = @"Animations",
InternalName = @"all-intro-doubletime",
Description = @"More complex than you think.",
}), Add);
});
}
}
}

View File

@ -1,25 +1,22 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Testing;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Shapes;
using osu.Game.Screens.Menu;
using OpenTK.Graphics;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseMenuButtonSystem : TestCase
internal class TestCaseMenuButtonSystem : OsuTestCase
{
public override string Description => @"Main menu button system";
public override void Reset()
public TestCaseMenuButtonSystem()
{
base.Reset();
Add(new Box
{
ColourInfo = ColourInfo.GradientVertical(Color4.Gray, Color4.WhiteSmoke),
Colour = ColourInfo.GradientVertical(Color4.Gray, Color4.WhiteSmoke),
RelativeSizeAxes = Framework.Graphics.Axes.Both,
});
Add(new ButtonSystem());

View File

@ -3,24 +3,20 @@
using osu.Framework.Graphics.Containers;
using osu.Framework.Logging;
using osu.Framework.Testing;
using osu.Game.Screens.Play;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseMenuOverlays : TestCase
internal class TestCaseMenuOverlays : OsuTestCase
{
public override string Description => @"Tests pause and fail overlays";
private PauseContainer.PauseOverlay pauseOverlay;
private FailOverlay failOverlay;
private int retryCount;
public override void Reset()
public TestCaseMenuOverlays()
{
base.Reset();
FailOverlay failOverlay;
PauseContainer.PauseOverlay pauseOverlay;
retryCount = 0;
var retryCount = 0;
Add(pauseOverlay = new PauseContainer.PauseOverlay
{
@ -34,14 +30,16 @@ namespace osu.Desktop.VisualTests.Tests
OnQuit = () => Logger.Log(@"Quit"),
});
AddStep(@"Pause", delegate {
if(failOverlay.State == Visibility.Visible)
AddStep(@"Pause", delegate
{
if (failOverlay.State == Visibility.Visible)
{
failOverlay.Hide();
}
pauseOverlay.Show();
});
AddStep("Fail", delegate {
AddStep("Fail", delegate
{
if (pauseOverlay.State == Visibility.Visible)
{
pauseOverlay.Hide();

View File

@ -4,32 +4,31 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Overlays.Mods;
using osu.Framework.Testing;
using osu.Game.Database;
using osu.Game.Rulesets;
using osu.Game.Screens.Play.HUD;
using OpenTK;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseMods : TestCase
internal class TestCaseMods : OsuTestCase
{
public override string Description => @"Mod select overlay and in-game display";
private ModSelectOverlay modSelect;
private ModDisplay modDisplay;
private RulesetDatabase rulesets;
private RulesetStore rulesets;
[BackgroundDependencyLoader]
private void load(RulesetDatabase rulesets)
private void load(RulesetStore rulesets)
{
this.rulesets = rulesets;
}
public override void Reset()
protected override void LoadComplete()
{
base.Reset();
base.LoadComplete();
Add(modSelect = new ModSelectOverlay
{

View File

@ -1,30 +1,28 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Testing;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Timing;
using osu.Game.Overlays;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing;
using osu.Game;
using osu.Game.Beatmaps;
using osu.Game.Overlays;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseMusicController : TestCase
internal class TestCaseMusicController : OsuTestCase
{
public override string Description => @"Tests music controller ui.";
private MusicController mc;
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
public TestCaseMusicController()
{
Clock = new FramedClock();
}
public override void Reset()
{
base.Reset();
Clock.ProcessFrame();
mc = new MusicController
var mc = new MusicController
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre
@ -33,6 +31,13 @@ namespace osu.Desktop.VisualTests.Tests
AddToggleStep(@"toggle visibility", state => mc.State = state ? Visibility.Visible : Visibility.Hidden);
AddStep(@"show", () => mc.State = Visibility.Visible);
AddToggleStep(@"toggle beatmap lock", state => beatmapBacking.Disabled = state);
}
[BackgroundDependencyLoader]
private void load(OsuGameBase game)
{
beatmapBacking.BindTo(game.Beatmap);
}
}
}

View File

@ -2,29 +2,28 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using osu.Game.Overlays;
using System.Linq;
using osu.Game.Overlays.Notifications;
using osu.Framework.Graphics.Containers;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseNotificationManager : TestCase
[TestFixture]
internal class TestCaseNotificationOverlay : OsuTestCase
{
public override string Description => @"I handle notifications";
private NotificationManager manager;
private readonly NotificationOverlay manager;
public override void Reset()
public TestCaseNotificationOverlay()
{
base.Reset();
progressingNotifications.Clear();
Content.Add(manager = new NotificationManager
Content.Add(manager = new NotificationOverlay
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
@ -58,10 +57,7 @@ namespace osu.Desktop.VisualTests.Tests
}
if (remaining > 0)
{
Delay(80);
Schedule(() => sendBarrage(remaining - 1));
}
Scheduler.AddDelayed(() => sendBarrage(remaining - 1), 80);
}
protected override void Update()
@ -72,7 +68,7 @@ namespace osu.Desktop.VisualTests.Tests
while (progressingNotifications.Count(n => n.State == ProgressNotificationState.Active) < 3)
{
var p = progressingNotifications.FirstOrDefault(n => n.IsLoaded && n.State == ProgressNotificationState.Queued);
var p = progressingNotifications.FirstOrDefault(n => n.IsAlive && n.State == ProgressNotificationState.Queued);
if (p == null)
break;

View File

@ -3,21 +3,20 @@
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Testing;
using osu.Game.Overlays;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseOnScreenDisplay : TestCase
internal class TestCaseOnScreenDisplay : OsuTestCase
{
private FrameworkConfigManager config;
private Bindable<FrameSync> frameSyncMode;
public override string Description => @"Make it easier to see setting changes";
public override void Reset()
protected override void LoadComplete()
{
base.Reset();
base.LoadComplete();
Add(new OnScreenDisplay());

View File

@ -2,43 +2,40 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Desktop.VisualTests.Platform;
using osu.Framework.Testing;
using osu.Desktop.Tests.Platform;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Rulesets;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Filter;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCasePlaySongSelect : TestCase
internal class TestCasePlaySongSelect : OsuTestCase
{
private BeatmapDatabase db;
private TestStorage storage;
private PlaySongSelect songSelect;
private readonly BeatmapManager manager;
public override string Description => @"with fake data";
private RulesetDatabase rulesets;
private readonly RulesetStore rulesets;
public override void Reset()
public TestCasePlaySongSelect()
{
base.Reset();
if (db == null)
PlaySongSelect songSelect;
if (manager == null)
{
storage = new TestStorage(@"TestCasePlaySongSelect");
var storage = new TestStorage(@"TestCasePlaySongSelect");
var backingDatabase = storage.GetDatabase(@"client");
backingDatabase.CreateTable<StoreVersion>();
rulesets = new RulesetDatabase(storage, backingDatabase);
db = new BeatmapDatabase(storage, backingDatabase, rulesets);
var sets = new List<BeatmapSetInfo>();
rulesets = new RulesetStore(backingDatabase);
manager = new BeatmapManager(storage, null, backingDatabase, rulesets);
for (int i = 0; i < 100; i += 10)
sets.Add(createTestBeatmapSet(i));
db.Import(sets);
manager.Import(createTestBeatmapSet(i));
}
Add(songSelect = new PlaySongSelect());
@ -49,21 +46,12 @@ namespace osu.Desktop.VisualTests.Tests
AddStep(@"Sort by Difficulty", delegate { songSelect.FilterControl.Sort = SortMode.Difficulty; });
}
//protected override void Dispose(bool isDisposing)
//{
// if (oldDb != null)
// db = null;
// base.Dispose(isDisposing);
//}
private BeatmapSetInfo createTestBeatmapSet(int i)
{
return new BeatmapSetInfo
{
OnlineBeatmapSetID = 1234 + i,
Hash = "d8e8fca2dc0f896fd7cb4cb0031ba249",
Path = string.Empty,
Metadata = new BeatmapMetadata
{
OnlineBeatmapSetID = 1234 + i,

View File

@ -0,0 +1,87 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Desktop.Tests.Beatmaps;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Screens.Play;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Desktop.Tests.Visual
{
internal class TestCasePlayer : OsuTestCase
{
protected Player Player;
private RulesetStore rulesets;
public override string Description => @"Showing everything to play the game.";
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
this.rulesets = rulesets;
}
protected override void LoadComplete()
{
base.LoadComplete();
var objects = new List<HitObject>();
int time = 1500;
for (int i = 0; i < 50; i++)
{
objects.Add(new HitCircle
{
StartTime = time,
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
});
time += 500;
}
Beatmap b = new Beatmap
{
HitObjects = objects,
BeatmapInfo = new BeatmapInfo
{
Difficulty = new BeatmapDifficulty(),
Ruleset = rulesets.Query<RulesetInfo>().First(),
Metadata = new BeatmapMetadata
{
Artist = @"Unknown",
Title = @"Sample Beatmap",
Author = @"peppy",
}
}
};
WorkingBeatmap beatmap = new TestWorkingBeatmap(b);
Add(new Box
{
RelativeSizeAxes = Framework.Graphics.Axes.Both,
Colour = Color4.Black,
});
Add(Player = CreatePlayer(beatmap));
}
protected virtual Player CreatePlayer(WorkingBeatmap beatmap)
{
return new Player
{
InitialBeatmap = beatmap
};
}
}
}

View File

@ -6,7 +6,7 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Screens.Play;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseReplay : TestCasePlayer
{

View File

@ -0,0 +1,52 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Play;
using osu.Game.Screens.Play.ReplaySettings;
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseReplaySettingsOverlay : OsuTestCase
{
public override string Description => @"Settings visible in replay/auto";
public TestCaseReplaySettingsOverlay()
{
ExampleContainer container;
Add(new ReplaySettingsOverlay
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
});
Add(container = new ExampleContainer());
AddStep(@"Add button", () => container.Add(new OsuButton
{
RelativeSizeAxes = Axes.X,
Text = @"Button",
}));
AddStep(@"Add checkbox", () => container.Add(new ReplayCheckbox
{
LabelText = "Checkbox",
}));
AddStep(@"Add textbox", () => container.Add(new FocusedTextBox
{
RelativeSizeAxes = Axes.X,
Height = 30,
PlaceholderText = "Textbox",
HoldFocus = false,
}));
}
private class ExampleContainer : ReplayGroup
{
protected override string Title => @"example";
}
}
}

View File

@ -3,44 +3,39 @@
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
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseResults : TestCase
internal class TestCaseResults : OsuTestCase
{
private BeatmapDatabase db;
private BeatmapManager beatmaps;
public override string Description => @"Results after playing.";
[BackgroundDependencyLoader]
private void load(BeatmapDatabase db)
private void load(BeatmapManager beatmaps)
{
this.db = db;
this.beatmaps = beatmaps;
}
private WorkingBeatmap beatmap;
public override void Reset()
protected override void LoadComplete()
{
base.Reset();
base.LoadComplete();
if (beatmap == null)
{
var beatmapInfo = db.Query<BeatmapInfo>().FirstOrDefault(b => b.RulesetID == 0);
var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0);
if (beatmapInfo != null)
beatmap = db.GetWorkingBeatmap(beatmapInfo);
beatmap = beatmaps.GetWorkingBeatmap(beatmapInfo);
}
base.Reset();
Add(new Results(new Score
{
TotalScore = 2845370,
@ -48,7 +43,7 @@ namespace osu.Desktop.VisualTests.Tests
MaxCombo = 123,
Rank = ScoreRank.A,
Date = DateTimeOffset.Now,
Statistics = new Dictionary<string, dynamic>()
Statistics = new Dictionary<string, dynamic>
{
{ "300", 50 },
{ "100", 20 },
@ -61,7 +56,7 @@ namespace osu.Desktop.VisualTests.Tests
}
})
{
Beatmap = beatmap
InitialBeatmap = beatmap
});
}
}

View File

@ -0,0 +1,143 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Online.Multiplayer;
using osu.Game.Rulesets;
using osu.Game.Screens.Multiplayer;
using osu.Game.Users;
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseRoomInspector : OsuTestCase
{
public override string Description => @"from the multiplayer lobby";
private RulesetStore rulesets;
protected override void LoadComplete()
{
base.LoadComplete();
var room = new Room
{
Name = { Value = @"My Awesome Room" },
Host = { Value = new User { Username = @"flyte", Id = 3103765, Country = new Country { FlagName = @"JP" } } },
Status = { Value = new RoomStatusOpen() },
Type = { Value = new GameTypeTeamVersus() },
Beatmap =
{
Value = new BeatmapInfo
{
StarDifficulty = 3.7,
Ruleset = rulesets.GetRuleset(3),
Metadata = new BeatmapMetadata
{
Title = @"Platina",
Artist = @"Maaya Sakamoto",
Author = @"uwutm8",
},
BeatmapSet = new BeatmapSetInfo
{
OnlineInfo = new BeatmapSetOnlineInfo
{
Covers = new BeatmapSetOnlineCovers
{
Cover = @"https://assets.ppy.sh/beatmaps/560573/covers/cover.jpg?1492722343",
},
},
},
}
},
MaxParticipants = { Value = 200 },
Participants =
{
Value = new[]
{
new User { Username = @"flyte", Id = 3103765, GlobalRank = 1425 },
new User { Username = @"Cookiezi", Id = 124493, GlobalRank = 5466 },
new User { Username = @"Angelsim", Id = 1777162, GlobalRank = 2873 },
new User { Username = @"Rafis", Id = 2558286, GlobalRank = 4687 },
new User { Username = @"hvick225", Id = 50265, GlobalRank = 3258 },
new User { Username = @"peppy", Id = 2, GlobalRank = 6251 }
}
}
};
RoomInspector inspector;
Add(inspector = new RoomInspector
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Room = room,
});
AddStep(@"change title", () => room.Name.Value = @"A Better Room Than The Above");
AddStep(@"change host", () => room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } });
AddStep(@"change status", () => room.Status.Value = new RoomStatusPlaying());
AddStep(@"change type", () => room.Type.Value = new GameTypeTag());
AddStep(@"change beatmap", () => room.Beatmap.Value = null);
AddStep(@"change max participants", () => room.MaxParticipants.Value = null);
AddStep(@"change participants", () => room.Participants.Value = new[]
{
new User { Username = @"filsdelama", Id = 2831793, GlobalRank = 8542 },
new User { Username = @"_index", Id = 652457, GlobalRank = 15024 }
});
AddStep(@"change room", () =>
{
var newRoom = new Room
{
Name = { Value = @"My New, Better Than Ever Room" },
Host = { Value = new User { Username = @"Angelsim", Id = 1777162, Country = new Country { FlagName = @"KR" } } },
Status = { Value = new RoomStatusOpen() },
Type = { Value = new GameTypeTagTeam() },
Beatmap =
{
Value = new BeatmapInfo
{
StarDifficulty = 7.07,
Ruleset = rulesets.GetRuleset(0),
Metadata = new BeatmapMetadata
{
Title = @"FREEDOM DIVE",
Artist = @"xi",
Author = @"Nakagawa-Kanon",
},
BeatmapSet = new BeatmapSetInfo
{
OnlineInfo = new BeatmapSetOnlineInfo
{
Covers = new BeatmapSetOnlineCovers
{
Cover = @"https://assets.ppy.sh/beatmaps/39804/covers/cover.jpg?1456506845",
},
},
},
},
},
MaxParticipants = { Value = 10 },
Participants =
{
Value = new[]
{
new User { Username = @"Angelsim", Id = 1777162, GlobalRank = 4 },
new User { Username = @"HappyStick", Id = 256802, GlobalRank = 752 },
new User { Username = @"-Konpaku-", Id = 2258797, GlobalRank = 571 }
}
}
};
inspector.Room = newRoom;
});
}
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
this.rulesets = rulesets;
}
}
}

View File

@ -1,24 +1,21 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.MathUtils;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Play.HUD;
using OpenTK;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseScoreCounter : TestCase
internal class TestCaseScoreCounter : OsuTestCase
{
public override string Description => @"Tests multiple counters";
public override void Reset()
public TestCaseScoreCounter()
{
base.Reset();
int numerator = 0, denominator = 0;
ScoreCounter score = new ScoreCounter(7)
@ -52,7 +49,7 @@ namespace osu.Desktop.VisualTests.Tests
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Position = new Vector2(20, -160),
Count = 5,
CountStars = 5,
};
Add(stars);
@ -61,7 +58,7 @@ namespace osu.Desktop.VisualTests.Tests
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Position = new Vector2(20, -190),
Text = stars.Count.ToString("0.00"),
Text = stars.CountStars.ToString("0.00"),
};
Add(starsLabel);
@ -71,15 +68,16 @@ namespace osu.Desktop.VisualTests.Tests
comboCounter.Current.Value = 0;
numerator = denominator = 0;
accuracyCounter.SetFraction(0, 0);
stars.Count = 0;
starsLabel.Text = stars.Count.ToString("0.00");
stars.CountStars = 0;
starsLabel.Text = stars.CountStars.ToString("0.00");
});
AddStep(@"Hit! :D", delegate
{
score.Current.Value += 300 + (ulong)(300.0 * (comboCounter.Current > 0 ? comboCounter.Current - 1 : 0) / 25.0);
comboCounter.Increment();
numerator++; denominator++;
numerator++;
denominator++;
accuracyCounter.SetFraction(numerator, denominator);
});
@ -92,8 +90,8 @@ namespace osu.Desktop.VisualTests.Tests
AddStep(@"Alter stars", delegate
{
stars.Count = RNG.NextSingle() * (stars.StarCount + 1);
starsLabel.Text = stars.Count.ToString("0.00");
stars.CountStars = RNG.NextSingle() * (stars.StarCount + 1);
starsLabel.Text = stars.CountStars.ToString("0.00");
});
AddStep(@"Stop counters", delegate

View File

@ -0,0 +1,226 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using NUnit.Framework;
using OpenTK;
using osu.Desktop.Tests.Beatmaps;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Beatmaps;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Timing;
using osu.Game.Rulesets.UI;
namespace osu.Desktop.Tests.Visual
{
/// <summary>
/// The most minimal implementation of a playfield with scrolling hit objects.
/// </summary>
[TestFixture]
public class TestCaseScrollingPlayfield : OsuTestCase
{
public TestCaseScrollingPlayfield()
{
Clock = new FramedClock();
var objects = new List<HitObject>();
int time = 1500;
for (int i = 0; i < 50; i++)
{
objects.Add(new TestHitObject { StartTime = time });
time += 500;
}
Beatmap b = new Beatmap
{
HitObjects = objects,
BeatmapInfo = new BeatmapInfo
{
Difficulty = new BeatmapDifficulty(),
Metadata = new BeatmapMetadata()
}
};
WorkingBeatmap beatmap = new TestWorkingBeatmap(b);
TestRulesetContainer horizontalRulesetContainer;
Add(horizontalRulesetContainer = new TestRulesetContainer(Axes.X, beatmap, true));
TestRulesetContainer verticalRulesetContainer;
Add(verticalRulesetContainer = new TestRulesetContainer(Axes.Y, beatmap, true));
AddStep("Reverse direction", () =>
{
horizontalRulesetContainer.Playfield.Reversed.Toggle();
verticalRulesetContainer.Playfield.Reversed.Toggle();
});
}
[Test]
public void TestSpeedAdjustmentOrdering()
{
var hitObjectContainer = new ScrollingPlayfield<TestHitObject, TestJudgement>.ScrollingHitObjectContainer(Axes.X);
var speedAdjustments = new[]
{
new SpeedAdjustmentContainer(new MultiplierControlPoint()),
new SpeedAdjustmentContainer(new MultiplierControlPoint(1000)
{
TimingPoint = new TimingControlPoint { BeatLength = 500 }
}),
new SpeedAdjustmentContainer(new MultiplierControlPoint(2000)
{
TimingPoint = new TimingControlPoint { BeatLength = 1000 },
DifficultyPoint = new DifficultyControlPoint { SpeedMultiplier = 2}
}),
new SpeedAdjustmentContainer(new MultiplierControlPoint(3000)
{
TimingPoint = new TimingControlPoint { BeatLength = 1000 },
DifficultyPoint = new DifficultyControlPoint { SpeedMultiplier = 1}
}),
};
var hitObjects = new[]
{
new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = -1000 }),
new DrawableTestHitObject(Axes.X, new TestHitObject()),
new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = 1000 }),
new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = 2000 }),
new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = 3000 }),
new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = 4000 }),
};
hitObjects.ForEach(h => hitObjectContainer.Add(h));
speedAdjustments.ForEach(hitObjectContainer.AddSpeedAdjustment);
// The 0th index in hitObjectContainer.SpeedAdjustments is the "default" control point
// Check multiplier of the default speed adjustment
Assert.AreEqual(1, hitObjectContainer.SpeedAdjustments[0].ControlPoint.Multiplier);
Assert.AreEqual(1, speedAdjustments[0].ControlPoint.Multiplier);
Assert.AreEqual(2, speedAdjustments[1].ControlPoint.Multiplier);
Assert.AreEqual(2, speedAdjustments[2].ControlPoint.Multiplier);
Assert.AreEqual(1, speedAdjustments[3].ControlPoint.Multiplier);
// Check insertion of hit objects
Assert.IsTrue(hitObjectContainer.SpeedAdjustments[0].Contains(hitObjects[0]));
Assert.IsTrue(speedAdjustments[0].Contains(hitObjects[1]));
Assert.IsTrue(speedAdjustments[1].Contains(hitObjects[2]));
Assert.IsTrue(speedAdjustments[2].Contains(hitObjects[3]));
Assert.IsTrue(speedAdjustments[3].Contains(hitObjects[4]));
Assert.IsTrue(speedAdjustments[3].Contains(hitObjects[5]));
hitObjectContainer.RemoveSpeedAdjustment(speedAdjustments[1]);
// The hit object contained in this speed adjustment should be resorted into the previous one
Assert.IsTrue(speedAdjustments[0].Contains(hitObjects[2]));
}
private class TestRulesetContainer : ScrollingRulesetContainer<TestPlayfield, TestHitObject, TestJudgement>
{
private readonly Axes scrollingAxes;
public TestRulesetContainer(Axes scrollingAxes, WorkingBeatmap beatmap, bool isForCurrentRuleset)
: base(null, beatmap, isForCurrentRuleset)
{
this.scrollingAxes = scrollingAxes;
}
public new TestPlayfield Playfield => base.Playfield;
public override ScoreProcessor CreateScoreProcessor() => new TestScoreProcessor();
public override PassThroughInputManager CreateInputManager() => new PassThroughInputManager();
protected override BeatmapConverter<TestHitObject> CreateBeatmapConverter() => new TestBeatmapConverter();
protected override Playfield<TestHitObject, TestJudgement> CreatePlayfield() => new TestPlayfield(scrollingAxes);
protected override DrawableHitObject<TestHitObject, TestJudgement> GetVisualRepresentation(TestHitObject h) => new DrawableTestHitObject(scrollingAxes, h);
}
private class TestScoreProcessor : ScoreProcessor<TestHitObject, TestJudgement>
{
protected override void OnNewJudgement(TestJudgement judgement)
{
}
}
private class TestBeatmapConverter : BeatmapConverter<TestHitObject>
{
protected override IEnumerable<Type> ValidConversionTypes => new[] { typeof(HitObject) };
protected override IEnumerable<TestHitObject> ConvertHitObject(HitObject original, Beatmap beatmap)
{
yield return original as TestHitObject;
}
}
private class DrawableTestHitObject : DrawableScrollingHitObject<TestHitObject, TestJudgement>
{
public DrawableTestHitObject(Axes scrollingAxes, TestHitObject hitObject)
: base(hitObject)
{
Anchor = scrollingAxes == Axes.Y ? Anchor.TopCentre : Anchor.CentreLeft;
Origin = Anchor.Centre;
AutoSizeAxes = Axes.Both;
Add(new Circle
{
Size = new Vector2(50)
});
}
protected override TestJudgement CreateJudgement() => new TestJudgement();
protected override void UpdateState(ArmedState state)
{
}
}
private class TestPlayfield : ScrollingPlayfield<TestHitObject, TestJudgement>
{
protected override Container<Drawable> Content => content;
private readonly Container<Drawable> content;
public TestPlayfield(Axes scrollingAxes)
: base(scrollingAxes)
{
InternalChildren = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0.2f
},
content = new Container { RelativeSizeAxes = Axes.Both }
};
}
}
private class TestHitObject : HitObject
{
}
private class TestJudgement : Judgement
{
public override string ResultString { get { throw new NotImplementedException(); } }
public override string MaxResultString { get { throw new NotImplementedException(); } }
}
}
}

View File

@ -0,0 +1,25 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Overlays;
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseSettings : OsuTestCase
{
public override string Description => @"Tests the settings overlay";
private readonly SettingsOverlay settings;
public TestCaseSettings()
{
Children = new[] { settings = new MainSettings() };
}
protected override void LoadComplete()
{
base.LoadComplete();
settings.ToggleVisibility();
}
}
}

View File

@ -0,0 +1,19 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Screens.Play;
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseSkipButton : OsuTestCase
{
public override string Description => @"Skip skip skippediskip";
protected override void LoadComplete()
{
base.LoadComplete();
Add(new SkipButton(Clock.CurrentTime + 5000));
}
}
}

View File

@ -0,0 +1,82 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Overlays;
using osu.Game.Users;
namespace osu.Desktop.Tests.Visual
{
public class TestCaseSocial : OsuTestCase
{
public override string Description => @"social browser overlay";
public TestCaseSocial()
{
SocialOverlay s = new SocialOverlay
{
Users = new[]
{
new User
{
Username = @"flyte",
Id = 3103765,
Country = new Country { FlagName = @"JP" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg",
},
new User
{
Username = @"Cookiezi",
Id = 124493,
Country = new Country { FlagName = @"KR" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c2.jpg",
},
new User
{
Username = @"Angelsim",
Id = 1777162,
Country = new Country { FlagName = @"KR" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
},
new User
{
Username = @"Rafis",
Id = 2558286,
Country = new Country { FlagName = @"PL" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c4.jpg",
},
new User
{
Username = @"hvick225",
Id = 50265,
Country = new Country { FlagName = @"TW" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c5.jpg",
},
new User
{
Username = @"peppy",
Id = 2,
Country = new Country { FlagName = @"AU" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg"
},
new User
{
Username = @"filsdelama",
Id = 2831793,
Country = new Country { FlagName = @"FR" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c7.jpg"
},
new User
{
Username = @"_index",
Id = 652457,
Country = new Country { FlagName = @"RU" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c8.jpg"
},
},
};
Add(s);
AddStep(@"toggle", s.ToggleVisibility);
}
}
}

View File

@ -4,26 +4,23 @@
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
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseSongProgress : TestCase
internal class TestCaseSongProgress : OsuTestCase
{
public override string Description => @"With fake data";
private SongProgress progress;
private SongProgressGraph graph;
private readonly SongProgress progress;
private readonly SongProgressGraph graph;
private StopwatchClock clock;
private readonly StopwatchClock clock;
public override void Reset()
public TestCaseSongProgress()
{
base.Reset();
clock = new StopwatchClock(true);
Add(progress = new SongProgress

View File

@ -2,22 +2,19 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using OpenTK;
using osu.Framework.Testing;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Select.Filter;
using OpenTK;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
public class TestCaseTabControl : TestCase
public class TestCaseTabControl : OsuTestCase
{
public override string Description => @"Filter for song select";
public override void Reset()
public TestCaseTabControl()
{
base.Reset();
OsuSpriteText text;
OsuTabControl<GroupMode> filter;
Add(filter = new OsuTabControl<GroupMode>

View File

@ -1,24 +1,30 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
using osu.Framework.Testing;
using osu.Framework.Timing;
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;
using OpenTK;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps;
using osu.Desktop.Tests.Beatmaps;
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseTaikoPlayfield : TestCase
internal class TestCaseTaikoPlayfield : OsuTestCase
{
private const double default_duration = 300;
private const double default_duration = 1000;
private const float scroll_time = 1000;
public override string Description => "Taiko playfield";
@ -26,14 +32,14 @@ namespace osu.Desktop.VisualTests.Tests
protected override double TimePerAction => default_duration * 2;
private readonly Random rng = new Random(1337);
private TaikoPlayfield playfield;
private TaikoRulesetContainer rulesetContainer;
private Container playfieldContainer;
public override void Reset()
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
base.Reset();
AddStep("Hit!", addHitJudgement);
AddStep("Hit!", () => addHitJudgement(false));
AddStep("Kiai hit", () => addHitJudgement(true));
AddStep("Miss :(", addMissJudgement);
AddStep("DrumRoll", () => addDrumRoll(false));
AddStep("Strong DrumRoll", () => addDrumRoll(true));
@ -51,6 +57,25 @@ namespace osu.Desktop.VisualTests.Tests
AddStep("Height test 5", () => changePlayfieldSize(5));
AddStep("Reset height", () => changePlayfieldSize(6));
var controlPointInfo = new ControlPointInfo();
controlPointInfo.TimingPoints.Add(new TimingControlPoint());
WorkingBeatmap beatmap = new TestWorkingBeatmap(new Beatmap
{
HitObjects = new List<HitObject> { new CentreHit() },
BeatmapInfo = new BeatmapInfo
{
Difficulty = new BeatmapDifficulty(),
Metadata = new BeatmapMetadata
{
Artist = @"Unknown",
Title = @"Sample Beatmap",
Author = @"peppy",
},
},
ControlPointInfo = controlPointInfo
});
var rateAdjustClock = new StopwatchClock(true) { Rate = 1 };
Add(playfieldContainer = new Container
@ -58,17 +83,16 @@ namespace osu.Desktop.VisualTests.Tests
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
Height = TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT,
Height = 768,
Clock = new FramedClock(rateAdjustClock),
Children = new[]
{
playfield = new TaikoPlayfield()
}
Children = new[] { rulesetContainer = new TaikoRulesetContainer(rulesets.GetRuleset(1).CreateInstance(), beatmap, true) }
});
}
private void changePlayfieldSize(int step)
{
double delay = 0;
// Add new hits
switch (step)
{
@ -85,8 +109,8 @@ namespace osu.Desktop.VisualTests.Tests
addDrumRoll(true);
break;
case 5:
addSwell(1000);
playfieldContainer.Delay(scroll_time - 100);
addSwell();
delay = scroll_time - 100;
break;
}
@ -94,19 +118,28 @@ namespace osu.Desktop.VisualTests.Tests
switch (step)
{
default:
playfieldContainer.ResizeTo(new Vector2(1, rng.Next(25, 400)), 500);
playfieldContainer.Delay(delay).ResizeTo(new Vector2(1, rng.Next(25, 400)), 500);
break;
case 6:
playfieldContainer.ResizeTo(new Vector2(1, TaikoPlayfield.DEFAULT_PLAYFIELD_HEIGHT), 500);
playfieldContainer.Delay(delay).ResizeTo(new Vector2(1, TaikoPlayfield.DEFAULT_HEIGHT), 500);
break;
}
}
private void addHitJudgement()
private void addHitJudgement(bool kiai)
{
TaikoHitResult hitResult = RNG.Next(2) == 0 ? TaikoHitResult.Good : TaikoHitResult.Great;
var h = new DrawableTestHit(new Hit())
var cpi = new ControlPointInfo();
cpi.EffectPoints.Add(new EffectControlPoint
{
KiaiMode = kiai
});
Hit hit = new Hit();
hit.ApplyDefaults(cpi, new BeatmapDifficulty());
var h = new DrawableTestHit(hit)
{
X = RNG.NextSingle(hitResult == TaikoHitResult.Good ? -0.1f : -0.05f, hitResult == TaikoHitResult.Good ? 0.1f : 0.05f),
Judgement = new TaikoJudgement
@ -117,18 +150,18 @@ namespace osu.Desktop.VisualTests.Tests
}
};
playfield.OnJudgement(h);
rulesetContainer.Playfield.OnJudgement(h);
if (RNG.Next(10) == 0)
{
h.Judgement.SecondHit = true;
playfield.OnJudgement(h);
rulesetContainer.Playfield.OnJudgement(h);
}
}
private void addMissJudgement()
{
playfield.OnJudgement(new DrawableTestHit(new Hit())
rulesetContainer.Playfield.OnJudgement(new DrawableTestHit(new Hit())
{
Judgement = new TaikoJudgement
{
@ -140,22 +173,17 @@ namespace osu.Desktop.VisualTests.Tests
private void addBarLine(bool major, double delay = scroll_time)
{
BarLine bl = new BarLine
{
StartTime = playfield.Time.Current + delay,
ScrollTime = scroll_time
};
BarLine bl = new BarLine { StartTime = rulesetContainer.Playfield.Time.Current + delay };
playfield.AddBarLine(major ? new DrawableBarLineMajor(bl) : new DrawableBarLine(bl));
rulesetContainer.Playfield.Add(major ? new DrawableBarLineMajor(bl) : new DrawableBarLine(bl));
}
private void addSwell(double duration = default_duration)
{
playfield.Add(new DrawableSwell(new Swell
rulesetContainer.Playfield.Add(new DrawableSwell(new Swell
{
StartTime = playfield.Time.Current + scroll_time,
StartTime = rulesetContainer.Playfield.Time.Current + scroll_time,
Duration = duration,
ScrollTime = scroll_time
}));
}
@ -166,41 +194,40 @@ namespace osu.Desktop.VisualTests.Tests
var d = new DrumRoll
{
StartTime = playfield.Time.Current + scroll_time,
StartTime = rulesetContainer.Playfield.Time.Current + scroll_time,
IsStrong = strong,
Duration = duration,
ScrollTime = scroll_time,
};
playfield.Add(new DrawableDrumRoll(d));
rulesetContainer.Playfield.Add(new DrawableDrumRoll(d));
}
private void addCentreHit(bool strong)
{
Hit h = new Hit
{
StartTime = playfield.Time.Current + scroll_time,
ScrollTime = scroll_time
StartTime = rulesetContainer.Playfield.Time.Current + scroll_time,
IsStrong = strong
};
if (strong)
playfield.Add(new DrawableCentreHitStrong(h));
rulesetContainer.Playfield.Add(new DrawableCentreHitStrong(h));
else
playfield.Add(new DrawableCentreHit(h));
rulesetContainer.Playfield.Add(new DrawableCentreHit(h));
}
private void addRimHit(bool strong)
{
Hit h = new Hit
{
StartTime = playfield.Time.Current + scroll_time,
ScrollTime = scroll_time
StartTime = rulesetContainer.Playfield.Time.Current + scroll_time,
IsStrong = strong
};
if (strong)
playfield.Add(new DrawableRimHitStrong(h));
rulesetContainer.Playfield.Add(new DrawableRimHitStrong(h));
else
playfield.Add(new DrawableRimHit(h));
rulesetContainer.Playfield.Add(new DrawableRimHit(h));
}
private class DrawableTestHit : DrawableHitObject<TaikoHitObject, TaikoJudgement>

View File

@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Testing;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.MathUtils;
@ -10,16 +9,14 @@ using osu.Game.Graphics;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseTextAwesome : TestCase
internal class TestCaseTextAwesome : OsuTestCase
{
public override string Description => @"Tests display of icons";
public override void Reset()
public TestCaseTextAwesome()
{
base.Reset();
FillFlowContainer flow;
Add(flow = new FillFlowContainer
@ -33,10 +30,10 @@ namespace osu.Desktop.VisualTests.Tests
int i = 50;
foreach (FontAwesome fa in Enum.GetValues(typeof(FontAwesome)))
{
flow.Add(new TextAwesome
flow.Add(new SpriteIcon
{
Icon = fa,
TextSize = 60,
Size = new Vector2(60),
Colour = new Color4(
Math.Max(0.5f, RNG.NextSingle()),
Math.Max(0.5f, RNG.NextSingle()),

View File

@ -0,0 +1,17 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Graphics.UserInterface;
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseTwoLayerButton : OsuTestCase
{
public override string Description => @"Mostly back button";
public TestCaseTwoLayerButton()
{
Add(new BackButton());
}
}
}

View File

@ -1,22 +1,19 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Testing;
using osu.Framework.Graphics;
using osu.Game.Users;
using osu.Framework.Graphics.Containers;
using osu.Game.Users;
using OpenTK;
namespace osu.Desktop.VisualTests.Tests
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseUserPanel : TestCase
internal class TestCaseUserPanel : OsuTestCase
{
public override string Description => @"Panels for displaying a user's status";
public override void Reset()
public TestCaseUserPanel()
{
base.Reset();
UserPanel flyte;
UserPanel peppy;
Add(new FillFlowContainer

View File

@ -0,0 +1,63 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq;
using osu.Game.Overlays;
using osu.Game.Users;
namespace osu.Desktop.Tests.Visual
{
internal class TestCaseUserProfile : OsuTestCase
{
public override string Description => "Tests user's profile page.";
public TestCaseUserProfile()
{
var profile = new UserProfileOverlay();
Add(profile);
AddStep("Show offline dummy", () => profile.ShowUser(new User
{
Username = @"Somebody",
Id = 1,
Country = new Country { FullName = @"Alien" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg",
JoinDate = DateTimeOffset.Now.AddDays(-1),
LastVisit = DateTimeOffset.Now,
Age = 1,
ProfileOrder = new[] { "me" },
CountryRank = 1,
Statistics = new UserStatistics
{
Rank = 2148,
PP = 4567.89m
},
AllRankHistories = new User.RankHistories
{
Osu = new User.RankHistory
{
Mode = @"osu",
Data = Enumerable.Range(2345,45).Concat(Enumerable.Range(2109,40)).ToArray()
}
}
}, false));
AddStep("Show ppy", () => profile.ShowUser(new User
{
Username = @"peppy",
Id = 2,
Country = new Country { FullName = @"Australia", FlagName = @"AU" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg"
}));
AddStep("Show flyte", () => profile.ShowUser(new User
{
Username = @"flyte",
Id = 3103765,
Country = new Country { FullName = @"Japan", FlagName = @"JP" },
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg"
}));
AddStep("Hide", profile.Hide);
AddStep("Show without reload", profile.Show);
}
}
}

View File

@ -1,22 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using NUnit.Framework;
using osu.Desktop.VisualTests;
using osu.Framework.Desktop.Platform;
namespace osu.Desktop.Tests
{
[TestFixture]
public class VisualTests
{
[Test]
public void TestVisualTests()
{
using (var host = new HeadlessGameHost())
{
host.Run(new AutomatedVisualTestGame());
}
}
}
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -37,8 +37,13 @@
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="nunit.framework, Version=3.6.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\NUnit.3.6.1\lib\net45\nunit.framework.dll</HintPath>
<Reference Include="nunit.framework, Version=3.7.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SQLite.Net, Version=3.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -54,15 +59,68 @@
<Reference Include="SQLite.Net.Platform.Generic">
<HintPath>$(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net40\SQLite.Net.Platform.Generic.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="VisualTests.cs" />
<Compile Include="Beatmaps\TestWorkingBeatmap.cs" />
<Compile Include="Platform\TestStorage.cs" />
<Compile Include="Visual\OsuTestCase.cs" />
<Compile Include="Visual\TestCaseBeatmapDetailArea.cs" />
<Compile Include="Visual\TestCaseBeatmapDetails.cs" />
<Compile Include="Visual\TestCaseBeatmapOptionsOverlay.cs" />
<Compile Include="Visual\TestCaseBeatSyncedContainer.cs" />
<Compile Include="Visual\TestCaseBreadcrumbs.cs" />
<Compile Include="Visual\TestCaseCatcher.cs" />
<Compile Include="Visual\TestCaseChatDisplay.cs" />
<Compile Include="Visual\TestCaseContextMenu.cs" />
<Compile Include="Visual\TestCaseDialogOverlay.cs" />
<Compile Include="Visual\TestCaseDirect.cs" />
<Compile Include="Visual\TestCaseDrawableRoom.cs" />
<Compile Include="Visual\TestCaseDrawings.cs" />
<Compile Include="Visual\TestCaseGamefield.cs" />
<Compile Include="Visual\TestCaseGraph.cs" />
<Compile Include="Visual\TestCaseHitObjects.cs" />
<Compile Include="Visual\TestCaseKeyConfiguration.cs" />
<Compile Include="Visual\TestCaseKeyCounter.cs" />
<Compile Include="Visual\TestCaseLeaderboard.cs" />
<Compile Include="Visual\TestCaseManiaHitObjects.cs" />
<Compile Include="Visual\TestCaseManiaPlayfield.cs" />
<Compile Include="Visual\TestCaseMedalOverlay.cs" />
<Compile Include="Visual\TestCaseMenuButtonSystem.cs" />
<Compile Include="Visual\TestCaseMenuOverlays.cs" />
<Compile Include="Visual\TestCaseMods.cs" />
<Compile Include="Visual\TestCaseMusicController.cs" />
<Compile Include="Visual\TestCaseNotificationOverlay.cs" />
<Compile Include="Visual\TestCaseOnScreenDisplay.cs" />
<Compile Include="Visual\TestCasePlayer.cs" />
<Compile Include="Visual\TestCasePlaySongSelect.cs" />
<Compile Include="Visual\TestCaseReplay.cs" />
<Compile Include="Visual\TestCaseReplaySettingsOverlay.cs" />
<Compile Include="Visual\TestCaseResults.cs" />
<Compile Include="Visual\TestCaseRoomInspector.cs" />
<Compile Include="Visual\TestCaseScoreCounter.cs" />
<Compile Include="Visual\TestCaseScrollingPlayfield.cs" />
<Compile Include="Visual\TestCaseSettings.cs" />
<Compile Include="Visual\TestCaseSkipButton.cs" />
<Compile Include="Visual\TestCaseSocial.cs" />
<Compile Include="Visual\TestCaseSongProgress.cs" />
<Compile Include="Visual\TestCaseTabControl.cs" />
<Compile Include="Visual\TestCaseTaikoPlayfield.cs" />
<Compile Include="Visual\TestCaseTextAwesome.cs" />
<Compile Include="Visual\TestCaseTwoLayerButton.cs" />
<Compile Include="Visual\TestCaseUserPanel.cs" />
<Compile Include="Visual\TestCaseUserProfile.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\osu-framework\osu.Framework.Desktop\osu.Framework.Desktop.csproj">
<Project>{65DC628F-A640-4111-AB35-3A5652BC1E17}</Project>
<Name>osu.Framework.Desktop</Name>
</ProjectReference>
<ProjectReference Include="..\osu-framework\osu.Framework.Testing\osu.Framework.Testing.csproj">
<Project>{007b2356-ab6f-4bd9-96d5-116fc2dce69a}</Project>
<Name>osu.Framework.Testing</Name>
</ProjectReference>
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
<Project>{C76BF5B3-985E-4D39-95FE-97C9C879B83A}</Project>
<Name>osu.Framework</Name>
@ -71,10 +129,6 @@
<Project>{d9a367c9-4c1a-489f-9b05-a0cea2b53b58}</Project>
<Name>osu.Game.Resources</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Desktop.VisualTests\osu.Desktop.VisualTests.csproj">
<Project>{69051C69-12AE-4E7D-A3E6-460D2E282312}</Project>
<Name>osu.Desktop.VisualTests</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj">
<Project>{58F6C80C-1253-4A0E-A465-B8C85EBEADF3}</Project>
<Name>osu.Game.Rulesets.Catch</Name>
@ -100,6 +154,7 @@
<None Include="..\osu.licenseheader">
<Link>osu.licenseheader</Link>
</None>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>

View File

@ -5,7 +5,8 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
-->
<packages>
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net45" />
<package id="NUnit" version="3.6.1" targetFramework="net45" />
<package id="NUnit" version="3.7.1" targetFramework="net45" />
<package id="ppy.OpenTK" version="3.0" targetFramework="net45" />
<package id="SQLite.Net.Core-PCL" version="3.1.1" targetFramework="net45" />
<package id="SQLite.Net-PCL" version="3.1.1" targetFramework="net45" />
<package id="SQLiteNetExtensions" version="1.3.0" targetFramework="net45" />

View File

@ -1,20 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Testing;
using osu.Game;
namespace osu.Desktop.VisualTests
{
public class AutomatedVisualTestGame : OsuGameBase
{
protected override void LoadComplete()
{
base.LoadComplete();
// Have to construct this here, rather than in the constructor, because
// we depend on some dependencies to be loaded within OsuGameBase.load().
Add(new TestRunner(new TestBrowser()));
}
}
}

View File

@ -4,6 +4,7 @@
using System;
using osu.Framework.Desktop;
using osu.Framework.Platform;
using osu.Framework.VisualTests;
namespace osu.Desktop.VisualTests
{

View File

@ -1,74 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Screens.Multiplayer;
using osu.Game.Online.Multiplayer;
using osu.Game.Users;
using osu.Game.Database;
namespace osu.Desktop.VisualTests.Tests
{
internal class TestCaseDrawableRoom : TestCase
{
public override string Description => @"Select your favourite room";
public override void Reset()
{
base.Reset();
DrawableRoom first;
DrawableRoom second;
Add(new FillFlowContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
AutoSizeAxes = Axes.Y,
Width = 500f,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
first = new DrawableRoom(new Room()),
second = new DrawableRoom(new Room()),
}
});
first.Room.Name.Value = @"Great Room Right Here";
first.Room.Host.Value = new User { Username = @"Naeferith", Id = 9492835, Country = new Country { FlagName = @"FR" }};
first.Room.Status.Value = new RoomStatusOpen();
first.Room.Beatmap.Value = new BeatmapMetadata { Title = @"Seiryu", Artist = @"Critical Crystal" };
second.Room.Name.Value = @"Relax It's The Weekend";
second.Room.Host.Value = new User { Username = @"peppy", Id = 2, Country = new Country { FlagName = @"AU" }};
second.Room.Status.Value = new RoomStatusPlaying();
second.Room.Beatmap.Value = new BeatmapMetadata { Title = @"ZAQ", Artist = @"Serendipity" };
AddStep(@"change state", () =>
{
first.Room.Status.Value = new RoomStatusPlaying();
});
AddStep(@"change name", () =>
{
first.Room.Name.Value = @"I Changed Name";
});
AddStep(@"change host", () =>
{
first.Room.Host.Value = new User { Username = @"DrabWeb", Id = 6946022, Country = new Country { FlagName = @"CA" } };
});
AddStep(@"change beatmap", () =>
{
first.Room.Beatmap.Value = null;
});
AddStep(@"change state", () =>
{
first.Room.Status.Value = new RoomStatusOpen();
});
}
}
}

View File

@ -1,104 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Testing;
using osu.Framework.Graphics;
using OpenTK.Input;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Configuration;
using osu.Framework.Graphics.Containers;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.MathUtils;
using osu.Framework.Graphics.Sprites;
using osu.Game.Screens.Play;
namespace osu.Desktop.VisualTests.Tests
{
internal class TestCaseKeyCounter : TestCase
{
public override string Description => @"Tests key counter";
public override void Reset()
{
base.Reset();
KeyCounterCollection kc = new KeyCounterCollection
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
IsCounting = true,
Children = new KeyCounter[]
{
new KeyCounterKeyboard(Key.Z),
new KeyCounterKeyboard(Key.X),
new KeyCounterMouse(MouseButton.Left),
new KeyCounterMouse(MouseButton.Right),
},
};
BindableInt bindable = new BindableInt { MinValue = 0, MaxValue = 200, Default = 50 };
bindable.ValueChanged += delegate { kc.FadeTime = bindable.Value; };
AddStep("Add Random", () =>
{
Key key = (Key)((int)Key.A + RNG.Next(26));
kc.Add(new KeyCounterKeyboard(key));
});
TestSliderBar<int> sliderBar;
Add(new Container
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Children = new Drawable[]
{
new SpriteText { Text = "FadeTime" },
sliderBar =new TestSliderBar<int>
{
Width = 150,
Height = 10,
SelectionColor = Color4.Orange,
}
}
});
sliderBar.Current.BindTo(bindable);
Add(kc);
}
private class TestSliderBar<T> : SliderBar<T> where T : struct
{
public Color4 Color
{
get { return Box.Colour; }
set { Box.Colour = value; }
}
public Color4 SelectionColor
{
get { return SelectionBox.Colour; }
set { SelectionBox.Colour = value; }
}
protected readonly Box SelectionBox;
protected readonly Box Box;
public TestSliderBar()
{
Children = new Drawable[]
{
Box = new Box { RelativeSizeAxes = Axes.Both },
SelectionBox = new Box { RelativeSizeAxes = Axes.Both }
};
}
protected override void UpdateValue(float value)
{
SelectionBox.ScaleTo(
new Vector2(value, 1),
300, EasingTypes.OutQuint);
}
}
}
}

View File

@ -1,100 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using OpenTK;
using osu.Framework.Graphics.Sprites;
using osu.Game.Database;
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
{
internal class TestCasePlayer : TestCase
{
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, RulesetDatabase rulesets)
{
this.rulesets = rulesets;
this.db = db;
}
public override void Reset()
{
base.Reset();
WorkingBeatmap beatmap = null;
var beatmapInfo = db.Query<BeatmapInfo>().FirstOrDefault(b => b.RulesetID == 0);
if (beatmapInfo != null)
beatmap = db.GetWorkingBeatmap(beatmapInfo);
if (beatmap?.Track == null)
{
var objects = new List<HitObject>();
int time = 1500;
for (int i = 0; i < 50; i++)
{
objects.Add(new HitCircle
{
StartTime = time,
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
});
time += 500;
}
Beatmap b = new Beatmap
{
HitObjects = objects,
BeatmapInfo = new BeatmapInfo
{
Difficulty = new BeatmapDifficulty(),
Ruleset = rulesets.Query<RulesetInfo>().First(),
Metadata = new BeatmapMetadata
{
Artist = @"Unknown",
Title = @"Sample Beatmap",
Author = @"peppy",
}
}
};
beatmap = new TestWorkingBeatmap(b);
}
Add(new Box
{
RelativeSizeAxes = Framework.Graphics.Axes.Both,
Colour = Color4.Black,
});
Add(Player = CreatePlayer(beatmap));
}
protected virtual Player CreatePlayer(WorkingBeatmap beatmap)
{
return new Player
{
Beatmap = beatmap
};
}
}
}

View File

@ -1,23 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Testing;
using osu.Game.Overlays;
namespace osu.Desktop.VisualTests.Tests
{
internal class TestCaseSettings : TestCase
{
public override string Description => @"Tests the settings overlay";
private SettingsOverlay settings;
public override void Reset()
{
base.Reset();
Children = new[] { settings = new SettingsOverlay() };
settings.ToggleVisibility();
}
}
}

View File

@ -1,121 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
namespace osu.Desktop.VisualTests.Tests
{
internal class TestCaseTaikoHitObjects : TestCase
{
public override string Description => "Taiko hit objects";
private bool kiai;
public override void Reset()
{
base.Reset();
AddToggleStep("Kiai", b =>
{
kiai = !kiai;
updateKiaiState();
});
Add(new CirclePiece
{
Position = new Vector2(100, 100),
AccentColour = Color4.DarkRed,
KiaiMode = kiai,
Children = new[]
{
new CentreHitSymbolPiece()
}
});
Add(new CirclePiece(true)
{
Position = new Vector2(350, 100),
AccentColour = Color4.DarkRed,
KiaiMode = kiai,
Children = new[]
{
new CentreHitSymbolPiece()
}
});
Add(new CirclePiece
{
Position = new Vector2(100, 300),
AccentColour = Color4.DarkBlue,
KiaiMode = kiai,
Children = new[]
{
new RimHitSymbolPiece()
}
});
Add(new CirclePiece(true)
{
Position = new Vector2(350, 300),
AccentColour = Color4.DarkBlue,
KiaiMode = kiai,
Children = new[]
{
new RimHitSymbolPiece()
}
});
Add(new CirclePiece
{
Position = new Vector2(100, 500),
AccentColour = Color4.Orange,
KiaiMode = kiai,
Children = new[]
{
new SwellSymbolPiece()
}
});
Add(new ElongatedCirclePiece
{
Position = new Vector2(575, 100),
AccentColour = Color4.Orange,
KiaiMode = kiai,
Length = 0.10f,
PlayfieldLengthReference = () => DrawSize.X
});
Add(new ElongatedCirclePiece(true)
{
Position = new Vector2(575, 300),
AccentColour = Color4.Orange,
KiaiMode = kiai,
Length = 0.10f,
PlayfieldLengthReference = () => DrawSize.X
});
}
private void updateKiaiState()
{
foreach (var c in Children.OfType<CirclePiece>())
c.KiaiMode = kiai;
}
private abstract class BaseCircle : Container
{
protected readonly CirclePiece Piece;
protected BaseCircle(CirclePiece piece)
{
Piece = piece;
Add(Piece);
}
}
}
}

View File

@ -1,22 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Play;
namespace osu.Desktop.VisualTests.Tests
{
internal class TestCaseTwoLayerButton : TestCase
{
public override string Description => @"Back and skip and what not";
public override void Reset()
{
base.Reset();
Add(new BackButton());
Add(new SkipButton(Clock.CurrentTime + 5000));
}
}
}

View File

@ -2,7 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Framework.VisualTests;
using osu.Game;
using osu.Game.Screens.Backgrounds;

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<ProjectGuid>{69051C69-12AE-4E7D-A3E6-460D2E282312}</ProjectGuid>
@ -87,11 +87,13 @@
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="OpenTK, Version=2.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll</HintPath>
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SharpCompress, Version=0.15.2.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\SharpCompress.0.15.2\lib\net45\SharpCompress.dll</HintPath>
<Reference Include="SharpCompress, Version=0.17.1.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\SharpCompress.0.17.1\lib\net45\SharpCompress.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SQLite.Net, Version=3.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -183,46 +185,8 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="AutomatedVisualTestGame.cs" />
<Compile Include="Program.cs" />
<Compile Include="Tests\TestCaseChatDisplay.cs" />
<Compile Include="Tests\TestCaseBeatmapDetails.cs" />
<Compile Include="Tests\TestCaseDrawings.cs" />
<Compile Include="Tests\TestCaseGamefield.cs" />
<Compile Include="Tests\TestCaseGraph.cs" />
<Compile Include="Tests\TestCaseManiaHitObjects.cs" />
<Compile Include="Tests\TestCaseManiaPlayfield.cs" />
<Compile Include="Tests\TestCaseMenuOverlays.cs" />
<Compile Include="Tests\TestCaseMusicController.cs" />
<Compile Include="Tests\TestCaseNotificationManager.cs" />
<Compile Include="Tests\TestCaseOnScreenDisplay.cs" />
<Compile Include="Tests\TestCasePlayer.cs" />
<Compile Include="Tests\TestCaseHitObjects.cs" />
<Compile Include="Tests\TestCaseKeyCounter.cs" />
<Compile Include="Tests\TestCaseMenuButtonSystem.cs" />
<Compile Include="Tests\TestCaseReplay.cs" />
<Compile Include="Tests\TestCaseResults.cs" />
<Compile Include="Tests\TestCaseScoreCounter.cs" />
<Compile Include="Tests\TestCaseTabControl.cs" />
<Compile Include="Tests\TestCaseTaikoHitObjects.cs" />
<Compile Include="Tests\TestCaseTaikoPlayfield.cs" />
<Compile Include="Tests\TestCaseTextAwesome.cs" />
<Compile Include="Tests\TestCasePlaySongSelect.cs" />
<Compile Include="Tests\TestCaseTwoLayerButton.cs" />
<Compile Include="VisualTestGame.cs" />
<Compile Include="Platform\TestStorage.cs" />
<Compile Include="Tests\TestCaseSettings.cs" />
<Compile Include="Tests\TestCaseSongProgress.cs" />
<Compile Include="Tests\TestCaseMods.cs" />
<Compile Include="Tests\TestCaseDialogOverlay.cs" />
<Compile Include="Tests\TestCaseBeatmapOptionsOverlay.cs" />
<Compile Include="Tests\TestCaseLeaderboard.cs" />
<Compile Include="Beatmaps\TestWorkingBeatmap.cs" />
<Compile Include="Tests\TestCaseBeatmapDetailArea.cs" />
<Compile Include="Tests\TestCaseDrawableRoom.cs" />
<Compile Include="Tests\TestCaseUserPanel.cs" />
<Compile Include="Tests\TestCaseDirect.cs" />
<Compile Include="Tests\TestCaseBreadcrumbs.cs" />
</ItemGroup>
<ItemGroup />
<ItemGroup />
@ -247,4 +211,4 @@
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>
</Project>

View File

@ -5,8 +5,8 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
-->
<packages>
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net45" />
<package id="ppy.OpenTK" version="2.0.50727.1341" targetFramework="net45" />
<package id="SharpCompress" version="0.15.2" targetFramework="net45" />
<package id="ppy.OpenTK" version="3.0" targetFramework="net45" />
<package id="SharpCompress" version="0.17.1" targetFramework="net45" />
<package id="SQLite.Net.Core-PCL" version="3.1.1" targetFramework="net45" />
<package id="SQLite.Net-PCL" version="3.1.1" targetFramework="net45" />
<package id="SQLiteNetExtensions" version="1.3.0" targetFramework="net45" />

View File

@ -1,43 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.IO;
using System.Linq;
using osu.Game.Beatmaps.IO;
namespace osu.Desktop.Beatmaps.IO
{
/// <summary>
/// Reads an extracted legacy beatmap from disk.
/// </summary>
public class LegacyFilesystemReader : ArchiveReader
{
public static void Register() => AddReader<LegacyFilesystemReader>((storage, path) => Directory.Exists(path));
private readonly string basePath;
public LegacyFilesystemReader(string path)
{
basePath = path;
BeatmapFilenames = Directory.GetFiles(basePath, @"*.osu").Select(Path.GetFileName).ToArray();
if (BeatmapFilenames.Length == 0)
throw new FileNotFoundException(@"This directory contains no beatmaps");
StoryboardFilename = Directory.GetFiles(basePath, @"*.osb").Select(Path.GetFileName).FirstOrDefault();
}
public override Stream GetStream(string name)
{
return File.OpenRead(Path.Combine(basePath, name));
}
public override void Dispose()
{
// no-op
}
public override Stream GetUnderlyingStream() => null;
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Game;
using System.Linq;
using System.Windows.Forms;
@ -11,6 +12,8 @@ using System.Reflection;
using System.Drawing;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Win32;
using osu.Framework.Graphics.Containers;
using osu.Game.Screens.Menu;
namespace osu.Desktop
@ -22,18 +25,74 @@ namespace osu.Desktop
public OsuGameDesktop(string[] args = null)
: base(args)
{
versionManager = new VersionManager { Depth = int.MinValue };
versionManager = new VersionManager
{
Depth = int.MinValue,
State = Visibility.Hidden
};
}
public override Storage GetStorageForStableInstall()
{
try
{
return new StableStorage();
}
catch
{
return null;
}
}
/// <summary>
/// A method of accessing an osu-stable install in a controlled fashion.
/// </summary>
private class StableStorage : DesktopStorage
{
protected override string LocateBasePath()
{
Func<string, bool> checkExists = p => Directory.Exists(Path.Combine(p, "Songs"));
string stableInstallPath;
try
{
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu"))
stableInstallPath = key?.OpenSubKey(@"shell\open\command")?.GetValue(String.Empty).ToString().Split('"')[1].Replace("osu!.exe", "");
if (checkExists(stableInstallPath))
return stableInstallPath;
}
catch
{
}
stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!");
if (checkExists(stableInstallPath))
return stableInstallPath;
stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".osu");
if (checkExists(stableInstallPath))
return stableInstallPath;
return null;
}
public StableStorage()
: base(string.Empty)
{
}
}
protected override void LoadComplete()
{
base.LoadComplete();
LoadComponentAsync(versionManager);
LoadComponentAsync(versionManager, Add);
ScreenChanged += s =>
{
if (!versionManager.IsAlive && s is Intro)
Add(versionManager);
if (!versionManager.IsPresent && s is Intro)
versionManager.State = Visibility.Visible;
};
}
@ -45,7 +104,7 @@ namespace osu.Desktop
{
desktopWindow.CursorState |= CursorState.Hidden;
desktopWindow.Icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location);
desktopWindow.Icon = new Icon(Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico"));
desktopWindow.Title = Name;
desktopWindow.DragEnter += dragEnter;
@ -60,11 +119,11 @@ namespace osu.Desktop
var filePaths = dropData.Select(f => f.ToString()).ToArray();
if (filePaths.All(f => Path.GetExtension(f) == @".osz"))
Task.Run(() => BeatmapDatabase.Import(filePaths));
Task.Run(() => BeatmapManager.Import(filePaths));
else if (filePaths.All(f => Path.GetExtension(f) == @".osr"))
Task.Run(() =>
{
var score = ScoreDatabase.ReadReplayFile(filePaths.First());
var score = ScoreStore.ReadReplayFile(filePaths.First());
Schedule(() => LoadScore(score));
});
}

View File

@ -0,0 +1,35 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Platform;
using osu.Framework.Testing;
using osu.Game;
using osu.Game.Screens.Backgrounds;
namespace osu.Desktop
{
internal class OsuTestBrowser : OsuGameBase
{
protected override void LoadComplete()
{
base.LoadComplete();
LoadComponentAsync(new BackgroundScreenDefault { Depth = 10 }, AddInternal);
// Have to construct this here, rather than in the constructor, because
// we depend on some dependencies to be loaded within OsuGameBase.load().
Add(new TestBrowser());
}
public override void SetHost(GameHost host)
{
base.SetHost(host);
host.UpdateThread.InactiveHz = host.UpdateThread.ActiveHz;
host.DrawThread.InactiveHz = host.DrawThread.ActiveHz;
host.InputThread.InactiveHz = host.InputThread.ActiveHz;
host.Window.CursorState |= CursorState.Hidden;
}
}
}

View File

@ -10,6 +10,7 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using Squirrel;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Graphics;
@ -24,16 +25,14 @@ namespace osu.Desktop.Overlays
public class VersionManager : OverlayContainer
{
private UpdateManager updateManager;
private NotificationManager notificationManager;
protected override bool HideOnEscape => false;
private NotificationOverlay notificationOverlay;
public override bool HandleInput => false;
[BackgroundDependencyLoader]
private void load(NotificationManager notification, OsuColour colours, TextureStore textures, OsuGameBase game)
private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game)
{
notificationManager = notification;
notificationOverlay = notification;
AutoSizeAxes = Axes.Both;
Anchor = Anchor.BottomCentre;
@ -92,12 +91,6 @@ namespace osu.Desktop.Overlays
checkForUpdateAsync();
}
protected override void LoadComplete()
{
base.LoadComplete();
State = Visibility.Visible;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
@ -121,7 +114,7 @@ namespace osu.Desktop.Overlays
if (notification == null)
{
notification = new UpdateProgressNotification { State = ProgressNotificationState.Active };
Schedule(() => notificationManager.Post(notification));
Schedule(() => notificationOverlay.Post(notification));
}
Schedule(() =>
@ -180,7 +173,7 @@ namespace osu.Desktop.Overlays
protected override void PopIn()
{
FadeIn(1000);
this.FadeIn(1000);
}
protected override void PopOut()
@ -191,7 +184,7 @@ namespace osu.Desktop.Overlays
{
private OsuGame game;
protected override Notification CreateCompletionNotification() => new ProgressCompletionNotification()
protected override Notification CreateCompletionNotification() => new ProgressCompletionNotification
{
Text = @"Update ready to install. Click to restart!",
Activated = () =>
@ -207,20 +200,20 @@ namespace osu.Desktop.Overlays
{
this.game = game;
IconContent.Add(new Drawable[]
IconContent.AddRange(new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
ColourInfo = ColourInfo.GradientVertical(colours.YellowDark, colours.Yellow)
Colour = ColourInfo.GradientVertical(colours.YellowDark, colours.Yellow)
},
new TextAwesome
new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.fa_upload,
Colour = Color4.White,
TextSize = 20
Size = new Vector2(20),
}
});
}

View File

@ -3,7 +3,7 @@
using System;
using System.IO;
using osu.Desktop.Beatmaps.IO;
using System.Linq;
using osu.Framework.Desktop;
using osu.Framework.Desktop.Platform;
using osu.Game.IPC;
@ -15,8 +15,6 @@ namespace osu.Desktop
[STAThread]
public static int Main(string[] args)
{
LegacyFilesystemReader.Register();
// Back up the cwd before DesktopGameHost changes it
var cwd = Environment.CurrentDirectory;
@ -36,7 +34,16 @@ namespace osu.Desktop
}
else
{
host.Run(new OsuGameDesktop(args));
switch (args.FirstOrDefault() ?? string.Empty)
{
case "--tests":
host.Run(new OsuTestBrowser());
break;
default:
host.Run(new OsuGameDesktop(args));
break;
}
}
return 0;
}

View File

@ -90,6 +90,21 @@
<PropertyGroup>
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'VisualTests|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<WarningLevel>0</WarningLevel>
<NoStdLib>true</NoStdLib>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<LangVersion>6</LangVersion>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<StartArguments>--tests</StartArguments>
</PropertyGroup>
<ItemGroup>
<Reference Include="DeltaCompressionDotNet, Version=1.1.0.0, Culture=neutral, PublicKeyToken=1d14d6e5194e7f4a, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\DeltaCompressionDotNet.1.1.0\lib\net20\DeltaCompressionDotNet.dll</HintPath>
@ -121,18 +136,23 @@
</Reference>
<Reference Include="mscorlib" />
<Reference Include="NuGet.Squirrel, Version=3.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\NuGet.Squirrel.dll</HintPath>
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.7.5\lib\Net45\NuGet.Squirrel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="OpenTK, Version=2.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll</HintPath>
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SharpCompress, Version=0.17.1.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\SharpCompress.0.17.1\lib\net45\SharpCompress.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Splat, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\Splat.2.0.0\lib\Net45\Splat.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Squirrel, Version=1.5.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.5.2\lib\Net45\Squirrel.dll</HintPath>
<Reference Include="Squirrel, Version=1.7.5.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\squirrel.windows.1.7.5\lib\Net45\Squirrel.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
@ -190,6 +210,10 @@
<Project>{65dc628f-a640-4111-ab35-3a5652bc1e17}</Project>
<Name>osu.Framework.Desktop</Name>
</ProjectReference>
<ProjectReference Include="..\osu-framework\osu.Framework.Testing\osu.Framework.Testing.csproj">
<Project>{007B2356-AB6F-4BD9-96D5-116FC2DCE69A}</Project>
<Name>osu.Framework.Testing</Name>
</ProjectReference>
<ProjectReference Include="..\osu-framework\osu.Framework\osu.Framework.csproj">
<Project>{c76bf5b3-985e-4d39-95fe-97c9c879b83a}</Project>
<Name>osu.Framework</Name>
@ -198,6 +222,10 @@
<Project>{d9a367c9-4c1a-489f-9b05-a0cea2b53b58}</Project>
<Name>osu.Game.Resources</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Desktop.Tests\osu.Desktop.Tests.csproj">
<Project>{230ac4f3-7783-49fb-9aec-b83cda3b9f3d}</Project>
<Name>osu.Desktop.Tests</Name>
</ProjectReference>
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj">
<Project>{c92a607b-1fdd-4954-9f92-03ff547d9080}</Project>
<Name>osu.Game.Rulesets.Osu</Name>
@ -221,13 +249,13 @@
</ItemGroup>
<ItemGroup>
<Compile Include="OsuGameDesktop.cs" />
<Compile Include="OsuTestBrowser.cs" />
<Compile Include="Overlays\VersionManager.cs" />
<Compile Include="Program.cs" />
<Compile Include="Beatmaps\IO\LegacyFilesystemReader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="lazer.ico" />
<EmbeddedResource Include="lazer.ico" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@ -7,7 +7,8 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
<package id="DeltaCompressionDotNet" version="1.1.0" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="Mono.Cecil" version="0.9.6.4" targetFramework="net45" />
<package id="ppy.OpenTK" version="2.0.50727.1341" targetFramework="net45" />
<package id="ppy.OpenTK" version="3.0" targetFramework="net45" />
<package id="SharpCompress" version="0.17.1" targetFramework="net45" />
<package id="Splat" version="2.0.0" targetFramework="net45" />
<package id="squirrel.windows" version="1.5.2" targetFramework="net45" />
<package id="squirrel.windows" version="1.7.5" targetFramework="net45" />
</packages>

View File

@ -8,6 +8,7 @@ using System;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Beatmaps;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.UI;
namespace osu.Game.Rulesets.Catch.Beatmaps
{
@ -15,9 +16,16 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
{
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
protected override IEnumerable<CatchBaseHit> ConvertHitObject(HitObject original, Beatmap beatmap)
protected override IEnumerable<CatchBaseHit> ConvertHitObject(HitObject obj, Beatmap beatmap)
{
yield return null;
if (!(obj is IHasXPosition))
yield break;
yield return new Fruit
{
StartTime = obj.StartTime,
Position = ((IHasXPosition)obj).X / OsuPlayfield.BASE_SIZE.X
};
}
}
}

View File

@ -0,0 +1,27 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.ComponentModel;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Catch
{
public class CatchInputManager : RulesetInputManager<CatchAction>
{
public CatchInputManager(RulesetInfo ruleset)
: base(ruleset, 0, SimultaneousBindingMode.Unique)
{
}
}
public enum CatchAction
{
[Description("Move left")]
MoveLeft,
[Description("Move right")]
MoveRight,
[Description("Engage dash")]
Dash
}
}

View File

@ -1,23 +1,33 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Input;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
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.Framework.Graphics;
using osu.Game.Rulesets.Catch.Scoring;
using osu.Game.Rulesets.Scoring;
using osu.Framework.Input.Bindings;
namespace osu.Game.Rulesets.Catch
{
public class CatchRuleset : Ruleset
{
public override HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchHitRenderer(beatmap, isForCurrentRuleset);
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new CatchRulesetContainer(this, beatmap, isForCurrentRuleset);
public override IEnumerable<KeyBinding> GetDefaultKeyBindings(int variant = 0) => new[]
{
new KeyBinding(InputKey.Z, CatchAction.MoveLeft),
new KeyBinding(InputKey.Left, CatchAction.MoveLeft),
new KeyBinding(InputKey.X, CatchAction.MoveRight),
new KeyBinding(InputKey.Right, CatchAction.MoveRight),
new KeyBinding(InputKey.Shift, CatchAction.Dash),
new KeyBinding(InputKey.Shift, CatchAction.Dash),
};
public override IEnumerable<Mod> GetModsFor(ModType type)
{
@ -28,7 +38,14 @@ namespace osu.Game.Rulesets.Catch
{
new CatchModEasy(),
new CatchModNoFail(),
new CatchModHalfTime(),
new MultiMod
{
Mods = new Mod[]
{
new CatchModHalfTime(),
new CatchModDaycore(),
},
},
};
case ModType.DifficultyIncrease:
@ -76,21 +93,21 @@ namespace osu.Game.Rulesets.Catch
}
}
public override Mod GetAutoplayMod() => new ModAutoplay();
public override string Description => "osu!catch";
public override FontAwesome Icon => FontAwesome.fa_osu_fruits_o;
public override IEnumerable<KeyCounter> CreateGameplayKeys() => new KeyCounter[]
{
new KeyCounterKeyboard(Key.ShiftLeft),
new KeyCounterMouse(MouseButton.Left),
new KeyCounterMouse(MouseButton.Right)
};
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o };
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new CatchDifficultyCalculator(beatmap);
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor();
public override int LegacyID => 2;
public CatchRuleset(RulesetInfo rulesetInfo)
: base(rulesetInfo)
{
}
}
}

View File

@ -32,6 +32,11 @@ namespace osu.Game.Rulesets.Catch.Mods
}
public class CatchModDaycore : ModDaycore
{
public override double ScoreMultiplier => 0.5;
}
public class CatchModDoubleTime : ModDoubleTime
{
public override double ScoreMultiplier => 1.06;

View File

@ -1,39 +1,128 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Graphics.Transforms;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.MathUtils;
using osu.Game.Graphics;
using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Objects.Drawables;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
internal class DrawableFruit : Sprite
public class DrawableFruit : DrawableScrollingHitObject<CatchBaseHit, CatchJudgement>
{
private readonly CatchBaseHit h;
private const float pulp_size = 30;
public DrawableFruit(CatchBaseHit h)
private class Pulp : Circle, IHasAccentColour
{
this.h = h;
public Pulp()
{
Size = new Vector2(pulp_size);
Origin = Anchor.Centre;
Scale = new Vector2(0.1f);
RelativePositionAxes = Axes.Y;
Position = new Vector2(h.Position, -0.1f);
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Radius = 5,
Colour = AccentColour.Opacity(0.5f),
};
}
public Color4 AccentColour { get; set; } = Color4.White;
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
public DrawableFruit(CatchBaseHit h)
: base(h)
{
Texture = textures.Get(@"Menu/logo");
Origin = Anchor.Centre;
Size = new Vector2(pulp_size * 2, pulp_size * 2.6f);
const double duration = 0;
RelativePositionAxes = Axes.Both;
X = h.Position;
Transforms.Add(new TransformPosition { StartTime = h.StartTime - 200, EndTime = h.StartTime, StartValue = new Vector2(h.Position, -0.1f), EndValue = new Vector2(h.Position, 0.9f) });
Transforms.Add(new TransformAlpha { StartTime = h.StartTime + duration + 200, EndTime = h.StartTime + duration + 400, StartValue = 1, EndValue = 0 });
Expire(true);
Colour = new Color4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1);
Rotation = (float)(RNG.NextDouble() - 0.5f) * 40;
}
public Func<CatchBaseHit, bool> CheckPosition;
[BackgroundDependencyLoader]
private void load()
{
Children = new Framework.Graphics.Drawable[]
{
//todo: share this more
new BufferedContainer
{
RelativeSizeAxes = Axes.Both,
CacheDrawnFrameBuffer = true,
Children = new Framework.Graphics.Drawable[]
{
new Pulp
{
RelativePositionAxes = Axes.Both,
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Scale = new Vector2(0.6f),
},
new Pulp
{
RelativePositionAxes = Axes.Both,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Y = -0.08f
},
new Pulp
{
RelativePositionAxes = Axes.Both,
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Y = -0.08f
},
new Pulp
{
RelativePositionAxes = Axes.Both,
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
},
}
}
};
}
protected override CatchJudgement CreateJudgement() => new CatchJudgement();
private const float preempt = 1000;
protected override void CheckJudgement(bool userTriggered)
{
if (Judgement.TimeOffset > 0)
Judgement.Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Hit : HitResult.Miss;
}
protected override void UpdateState(ArmedState state)
{
using (BeginAbsoluteSequence(HitObject.StartTime - preempt))
{
// animation
this.FadeIn(200);
}
switch (state)
{
case ArmedState.Miss:
using (BeginAbsoluteSequence(HitObject.StartTime, true))
this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out);
break;
}
}
}
}

View File

@ -14,11 +14,19 @@ namespace osu.Game.Rulesets.Catch.Scoring
{
}
public CatchScoreProcessor(HitRenderer<CatchBaseHit, CatchJudgement> hitRenderer)
: base(hitRenderer)
public CatchScoreProcessor(RulesetContainer<CatchBaseHit, CatchJudgement> rulesetContainer)
: base(rulesetContainer)
{
}
protected override void Reset()
{
base.Reset();
Health.Value = 1;
Accuracy.Value = 1;
}
protected override void OnNewJudgement(CatchJudgement judgement)
{
}

View File

@ -2,23 +2,65 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.UI;
using OpenTK;
using osu.Game.Rulesets.Catch.Judgements;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Catch.Objects.Drawable;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Catch.UI
{
public class CatchPlayfield : Playfield<CatchBaseHit, CatchJudgement>
public class CatchPlayfield : ScrollingPlayfield<CatchBaseHit, CatchJudgement>
{
public CatchPlayfield()
{
Size = new Vector2(1, 0.9f);
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
protected override Container<Drawable> Content => content;
private readonly Container<Drawable> content;
private readonly CatcherArea catcherArea;
Add(new Box { RelativeSizeAxes = Axes.Both, Alpha = 0.5f });
public CatchPlayfield()
: base(Axes.Y)
{
Reversed.Value = true;
Size = new Vector2(1);
Anchor = Anchor.TopCentre;
Origin = Anchor.TopCentre;
InternalChildren = new Drawable[]
{
content = new Container<Drawable>
{
RelativeSizeAxes = Axes.Both,
},
catcherArea = new CatcherArea
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.BottomLeft,
Origin = Anchor.TopLeft,
Height = 0.3f
}
};
}
public override void Add(DrawableHitObject<CatchBaseHit, CatchJudgement> h)
{
base.Add(h);
var fruit = (DrawableFruit)h;
fruit.CheckPosition = catcherArea.CheckIfWeCanCatch;
fruit.OnJudgement += Fruit_OnJudgement;
}
private void Fruit_OnJudgement(DrawableHitObject<CatchBaseHit, CatchJudgement> obj)
{
if (obj.Judgement.Result == HitResult.Hit)
{
Vector2 screenPosition = obj.ScreenSpaceDrawQuad.Centre;
Remove(obj);
catcherArea.Add(obj, screenPosition);
}
}
}
}
}

View File

@ -1,11 +1,13 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Input;
using osu.Game.Beatmaps;
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.Objects.Drawable;
using osu.Game.Rulesets.Catch.Scoring;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
@ -13,10 +15,10 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Catch.UI
{
public class CatchHitRenderer : HitRenderer<CatchBaseHit, CatchJudgement>
public class CatchRulesetContainer : ScrollingRulesetContainer<CatchPlayfield, CatchBaseHit, CatchJudgement>
{
public CatchHitRenderer(WorkingBeatmap beatmap, bool isForCurrentRuleset)
: base(beatmap, isForCurrentRuleset)
public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap, bool isForCurrentRuleset)
: base(ruleset, beatmap, isForCurrentRuleset)
{
}
@ -26,6 +28,14 @@ namespace osu.Game.Rulesets.Catch.UI
protected override Playfield<CatchBaseHit, CatchJudgement> CreatePlayfield() => new CatchPlayfield();
protected override DrawableHitObject<CatchBaseHit, CatchJudgement> GetVisualRepresentation(CatchBaseHit h) => null;
public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
protected override DrawableHitObject<CatchBaseHit, CatchJudgement> GetVisualRepresentation(CatchBaseHit h)
{
if (h is Fruit)
return new DrawableFruit(h);
return null;
}
}
}

View File

@ -0,0 +1,178 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input.Bindings;
using osu.Framework.MathUtils;
using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawable;
using osu.Game.Rulesets.Objects.Drawables;
using OpenTK;
namespace osu.Game.Rulesets.Catch.UI
{
public class CatcherArea : Container
{
private Catcher catcher;
public void Add(DrawableHitObject<CatchBaseHit, CatchJudgement> fruit, Vector2 screenPosition) => catcher.AddToStack(fruit, screenPosition);
public bool CheckIfWeCanCatch(CatchBaseHit obj) => Math.Abs(catcher.Position.X - obj.Position) < catcher.DrawSize.X / DrawSize.X / 2;
[BackgroundDependencyLoader]
private void load()
{
Children = new Drawable[]
{
catcher = new Catcher
{
RelativePositionAxes = Axes.Both,
Anchor = Anchor.TopLeft,
Origin = Anchor.TopCentre,
X = 0.5f,
}
};
}
protected override void Update()
{
base.Update();
catcher.Size = new Vector2(DrawSize.Y);
}
private class Catcher : Container, IKeyBindingHandler<CatchAction>
{
private Texture texture;
[BackgroundDependencyLoader]
private void load(TextureStore textures)
{
texture = textures.Get(@"Play/Catch/fruit-catcher-idle");
Child = createCatcherSprite();
}
private int currentDirection;
private bool dashing;
protected bool Dashing
{
get { return dashing; }
set
{
if (value == dashing) return;
dashing = value;
if (dashing)
Schedule(addAdditiveSprite);
}
}
private void addAdditiveSprite()
{
if (!dashing) return;
var additive = createCatcherSprite();
additive.RelativePositionAxes = Axes.Both;
additive.BlendingMode = BlendingMode.Additive;
additive.Position = Position;
additive.Scale = Scale;
((CatcherArea)Parent).Add(additive);
additive.FadeTo(0.4f).FadeOut(800, Easing.OutQuint).Expire();
Scheduler.AddDelayed(addAdditiveSprite, 50);
}
private Sprite createCatcherSprite() => new Sprite
{
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
Texture = texture,
OriginPosition = new Vector2(DrawWidth / 2, 10) //temporary until the sprite is aligned correctly.
};
public bool OnPressed(CatchAction action)
{
switch (action)
{
case CatchAction.MoveLeft:
currentDirection--;
return true;
case CatchAction.MoveRight:
currentDirection++;
return true;
case CatchAction.Dash:
Dashing = true;
return true;
}
return false;
}
public bool OnReleased(CatchAction action)
{
switch (action)
{
case CatchAction.MoveLeft:
currentDirection++;
return true;
case CatchAction.MoveRight:
currentDirection--;
return true;
case CatchAction.Dash:
Dashing = false;
return true;
}
return false;
}
protected override void Update()
{
base.Update();
if (currentDirection == 0) return;
float speed = Dashing ? 1.5f : 1;
Scale = new Vector2(Math.Sign(currentDirection), 1);
X = (float)MathHelper.Clamp(X + Math.Sign(currentDirection) * Clock.ElapsedFrameTime / 1800 * speed, 0, 1);
}
public void AddToStack(DrawableHitObject<CatchBaseHit, CatchJudgement> fruit, Vector2 absolutePosition)
{
fruit.RelativePositionAxes = Axes.None;
fruit.Position = new Vector2(ToLocalSpace(absolutePosition).X - DrawSize.X / 2, 0);
fruit.Anchor = Anchor.TopCentre;
fruit.Origin = Anchor.BottomCentre;
fruit.Scale *= 0.7f;
fruit.LifetimeEnd = double.MaxValue;
fruit.Depth = (float)Time.Current;
float distance = fruit.DrawSize.X / 2 * fruit.Scale.X;
while (Children.OfType<DrawableFruit>().Any(f => Vector2.DistanceSquared(f.Position, fruit.Position) < distance * distance))
{
fruit.X += RNG.Next(-5, 5);
fruit.Y -= RNG.Next(0, 5);
}
Add(fruit);
}
}
}
}

View File

@ -33,10 +33,12 @@
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Reference Include="OpenTK, Version=2.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1341\lib\net45\OpenTK.dll</HintPath>
<Reference Include="OpenTK, Version=3.0.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>$(SolutionDir)\packages\ppy.OpenTK.3.0\lib\net45\OpenTK.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Collections" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
@ -49,6 +51,7 @@
<ItemGroup>
<Compile Include="Beatmaps\CatchBeatmapConverter.cs" />
<Compile Include="CatchDifficultyCalculator.cs" />
<Compile Include="CatchInputManager.cs" />
<Compile Include="Scoring\CatchScoreProcessor.cs" />
<Compile Include="Judgements\CatchJudgement.cs" />
<Compile Include="Objects\CatchBaseHit.cs" />
@ -56,7 +59,8 @@
<Compile Include="Objects\Droplet.cs" />
<Compile Include="Objects\Fruit.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="UI\CatchHitRenderer.cs" />
<Compile Include="UI\CatcherArea.cs" />
<Compile Include="UI\CatchRulesetContainer.cs" />
<Compile Include="UI\CatchPlayfield.cs" />
<Compile Include="CatchRuleset.cs" />
<Compile Include="Mods\CatchMod.cs" />

View File

@ -5,5 +5,5 @@ Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-->
<packages>
<package id="ppy.OpenTK" version="2.0.50727.1341" targetFramework="net45" />
<package id="ppy.OpenTK" version="3.0" targetFramework="net45" />
</packages>

View File

@ -10,7 +10,6 @@ using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Mania.Beatmaps.Patterns;
using osu.Game.Rulesets.Mania.MathUtils;
using osu.Game.Database;
using osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy;
using OpenTK;
using osu.Game.Audio;
@ -29,12 +28,20 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
private Pattern lastPattern = new Pattern();
private FastRandom random;
private Beatmap beatmap;
private bool isForCurrentRuleset;
protected override Beatmap<ManiaHitObject> ConvertBeatmap(Beatmap original, bool isForCurrentRuleset)
private readonly int availableColumns;
private readonly bool isForCurrentRuleset;
public ManiaBeatmapConverter(bool isForCurrentRuleset, int availableColumns)
{
this.isForCurrentRuleset = isForCurrentRuleset;
if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns));
this.isForCurrentRuleset = isForCurrentRuleset;
this.availableColumns = availableColumns;
}
protected override Beatmap<ManiaHitObject> ConvertBeatmap(Beatmap original)
{
beatmap = original;
BeatmapDifficulty difficulty = original.BeatmapInfo.Difficulty;
@ -42,7 +49,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate);
random = new FastRandom(seed);
return base.ConvertBeatmap(original, isForCurrentRuleset);
return base.ConvertBeatmap(original);
}
protected override IEnumerable<ManiaHitObject> ConvertHitObject(HitObject original, Beatmap beatmap)
@ -90,7 +97,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
/// <returns>The hit objects generated.</returns>
private IEnumerable<ManiaHitObject> generateSpecific(HitObject original)
{
var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern);
var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, availableColumns, lastPattern);
Pattern newPattern = generator.Generate();
lastPattern = newPattern;
@ -114,14 +121,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
Patterns.PatternGenerator conversion = null;
if (distanceData != null)
conversion = new DistanceObjectPatternGenerator(random, original, beatmap, lastPattern);
conversion = new DistanceObjectPatternGenerator(random, original, beatmap, availableColumns, lastPattern);
else if (endTimeData != null)
conversion = new EndTimeObjectPatternGenerator(random, original, beatmap);
conversion = new EndTimeObjectPatternGenerator(random, original, beatmap, availableColumns);
else if (positionData != null)
{
computeDensity(original.StartTime);
conversion = new HitObjectPatternGenerator(random, original, beatmap, lastPattern, lastTime, lastPosition, density, lastStair);
conversion = new HitObjectPatternGenerator(random, original, beatmap, availableColumns, lastPattern, lastTime, lastPosition, density, lastStair);
recordNote(original.StartTime, positionData.Position);
}
@ -143,8 +150,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
/// </summary>
private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator
{
public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, Pattern previousPattern)
: base(random, hitObject, beatmap, previousPattern)
public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
: base(random, hitObject, beatmap, availableColumns, previousPattern)
{
}

View File

@ -29,8 +29,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
private PatternType convertType;
public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, Pattern previousPattern)
: base(random, hitObject, beatmap, previousPattern)
public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
: base(random, hitObject, beatmap, availableColumns, previousPattern)
{
convertType = PatternType.None;
if (Beatmap.ControlPointInfo.EffectPointAt(hitObject.StartTime).KiaiMode)
@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
// The true distance, accounting for any repeats
double distance = (distanceData?.Distance ?? 0) * repeatCount;
// The velocity of the osu! hit object - calculated as the velocity of a slider
double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.Difficulty.SliderMultiplier / (timingPoint.BeatLength * difficultyPoint.SpeedMultiplier);
double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.Difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier / timingPoint.BeatLength;
// The duration of the osu! hit object
double osuDuration = distance / osuVelocity;
@ -448,7 +448,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
return curveData.RepeatSamples[index];
}
/// <summary>
/// Constructs and adds a note to a pattern.
/// </summary>
@ -480,7 +479,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
Tail = { Samples = sampleInfoListAt(endTime) }
};
newObject = holdNote;
}

View File

@ -15,8 +15,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
private readonly double endTime;
public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap)
: base(random, hitObject, beatmap, new Pattern())
public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns)
: base(random, hitObject, beatmap, availableColumns, new Pattern())
{
var endtimeData = HitObject as IHasEndTime;

View File

@ -20,9 +20,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
private readonly PatternType convertType;
public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair)
: base(random, hitObject, beatmap, previousPattern)
public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair)
: base(random, hitObject, beatmap, availableColumns, previousPattern)
{
if (previousTime > hitObject.StartTime) throw new ArgumentOutOfRangeException(nameof(previousTime));
if (density < 0) throw new ArgumentOutOfRangeException(nameof(density));
StairType = lastStair;
TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime);
@ -33,12 +36,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
float positionSeparation = ((positionData?.Position ?? Vector2.Zero) - previousPosition).Length;
double timeSeparation = hitObject.StartTime - previousTime;
if (timeSeparation <= 125)
{
// More than 120 BPM
convertType |= PatternType.ForceNotStack;
}
if (timeSeparation <= 80)
{
// More than 187 BPM
@ -64,7 +61,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
// More than 111 BPM stream
convertType |= PatternType.Cycle | PatternType.KeepSingle;
}
else if (timeSeparation <= 150 & positionSeparation < 20)
else if (timeSeparation <= 150 && positionSeparation < 20)
{
// More than 100 BPM stream
convertType |= PatternType.ForceStack | PatternType.LowProbability;
@ -401,4 +398,4 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
});
}
}
}
}

View File

@ -4,7 +4,6 @@
using System;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Rulesets.Mania.MathUtils;
using osu.Game.Rulesets.Objects;
using OpenTK;
@ -26,11 +25,15 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
/// </summary>
protected readonly FastRandom Random;
protected PatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, Pattern previousPattern)
: base(hitObject, beatmap, previousPattern)
protected PatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
: base(hitObject, beatmap, availableColumns, previousPattern)
{
Random = random;
if (random == null) throw new ArgumentNullException(nameof(random));
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns));
if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern));
Random = random;
RandomStart = AvailableColumns == 8 ? 1 : 0;
}
@ -63,6 +66,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
/// <returns>The amount of notes to be generated.</returns>
protected int GetRandomNoteCount(double p2, double p3, double p4 = 0, double p5 = 0, double p6 = 0)
{
if (p2 < 0 || p2 > 1) throw new ArgumentOutOfRangeException(nameof(p2));
if (p3 < 0 || p3 > 1) throw new ArgumentOutOfRangeException(nameof(p3));
if (p4 < 0 || p4 > 1) throw new ArgumentOutOfRangeException(nameof(p4));
if (p5 < 0 || p5 > 1) throw new ArgumentOutOfRangeException(nameof(p5));
if (p6 < 0 || p6 > 1) throw new ArgumentOutOfRangeException(nameof(p6));
double val = Random.NextDouble();
if (val >= 1 - p6)
return 6;

View File

@ -32,13 +32,17 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
/// </summary>
protected readonly Beatmap Beatmap;
protected PatternGenerator(HitObject hitObject, Beatmap beatmap, Pattern previousPattern)
protected PatternGenerator(HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
{
PreviousPattern = previousPattern;
if (hitObject == null) throw new ArgumentNullException(nameof(hitObject));
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns));
if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern));
HitObject = hitObject;
Beatmap = beatmap;
AvailableColumns = (int)Math.Round(beatmap.BeatmapInfo.Difficulty.CircleSize);
AvailableColumns = availableColumns;
PreviousPattern = previousPattern;
}
/// <summary>

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Database;
using osu.Game.Beatmaps;
namespace osu.Game.Rulesets.Mania.Judgements
{

View File

@ -6,6 +6,7 @@ using osu.Game.Rulesets.Beatmaps;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
using System.Collections.Generic;
using System;
namespace osu.Game.Rulesets.Mania
{
@ -21,6 +22,6 @@ namespace osu.Game.Rulesets.Mania
return 0;
}
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter() => new ManiaBeatmapConverter();
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter() => new ManiaBeatmapConverter(true, (int)Math.Max(1, Math.Round(Beatmap.BeatmapInfo.Difficulty.CircleSize)));
}
}
}

View File

@ -0,0 +1,21 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Mania
{
public class ManiaInputManager : RulesetInputManager<ManiaAction>
{
public ManiaInputManager(RulesetInfo ruleset)
: base(ruleset, 0, SimultaneousBindingMode.Unique)
{
}
}
public enum ManiaAction
{
// placeholder
}
}

View File

@ -2,13 +2,13 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using osu.Game.Graphics;
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.Framework.Graphics;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Scoring;
@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania
{
public class ManiaRuleset : Ruleset
{
public override HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new ManiaHitRenderer(beatmap, isForCurrentRuleset);
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new ManiaRulesetContainer(this, beatmap, isForCurrentRuleset);
public override IEnumerable<Mod> GetModsFor(ModType type)
{
@ -27,7 +27,14 @@ namespace osu.Game.Rulesets.Mania
{
new ManiaModEasy(),
new ManiaModNoFail(),
new ManiaModHalfTime(),
new MultiMod
{
Mods = new Mod[]
{
new ManiaModHalfTime(),
new ManiaModDaycore(),
},
},
};
case ModType.DifficultyIncrease:
@ -89,6 +96,7 @@ namespace osu.Game.Rulesets.Mania
new ModCinema(),
},
},
new ManiaModGravity()
};
default:
@ -96,16 +104,21 @@ namespace osu.Game.Rulesets.Mania
}
}
public override Mod GetAutoplayMod() => new ModAutoplay();
public override string Description => "osu!mania";
public override FontAwesome Icon => FontAwesome.fa_osu_mania_o;
public override IEnumerable<KeyCounter> CreateGameplayKeys() => new KeyCounter[] { /* Todo: Should be keymod specific */ };
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o };
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new ManiaDifficultyCalculator(beatmap);
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor();
public override int LegacyID => 3;
public ManiaRuleset(RulesetInfo rulesetInfo)
: base(rulesetInfo)
{
}
}
}

Some files were not shown because too many files have changed in this diff Show More