mirror of
https://github.com/ppy/osu.git
synced 2025-02-15 18:52:55 +08:00
Merge remote-tracking branch 'upstream/master' into user-status-wiring
This commit is contained in:
commit
141775d98c
21
README.md
21
README.md
@ -10,6 +10,8 @@ This project is still heavily under development, but is in a state where users a
|
|||||||
|
|
||||||
We are accepting bug reports (please report with as much detail as possible). Feature requests are welcome as long as you read and understand the contribution guidelines listed below.
|
We are accepting bug reports (please report with as much detail as possible). Feature requests are welcome as long as you read and understand the contribution guidelines listed below.
|
||||||
|
|
||||||
|
Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh/home/changelog).
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed.
|
- A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed.
|
||||||
@ -20,17 +22,24 @@ We are accepting bug reports (please report with as much detail as possible). Fe
|
|||||||
|
|
||||||
### Releases
|
### Releases
|
||||||
|
|
||||||
If you are not interested in developing the game, please head over to the [releases](https://github.com/ppy/osu/releases) to download a precompiled build with automatic updating enabled.
|
![](https://puu.sh/DCmvA/f6a74f5fbb.png)
|
||||||
|
|
||||||
- Windows (x64) users should download and run `install.exe`.
|
If you are not interested in developing the game, you can consume our [binary releases](https://github.com/ppy/osu/releases).
|
||||||
- macOS users (10.12 "Sierra" and higher) should download and run `osu.app.zip`.
|
|
||||||
- iOS users can join the [TestFlight beta program](https://t.co/xQJmHkfC18).
|
**Latest build:***
|
||||||
|
|
||||||
|
| [Windows (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | [macOS 10.12+](https://github.com/ppy/osu/releases/latest/download/osu.app.zip) |
|
||||||
|
| ------------- | ------------- |
|
||||||
|
|
||||||
|
- **Linux** users are recommended to self-compile until we have official deployment in place.
|
||||||
|
- **iOS** users can join the [TestFlight beta program](https://t.co/xQJmHkfC18) (note that due to high demand this is regularly full).
|
||||||
|
- **Android** users can self-compile, and expect a public beta soon.
|
||||||
|
|
||||||
If your platform is not listed above, there is still a chance you can manually build it by following the instructions below.
|
If your platform is not listed above, there is still a chance you can manually build it by following the instructions below.
|
||||||
|
|
||||||
### Downloading the source code
|
### Downloading the source code
|
||||||
|
|
||||||
Clone the repository **including submodules**:
|
Clone the repository:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git clone https://github.com/ppy/osu
|
git clone https://github.com/ppy/osu
|
||||||
@ -45,7 +54,7 @@ git pull
|
|||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
Build configurations for the recommended IDEs (listed above) are included. You should use the provided Build/Run functionality of your IDE to get things going. When testing or building new components, it's highly encouraged you use the `VisualTests` project/configuration. More information on this provided below.
|
Build configurations for the recommended IDEs (listed above) are included. You should use the provided Build/Run functionality of your IDE to get things going. When testing or building new components, it's highly encouraged you use the `VisualTests` project/configuration. More information on this provided [below](#contributing).
|
||||||
|
|
||||||
> Visual Studio Code users must run the `Restore` task before any build attempt.
|
> Visual Studio Code users must run the `Restore` task before any build attempt.
|
||||||
|
|
||||||
|
@ -2,13 +2,10 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Lines;
|
using osu.Framework.Graphics.Lines;
|
||||||
using osu.Framework.Graphics.Primitives;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osuTK.Graphics.ES30;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||||
{
|
{
|
||||||
@ -19,8 +16,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
private readonly SliderPath path;
|
private readonly SliderPath path;
|
||||||
protected Path Path => path;
|
protected Path Path => path;
|
||||||
|
|
||||||
private readonly BufferedContainer container;
|
|
||||||
|
|
||||||
public float PathRadius
|
public float PathRadius
|
||||||
{
|
{
|
||||||
get => path.PathRadius;
|
get => path.PathRadius;
|
||||||
@ -44,8 +39,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
path.AccentColour = value;
|
path.AccentColour = value;
|
||||||
|
|
||||||
container.ForceRedraw();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,8 +54,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
path.BorderColour = value;
|
path.BorderColour = value;
|
||||||
|
|
||||||
container.ForceRedraw();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,23 +69,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
path.BorderSize = value;
|
path.BorderSize = value;
|
||||||
|
|
||||||
container.ForceRedraw();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Quad PathDrawQuad => container.ScreenSpaceDrawQuad;
|
|
||||||
|
|
||||||
protected SliderBody()
|
protected SliderBody()
|
||||||
{
|
{
|
||||||
InternalChild = container = new BufferedContainer
|
InternalChild = path = new SliderPath();
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
CacheDrawnFrameBuffer = true,
|
|
||||||
Child = path = new SliderPath { Blending = BlendingMode.None }
|
|
||||||
};
|
|
||||||
|
|
||||||
container.Attach(RenderbufferInternalFormat.DepthComponent16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => path.ReceivePositionalInputAt(screenSpacePos);
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => path.ReceivePositionalInputAt(screenSpacePos);
|
||||||
@ -103,11 +83,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
/// Sets the vertices of the path which should be drawn by this <see cref="SliderBody"/>.
|
/// Sets the vertices of the path which should be drawn by this <see cref="SliderBody"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vertices">The vertices</param>
|
/// <param name="vertices">The vertices</param>
|
||||||
protected void SetVertices(IReadOnlyList<Vector2> vertices)
|
protected void SetVertices(IReadOnlyList<Vector2> vertices) => path.Vertices = vertices;
|
||||||
{
|
|
||||||
path.Vertices = vertices;
|
|
||||||
container.ForceRedraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SliderPath : SmoothPath
|
private class SliderPath : SmoothPath
|
||||||
{
|
{
|
||||||
|
@ -54,7 +54,9 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
|
|
||||||
for (int i = 0; i < max_sprites; i++)
|
for (int i = 0; i < max_sprites; i++)
|
||||||
{
|
{
|
||||||
parts[i].InvalidationID = 0;
|
// InvalidationID 1 forces an update of each part of the cursor trail the first time ApplyState is run on the draw node
|
||||||
|
// This is to prevent garbage data from being sent to the vertex shader, resulting in visual issues on some platforms
|
||||||
|
parts[i].InvalidationID = 1;
|
||||||
parts[i].WasUpdated = true;
|
parts[i].WasUpdated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +212,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
Vector2 pos = parts[i].Position;
|
Vector2 pos = parts[i].Position;
|
||||||
float localTime = parts[i].Time;
|
float localTime = parts[i].Time;
|
||||||
|
|
||||||
texture.DrawQuad(
|
DrawQuad(
|
||||||
|
texture,
|
||||||
new Quad(pos.X - size.X / 2, pos.Y - size.Y / 2, size.X, size.Y),
|
new Quad(pos.X - size.X / 2, pos.Y - size.Y / 2, size.X, size.Y),
|
||||||
DrawColourInfo.Colour,
|
DrawColourInfo.Colour,
|
||||||
null,
|
null,
|
||||||
|
50
osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs
Normal file
50
osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
|
{
|
||||||
|
public class TestSceneFailAnimation : AllPlayersTestScene
|
||||||
|
{
|
||||||
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
|
{
|
||||||
|
Mods.Value = Array.Empty<Mod>();
|
||||||
|
return new FailPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(AllPlayersTestScene),
|
||||||
|
typeof(TestPlayer),
|
||||||
|
typeof(Player),
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override void AddCheckSteps()
|
||||||
|
{
|
||||||
|
AddUntilStep("wait for fail", () => Player.HasFailed);
|
||||||
|
AddUntilStep("wait for fail overlay", () => ((FailPlayer)Player).FailOverlay.State == Visibility.Visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FailPlayer : TestPlayer
|
||||||
|
{
|
||||||
|
public new FailOverlay FailOverlay => base.FailOverlay;
|
||||||
|
|
||||||
|
public FailPlayer()
|
||||||
|
: base(false, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
ScoreProcessor.FailConditions += _ => true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -113,7 +113,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
public void TestPauseAfterFail()
|
public void TestPauseAfterFail()
|
||||||
{
|
{
|
||||||
AddUntilStep("wait for fail", () => Player.HasFailed);
|
AddUntilStep("wait for fail", () => Player.HasFailed);
|
||||||
AddAssert("fail overlay shown", () => Player.FailOverlayVisible);
|
AddUntilStep("fail overlay shown", () => Player.FailOverlayVisible);
|
||||||
|
|
||||||
confirmClockRunning(false);
|
confirmClockRunning(false);
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
FlagName = @"TH",
|
FlagName = @"TH",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Rank = ScoreRank.F,
|
Rank = ScoreRank.D,
|
||||||
PP = 160,
|
PP = 160,
|
||||||
MaxCombo = 1234,
|
MaxCombo = 1234,
|
||||||
TotalScore = 123456,
|
TotalScore = 123456,
|
||||||
|
@ -188,7 +188,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
},
|
},
|
||||||
new ScoreInfo
|
new ScoreInfo
|
||||||
{
|
{
|
||||||
Rank = ScoreRank.F,
|
Rank = ScoreRank.D,
|
||||||
Accuracy = 0.6025,
|
Accuracy = 0.6025,
|
||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
@ -206,7 +206,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
},
|
},
|
||||||
new ScoreInfo
|
new ScoreInfo
|
||||||
{
|
{
|
||||||
Rank = ScoreRank.F,
|
Rank = ScoreRank.D,
|
||||||
Accuracy = 0.5140,
|
Accuracy = 0.5140,
|
||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
@ -224,7 +224,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
},
|
},
|
||||||
new ScoreInfo
|
new ScoreInfo
|
||||||
{
|
{
|
||||||
Rank = ScoreRank.F,
|
Rank = ScoreRank.D,
|
||||||
Accuracy = 0.4222,
|
Accuracy = 0.4222,
|
||||||
MaxCombo = 244,
|
MaxCombo = 244,
|
||||||
TotalScore = 1707827,
|
TotalScore = 1707827,
|
||||||
|
50
osu.Game.Tests/Visual/UserInterface/OsuGridTestScene.cs
Normal file
50
osu.Game.Tests/Visual/UserInterface/OsuGridTestScene.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.UserInterface
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An abstract test case which exposes small cells arranged in a grid.
|
||||||
|
/// Useful for displaying multiple configurations of a tested component at a glance.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class OsuGridTestScene : OsuTestScene
|
||||||
|
{
|
||||||
|
private readonly Drawable[,] cells;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of rows in the grid.
|
||||||
|
/// </summary>
|
||||||
|
protected readonly int Rows;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount of columns in the grid.
|
||||||
|
/// </summary>
|
||||||
|
protected readonly int Cols;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a grid test case with the given dimensions.
|
||||||
|
/// </summary>
|
||||||
|
protected OsuGridTestScene(int rows, int cols)
|
||||||
|
{
|
||||||
|
Rows = rows;
|
||||||
|
Cols = cols;
|
||||||
|
|
||||||
|
GridContainer testContainer;
|
||||||
|
Add(testContainer = new GridContainer { RelativeSizeAxes = Axes.Both });
|
||||||
|
|
||||||
|
cells = new Drawable[rows, cols];
|
||||||
|
for (int r = 0; r < rows; r++)
|
||||||
|
for (int c = 0; c < cols; c++)
|
||||||
|
cells[r, c] = new Container { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
|
testContainer.Content = cells.ToJagged();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Container Cell(int index) => (Container)cells[index / Cols, index % Cols];
|
||||||
|
protected Container Cell(int row, int col) => (Container)cells[row, col];
|
||||||
|
}
|
||||||
|
}
|
@ -84,7 +84,6 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
testLocalCursor();
|
testLocalCursor();
|
||||||
testUserCursorOverride();
|
testUserCursorOverride();
|
||||||
testMultipleLocalCursors();
|
testMultipleLocalCursors();
|
||||||
ReturnUserInput();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -3,13 +3,12 @@
|
|||||||
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Testing;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.UserInterface
|
namespace osu.Game.Tests.Visual.UserInterface
|
||||||
{
|
{
|
||||||
public class TestSceneLoadingAnimation : GridTestScene //todo: this should be an OsuTestScene
|
public class TestSceneLoadingAnimation : OsuGridTestScene
|
||||||
{
|
{
|
||||||
public TestSceneLoadingAnimation()
|
public TestSceneLoadingAnimation()
|
||||||
: base(2, 2)
|
: base(2, 2)
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.UserInterface
|
||||||
|
{
|
||||||
|
public class TestSceneOsuAnimatedButton : OsuGridTestScene
|
||||||
|
{
|
||||||
|
public TestSceneOsuAnimatedButton()
|
||||||
|
: base(3, 2)
|
||||||
|
{
|
||||||
|
Cell(0).Add(new BaseContainer("relative sized")
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
});
|
||||||
|
|
||||||
|
Cell(1).Add(new BaseContainer("auto sized")
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both
|
||||||
|
});
|
||||||
|
|
||||||
|
Cell(2).Add(new BaseContainer("relative Y auto X")
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Y,
|
||||||
|
AutoSizeAxes = Axes.X
|
||||||
|
});
|
||||||
|
|
||||||
|
Cell(3).Add(new BaseContainer("relative X auto Y")
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y
|
||||||
|
});
|
||||||
|
|
||||||
|
Cell(4).Add(new BaseContainer("fixed")
|
||||||
|
{
|
||||||
|
Size = new Vector2(100),
|
||||||
|
});
|
||||||
|
|
||||||
|
Cell(5).Add(new BaseContainer("fixed")
|
||||||
|
{
|
||||||
|
Size = new Vector2(100, 50),
|
||||||
|
});
|
||||||
|
|
||||||
|
AddToggleStep("toggle enabled", toggle =>
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
((BaseContainer)Cell(i).Child).Action = toggle ? () => { } : (Action)null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BaseContainer : OsuAnimatedButton
|
||||||
|
{
|
||||||
|
public BaseContainer(string text)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre;
|
||||||
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
|
Add(new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Text = text
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,194 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.UserInterface
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneOsuHoverContainer : ManualInputManagerTestScene
|
||||||
|
{
|
||||||
|
private OsuHoverTestContainer hoverContainer;
|
||||||
|
private Box colourContainer;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp() => Schedule(() =>
|
||||||
|
{
|
||||||
|
Child = hoverContainer = new OsuHoverTestContainer
|
||||||
|
{
|
||||||
|
Enabled = { Value = true },
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(100),
|
||||||
|
Child = colourContainer = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
doMoveOut();
|
||||||
|
});
|
||||||
|
|
||||||
|
[Description("Checks IsHovered property value on a container when it is hovered/unhovered.")]
|
||||||
|
[TestCase(true, TestName = "Enabled_Check_IsHovered")]
|
||||||
|
[TestCase(false, TestName = "Disabled_Check_IsHovered")]
|
||||||
|
public void TestIsHoveredHasProperValue(bool isEnabled)
|
||||||
|
{
|
||||||
|
setContainerEnabledTo(isEnabled);
|
||||||
|
|
||||||
|
checkNotHovered();
|
||||||
|
|
||||||
|
moveToText();
|
||||||
|
checkHovered();
|
||||||
|
|
||||||
|
moveOut();
|
||||||
|
checkNotHovered();
|
||||||
|
|
||||||
|
moveToText();
|
||||||
|
checkHovered();
|
||||||
|
|
||||||
|
moveOut();
|
||||||
|
checkNotHovered();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Description("Checks colour fading on an enabled container when it is hovered/unhovered.")]
|
||||||
|
public void TestTransitionWhileEnabled()
|
||||||
|
{
|
||||||
|
enableContainer();
|
||||||
|
|
||||||
|
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
|
||||||
|
moveToText();
|
||||||
|
waitUntilColourIs(OsuHoverTestContainer.HOVER_COLOUR);
|
||||||
|
|
||||||
|
moveOut();
|
||||||
|
waitUntilColourIs(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
|
||||||
|
moveToText();
|
||||||
|
waitUntilColourIs(OsuHoverTestContainer.HOVER_COLOUR);
|
||||||
|
|
||||||
|
moveOut();
|
||||||
|
waitUntilColourIs(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Description("Checks colour fading on a disabled container when it is hovered/unhovered.")]
|
||||||
|
public void TestNoTransitionWhileDisabled()
|
||||||
|
{
|
||||||
|
disableContainer();
|
||||||
|
|
||||||
|
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
|
||||||
|
moveToText();
|
||||||
|
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
|
||||||
|
moveOut();
|
||||||
|
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
|
||||||
|
moveToText();
|
||||||
|
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
|
||||||
|
moveOut();
|
||||||
|
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Description("Checks that when a disabled & hovered container gets enabled, colour fading happens")]
|
||||||
|
public void TestBecomesEnabledTransition()
|
||||||
|
{
|
||||||
|
disableContainer();
|
||||||
|
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
|
||||||
|
moveToText();
|
||||||
|
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
|
||||||
|
enableContainer();
|
||||||
|
waitUntilColourIs(OsuHoverTestContainer.HOVER_COLOUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Description("Checks that when an enabled & hovered container gets disabled, colour fading happens")]
|
||||||
|
public void TestBecomesDisabledTransition()
|
||||||
|
{
|
||||||
|
enableContainer();
|
||||||
|
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
|
||||||
|
moveToText();
|
||||||
|
waitUntilColourIs(OsuHoverTestContainer.HOVER_COLOUR);
|
||||||
|
|
||||||
|
disableContainer();
|
||||||
|
waitUntilColourIs(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[Description("Checks that when a hovered container gets enabled and disabled multiple times, colour fading happens")]
|
||||||
|
public void TestDisabledChangesMultipleTimes()
|
||||||
|
{
|
||||||
|
enableContainer();
|
||||||
|
checkColour(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
|
||||||
|
moveToText();
|
||||||
|
waitUntilColourIs(OsuHoverTestContainer.HOVER_COLOUR);
|
||||||
|
|
||||||
|
disableContainer();
|
||||||
|
waitUntilColourIs(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
|
||||||
|
enableContainer();
|
||||||
|
waitUntilColourIs(OsuHoverTestContainer.HOVER_COLOUR);
|
||||||
|
|
||||||
|
disableContainer();
|
||||||
|
waitUntilColourIs(OsuHoverTestContainer.IDLE_COLOUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableContainer() => setContainerEnabledTo(true);
|
||||||
|
|
||||||
|
private void disableContainer() => setContainerEnabledTo(false);
|
||||||
|
|
||||||
|
private void setContainerEnabledTo(bool newValue)
|
||||||
|
{
|
||||||
|
string word = newValue ? "Enable" : "Disable";
|
||||||
|
AddStep($"{word} container", () => hoverContainer.Enabled.Value = newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveToText() => AddStep("Move mouse to text", () => InputManager.MoveMouseTo(hoverContainer));
|
||||||
|
|
||||||
|
private void moveOut() => AddStep("Move out", doMoveOut);
|
||||||
|
|
||||||
|
private void checkHovered() => AddAssert("Check hovered", () => hoverContainer.IsHovered);
|
||||||
|
|
||||||
|
private void checkNotHovered() => AddAssert("Check not hovered", () => !hoverContainer.IsHovered);
|
||||||
|
|
||||||
|
private void checkColour(ColourInfo expectedColour)
|
||||||
|
=> AddAssert($"Check colour to be '{expectedColour}'", () => currentColour.Equals(expectedColour));
|
||||||
|
|
||||||
|
private void waitUntilColourIs(ColourInfo expectedColour)
|
||||||
|
=> AddUntilStep($"Wait until hover colour is {expectedColour}", () => currentColour.Equals(expectedColour));
|
||||||
|
|
||||||
|
private ColourInfo currentColour => colourContainer.DrawColourInfo.Colour;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Moves the cursor to top left corner of the screen
|
||||||
|
/// </summary>
|
||||||
|
private void doMoveOut()
|
||||||
|
=> InputManager.MoveMouseTo(new Vector2(InputManager.ScreenSpaceDrawQuad.TopLeft.X, InputManager.ScreenSpaceDrawQuad.TopLeft.Y));
|
||||||
|
|
||||||
|
private sealed class OsuHoverTestContainer : OsuHoverContainer
|
||||||
|
{
|
||||||
|
public static readonly Color4 HOVER_COLOUR = Color4.Red;
|
||||||
|
public static readonly Color4 IDLE_COLOUR = Color4.Green;
|
||||||
|
|
||||||
|
public OsuHoverTestContainer()
|
||||||
|
{
|
||||||
|
HoverColour = HOVER_COLOUR;
|
||||||
|
IdleColour = IDLE_COLOUR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,10 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
@ -12,22 +16,24 @@ using osu.Game.Beatmaps;
|
|||||||
|
|
||||||
namespace osu.Game.Audio
|
namespace osu.Game.Audio
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// A central store for the retrieval of <see cref="PreviewTrack"/>s.
|
|
||||||
/// </summary>
|
|
||||||
public class PreviewTrackManager : Component
|
public class PreviewTrackManager : Component
|
||||||
{
|
{
|
||||||
private readonly BindableDouble muteBindable = new BindableDouble();
|
private readonly BindableDouble muteBindable = new BindableDouble();
|
||||||
|
|
||||||
private AudioManager audio;
|
private AudioManager audio;
|
||||||
private ITrackStore trackStore;
|
private PreviewTrackStore trackStore;
|
||||||
|
|
||||||
private TrackManagerPreviewTrack current;
|
private TrackManagerPreviewTrack current;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio, FrameworkConfigManager config)
|
private void load(AudioManager audio, FrameworkConfigManager config)
|
||||||
{
|
{
|
||||||
trackStore = audio.GetTrackStore(new OnlineStore());
|
// this is a temporary solution to get around muting ourselves.
|
||||||
|
// todo: update this once we have a BackgroundTrackManager or similar.
|
||||||
|
trackStore = new PreviewTrackStore(new OnlineStore());
|
||||||
|
|
||||||
|
audio.AddItem(trackStore);
|
||||||
|
trackStore.AddAdjustment(AdjustableProperty.Volume, audio.VolumeTrack);
|
||||||
|
|
||||||
this.audio = audio;
|
this.audio = audio;
|
||||||
|
|
||||||
@ -103,5 +109,46 @@ namespace osu.Game.Audio
|
|||||||
|
|
||||||
protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo?.OnlineBeatmapSetID}.mp3");
|
protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo?.OnlineBeatmapSetID}.mp3");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class PreviewTrackStore : AudioCollectionManager<AdjustableAudioComponent>, ITrackStore
|
||||||
|
{
|
||||||
|
private readonly IResourceStore<byte[]> store;
|
||||||
|
|
||||||
|
internal PreviewTrackStore(IResourceStore<byte[]> store)
|
||||||
|
{
|
||||||
|
this.store = store;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Track GetVirtual(double length = double.PositiveInfinity)
|
||||||
|
{
|
||||||
|
if (IsDisposed) throw new ObjectDisposedException($"Cannot retrieve items for an already disposed {nameof(PreviewTrackStore)}");
|
||||||
|
|
||||||
|
var track = new TrackVirtual(length);
|
||||||
|
AddItem(track);
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Track Get(string name)
|
||||||
|
{
|
||||||
|
if (IsDisposed) throw new ObjectDisposedException($"Cannot retrieve items for an already disposed {nameof(PreviewTrackStore)}");
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(name)) return null;
|
||||||
|
|
||||||
|
var dataStream = store.GetStream(name);
|
||||||
|
|
||||||
|
if (dataStream == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Track track = new TrackBass(dataStream);
|
||||||
|
AddItem(track);
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Track> GetAsync(string name) => Task.Run(() => Get(name));
|
||||||
|
|
||||||
|
public Stream GetStream(string name) => store.GetStream(name);
|
||||||
|
|
||||||
|
public IEnumerable<string> GetAvailableResources() => store.GetAvailableResources();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,6 +342,7 @@ namespace osu.Game.Beatmaps
|
|||||||
OnlineBeatmapSetID = beatmap.BeatmapInfo.BeatmapSet?.OnlineBeatmapSetID,
|
OnlineBeatmapSetID = beatmap.BeatmapInfo.BeatmapSet?.OnlineBeatmapSetID,
|
||||||
Beatmaps = new List<BeatmapInfo>(),
|
Beatmaps = new List<BeatmapInfo>(),
|
||||||
Metadata = beatmap.Metadata,
|
Metadata = beatmap.Metadata,
|
||||||
|
DateAdded = DateTimeOffset.UtcNow
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -20,6 +21,8 @@ namespace osu.Game.Beatmaps
|
|||||||
set => onlineBeatmapSetID = value > 0 ? value : null;
|
set => onlineBeatmapSetID = value > 0 ? value : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DateTimeOffset DateAdded { get; set; }
|
||||||
|
|
||||||
public BeatmapSetOnlineStatus Status { get; set; } = BeatmapSetOnlineStatus.None;
|
public BeatmapSetOnlineStatus Status { get; set; } = BeatmapSetOnlineStatus.None;
|
||||||
|
|
||||||
public BeatmapMetadata Metadata { get; set; }
|
public BeatmapMetadata Metadata { get; set; }
|
||||||
|
@ -15,6 +15,8 @@ namespace osu.Game.Configuration
|
|||||||
|
|
||||||
public int? Variant { get; set; }
|
public int? Variant { get; set; }
|
||||||
|
|
||||||
|
public int? SkinInfoID { get; set; }
|
||||||
|
|
||||||
[Column("Key")]
|
[Column("Key")]
|
||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
|
|
||||||
|
@ -214,7 +214,6 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
base.Draw(vertexAction);
|
base.Draw(vertexAction);
|
||||||
|
|
||||||
shader.Bind();
|
shader.Bind();
|
||||||
texture.TextureGL.Bind();
|
|
||||||
|
|
||||||
Vector2 localInflationAmount = edge_smoothness * DrawInfo.MatrixInverse.ExtractScale().Xy;
|
Vector2 localInflationAmount = edge_smoothness * DrawInfo.MatrixInverse.ExtractScale().Xy;
|
||||||
|
|
||||||
@ -231,7 +230,8 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
ColourInfo colourInfo = DrawColourInfo.Colour;
|
ColourInfo colourInfo = DrawColourInfo.Colour;
|
||||||
colourInfo.ApplyChild(particle.Colour);
|
colourInfo.ApplyChild(particle.Colour);
|
||||||
|
|
||||||
texture.DrawTriangle(
|
DrawTriangle(
|
||||||
|
texture,
|
||||||
triangle,
|
triangle,
|
||||||
colourInfo,
|
colourInfo,
|
||||||
null,
|
null,
|
||||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Graphics.Containers
|
|||||||
{
|
{
|
||||||
if (AutoSizeAxes != Axes.None)
|
if (AutoSizeAxes != Axes.None)
|
||||||
{
|
{
|
||||||
content.RelativeSizeAxes = RelativeSizeAxes;
|
content.RelativeSizeAxes = (Axes.Both & ~AutoSizeAxes);
|
||||||
content.AutoSizeAxes = AutoSizeAxes;
|
content.AutoSizeAxes = AutoSizeAxes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,13 @@ namespace osu.Game.Graphics.Containers
|
|||||||
{
|
{
|
||||||
Enabled.ValueChanged += e =>
|
Enabled.ValueChanged += e =>
|
||||||
{
|
{
|
||||||
if (!e.NewValue)
|
if (isHovered)
|
||||||
unhover();
|
{
|
||||||
|
if (e.NewValue)
|
||||||
|
fadeIn();
|
||||||
|
else
|
||||||
|
fadeOut();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,28 +38,28 @@ namespace osu.Game.Graphics.Containers
|
|||||||
|
|
||||||
protected override bool OnHover(HoverEvent e)
|
protected override bool OnHover(HoverEvent e)
|
||||||
{
|
{
|
||||||
|
if (isHovered)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
isHovered = true;
|
||||||
|
|
||||||
if (!Enabled.Value)
|
if (!Enabled.Value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
EffectTargets.ForEach(d => d.FadeColour(HoverColour, FADE_DURATION, Easing.OutQuint));
|
fadeIn();
|
||||||
isHovered = true;
|
|
||||||
|
|
||||||
return base.OnHover(e);
|
return base.OnHover(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnHoverLost(HoverLostEvent e)
|
protected override void OnHoverLost(HoverLostEvent e)
|
||||||
{
|
|
||||||
unhover();
|
|
||||||
base.OnHoverLost(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void unhover()
|
|
||||||
{
|
{
|
||||||
if (!isHovered)
|
if (!isHovered)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
isHovered = false;
|
isHovered = false;
|
||||||
EffectTargets.ForEach(d => d.FadeColour(IdleColour, FADE_DURATION, Easing.OutQuint));
|
fadeOut();
|
||||||
|
|
||||||
|
base.OnHoverLost(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -69,5 +74,9 @@ namespace osu.Game.Graphics.Containers
|
|||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
EffectTargets.ForEach(d => d.FadeColour(IdleColour));
|
EffectTargets.ForEach(d => d.FadeColour(IdleColour));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fadeIn() => EffectTargets.ForEach(d => d.FadeColour(HoverColour, FADE_DURATION, Easing.OutQuint));
|
||||||
|
|
||||||
|
private void fadeOut() => EffectTargets.ForEach(d => d.FadeColour(IdleColour, FADE_DURATION, Easing.OutQuint));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
Content.RelativeSizeAxes = Axes.None;
|
Content.RelativeSizeAxes = Axes.None;
|
||||||
|
Content.AutoSizeAxes = Axes.None;
|
||||||
Content.Size = value;
|
Content.Size = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,12 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
{
|
{
|
||||||
|
if (AutoSizeAxes != Axes.None)
|
||||||
|
{
|
||||||
|
content.RelativeSizeAxes = (Axes.Both & ~AutoSizeAxes);
|
||||||
|
content.AutoSizeAxes = AutoSizeAxes;
|
||||||
|
}
|
||||||
|
|
||||||
Enabled.BindValueChanged(enabled => this.FadeColour(enabled.NewValue ? Color4.White : colours.Gray9, 200, Easing.OutQuint), true);
|
Enabled.BindValueChanged(enabled => this.FadeColour(enabled.NewValue ? Color4.White : colours.Gray9, 200, Easing.OutQuint), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
498
osu.Game/Migrations/20190525060824_SkinSettings.Designer.cs
generated
Normal file
498
osu.Game/Migrations/20190525060824_SkinSettings.Designer.cs
generated
Normal file
@ -0,0 +1,498 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using osu.Game.Database;
|
||||||
|
|
||||||
|
namespace osu.Game.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(OsuDbContext))]
|
||||||
|
[Migration("20190525060824_SkinSettings")]
|
||||||
|
partial class SkinSettings
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<float>("ApproachRate");
|
||||||
|
|
||||||
|
b.Property<float>("CircleSize");
|
||||||
|
|
||||||
|
b.Property<float>("DrainRate");
|
||||||
|
|
||||||
|
b.Property<float>("OverallDifficulty");
|
||||||
|
|
||||||
|
b.Property<double>("SliderMultiplier");
|
||||||
|
|
||||||
|
b.Property<double>("SliderTickRate");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapDifficulty");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AudioLeadIn");
|
||||||
|
|
||||||
|
b.Property<int>("BaseDifficultyID");
|
||||||
|
|
||||||
|
b.Property<int>("BeatDivisor");
|
||||||
|
|
||||||
|
b.Property<int>("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.Property<bool>("Countdown");
|
||||||
|
|
||||||
|
b.Property<double>("DistanceSpacing");
|
||||||
|
|
||||||
|
b.Property<int>("GridSize");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<bool>("Hidden");
|
||||||
|
|
||||||
|
b.Property<bool>("LetterboxInBreaks");
|
||||||
|
|
||||||
|
b.Property<string>("MD5Hash");
|
||||||
|
|
||||||
|
b.Property<int?>("MetadataID");
|
||||||
|
|
||||||
|
b.Property<int?>("OnlineBeatmapID");
|
||||||
|
|
||||||
|
b.Property<string>("Path");
|
||||||
|
|
||||||
|
b.Property<int>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<bool>("SpecialStyle");
|
||||||
|
|
||||||
|
b.Property<float>("StackLeniency");
|
||||||
|
|
||||||
|
b.Property<double>("StarDifficulty");
|
||||||
|
|
||||||
|
b.Property<int>("Status");
|
||||||
|
|
||||||
|
b.Property<string>("StoredBookmarks");
|
||||||
|
|
||||||
|
b.Property<double>("TimelineZoom");
|
||||||
|
|
||||||
|
b.Property<string>("Version");
|
||||||
|
|
||||||
|
b.Property<bool>("WidescreenStoryboard");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("BaseDifficultyID");
|
||||||
|
|
||||||
|
b.HasIndex("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("Hash");
|
||||||
|
|
||||||
|
b.HasIndex("MD5Hash");
|
||||||
|
|
||||||
|
b.HasIndex("MetadataID");
|
||||||
|
|
||||||
|
b.HasIndex("OnlineBeatmapID")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Artist");
|
||||||
|
|
||||||
|
b.Property<string>("ArtistUnicode");
|
||||||
|
|
||||||
|
b.Property<string>("AudioFile");
|
||||||
|
|
||||||
|
b.Property<string>("AuthorString")
|
||||||
|
.HasColumnName("Author");
|
||||||
|
|
||||||
|
b.Property<string>("BackgroundFile");
|
||||||
|
|
||||||
|
b.Property<int>("PreviewTime");
|
||||||
|
|
||||||
|
b.Property<string>("Source");
|
||||||
|
|
||||||
|
b.Property<string>("Tags");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("TitleUnicode");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapMetadata");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.Property<int>("FileInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("FileInfoID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapSetFileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("DeletePending");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<int?>("MetadataID");
|
||||||
|
|
||||||
|
b.Property<int?>("OnlineBeatmapSetID");
|
||||||
|
|
||||||
|
b.Property<bool>("Protected");
|
||||||
|
|
||||||
|
b.Property<int>("Status");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("DeletePending");
|
||||||
|
|
||||||
|
b.HasIndex("Hash")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("MetadataID");
|
||||||
|
|
||||||
|
b.HasIndex("OnlineBeatmapSetID")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("BeatmapSetInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.HasColumnName("Key");
|
||||||
|
|
||||||
|
b.Property<int?>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<int?>("SkinInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("StringValue")
|
||||||
|
.HasColumnName("Value");
|
||||||
|
|
||||||
|
b.Property<int?>("Variant");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("SkinInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID", "Variant");
|
||||||
|
|
||||||
|
b.ToTable("Settings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.IO.FileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<int>("ReferenceCount");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("Hash")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("ReferenceCount");
|
||||||
|
|
||||||
|
b.ToTable("FileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("IntAction")
|
||||||
|
.HasColumnName("Action");
|
||||||
|
|
||||||
|
b.Property<string>("KeysString")
|
||||||
|
.HasColumnName("Keys");
|
||||||
|
|
||||||
|
b.Property<int?>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<int?>("Variant");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("IntAction");
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID", "Variant");
|
||||||
|
|
||||||
|
b.ToTable("KeyBinding");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int?>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Available");
|
||||||
|
|
||||||
|
b.Property<string>("InstantiationInfo");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<string>("ShortName");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("Available");
|
||||||
|
|
||||||
|
b.HasIndex("ShortName")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("RulesetInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("FileInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<int?>("ScoreInfoID");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("FileInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("ScoreInfoID");
|
||||||
|
|
||||||
|
b.ToTable("ScoreFileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<double>("Accuracy")
|
||||||
|
.HasColumnType("DECIMAL(1,4)");
|
||||||
|
|
||||||
|
b.Property<int>("BeatmapInfoID");
|
||||||
|
|
||||||
|
b.Property<int>("Combo");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("Date");
|
||||||
|
|
||||||
|
b.Property<bool>("DeletePending");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<int>("MaxCombo");
|
||||||
|
|
||||||
|
b.Property<string>("ModsJson")
|
||||||
|
.HasColumnName("Mods");
|
||||||
|
|
||||||
|
b.Property<long?>("OnlineScoreID");
|
||||||
|
|
||||||
|
b.Property<double?>("PP");
|
||||||
|
|
||||||
|
b.Property<int>("Rank");
|
||||||
|
|
||||||
|
b.Property<int>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<string>("StatisticsJson")
|
||||||
|
.HasColumnName("Statistics");
|
||||||
|
|
||||||
|
b.Property<long>("TotalScore");
|
||||||
|
|
||||||
|
b.Property<long?>("UserID")
|
||||||
|
.HasColumnName("UserID");
|
||||||
|
|
||||||
|
b.Property<string>("UserString")
|
||||||
|
.HasColumnName("User");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("BeatmapInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("OnlineScoreID")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID");
|
||||||
|
|
||||||
|
b.ToTable("ScoreInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("FileInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<int>("SkinInfoID");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("FileInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("SkinInfoID");
|
||||||
|
|
||||||
|
b.ToTable("SkinFileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Skinning.SkinInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Creator");
|
||||||
|
|
||||||
|
b.Property<bool>("DeletePending");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("DeletePending");
|
||||||
|
|
||||||
|
b.HasIndex("Hash")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("SkinInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BaseDifficultyID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet")
|
||||||
|
.WithMany("Beatmaps")
|
||||||
|
.HasForeignKey("BeatmapSetInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
|
||||||
|
.WithMany("Beatmaps")
|
||||||
|
.HasForeignKey("MetadataID");
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RulesetID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("BeatmapSetInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FileInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
|
||||||
|
.WithMany("BeatmapSets")
|
||||||
|
.HasForeignKey("MetadataID");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Skinning.SkinInfo")
|
||||||
|
.WithMany("Settings")
|
||||||
|
.HasForeignKey("SkinInfoID");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FileInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Scoring.ScoreInfo")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("ScoreInfoID");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapInfo", "Beatmap")
|
||||||
|
.WithMany("Scores")
|
||||||
|
.HasForeignKey("BeatmapInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RulesetID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FileInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Skinning.SkinInfo")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("SkinInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
54
osu.Game/Migrations/20190525060824_SkinSettings.cs
Normal file
54
osu.Game/Migrations/20190525060824_SkinSettings.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace osu.Game.Migrations
|
||||||
|
{
|
||||||
|
public partial class SkinSettings : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.Sql(@"create table Settings_dg_tmp
|
||||||
|
(
|
||||||
|
ID INTEGER not null
|
||||||
|
constraint PK_Settings
|
||||||
|
primary key autoincrement,
|
||||||
|
Key TEXT not null,
|
||||||
|
RulesetID INTEGER,
|
||||||
|
Value TEXT,
|
||||||
|
Variant INTEGER,
|
||||||
|
SkinInfoID int
|
||||||
|
constraint Settings_SkinInfo_ID_fk
|
||||||
|
references SkinInfo
|
||||||
|
on delete restrict
|
||||||
|
);
|
||||||
|
|
||||||
|
insert into Settings_dg_tmp(ID, Key, RulesetID, Value, Variant) select ID, Key, RulesetID, Value, Variant from Settings;
|
||||||
|
|
||||||
|
drop table Settings;
|
||||||
|
|
||||||
|
alter table Settings_dg_tmp rename to Settings;
|
||||||
|
|
||||||
|
create index IX_Settings_RulesetID_Variant
|
||||||
|
on Settings (RulesetID, Variant);
|
||||||
|
|
||||||
|
create index Settings_SkinInfoID_index
|
||||||
|
on Settings (SkinInfoID);
|
||||||
|
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_Settings_SkinInfo_SkinInfoID",
|
||||||
|
table: "Settings");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_Settings_SkinInfoID",
|
||||||
|
table: "Settings");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "SkinInfoID",
|
||||||
|
table: "Settings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
489
osu.Game/Migrations/20190605091246_AddDateAddedColumnToBeatmapSet.Designer.cs
generated
Normal file
489
osu.Game/Migrations/20190605091246_AddDateAddedColumnToBeatmapSet.Designer.cs
generated
Normal file
@ -0,0 +1,489 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using osu.Game.Database;
|
||||||
|
|
||||||
|
namespace osu.Game.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(OsuDbContext))]
|
||||||
|
[Migration("20190605091246_AddDateAddedColumnToBeatmapSet")]
|
||||||
|
partial class AddDateAddedColumnToBeatmapSet
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<float>("ApproachRate");
|
||||||
|
|
||||||
|
b.Property<float>("CircleSize");
|
||||||
|
|
||||||
|
b.Property<float>("DrainRate");
|
||||||
|
|
||||||
|
b.Property<float>("OverallDifficulty");
|
||||||
|
|
||||||
|
b.Property<double>("SliderMultiplier");
|
||||||
|
|
||||||
|
b.Property<double>("SliderTickRate");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapDifficulty");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("AudioLeadIn");
|
||||||
|
|
||||||
|
b.Property<int>("BaseDifficultyID");
|
||||||
|
|
||||||
|
b.Property<int>("BeatDivisor");
|
||||||
|
|
||||||
|
b.Property<int>("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.Property<bool>("Countdown");
|
||||||
|
|
||||||
|
b.Property<double>("DistanceSpacing");
|
||||||
|
|
||||||
|
b.Property<int>("GridSize");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<bool>("Hidden");
|
||||||
|
|
||||||
|
b.Property<bool>("LetterboxInBreaks");
|
||||||
|
|
||||||
|
b.Property<string>("MD5Hash");
|
||||||
|
|
||||||
|
b.Property<int?>("MetadataID");
|
||||||
|
|
||||||
|
b.Property<int?>("OnlineBeatmapID");
|
||||||
|
|
||||||
|
b.Property<string>("Path");
|
||||||
|
|
||||||
|
b.Property<int>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<bool>("SpecialStyle");
|
||||||
|
|
||||||
|
b.Property<float>("StackLeniency");
|
||||||
|
|
||||||
|
b.Property<double>("StarDifficulty");
|
||||||
|
|
||||||
|
b.Property<int>("Status");
|
||||||
|
|
||||||
|
b.Property<string>("StoredBookmarks");
|
||||||
|
|
||||||
|
b.Property<double>("TimelineZoom");
|
||||||
|
|
||||||
|
b.Property<string>("Version");
|
||||||
|
|
||||||
|
b.Property<bool>("WidescreenStoryboard");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("BaseDifficultyID");
|
||||||
|
|
||||||
|
b.HasIndex("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("Hash");
|
||||||
|
|
||||||
|
b.HasIndex("MD5Hash");
|
||||||
|
|
||||||
|
b.HasIndex("MetadataID");
|
||||||
|
|
||||||
|
b.HasIndex("OnlineBeatmapID")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Artist");
|
||||||
|
|
||||||
|
b.Property<string>("ArtistUnicode");
|
||||||
|
|
||||||
|
b.Property<string>("AudioFile");
|
||||||
|
|
||||||
|
b.Property<string>("AuthorString")
|
||||||
|
.HasColumnName("Author");
|
||||||
|
|
||||||
|
b.Property<string>("BackgroundFile");
|
||||||
|
|
||||||
|
b.Property<int>("PreviewTime");
|
||||||
|
|
||||||
|
b.Property<string>("Source");
|
||||||
|
|
||||||
|
b.Property<string>("Tags");
|
||||||
|
|
||||||
|
b.Property<string>("Title");
|
||||||
|
|
||||||
|
b.Property<string>("TitleUnicode");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapMetadata");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.Property<int>("FileInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("BeatmapSetInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("FileInfoID");
|
||||||
|
|
||||||
|
b.ToTable("BeatmapSetFileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("DateAdded");
|
||||||
|
|
||||||
|
b.Property<bool>("DeletePending");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<int?>("MetadataID");
|
||||||
|
|
||||||
|
b.Property<int?>("OnlineBeatmapSetID");
|
||||||
|
|
||||||
|
b.Property<bool>("Protected");
|
||||||
|
|
||||||
|
b.Property<int>("Status");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("DeletePending");
|
||||||
|
|
||||||
|
b.HasIndex("Hash")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("MetadataID");
|
||||||
|
|
||||||
|
b.HasIndex("OnlineBeatmapSetID")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("BeatmapSetInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.HasColumnName("Key");
|
||||||
|
|
||||||
|
b.Property<int?>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<string>("StringValue")
|
||||||
|
.HasColumnName("Value");
|
||||||
|
|
||||||
|
b.Property<int?>("Variant");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID", "Variant");
|
||||||
|
|
||||||
|
b.ToTable("Settings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.IO.FileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<int>("ReferenceCount");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("Hash")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("ReferenceCount");
|
||||||
|
|
||||||
|
b.ToTable("FileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("IntAction")
|
||||||
|
.HasColumnName("Action");
|
||||||
|
|
||||||
|
b.Property<string>("KeysString")
|
||||||
|
.HasColumnName("Keys");
|
||||||
|
|
||||||
|
b.Property<int?>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<int?>("Variant");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("IntAction");
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID", "Variant");
|
||||||
|
|
||||||
|
b.ToTable("KeyBinding");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int?>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<bool>("Available");
|
||||||
|
|
||||||
|
b.Property<string>("InstantiationInfo");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.Property<string>("ShortName");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("Available");
|
||||||
|
|
||||||
|
b.HasIndex("ShortName")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("RulesetInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("FileInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<int?>("ScoreInfoID");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("FileInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("ScoreInfoID");
|
||||||
|
|
||||||
|
b.ToTable("ScoreFileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<double>("Accuracy")
|
||||||
|
.HasColumnType("DECIMAL(1,4)");
|
||||||
|
|
||||||
|
b.Property<int>("BeatmapInfoID");
|
||||||
|
|
||||||
|
b.Property<int>("Combo");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("Date");
|
||||||
|
|
||||||
|
b.Property<bool>("DeletePending");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<int>("MaxCombo");
|
||||||
|
|
||||||
|
b.Property<string>("ModsJson")
|
||||||
|
.HasColumnName("Mods");
|
||||||
|
|
||||||
|
b.Property<long?>("OnlineScoreID");
|
||||||
|
|
||||||
|
b.Property<double?>("PP");
|
||||||
|
|
||||||
|
b.Property<int>("Rank");
|
||||||
|
|
||||||
|
b.Property<int>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<string>("StatisticsJson")
|
||||||
|
.HasColumnName("Statistics");
|
||||||
|
|
||||||
|
b.Property<long>("TotalScore");
|
||||||
|
|
||||||
|
b.Property<long?>("UserID")
|
||||||
|
.HasColumnName("UserID");
|
||||||
|
|
||||||
|
b.Property<string>("UserString")
|
||||||
|
.HasColumnName("User");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("BeatmapInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("OnlineScoreID")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("RulesetID");
|
||||||
|
|
||||||
|
b.ToTable("ScoreInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<int>("FileInfoID");
|
||||||
|
|
||||||
|
b.Property<string>("Filename")
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Property<int>("SkinInfoID");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("FileInfoID");
|
||||||
|
|
||||||
|
b.HasIndex("SkinInfoID");
|
||||||
|
|
||||||
|
b.ToTable("SkinFileInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Skinning.SkinInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ID")
|
||||||
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<string>("Creator");
|
||||||
|
|
||||||
|
b.Property<bool>("DeletePending");
|
||||||
|
|
||||||
|
b.Property<string>("Hash");
|
||||||
|
|
||||||
|
b.Property<string>("Name");
|
||||||
|
|
||||||
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("DeletePending");
|
||||||
|
|
||||||
|
b.HasIndex("Hash")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("SkinInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BaseDifficultyID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet")
|
||||||
|
.WithMany("Beatmaps")
|
||||||
|
.HasForeignKey("BeatmapSetInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
|
||||||
|
.WithMany("Beatmaps")
|
||||||
|
.HasForeignKey("MetadataID");
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RulesetID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("BeatmapSetInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FileInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
|
||||||
|
.WithMany("BeatmapSets")
|
||||||
|
.HasForeignKey("MetadataID");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FileInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Scoring.ScoreInfo")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("ScoreInfoID");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Beatmaps.BeatmapInfo", "Beatmap")
|
||||||
|
.WithMany("Scores")
|
||||||
|
.HasForeignKey("BeatmapInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("RulesetID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("FileInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
b.HasOne("osu.Game.Skinning.SkinInfo")
|
||||||
|
.WithMany("Files")
|
||||||
|
.HasForeignKey("SkinInfoID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace osu.Game.Migrations
|
||||||
|
{
|
||||||
|
public partial class AddDateAddedColumnToBeatmapSet : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<DateTimeOffset>(
|
||||||
|
name: "DateAdded",
|
||||||
|
table: "BeatmapSetInfo",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: new DateTimeOffset(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new TimeSpan(0, 0, 0, 0, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "DateAdded",
|
||||||
|
table: "BeatmapSetInfo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -166,6 +166,8 @@ namespace osu.Game.Migrations
|
|||||||
b.Property<int>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd();
|
.ValueGeneratedOnAdd();
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("DateAdded");
|
||||||
|
|
||||||
b.Property<bool>("DeletePending");
|
b.Property<bool>("DeletePending");
|
||||||
|
|
||||||
b.Property<string>("Hash");
|
b.Property<string>("Hash");
|
||||||
@ -203,6 +205,8 @@ namespace osu.Game.Migrations
|
|||||||
|
|
||||||
b.Property<int?>("RulesetID");
|
b.Property<int?>("RulesetID");
|
||||||
|
|
||||||
|
b.Property<int?>("SkinInfoID");
|
||||||
|
|
||||||
b.Property<string>("StringValue")
|
b.Property<string>("StringValue")
|
||||||
.HasColumnName("Value");
|
.HasColumnName("Value");
|
||||||
|
|
||||||
@ -210,6 +214,8 @@ namespace osu.Game.Migrations
|
|||||||
|
|
||||||
b.HasKey("ID");
|
b.HasKey("ID");
|
||||||
|
|
||||||
|
b.HasIndex("SkinInfoID");
|
||||||
|
|
||||||
b.HasIndex("RulesetID", "Variant");
|
b.HasIndex("RulesetID", "Variant");
|
||||||
|
|
||||||
b.ToTable("Settings");
|
b.ToTable("Settings");
|
||||||
@ -442,6 +448,13 @@ namespace osu.Game.Migrations
|
|||||||
.HasForeignKey("MetadataID");
|
.HasForeignKey("MetadataID");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("osu.Game.Skinning.SkinInfo")
|
||||||
|
.WithMany("Settings")
|
||||||
|
.HasForeignKey("SkinInfoID");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b =>
|
modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||||
|
@ -36,7 +36,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
public string MessageHtml { get; set; }
|
public string MessageHtml { get; set; }
|
||||||
|
|
||||||
[JsonProperty("major")]
|
[JsonProperty("major")]
|
||||||
public bool? Major { get; set; }
|
public bool Major { get; set; }
|
||||||
|
|
||||||
[JsonProperty("created_at")]
|
[JsonProperty("created_at")]
|
||||||
public DateTimeOffset? CreatedAt { get; set; }
|
public DateTimeOffset? CreatedAt { get; set; }
|
||||||
|
@ -46,7 +46,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
Text = "#1",
|
Text = "#1",
|
||||||
Font = OsuFont.GetFont(size: 30, weight: FontWeight.Bold, italics: true)
|
Font = OsuFont.GetFont(size: 30, weight: FontWeight.Bold, italics: true)
|
||||||
},
|
},
|
||||||
rank = new DrawableRank(ScoreRank.F)
|
rank = new DrawableRank(ScoreRank.D)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
@ -13,6 +13,7 @@ using System.Text.RegularExpressions;
|
|||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Changelog
|
namespace osu.Game.Overlays.Changelog
|
||||||
{
|
{
|
||||||
@ -45,8 +46,12 @@ namespace osu.Game.Overlays.Changelog
|
|||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var categoryEntries in build.ChangelogEntries.GroupBy(b => b.Category).OrderBy(c => c.Key))
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colours)
|
||||||
|
{
|
||||||
|
foreach (var categoryEntries in Build.ChangelogEntries.GroupBy(b => b.Category).OrderBy(c => c.Key))
|
||||||
{
|
{
|
||||||
ChangelogEntries.Add(new OsuSpriteText
|
ChangelogEntries.Add(new OsuSpriteText
|
||||||
{
|
{
|
||||||
@ -69,34 +74,69 @@ namespace osu.Game.Overlays.Changelog
|
|||||||
Margin = new MarginPadding { Vertical = 5 },
|
Margin = new MarginPadding { Vertical = 5 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var entryColour = entry.Major ? colours.YellowLight : Color4.White;
|
||||||
|
|
||||||
title.AddIcon(FontAwesome.Solid.Check, t =>
|
title.AddIcon(FontAwesome.Solid.Check, t =>
|
||||||
{
|
{
|
||||||
t.Font = fontSmall;
|
t.Font = fontSmall;
|
||||||
|
t.Colour = entryColour;
|
||||||
t.Padding = new MarginPadding { Left = -17, Right = 5 };
|
t.Padding = new MarginPadding { Left = -17, Right = 5 };
|
||||||
});
|
});
|
||||||
|
|
||||||
title.AddText(entry.Title, t => { t.Font = fontLarge; });
|
title.AddText(entry.Title, t =>
|
||||||
|
{
|
||||||
|
t.Font = fontLarge;
|
||||||
|
t.Colour = entryColour;
|
||||||
|
});
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(entry.Repository))
|
if (!string.IsNullOrEmpty(entry.Repository))
|
||||||
{
|
{
|
||||||
title.AddText(" (", t => t.Font = fontLarge);
|
title.AddText(" (", t =>
|
||||||
|
{
|
||||||
|
t.Font = fontLarge;
|
||||||
|
t.Colour = entryColour;
|
||||||
|
});
|
||||||
title.AddLink($"{entry.Repository.Replace("ppy/", "")}#{entry.GithubPullRequestId}", entry.GithubUrl, Online.Chat.LinkAction.External,
|
title.AddLink($"{entry.Repository.Replace("ppy/", "")}#{entry.GithubPullRequestId}", entry.GithubUrl, Online.Chat.LinkAction.External,
|
||||||
creationParameters: t => { t.Font = fontLarge; });
|
creationParameters: t =>
|
||||||
title.AddText(")", t => t.Font = fontLarge);
|
{
|
||||||
|
t.Font = fontLarge;
|
||||||
|
t.Colour = entryColour;
|
||||||
|
});
|
||||||
|
title.AddText(")", t =>
|
||||||
|
{
|
||||||
|
t.Font = fontLarge;
|
||||||
|
t.Colour = entryColour;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
title.AddText(" by ", t => t.Font = fontMedium);
|
title.AddText(" by ", t =>
|
||||||
|
{
|
||||||
|
t.Font = fontMedium;
|
||||||
|
t.Colour = entryColour;
|
||||||
|
});
|
||||||
|
|
||||||
if (entry.GithubUser.UserId != null)
|
if (entry.GithubUser.UserId != null)
|
||||||
title.AddUserLink(new User
|
title.AddUserLink(new User
|
||||||
{
|
{
|
||||||
Username = entry.GithubUser.OsuUsername,
|
Username = entry.GithubUser.OsuUsername,
|
||||||
Id = entry.GithubUser.UserId.Value
|
Id = entry.GithubUser.UserId.Value
|
||||||
}, t => t.Font = fontMedium);
|
}, t =>
|
||||||
|
{
|
||||||
|
t.Font = fontMedium;
|
||||||
|
t.Colour = entryColour;
|
||||||
|
});
|
||||||
else if (entry.GithubUser.GithubUrl != null)
|
else if (entry.GithubUser.GithubUrl != null)
|
||||||
title.AddLink(entry.GithubUser.DisplayName, entry.GithubUser.GithubUrl, Online.Chat.LinkAction.External, null, null, t => t.Font = fontMedium);
|
title.AddLink(entry.GithubUser.DisplayName, entry.GithubUser.GithubUrl, Online.Chat.LinkAction.External, null, null, t =>
|
||||||
|
{
|
||||||
|
t.Font = fontMedium;
|
||||||
|
t.Colour = entryColour;
|
||||||
|
});
|
||||||
else
|
else
|
||||||
title.AddText(entry.GithubUser.DisplayName, t => t.Font = fontSmall);
|
title.AddText(entry.GithubUser.DisplayName, t =>
|
||||||
|
{
|
||||||
|
t.Font = fontSmall;
|
||||||
|
t.Colour = entryColour;
|
||||||
|
});
|
||||||
|
|
||||||
ChangelogEntries.Add(title);
|
ChangelogEntries.Add(title);
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
@ -17,6 +19,11 @@ namespace osu.Game.Overlays
|
|||||||
{
|
{
|
||||||
private Box overlay;
|
private Box overlay;
|
||||||
|
|
||||||
|
private readonly BindableDouble audioVolume = new BindableDouble(1);
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private AudioManager audio { get; set; }
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
@ -33,7 +40,19 @@ namespace osu.Game.Overlays
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Progress.ValueChanged += p => overlay.Alpha = (float)p.NewValue;
|
Progress.ValueChanged += p =>
|
||||||
|
{
|
||||||
|
audioVolume.Value = 1 - p.NewValue;
|
||||||
|
overlay.Alpha = (float)p.NewValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
audio.Tracks.AddAdjustment(AdjustableProperty.Volume, audioVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
audio.Tracks.RemoveAdjustment(AdjustableProperty.Volume, audioVolume);
|
||||||
|
base.Dispose(isDisposing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,40 +1,40 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osuTK;
|
|
||||||
using osuTK.Graphics;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.Backgrounds;
|
|
||||||
using osu.Game.Graphics.Sprites;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Backgrounds;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays.Mods.Sections;
|
using osu.Game.Overlays.Mods.Sections;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens;
|
using osu.Game.Screens;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Mods
|
namespace osu.Game.Overlays.Mods
|
||||||
{
|
{
|
||||||
public class ModSelectOverlay : WaveOverlayContainer
|
public class ModSelectOverlay : WaveOverlayContainer
|
||||||
{
|
{
|
||||||
private const float content_width = 0.8f;
|
|
||||||
|
|
||||||
protected Color4 LowMultiplierColour, HighMultiplierColour;
|
|
||||||
|
|
||||||
protected readonly TriangleButton DeselectAllButton;
|
protected readonly TriangleButton DeselectAllButton;
|
||||||
protected readonly OsuSpriteText MultiplierLabel, UnrankedLabel;
|
protected readonly TriangleButton CloseButton;
|
||||||
private readonly FillFlowContainer footerContainer;
|
|
||||||
|
protected readonly OsuSpriteText MultiplierLabel;
|
||||||
|
protected readonly OsuSpriteText UnrankedLabel;
|
||||||
|
|
||||||
protected override bool BlockNonPositionalInput => false;
|
protected override bool BlockNonPositionalInput => false;
|
||||||
|
|
||||||
@ -46,154 +46,14 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
protected readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
protected readonly IBindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
protected Color4 LowMultiplierColour;
|
||||||
private void load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio, Bindable<IReadOnlyList<Mod>> mods)
|
protected Color4 HighMultiplierColour;
|
||||||
{
|
|
||||||
LowMultiplierColour = colours.Red;
|
|
||||||
HighMultiplierColour = colours.Green;
|
|
||||||
UnrankedLabel.Colour = colours.Blue;
|
|
||||||
|
|
||||||
Ruleset.BindTo(ruleset);
|
private const float content_width = 0.8f;
|
||||||
if (mods != null) SelectedMods.BindTo(mods);
|
private readonly FillFlowContainer footerContainer;
|
||||||
|
|
||||||
sampleOn = audio.Samples.Get(@"UI/check-on");
|
|
||||||
sampleOff = audio.Samples.Get(@"UI/check-off");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
Ruleset.BindValueChanged(rulesetChanged, true);
|
|
||||||
SelectedMods.BindValueChanged(selectedModsChanged, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
|
||||||
{
|
|
||||||
base.Dispose(isDisposing);
|
|
||||||
|
|
||||||
Ruleset.UnbindAll();
|
|
||||||
SelectedMods.UnbindAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void rulesetChanged(ValueChangedEvent<RulesetInfo> e)
|
|
||||||
{
|
|
||||||
if (e.NewValue == null) return;
|
|
||||||
|
|
||||||
var instance = e.NewValue.CreateInstance();
|
|
||||||
|
|
||||||
foreach (ModSection section in ModSectionsContainer.Children)
|
|
||||||
section.Mods = instance.GetModsFor(section.ModType);
|
|
||||||
|
|
||||||
// attempt to re-select any already selected mods.
|
|
||||||
// this may be the first time we are receiving the ruleset, in which case they will still match.
|
|
||||||
selectedModsChanged(new ValueChangedEvent<IReadOnlyList<Mod>>(SelectedMods.Value, SelectedMods.Value));
|
|
||||||
|
|
||||||
// write the mods back to the SelectedMods bindable in the case a change was not applicable.
|
|
||||||
// this generally isn't required as the previous line will perform deselection; just here for safety.
|
|
||||||
refreshSelectedMods();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectedModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> e)
|
|
||||||
{
|
|
||||||
foreach (ModSection section in ModSectionsContainer.Children)
|
|
||||||
section.SelectTypes(e.NewValue.Select(m => m.GetType()).ToList());
|
|
||||||
|
|
||||||
updateMods();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateMods()
|
|
||||||
{
|
|
||||||
double multiplier = 1.0;
|
|
||||||
bool ranked = true;
|
|
||||||
|
|
||||||
foreach (Mod mod in SelectedMods.Value)
|
|
||||||
{
|
|
||||||
multiplier *= mod.ScoreMultiplier;
|
|
||||||
ranked &= mod.Ranked;
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiplierLabel.Text = $"{multiplier:N2}x";
|
|
||||||
if (multiplier > 1.0)
|
|
||||||
MultiplierLabel.FadeColour(HighMultiplierColour, 200);
|
|
||||||
else if (multiplier < 1.0)
|
|
||||||
MultiplierLabel.FadeColour(LowMultiplierColour, 200);
|
|
||||||
else
|
|
||||||
MultiplierLabel.FadeColour(Color4.White, 200);
|
|
||||||
|
|
||||||
UnrankedLabel.FadeTo(ranked ? 0 : 1, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void PopOut()
|
|
||||||
{
|
|
||||||
base.PopOut();
|
|
||||||
|
|
||||||
footerContainer.MoveToX(footerContainer.DrawSize.X, WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
|
|
||||||
footerContainer.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
|
|
||||||
|
|
||||||
foreach (ModSection section in ModSectionsContainer.Children)
|
|
||||||
{
|
|
||||||
section.ButtonsContainer.TransformSpacingTo(new Vector2(100f, 0f), WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
|
|
||||||
section.ButtonsContainer.MoveToX(100f, WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
|
|
||||||
section.ButtonsContainer.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void PopIn()
|
|
||||||
{
|
|
||||||
base.PopIn();
|
|
||||||
|
|
||||||
footerContainer.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint);
|
|
||||||
footerContainer.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint);
|
|
||||||
|
|
||||||
foreach (ModSection section in ModSectionsContainer.Children)
|
|
||||||
{
|
|
||||||
section.ButtonsContainer.TransformSpacingTo(new Vector2(50f, 0f), WaveContainer.APPEAR_DURATION, Easing.OutQuint);
|
|
||||||
section.ButtonsContainer.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint);
|
|
||||||
section.ButtonsContainer.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeselectAll()
|
|
||||||
{
|
|
||||||
foreach (ModSection section in ModSectionsContainer.Children)
|
|
||||||
section.DeselectAll();
|
|
||||||
|
|
||||||
refreshSelectedMods();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deselect one or more mods.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="modTypes">The types of <see cref="Mod"/>s which should be deselected.</param>
|
|
||||||
/// <param name="immediate">Set to true to bypass animations and update selections immediately.</param>
|
|
||||||
public void DeselectTypes(Type[] modTypes, bool immediate = false)
|
|
||||||
{
|
|
||||||
if (modTypes.Length == 0) return;
|
|
||||||
|
|
||||||
foreach (ModSection section in ModSectionsContainer.Children)
|
|
||||||
section.DeselectTypes(modTypes, immediate);
|
|
||||||
}
|
|
||||||
|
|
||||||
private SampleChannel sampleOn, sampleOff;
|
private SampleChannel sampleOn, sampleOff;
|
||||||
|
|
||||||
private void modButtonPressed(Mod selectedMod)
|
|
||||||
{
|
|
||||||
if (selectedMod != null)
|
|
||||||
{
|
|
||||||
if (State == Visibility.Visible) sampleOn?.Play();
|
|
||||||
DeselectTypes(selectedMod.IncompatibleMods, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (State == Visibility.Visible) sampleOff?.Play();
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshSelectedMods();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void refreshSelectedMods() => SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray();
|
|
||||||
|
|
||||||
public ModSelectOverlay()
|
public ModSelectOverlay()
|
||||||
{
|
{
|
||||||
Waves.FirstWaveColour = OsuColour.FromHex(@"19b0e2");
|
Waves.FirstWaveColour = OsuColour.FromHex(@"19b0e2");
|
||||||
@ -364,6 +224,16 @@ namespace osu.Game.Overlays.Mods
|
|||||||
Right = 20
|
Right = 20
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
CloseButton = new TriangleButton
|
||||||
|
{
|
||||||
|
Width = 180,
|
||||||
|
Text = "Close",
|
||||||
|
Action = Hide,
|
||||||
|
Margin = new MarginPadding
|
||||||
|
{
|
||||||
|
Right = 20
|
||||||
|
}
|
||||||
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = @"Score Multiplier:",
|
Text = @"Score Multiplier:",
|
||||||
@ -401,5 +271,171 @@ namespace osu.Game.Overlays.Mods
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader(true)]
|
||||||
|
private void load(OsuColour colours, IBindable<RulesetInfo> ruleset, AudioManager audio, Bindable<IReadOnlyList<Mod>> mods)
|
||||||
|
{
|
||||||
|
LowMultiplierColour = colours.Red;
|
||||||
|
HighMultiplierColour = colours.Green;
|
||||||
|
UnrankedLabel.Colour = colours.Blue;
|
||||||
|
|
||||||
|
Ruleset.BindTo(ruleset);
|
||||||
|
if (mods != null) SelectedMods.BindTo(mods);
|
||||||
|
|
||||||
|
sampleOn = audio.Samples.Get(@"UI/check-on");
|
||||||
|
sampleOff = audio.Samples.Get(@"UI/check-off");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeselectAll()
|
||||||
|
{
|
||||||
|
foreach (var section in ModSectionsContainer.Children)
|
||||||
|
section.DeselectAll();
|
||||||
|
|
||||||
|
refreshSelectedMods();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deselect one or more mods.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="modTypes">The types of <see cref="Mod"/>s which should be deselected.</param>
|
||||||
|
/// <param name="immediate">Set to true to bypass animations and update selections immediately.</param>
|
||||||
|
public void DeselectTypes(Type[] modTypes, bool immediate = false)
|
||||||
|
{
|
||||||
|
if (modTypes.Length == 0) return;
|
||||||
|
|
||||||
|
foreach (var section in ModSectionsContainer.Children)
|
||||||
|
section.DeselectTypes(modTypes, immediate);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
Ruleset.BindValueChanged(rulesetChanged, true);
|
||||||
|
SelectedMods.BindValueChanged(selectedModsChanged, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PopOut()
|
||||||
|
{
|
||||||
|
base.PopOut();
|
||||||
|
|
||||||
|
footerContainer.MoveToX(footerContainer.DrawSize.X, WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
|
||||||
|
footerContainer.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
|
||||||
|
|
||||||
|
foreach (var section in ModSectionsContainer.Children)
|
||||||
|
{
|
||||||
|
section.ButtonsContainer.TransformSpacingTo(new Vector2(100f, 0f), WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
|
||||||
|
section.ButtonsContainer.MoveToX(100f, WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
|
||||||
|
section.ButtonsContainer.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.InSine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PopIn()
|
||||||
|
{
|
||||||
|
base.PopIn();
|
||||||
|
|
||||||
|
footerContainer.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint);
|
||||||
|
footerContainer.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint);
|
||||||
|
|
||||||
|
foreach (var section in ModSectionsContainer.Children)
|
||||||
|
{
|
||||||
|
section.ButtonsContainer.TransformSpacingTo(new Vector2(50f, 0f), WaveContainer.APPEAR_DURATION, Easing.OutQuint);
|
||||||
|
section.ButtonsContainer.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint);
|
||||||
|
section.ButtonsContainer.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool OnKeyDown(KeyDownEvent e)
|
||||||
|
{
|
||||||
|
switch (e.Key)
|
||||||
|
{
|
||||||
|
case Key.Number1:
|
||||||
|
DeselectAllButton.Click();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Key.Number2:
|
||||||
|
CloseButton.Click();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnKeyDown(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rulesetChanged(ValueChangedEvent<RulesetInfo> e)
|
||||||
|
{
|
||||||
|
if (e.NewValue == null) return;
|
||||||
|
|
||||||
|
var instance = e.NewValue.CreateInstance();
|
||||||
|
|
||||||
|
foreach (var section in ModSectionsContainer.Children)
|
||||||
|
section.Mods = instance.GetModsFor(section.ModType);
|
||||||
|
|
||||||
|
// attempt to re-select any already selected mods.
|
||||||
|
// this may be the first time we are receiving the ruleset, in which case they will still match.
|
||||||
|
selectedModsChanged(new ValueChangedEvent<IReadOnlyList<Mod>>(SelectedMods.Value, SelectedMods.Value));
|
||||||
|
|
||||||
|
// write the mods back to the SelectedMods bindable in the case a change was not applicable.
|
||||||
|
// this generally isn't required as the previous line will perform deselection; just here for safety.
|
||||||
|
refreshSelectedMods();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectedModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> e)
|
||||||
|
{
|
||||||
|
foreach (var section in ModSectionsContainer.Children)
|
||||||
|
section.SelectTypes(e.NewValue.Select(m => m.GetType()).ToList());
|
||||||
|
|
||||||
|
updateMods();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMods()
|
||||||
|
{
|
||||||
|
var multiplier = 1.0;
|
||||||
|
var ranked = true;
|
||||||
|
|
||||||
|
foreach (var mod in SelectedMods.Value)
|
||||||
|
{
|
||||||
|
multiplier *= mod.ScoreMultiplier;
|
||||||
|
ranked &= mod.Ranked;
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiplierLabel.Text = $"{multiplier:N2}x";
|
||||||
|
if (multiplier > 1.0)
|
||||||
|
MultiplierLabel.FadeColour(HighMultiplierColour, 200);
|
||||||
|
else if (multiplier < 1.0)
|
||||||
|
MultiplierLabel.FadeColour(LowMultiplierColour, 200);
|
||||||
|
else
|
||||||
|
MultiplierLabel.FadeColour(Color4.White, 200);
|
||||||
|
|
||||||
|
UnrankedLabel.FadeTo(ranked ? 0 : 1, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void modButtonPressed(Mod selectedMod)
|
||||||
|
{
|
||||||
|
if (selectedMod != null)
|
||||||
|
{
|
||||||
|
if (State == Visibility.Visible) sampleOn?.Play();
|
||||||
|
DeselectTypes(selectedMod.IncompatibleMods, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (State == Visibility.Visible) sampleOff?.Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshSelectedMods();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshSelectedMods() => SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray();
|
||||||
|
|
||||||
|
#region Disposal
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
Ruleset.UnbindAll();
|
||||||
|
SelectedMods.UnbindAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,6 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Direction = FillDirection.Vertical,
|
|
||||||
Spacing = new Vector2(0, 2),
|
Spacing = new Vector2(0, 2),
|
||||||
},
|
},
|
||||||
MoreButton = new ShowMoreButton
|
MoreButton = new ShowMoreButton
|
||||||
|
@ -31,6 +31,11 @@ namespace osu.Game.Overlays.Settings.Sections.Debug
|
|||||||
LabelText = "Bypass caching (slow)",
|
LabelText = "Bypass caching (slow)",
|
||||||
Bindable = config.GetBindable<bool>(DebugSetting.BypassCaching)
|
Bindable = config.GetBindable<bool>(DebugSetting.BypassCaching)
|
||||||
},
|
},
|
||||||
|
new SettingsCheckbox
|
||||||
|
{
|
||||||
|
LabelText = "Bypass front-to-back render pass",
|
||||||
|
Bindable = config.GetBindable<bool>(DebugSetting.BypassFrontToBackPass)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
|
|
||||||
private Bindable<ScalingMode> scalingMode;
|
private Bindable<ScalingMode> scalingMode;
|
||||||
private Bindable<Size> sizeFullscreen;
|
private Bindable<Size> sizeFullscreen;
|
||||||
private readonly BindableList<WindowMode> windowModes = new BindableList<WindowMode>();
|
private readonly IBindableList<WindowMode> windowModes = new BindableList<WindowMode>();
|
||||||
|
|
||||||
private OsuGameBase game;
|
private OsuGameBase game;
|
||||||
private SettingsDropdown<Size> resolutionDropdown;
|
private SettingsDropdown<Size> resolutionDropdown;
|
||||||
|
@ -31,6 +31,7 @@ namespace osu.Game.Overlays.Toolbar
|
|||||||
public ToolbarRulesetSelector()
|
public ToolbarRulesetSelector()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Y;
|
RelativeSizeAxes = Axes.Y;
|
||||||
|
AutoSizeAxes = Axes.X;
|
||||||
|
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
@ -111,12 +112,6 @@ namespace osu.Game.Overlays.Toolbar
|
|||||||
|
|
||||||
private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300);
|
private void disabledChanged(bool isDisabled) => this.FadeColour(isDisabled ? Color4.Gray : Color4.White, 300);
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
Size = new Vector2(modeButtons.DrawSize.X, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void rulesetChanged(ValueChangedEvent<RulesetInfo> e)
|
private void rulesetChanged(ValueChangedEvent<RulesetInfo> e)
|
||||||
{
|
{
|
||||||
foreach (ToolbarRulesetButton m in modeButtons.Children.Cast<ToolbarRulesetButton>())
|
foreach (ToolbarRulesetButton m in modeButtons.Children.Cast<ToolbarRulesetButton>())
|
||||||
|
@ -179,7 +179,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
shader.GetUniform<Vector2>("flashlightSize").UpdateValue(ref flashlightSize);
|
shader.GetUniform<Vector2>("flashlightSize").UpdateValue(ref flashlightSize);
|
||||||
shader.GetUniform<float>("flashlightDim").UpdateValue(ref flashlightDim);
|
shader.GetUniform<float>("flashlightDim").UpdateValue(ref flashlightDim);
|
||||||
|
|
||||||
Texture.WhitePixel.DrawQuad(screenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction);
|
DrawQuad(Texture.WhitePixel, screenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction);
|
||||||
|
|
||||||
shader.Unbind();
|
shader.Unbind();
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The playfield.
|
/// The playfield.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Playfield Playfield => playfield.Value;
|
public override Playfield Playfield => playfield.Value;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Place to put drawables above hit objects but below UI.
|
/// Place to put drawables above hit objects but below UI.
|
||||||
@ -342,6 +342,11 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly BindableBool IsPaused = new BindableBool();
|
public readonly BindableBool IsPaused = new BindableBool();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The playfield.
|
||||||
|
/// </summary>
|
||||||
|
public abstract Playfield Playfield { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The frame-stable clock which is being used for playfield display.
|
/// The frame-stable clock which is being used for playfield display.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -7,10 +7,7 @@ namespace osu.Game.Scoring
|
|||||||
{
|
{
|
||||||
public enum ScoreRank
|
public enum ScoreRank
|
||||||
{
|
{
|
||||||
[Description(@"F")]
|
[Description(@"D")]
|
||||||
F,
|
|
||||||
|
|
||||||
[Description(@"F")]
|
|
||||||
D,
|
D,
|
||||||
|
|
||||||
[Description(@"C")]
|
[Description(@"C")]
|
||||||
|
@ -189,7 +189,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
base.Draw(vertexAction);
|
base.Draw(vertexAction);
|
||||||
|
|
||||||
shader.Bind();
|
shader.Bind();
|
||||||
texture.TextureGL.Bind();
|
|
||||||
|
|
||||||
Vector2 inflation = DrawInfo.MatrixInverse.ExtractScale().Xy;
|
Vector2 inflation = DrawInfo.MatrixInverse.ExtractScale().Xy;
|
||||||
|
|
||||||
@ -224,7 +223,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
Vector2Extensions.Transform(barPosition + bottomOffset + amplitudeOffset, DrawInfo.Matrix)
|
Vector2Extensions.Transform(barPosition + bottomOffset + amplitudeOffset, DrawInfo.Matrix)
|
||||||
);
|
);
|
||||||
|
|
||||||
texture.DrawQuad(
|
DrawQuad(
|
||||||
|
texture,
|
||||||
rectangle,
|
rectangle,
|
||||||
colourInfo,
|
colourInfo,
|
||||||
null,
|
null,
|
||||||
|
113
osu.Game/Screens/Play/FailAnimation.cs
Normal file
113
osu.Game/Screens/Play/FailAnimation.cs
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Play
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manage the animation to be applied when a player fails.
|
||||||
|
/// Single file; automatically disposed after use.
|
||||||
|
/// </summary>
|
||||||
|
public class FailAnimation : Component
|
||||||
|
{
|
||||||
|
public Action OnComplete;
|
||||||
|
|
||||||
|
private readonly DrawableRuleset drawableRuleset;
|
||||||
|
|
||||||
|
private readonly BindableDouble trackFreq = new BindableDouble(1);
|
||||||
|
|
||||||
|
private Track track;
|
||||||
|
|
||||||
|
private const float duration = 2500;
|
||||||
|
|
||||||
|
private SampleChannel failSample;
|
||||||
|
|
||||||
|
public FailAnimation(DrawableRuleset drawableRuleset)
|
||||||
|
{
|
||||||
|
this.drawableRuleset = drawableRuleset;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(AudioManager audio, IBindable<WorkingBeatmap> beatmap)
|
||||||
|
{
|
||||||
|
track = beatmap.Value.Track;
|
||||||
|
failSample = audio.Samples.Get(@"Gameplay/failsound");
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool started;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start the fail animation playing.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException">Thrown if started more than once.</exception>
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
if (started) throw new InvalidOperationException("Animation cannot be started more than once.");
|
||||||
|
|
||||||
|
started = true;
|
||||||
|
|
||||||
|
failSample.Play();
|
||||||
|
|
||||||
|
this.TransformBindableTo(trackFreq, 0, duration).OnComplete(_ =>
|
||||||
|
{
|
||||||
|
OnComplete?.Invoke();
|
||||||
|
Expire();
|
||||||
|
});
|
||||||
|
|
||||||
|
track.AddAdjustment(AdjustableProperty.Frequency, trackFreq);
|
||||||
|
|
||||||
|
applyToPlayfield(drawableRuleset.Playfield);
|
||||||
|
drawableRuleset.Playfield.HitObjectContainer.FlashColour(Color4.Red, 500);
|
||||||
|
drawableRuleset.Playfield.HitObjectContainer.FadeOut(duration / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
if (!started)
|
||||||
|
return;
|
||||||
|
|
||||||
|
applyToPlayfield(drawableRuleset.Playfield);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly List<DrawableHitObject> appliedObjects = new List<DrawableHitObject>();
|
||||||
|
|
||||||
|
private void applyToPlayfield(Playfield playfield)
|
||||||
|
{
|
||||||
|
foreach (var nested in playfield.NestedPlayfields)
|
||||||
|
applyToPlayfield(nested);
|
||||||
|
|
||||||
|
foreach (DrawableHitObject obj in playfield.HitObjectContainer.AliveObjects)
|
||||||
|
{
|
||||||
|
if (appliedObjects.Contains(obj))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
obj.RotateTo(RNG.NextSingle(-90, 90), duration);
|
||||||
|
obj.ScaleTo(obj.Scale * 0.5f, duration);
|
||||||
|
obj.MoveToOffset(new Vector2(0, 400), duration);
|
||||||
|
appliedObjects.Add(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
track?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
@ -176,7 +176,8 @@ namespace osu.Game.Screens.Play
|
|||||||
fadeOut(true);
|
fadeOut(true);
|
||||||
Restart();
|
Restart();
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
failAnimation = new FailAnimation(DrawableRuleset) { OnComplete = onFailComplete, }
|
||||||
};
|
};
|
||||||
|
|
||||||
DrawableRuleset.HasReplayLoaded.BindValueChanged(e => HUDOverlay.HoldToQuit.PauseOnFocusLost = !e.NewValue && PauseOnFocusLost, true);
|
DrawableRuleset.HasReplayLoaded.BindValueChanged(e => HUDOverlay.HoldToQuit.PauseOnFocusLost = !e.NewValue && PauseOnFocusLost, true);
|
||||||
@ -348,13 +349,13 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
protected FailOverlay FailOverlay { get; private set; }
|
protected FailOverlay FailOverlay { get; private set; }
|
||||||
|
|
||||||
|
private FailAnimation failAnimation;
|
||||||
|
|
||||||
private bool onFail()
|
private bool onFail()
|
||||||
{
|
{
|
||||||
if (Mods.Value.OfType<IApplicableFailOverride>().Any(m => !m.AllowFail))
|
if (Mods.Value.OfType<IApplicableFailOverride>().Any(m => !m.AllowFail))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
GameplayClockContainer.Stop();
|
|
||||||
|
|
||||||
HasFailed = true;
|
HasFailed = true;
|
||||||
|
|
||||||
// There is a chance that we could be in a paused state as the ruleset's internal clock (see FrameStabilityContainer)
|
// There is a chance that we could be in a paused state as the ruleset's internal clock (see FrameStabilityContainer)
|
||||||
@ -363,9 +364,17 @@ namespace osu.Game.Screens.Play
|
|||||||
if (PauseOverlay.State == Visibility.Visible)
|
if (PauseOverlay.State == Visibility.Visible)
|
||||||
PauseOverlay.Hide();
|
PauseOverlay.Hide();
|
||||||
|
|
||||||
|
failAnimation.Start();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called back when the transform finishes
|
||||||
|
private void onFailComplete()
|
||||||
|
{
|
||||||
|
GameplayClockContainer.Stop();
|
||||||
|
|
||||||
FailOverlay.Retries = RestartCount;
|
FailOverlay.Retries = RestartCount;
|
||||||
FailOverlay.Show();
|
FailOverlay.Show();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -492,6 +501,13 @@ namespace osu.Game.Screens.Play
|
|||||||
// still want to block if we are within the cooldown period and not already paused.
|
// still want to block if we are within the cooldown period and not already paused.
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (HasFailed && ValidForResume && !FailOverlay.IsPresent)
|
||||||
|
// ValidForResume is false when restarting
|
||||||
|
{
|
||||||
|
failAnimation.FinishTransforms(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
GameplayClockContainer.ResetLocalAdjustments();
|
GameplayClockContainer.ResetLocalAdjustments();
|
||||||
|
|
||||||
fadeOut();
|
fadeOut();
|
||||||
|
@ -45,6 +45,9 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
case SortMode.Author:
|
case SortMode.Author:
|
||||||
return string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.InvariantCultureIgnoreCase);
|
return string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
|
||||||
|
case SortMode.DateAdded:
|
||||||
|
return otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded);
|
||||||
|
|
||||||
case SortMode.Difficulty:
|
case SortMode.Difficulty:
|
||||||
return BeatmapSet.MaxStarDifficulty.CompareTo(otherSet.BeatmapSet.MaxStarDifficulty);
|
return BeatmapSet.MaxStarDifficulty.CompareTo(otherSet.BeatmapSet.MaxStarDifficulty);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
|
|
||||||
namespace osu.Game.Skinning
|
namespace osu.Game.Skinning
|
||||||
@ -19,6 +20,8 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
public List<SkinFileInfo> Files { get; set; }
|
public List<SkinFileInfo> Files { get; set; }
|
||||||
|
|
||||||
|
public List<DatabasedSetting> Settings { get; set; }
|
||||||
|
|
||||||
public bool DeletePending { get; set; }
|
public bool DeletePending { get; set; }
|
||||||
|
|
||||||
public string FullName => $"\"{Name}\" by {Creator}";
|
public string FullName => $"\"{Name}\" by {Creator}";
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
|
|
||||||
@ -12,5 +14,9 @@ namespace osu.Game.Skinning
|
|||||||
: base(contextFactory, storage)
|
: base(contextFactory, storage)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override IQueryable<SkinInfo> AddIncludesForDeletion(IQueryable<SkinInfo> query) =>
|
||||||
|
base.AddIncludesForDeletion(query)
|
||||||
|
.Include(s => s.Settings); // don't include FileInfo. these are handled by the FileStore itself.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,13 @@
|
|||||||
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Testing.Input;
|
using osu.Framework.Testing.Input;
|
||||||
using osu.Game.Graphics.Cursor;
|
using osu.Game.Graphics.Cursor;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
@ -15,21 +20,92 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
protected readonly ManualInputManager InputManager;
|
protected readonly ManualInputManager InputManager;
|
||||||
|
|
||||||
|
private readonly TriangleButton buttonTest;
|
||||||
|
private readonly TriangleButton buttonLocal;
|
||||||
|
|
||||||
protected ManualInputManagerTestScene()
|
protected ManualInputManagerTestScene()
|
||||||
{
|
{
|
||||||
base.Content.Add(InputManager = new ManualInputManager
|
base.Content.AddRange(new Drawable[]
|
||||||
{
|
{
|
||||||
UseParentInput = true,
|
InputManager = new ManualInputManager
|
||||||
Child = content = new MenuCursorContainer { RelativeSizeAxes = Axes.Both },
|
{
|
||||||
|
UseParentInput = true,
|
||||||
|
Child = content = new MenuCursorContainer { RelativeSizeAxes = Axes.Both },
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Margin = new MarginPadding(5),
|
||||||
|
CornerRadius = 5,
|
||||||
|
Masking = true,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
Colour = Color4.Black,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0.5f,
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Margin = new MarginPadding(5),
|
||||||
|
Spacing = new Vector2(5),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Text = "Input Priority"
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Margin = new MarginPadding(5),
|
||||||
|
Spacing = new Vector2(5),
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
buttonLocal = new TriangleButton
|
||||||
|
{
|
||||||
|
Text = "local",
|
||||||
|
Size = new Vector2(50, 30),
|
||||||
|
Action = returnUserInput
|
||||||
|
},
|
||||||
|
buttonTest = new TriangleButton
|
||||||
|
{
|
||||||
|
Text = "test",
|
||||||
|
Size = new Vector2(50, 30),
|
||||||
|
Action = returnTestInput
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
protected override void Update()
|
||||||
/// Returns input back to the user.
|
|
||||||
/// </summary>
|
|
||||||
protected void ReturnUserInput()
|
|
||||||
{
|
{
|
||||||
AddStep("Return user input", () => InputManager.UseParentInput = true);
|
base.Update();
|
||||||
|
|
||||||
|
buttonTest.Enabled.Value = InputManager.UseParentInput;
|
||||||
|
buttonLocal.Enabled.Value = !InputManager.UseParentInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void returnUserInput() =>
|
||||||
|
InputManager.UseParentInput = true;
|
||||||
|
|
||||||
|
private void returnTestInput() =>
|
||||||
|
InputManager.UseParentInput = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.4" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.4" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.518.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.609.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2019.604.1" />
|
<PackageReference Include="ppy.osu.Framework" Version="2019.607.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.23.0" />
|
<PackageReference Include="SharpCompress" Version="0.23.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
@ -104,9 +104,9 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.128.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.518.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2019.523.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2019.607.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.523.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.607.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
<PackageReference Include="SharpCompress" Version="0.22.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user