mirror of
https://github.com/osukey/osukey.git
synced 2025-05-09 23:57:18 +09:00
Merge remote-tracking branch 'upstream/master' into android
This commit is contained in:
commit
e3ce203c68
68
README.md
68
README.md
@ -11,25 +11,71 @@ We are accepting bug reports (please report with as much detail as possible). Fe
|
|||||||
# 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.
|
||||||
- When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio Community Edition](https://www.visualstudio.com/) (Windows), [Visual Studio Code](https://code.visualstudio.com/) (with the C# plugin installed) or [Jetbrains Rider](https://www.jetbrains.com/rider/) (commercial).
|
- When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio 2017+](https://visualstudio.microsoft.com/vs/), [Jetbrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/).
|
||||||
|
- Note that there are **[additional requirements for Windows 7 and Windows 8.1](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)** which you may need to manually install if your operating system is not up-to-date.
|
||||||
|
|
||||||
# Building and running
|
# Running osu!
|
||||||
|
|
||||||
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 (download and run the install executable for your platform).
|
## Releases
|
||||||
|
|
||||||
Clone the repository including submodules
|
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.
|
||||||
|
|
||||||
`git clone --recurse-submodules https://github.com/ppy/osu`
|
- Windows (x64) users should download and run `install.exe`.
|
||||||
|
- 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).
|
||||||
|
|
||||||
Build and run
|
If your platform is not listed above, there is still a chance you can manually build it by following the instructions below.
|
||||||
|
|
||||||
- Using Visual Studio 2017, Rider or Visual Studio Code (configurations are included)
|
## Downloading the source code
|
||||||
- From command line using `dotnet run --project osu.Desktop`. When building for non-development purposes, add `-c Release` to gain higher performance.
|
|
||||||
- To run with code analysis, instead use `powershell ./build.ps1` or `build.sh`. This is currently only supported under windows due to [resharper cli shortcomings](https://youtrack.jetbrains.com/issue/RSRP-410004). Alternative, you can install resharper or use rider to get inline support in your IDE of choice.
|
|
||||||
|
|
||||||
Note: If you run from command line under linux, you will need to prefix the output folder to your `LD_LIBRARY_PATH`. See `.vscode/launch.json` for an example
|
Clone the repository **including submodules**:
|
||||||
|
|
||||||
If you run into issues building you may need to restore nuget packages (commonly via `dotnet restore`). Visual Studio Code users must run `Restore` task from debug tab before attempt to build.
|
```shell
|
||||||
|
git clone --recurse-submodules https://github.com/ppy/osu
|
||||||
|
cd osu
|
||||||
|
```
|
||||||
|
|
||||||
|
> If you forgot the `--recurse-submodules` option, run this command inside the `osu` directory:
|
||||||
|
>
|
||||||
|
> `git submodule update --init --recursive`
|
||||||
|
|
||||||
|
To update the source code to the latest commit, run the following command inside the `osu` directory:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git pull --recurse-submodules
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
> Visual Studio Code users must run the `Restore` task before any build attempt.
|
||||||
|
|
||||||
|
You can also build and run osu! from the command-line with a single command:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dotnet run --project osu.Desktop
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are not interested in debugging osu!, you can add `-c Release` to gain performance. In this case, you must replace `Debug` with `Release` in any commands mentioned in this document.
|
||||||
|
|
||||||
|
If the build fails, try to restore nuget packages with `dotnet restore`.
|
||||||
|
|
||||||
|
### A note for Linux users
|
||||||
|
|
||||||
|
On Linux, the environment variable `LD_LIBRARY_PATH` must point to the build directory, located at `osu.Desktop/bin/Debug/$NETCORE_VERSION`.
|
||||||
|
|
||||||
|
`$NETCORE_VERSION` is the version of .NET Core SDK. You can have it with `grep TargetFramework osu.Desktop/osu.Desktop.csproj | sed -r 's/.*>(.*)<\/.*/\1/'`.
|
||||||
|
|
||||||
|
For example, you can run osu! with the following command:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
LD_LIBRARY_PATH="$(pwd)/osu.Desktop/bin/Debug/netcoreapp2.2" dotnet run --project osu.Desktop
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code analysis
|
||||||
|
|
||||||
|
Code analysis can be run with `powershell ./build.ps1` or `build.sh`. This is currently only supported under windows due to [resharper cli shortcomings](https://youtrack.jetbrains.com/issue/RSRP-410004). Alternative, you can install resharper or use rider to get inline support in your IDE of choice.
|
||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ namespace osu.Desktop
|
|||||||
|
|
||||||
private void fileDrop(object sender, FileDropEventArgs e)
|
private void fileDrop(object sender, FileDropEventArgs e)
|
||||||
{
|
{
|
||||||
var filePaths = new[] { e.FileName };
|
var filePaths = e.FileNames;
|
||||||
|
|
||||||
var firstExtension = Path.GetExtension(filePaths.First());
|
var firstExtension = Path.GetExtension(filePaths.First());
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="System.IO.Packaging" Version="4.5.0" />
|
<PackageReference Include="System.IO.Packaging" Version="4.5.0" />
|
||||||
<PackageReference Include="ppy.squirrel.windows" Version="1.9.0.3" />
|
<PackageReference Include="ppy.squirrel.windows" Version="1.9.0.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Resources">
|
<ItemGroup Label="Resources">
|
||||||
<EmbeddedResource Include="lazer.ico" />
|
<EmbeddedResource Include="lazer.ico" />
|
||||||
|
@ -26,7 +26,6 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < 512; i++)
|
for (int i = 0; i < 512; i++)
|
||||||
beatmap.HitObjects.Add(new Fruit { X = 0.5f + i / 2048f * (i % 10 - 5), StartTime = i * 100, NewCombo = i % 8 == 0 });
|
beatmap.HitObjects.Add(new Fruit { X = 0.5f + i / 2048f * (i % 10 - 5), StartTime = i * 100, NewCombo = i % 8 == 0 });
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
{
|
{
|
||||||
var beatmap = new Beatmap { BeatmapInfo = { Ruleset = ruleset.RulesetInfo } };
|
var beatmap = new Beatmap { BeatmapInfo = { Ruleset = ruleset.RulesetInfo } };
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < 512; i++)
|
for (int i = 0; i < 512; i++)
|
||||||
if (i % 5 < 3)
|
if (i % 5 < 3)
|
||||||
beatmap.HitObjects.Add(new Fruit { X = i % 10 < 5 ? 0.02f : 0.98f, StartTime = i * 100, NewCombo = i % 8 == 0 });
|
beatmap.HitObjects.Add(new Fruit { X = i % 10 < 5 ? 0.02f : 0.98f, StartTime = i * 100, NewCombo = i % 8 == 0 });
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.11.2" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
|
@ -14,7 +14,6 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
{
|
{
|
||||||
public class CatchDifficultyCalculator : DifficultyCalculator
|
public class CatchDifficultyCalculator : DifficultyCalculator
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// In milliseconds. For difficulty calculation we will only look at the highest strain value in each time interval of size STRAIN_STEP.
|
/// In milliseconds. For difficulty calculation we will only look at the highest strain value in each time interval of size STRAIN_STEP.
|
||||||
/// This is to eliminate higher influence of stream over aim by simply having more HitObjects with high strain.
|
/// This is to eliminate higher influence of stream over aim by simply having more HitObjects with high strain.
|
||||||
|
@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
|||||||
base.SkinChanged(skin, allowFallback);
|
base.SkinChanged(skin, allowFallback);
|
||||||
|
|
||||||
if (HitObject is IHasComboInformation combo)
|
if (HitObject is IHasComboInformation combo)
|
||||||
AccentColour = skin.GetValue<SkinConfiguration, Color4>(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : (Color4?)null) ?? Color4.White;
|
AccentColour = skin.GetValue<SkinConfiguration, Color4>(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : Color4.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
private const float preempt = 1000;
|
private const float preempt = 1000;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.11.2" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
|
@ -180,7 +180,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
|
|
||||||
foreach (var obj in newPattern.HitObjects)
|
foreach (var obj in newPattern.HitObjects)
|
||||||
yield return obj;
|
yield return obj;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,6 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
|||||||
if (!calculateStrainValues(difficultyHitObjects, timeRate))
|
if (!calculateStrainValues(difficultyHitObjects, timeRate))
|
||||||
return new DifficultyAttributes(mods, 0);
|
return new DifficultyAttributes(mods, 0);
|
||||||
|
|
||||||
|
|
||||||
double starRating = calculateDifficulty(difficultyHitObjects, timeRate) * star_scaling_factor;
|
double starRating = calculateDifficulty(difficultyHitObjects, timeRate) * star_scaling_factor;
|
||||||
|
|
||||||
return new ManiaDifficultyAttributes(mods, starRating)
|
return new ManiaDifficultyAttributes(mods, starRating)
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
|
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.UI;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
public class ManiaModMirror : Mod, IApplicableToRulesetContainer<ManiaHitObject>
|
public class ManiaModMirror : Mod, IApplicableToBeatmap<ManiaHitObject>
|
||||||
{
|
{
|
||||||
public override string Name => "Mirror";
|
public override string Name => "Mirror";
|
||||||
public override string Acronym => "MR";
|
public override string Acronym => "MR";
|
||||||
@ -18,11 +18,11 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override bool Ranked => true;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public void ApplyToRulesetContainer(RulesetContainer<ManiaHitObject> rulesetContainer)
|
public void ApplyToBeatmap(Beatmap<ManiaHitObject> beatmap)
|
||||||
{
|
{
|
||||||
var availableColumns = ((ManiaRulesetContainer)rulesetContainer).Beatmap.TotalColumns;
|
var availableColumns = ((ManiaBeatmap)beatmap).TotalColumns;
|
||||||
|
|
||||||
rulesetContainer.Objects.OfType<ManiaHitObject>().ForEach(h => h.Column = availableColumns - 1 - h.Column);
|
beatmap.HitObjects.OfType<ManiaHitObject>().ForEach(h => h.Column = availableColumns - 1 - h.Column);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,15 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.UI;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
public class ManiaModRandom : Mod, IApplicableToRulesetContainer<ManiaHitObject>
|
public class ManiaModRandom : Mod, IApplicableToBeatmap<ManiaHitObject>
|
||||||
{
|
{
|
||||||
public override string Name => "Random";
|
public override string Name => "Random";
|
||||||
public override string Acronym => "RD";
|
public override string Acronym => "RD";
|
||||||
@ -21,12 +21,12 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Description => @"Shuffle around the keys!";
|
public override string Description => @"Shuffle around the keys!";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
public void ApplyToRulesetContainer(RulesetContainer<ManiaHitObject> rulesetContainer)
|
public void ApplyToBeatmap(Beatmap<ManiaHitObject> beatmap)
|
||||||
{
|
{
|
||||||
var availableColumns = ((ManiaRulesetContainer)rulesetContainer).Beatmap.TotalColumns;
|
var availableColumns = ((ManiaBeatmap)beatmap).TotalColumns;
|
||||||
var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList();
|
var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList();
|
||||||
|
|
||||||
rulesetContainer.Objects.OfType<ManiaHitObject>().ForEach(h => h.Column = shuffledColumns[h.Column]);
|
beatmap.HitObjects.OfType<ManiaHitObject>().ForEach(h => h.Column = shuffledColumns[h.Column]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ namespace osu.Game.Rulesets.Mania.Objects
|
|||||||
|
|
||||||
private readonly int beatmapColumnCount;
|
private readonly int beatmapColumnCount;
|
||||||
|
|
||||||
|
|
||||||
private readonly double endTime;
|
private readonly double endTime;
|
||||||
private readonly double[] heldUntil;
|
private readonly double[] heldUntil;
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.11.2" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
|
@ -57,6 +57,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
s.Process(h);
|
s.Process(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The peak strain will not be saved for the last section in the above loop
|
||||||
|
foreach (Skill s in skills)
|
||||||
|
s.SaveCurrentPeak();
|
||||||
|
|
||||||
double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
|
double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
|
||||||
double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
|
double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
|
||||||
double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;
|
double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;
|
||||||
|
@ -105,13 +105,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
|
|
||||||
double approachRateFactor = 1.0f;
|
double approachRateFactor = 1.0f;
|
||||||
if (Attributes.ApproachRate > 10.33f)
|
if (Attributes.ApproachRate > 10.33f)
|
||||||
approachRateFactor += 0.45f * (Attributes.ApproachRate - 10.33f);
|
approachRateFactor += 0.3f * (Attributes.ApproachRate - 10.33f);
|
||||||
else if (Attributes.ApproachRate < 8.0f)
|
else if (Attributes.ApproachRate < 8.0f)
|
||||||
{
|
{
|
||||||
// HD is worth more with lower ar!
|
|
||||||
if (mods.Any(h => h is OsuModHidden))
|
|
||||||
approachRateFactor += 0.02f * (8.0f - Attributes.ApproachRate);
|
|
||||||
else
|
|
||||||
approachRateFactor += 0.01f * (8.0f - Attributes.ApproachRate);
|
approachRateFactor += 0.01f * (8.0f - Attributes.ApproachRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +115,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
|
|
||||||
// We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR.
|
// We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR.
|
||||||
if (mods.Any(h => h is OsuModHidden))
|
if (mods.Any(h => h is OsuModHidden))
|
||||||
aimValue *= 1.02 + (11.0f - Attributes.ApproachRate) / 50.0; // Gives a 1.04 bonus for AR10, a 1.06 bonus for AR9, a 1.02 bonus for AR11.
|
aimValue *= 1.0f + 0.04f * (12.0f - Attributes.ApproachRate);
|
||||||
|
|
||||||
if (mods.Any(h => h is OsuModFlashlight))
|
if (mods.Any(h => h is OsuModFlashlight))
|
||||||
{
|
{
|
||||||
@ -152,13 +148,19 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
if (beatmapMaxCombo > 0)
|
if (beatmapMaxCombo > 0)
|
||||||
speedValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8f) / Math.Pow(beatmapMaxCombo, 0.8f), 1.0f);
|
speedValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8f) / Math.Pow(beatmapMaxCombo, 0.8f), 1.0f);
|
||||||
|
|
||||||
|
double approachRateFactor = 1.0f;
|
||||||
|
if (Attributes.ApproachRate > 10.33f)
|
||||||
|
approachRateFactor += 0.3f * (Attributes.ApproachRate - 10.33f);
|
||||||
|
|
||||||
|
speedValue *= approachRateFactor;
|
||||||
|
|
||||||
if (mods.Any(m => m is OsuModHidden))
|
if (mods.Any(m => m is OsuModHidden))
|
||||||
speedValue *= 1.18f;
|
speedValue *= 1.0f + 0.04f * (12.0f - Attributes.ApproachRate);
|
||||||
|
|
||||||
// Scale the speed value with accuracy _slightly_
|
// Scale the speed value with accuracy _slightly_
|
||||||
speedValue *= 0.5f + accuracy / 2.0f;
|
speedValue *= 0.02f + accuracy;
|
||||||
// It is important to also consider accuracy difficulty when doing that
|
// It is important to also consider accuracy difficulty when doing that
|
||||||
speedValue *= 0.98f + Math.Pow(Attributes.OverallDifficulty, 2) / 2500;
|
speedValue *= 0.96f + Math.Pow(Attributes.OverallDifficulty, 2) / 1600;
|
||||||
|
|
||||||
return speedValue;
|
return speedValue;
|
||||||
}
|
}
|
||||||
@ -186,7 +188,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
accuracyValue *= Math.Min(1.15f, Math.Pow(amountHitObjectsWithAccuracy / 1000.0f, 0.3f));
|
accuracyValue *= Math.Min(1.15f, Math.Pow(amountHitObjectsWithAccuracy / 1000.0f, 0.3f));
|
||||||
|
|
||||||
if (mods.Any(m => m is OsuModHidden))
|
if (mods.Any(m => m is OsuModHidden))
|
||||||
accuracyValue *= 1.02f;
|
accuracyValue *= 1.08f;
|
||||||
if (mods.Any(m => m is OsuModFlashlight))
|
if (mods.Any(m => m is OsuModFlashlight))
|
||||||
accuracyValue *= 1.02f;
|
accuracyValue *= 1.02f;
|
||||||
|
|
||||||
|
@ -101,8 +101,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
float approxFollowCircleRadius = (float)(slider.Radius * 3);
|
float approxFollowCircleRadius = (float)(slider.Radius * 3);
|
||||||
var computeVertex = new Action<double>(t =>
|
var computeVertex = new Action<double>(t =>
|
||||||
{
|
{
|
||||||
double progress = ((int)t - (int)slider.StartTime) / (float)(int)slider.SpanDuration;
|
double progress = (t - slider.StartTime) / slider.SpanDuration;
|
||||||
if (progress % 2 > 1)
|
if (progress % 2 >= 1)
|
||||||
progress = 1 - progress % 1;
|
progress = 1 - progress % 1;
|
||||||
else
|
else
|
||||||
progress = progress % 1;
|
progress = progress % 1;
|
||||||
|
@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
base.SkinChanged(skin, allowFallback);
|
base.SkinChanged(skin, allowFallback);
|
||||||
|
|
||||||
if (HitObject is IHasComboInformation combo)
|
if (HitObject is IHasComboInformation combo)
|
||||||
AccentColour = skin.GetValue<SkinConfiguration, Color4>(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : (Color4?)null) ?? Color4.White;
|
AccentColour = skin.GetValue<SkinConfiguration, Color4>(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : Color4.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void UpdatePreemptState() => this.FadeIn(HitObject.TimeFadeIn);
|
protected virtual void UpdatePreemptState() => this.FadeIn(HitObject.TimeFadeIn);
|
||||||
|
@ -101,7 +101,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float aimRotation = MathHelper.RadiansToDegrees((float)Math.Atan2(aimRotationVector.Y - Position.Y, aimRotationVector.X - Position.X));
|
float aimRotation = MathHelper.RadiansToDegrees((float)Math.Atan2(aimRotationVector.Y - Position.Y, aimRotationVector.X - Position.X));
|
||||||
while (Math.Abs(aimRotation - Rotation) > 180)
|
while (Math.Abs(aimRotation - Rotation) > 180)
|
||||||
aimRotation += aimRotation < Rotation ? 360 : -360;
|
aimRotation += aimRotation < Rotation ? 360 : -360;
|
||||||
|
@ -14,6 +14,7 @@ using osu.Game.Configuration;
|
|||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||||
{
|
{
|
||||||
@ -151,6 +152,15 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
||||||
|
{
|
||||||
|
base.SkinChanged(skin, allowFallback);
|
||||||
|
|
||||||
|
Body.AccentColour = skin.GetValue<SkinConfiguration, Color4>(s => s.CustomColours.ContainsKey("SliderTrackOverride") ? s.CustomColours["SliderTrackOverride"] : Body.AccentColour);
|
||||||
|
Body.BorderColour = skin.GetValue<SkinConfiguration, Color4>(s => s.CustomColours.ContainsKey("SliderBorder") ? s.CustomColours["SliderBorder"] : Body.BorderColour);
|
||||||
|
Ball.AccentColour = skin.GetValue<SkinConfiguration, Color4>(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : Ball.AccentColour);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||||
{
|
{
|
||||||
if (userTriggered || Time.Current < slider.EndTime)
|
if (userTriggered || Time.Current < slider.EndTime)
|
||||||
|
@ -198,7 +198,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
|
|
||||||
if (tickDistance == 0) return;
|
if (tickDistance == 0) return;
|
||||||
|
|
||||||
var minDistanceFromEnd = Velocity * 0.01;
|
var minDistanceFromEnd = Velocity * 10;
|
||||||
|
|
||||||
var spanCount = this.SpanCount();
|
var spanCount = this.SpanCount();
|
||||||
|
|
||||||
|
@ -39,10 +39,13 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
|
|
||||||
private int downCount;
|
private int downCount;
|
||||||
|
|
||||||
private const float pressed_scale = 1.2f;
|
private void updateExpandedState()
|
||||||
private const float released_scale = 1f;
|
{
|
||||||
|
if (downCount > 0)
|
||||||
private float targetScale => downCount > 0 ? pressed_scale : released_scale;
|
(ActiveCursor as OsuCursor)?.Expand();
|
||||||
|
else
|
||||||
|
(ActiveCursor as OsuCursor)?.Contract();
|
||||||
|
}
|
||||||
|
|
||||||
public bool OnPressed(OsuAction action)
|
public bool OnPressed(OsuAction action)
|
||||||
{
|
{
|
||||||
@ -51,7 +54,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
case OsuAction.LeftButton:
|
case OsuAction.LeftButton:
|
||||||
case OsuAction.RightButton:
|
case OsuAction.RightButton:
|
||||||
downCount++;
|
downCount++;
|
||||||
ActiveCursor.ScaleTo(released_scale).ScaleTo(targetScale, 100, Easing.OutQuad);
|
updateExpandedState();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
case OsuAction.LeftButton:
|
case OsuAction.LeftButton:
|
||||||
case OsuAction.RightButton:
|
case OsuAction.RightButton:
|
||||||
if (--downCount == 0)
|
if (--downCount == 0)
|
||||||
ActiveCursor.ScaleTo(targetScale, 200, Easing.OutQuad);
|
updateExpandedState();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,33 +80,46 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
protected override void PopIn()
|
protected override void PopIn()
|
||||||
{
|
{
|
||||||
fadeContainer.FadeTo(1, 300, Easing.OutQuint);
|
fadeContainer.FadeTo(1, 300, Easing.OutQuint);
|
||||||
ActiveCursor.ScaleTo(targetScale, 400, Easing.OutQuint);
|
ActiveCursor.ScaleTo(1, 400, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PopOut()
|
protected override void PopOut()
|
||||||
{
|
{
|
||||||
fadeContainer.FadeTo(0.05f, 450, Easing.OutQuint);
|
fadeContainer.FadeTo(0.05f, 450, Easing.OutQuint);
|
||||||
ActiveCursor.ScaleTo(targetScale * 0.8f, 450, Easing.OutQuint);
|
ActiveCursor.ScaleTo(0.8f, 450, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OsuCursor : Container
|
public class OsuCursor : SkinReloadableDrawable
|
||||||
{
|
{
|
||||||
private Drawable cursorContainer;
|
private bool cursorExpand;
|
||||||
|
|
||||||
private Bindable<double> cursorScale;
|
private Bindable<double> cursorScale;
|
||||||
private Bindable<bool> autoCursorScale;
|
private Bindable<bool> autoCursorScale;
|
||||||
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||||
|
|
||||||
|
private Container expandTarget;
|
||||||
|
private Drawable scaleTarget;
|
||||||
|
|
||||||
public OsuCursor()
|
public OsuCursor()
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
Size = new Vector2(42);
|
Size = new Vector2(42);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
||||||
|
{
|
||||||
|
cursorExpand = skin.GetValue<SkinConfiguration, bool>(s => s.CursorExpand ?? true);
|
||||||
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config, IBindableBeatmap beatmap)
|
private void load(OsuConfigManager config, IBindableBeatmap beatmap)
|
||||||
{
|
{
|
||||||
Child = cursorContainer = new SkinnableDrawable("cursor", _ => new CircularContainer
|
InternalChild = expandTarget = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Child = scaleTarget = new SkinnableDrawable("cursor", _ => new CircularContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Masking = true,
|
Masking = true,
|
||||||
@ -163,6 +179,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.beatmap.BindTo(beatmap);
|
this.beatmap.BindTo(beatmap);
|
||||||
@ -187,8 +204,19 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
scale *= (float)(1 - 0.7 * (1 + beatmap.Value.BeatmapInfo.BaseDifficulty.CircleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY);
|
scale *= (float)(1 - 0.7 * (1 + beatmap.Value.BeatmapInfo.BaseDifficulty.CircleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
cursorContainer.Scale = new Vector2(scale);
|
scaleTarget.Scale = new Vector2(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const float pressed_scale = 1.2f;
|
||||||
|
private const float released_scale = 1f;
|
||||||
|
|
||||||
|
public void Expand()
|
||||||
|
{
|
||||||
|
if (!cursorExpand) return;
|
||||||
|
expandTarget.ScaleTo(released_scale).ScaleTo(pressed_scale, 100, Easing.OutQuad);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Contract() => expandTarget.ScaleTo(released_scale, 100, Easing.OutQuad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.11.2" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
|
@ -149,7 +149,6 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
using (var stream = Resource.OpenResource(filename))
|
using (var stream = Resource.OpenResource(filename))
|
||||||
using (var sr = new StreamReader(stream))
|
using (var sr = new StreamReader(stream))
|
||||||
{
|
{
|
||||||
|
|
||||||
var legacyDecoded = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(sr);
|
var legacyDecoded = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(sr);
|
||||||
using (var ms = new MemoryStream())
|
using (var ms = new MemoryStream())
|
||||||
using (var sw = new StreamWriter(ms))
|
using (var sw = new StreamWriter(ms))
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@ -23,11 +24,17 @@ namespace osu.Game.Tests.Visual
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool ContinueCondition(Player player) => base.ContinueCondition(player) && ((ScoreAccessiblePlayer)player).ScoreProcessor.TotalScore > 0;
|
protected override void AddCheckSteps(Func<Player> player)
|
||||||
|
{
|
||||||
|
base.AddCheckSteps(player);
|
||||||
|
AddUntilStep(() => ((ScoreAccessiblePlayer)player()).ScoreProcessor.TotalScore > 0, "score above zero");
|
||||||
|
AddUntilStep(() => ((ScoreAccessiblePlayer)player()).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0), "key counter counted keys");
|
||||||
|
}
|
||||||
|
|
||||||
private class ScoreAccessiblePlayer : Player
|
private class ScoreAccessiblePlayer : Player
|
||||||
{
|
{
|
||||||
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||||
|
public new HUDOverlay HUDOverlay => base.HUDOverlay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
typeof(DrawableCarouselBeatmapSet),
|
typeof(DrawableCarouselBeatmapSet),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
private readonly Stack<BeatmapSetInfo> selectedSets = new Stack<BeatmapSetInfo>();
|
private readonly Stack<BeatmapSetInfo> selectedSets = new Stack<BeatmapSetInfo>();
|
||||||
private readonly HashSet<int> eagerSelectedIDs = new HashSet<int>();
|
private readonly HashSet<int> eagerSelectedIDs = new HashSet<int>();
|
||||||
|
|
||||||
|
@ -55,7 +55,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
AddStep("resize to normal", () => container.ResizeWidthTo(0.8f, 300));
|
AddStep("resize to normal", () => container.ResizeWidthTo(0.8f, 300));
|
||||||
AddStep("online scores", () => scoresContainer.Beatmap = new BeatmapInfo { OnlineBeatmapID = 75, Ruleset = new OsuRuleset().RulesetInfo });
|
AddStep("online scores", () => scoresContainer.Beatmap = new BeatmapInfo { OnlineBeatmapID = 75, Ruleset = new OsuRuleset().RulesetInfo });
|
||||||
|
|
||||||
|
|
||||||
scores = new[]
|
scores = new[]
|
||||||
{
|
{
|
||||||
new APIScoreInfo
|
new APIScoreInfo
|
||||||
|
@ -16,7 +16,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
public TestCaseBreadcrumbs()
|
public TestCaseBreadcrumbs()
|
||||||
{
|
{
|
||||||
|
|
||||||
Add(breadcrumbs = new BreadcrumbControl<BreadcrumbTab>
|
Add(breadcrumbs = new BreadcrumbControl<BreadcrumbTab>
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
|
@ -39,7 +39,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
AddStep("Add random", () =>
|
AddStep("Add random", () =>
|
||||||
{
|
{
|
||||||
Key key = (Key)((int)Key.A + RNG.Next(26));
|
Key key = (Key)((int)Key.A + RNG.Next(26));
|
||||||
|
@ -17,12 +17,13 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
public TestCaseMatchLeaderboard()
|
public TestCaseMatchLeaderboard()
|
||||||
{
|
{
|
||||||
Add(new MatchLeaderboard(new Room { RoomID = { Value = 3 } })
|
Add(new MatchLeaderboard
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Size = new Vector2(550f, 450f),
|
Size = new Vector2(550f, 450f),
|
||||||
Scope = MatchLeaderboardScope.Overall,
|
Scope = MatchLeaderboardScope.Overall,
|
||||||
|
Room = new Room { RoomID = { Value = 3 } }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,11 +57,19 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
private class TestSongSelect : PlaySongSelect
|
private class TestSongSelect : PlaySongSelect
|
||||||
{
|
{
|
||||||
|
public Action StartRequested;
|
||||||
|
|
||||||
public new Bindable<RulesetInfo> Ruleset => base.Ruleset;
|
public new Bindable<RulesetInfo> Ruleset => base.Ruleset;
|
||||||
|
|
||||||
public WorkingBeatmap CurrentBeatmap => Beatmap.Value;
|
public WorkingBeatmap CurrentBeatmap => Beatmap.Value;
|
||||||
public WorkingBeatmap CurrentBeatmapDetailsBeatmap => BeatmapDetails.Beatmap;
|
public WorkingBeatmap CurrentBeatmapDetailsBeatmap => BeatmapDetails.Beatmap;
|
||||||
public new BeatmapCarousel Carousel => base.Carousel;
|
public new BeatmapCarousel Carousel => base.Carousel;
|
||||||
|
|
||||||
|
protected override bool OnStart()
|
||||||
|
{
|
||||||
|
StartRequested?.Invoke();
|
||||||
|
return base.OnStart();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestSongSelect songSelect;
|
private TestSongSelect songSelect;
|
||||||
@ -182,6 +190,27 @@ namespace osu.Game.Tests.Visual
|
|||||||
void onRulesetChange(RulesetInfo ruleset) => rulesetChangeIndex = actionIndex--;
|
void onRulesetChange(RulesetInfo ruleset) => rulesetChangeIndex = actionIndex--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestStartAfterUnMatchingFilterDoesNotStart()
|
||||||
|
{
|
||||||
|
addManyTestMaps();
|
||||||
|
AddUntilStep(() => songSelect.Carousel.SelectedBeatmap != null, "has selection");
|
||||||
|
|
||||||
|
bool startRequested = false;
|
||||||
|
|
||||||
|
AddStep("set filter and finalize", () =>
|
||||||
|
{
|
||||||
|
songSelect.StartRequested = () => startRequested = true;
|
||||||
|
|
||||||
|
songSelect.Carousel.Filter(new FilterCriteria { SearchText = "somestringthatshouldn'tbematchable" });
|
||||||
|
songSelect.FinaliseSelection();
|
||||||
|
|
||||||
|
songSelect.StartRequested = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("start not requested", () => !startRequested);
|
||||||
|
}
|
||||||
|
|
||||||
private void importForRuleset(int id) => AddStep($"import test map for ruleset {id}", () => manager.Import(createTestBeatmapSet(getImportId(), rulesets.AvailableRulesets.Where(r => r.ID == id).ToArray())));
|
private void importForRuleset(int id) => AddStep($"import test map for ruleset {id}", () => manager.Import(createTestBeatmapSet(getImportId(), rulesets.AvailableRulesets.Where(r => r.ID == id).ToArray())));
|
||||||
|
|
||||||
private static int importId;
|
private static int importId;
|
||||||
|
@ -57,5 +57,4 @@ namespace osu.Game.Tests.Visual
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ using osu.Game.Screens.Play;
|
|||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestCaseSkipButton : OsuTestCase
|
public class TestCaseSkipOverlay : OsuTestCase
|
||||||
{
|
{
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
@ -5,7 +5,7 @@
|
|||||||
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.11.2" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
|
@ -17,7 +17,6 @@ using osu.Framework.Logging;
|
|||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Beatmaps.Formats;
|
using osu.Game.Beatmaps.Formats;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.IO.Archives;
|
using osu.Game.IO.Archives;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
@ -147,16 +146,6 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
if (existing != null || api == null) return false;
|
if (existing != null || api == null) return false;
|
||||||
|
|
||||||
if (!api.LocalUser.Value.IsSupporter)
|
|
||||||
{
|
|
||||||
PostNotification?.Invoke(new SimpleNotification
|
|
||||||
{
|
|
||||||
Icon = FontAwesome.fa_superpowers,
|
|
||||||
Text = "You gotta be an osu!supporter to download for now 'yo"
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var downloadNotification = new DownloadNotification
|
var downloadNotification = new DownloadNotification
|
||||||
{
|
{
|
||||||
CompletionText = $"Imported {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}!",
|
CompletionText = $"Imported {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}!",
|
||||||
|
@ -105,6 +105,8 @@ namespace osu.Game.Configuration
|
|||||||
|
|
||||||
Set(OsuSetting.ScalingPositionX, 0.5f, 0f, 1f);
|
Set(OsuSetting.ScalingPositionX, 0.5f, 0f, 1f);
|
||||||
Set(OsuSetting.ScalingPositionY, 0.5f, 0f, 1f);
|
Set(OsuSetting.ScalingPositionY, 0.5f, 0f, 1f);
|
||||||
|
|
||||||
|
Set(OsuSetting.UIScale, 1f, 0.8f, 1.6f, 0.01f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OsuConfigManager(Storage storage)
|
public OsuConfigManager(Storage storage)
|
||||||
@ -167,6 +169,7 @@ namespace osu.Game.Configuration
|
|||||||
ScalingPositionX,
|
ScalingPositionX,
|
||||||
ScalingPositionY,
|
ScalingPositionY,
|
||||||
ScalingSizeX,
|
ScalingSizeX,
|
||||||
ScalingSizeY
|
ScalingSizeY,
|
||||||
|
UIScale
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,24 +61,25 @@ namespace osu.Game.Graphics.Containers
|
|||||||
AddText(text.Substring(previousLinkEnd));
|
AddText(text.Substring(previousLinkEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
public IEnumerable<Drawable> AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
||||||
=> createLink(AddText(text, creationParameters), text, url, linkType, linkArgument, tooltipText);
|
=> createLink(AddText(text, creationParameters), text, url, linkType, linkArgument, tooltipText);
|
||||||
|
|
||||||
public void AddLink(string text, Action action, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
public IEnumerable<Drawable> AddLink(string text, Action action, string tooltipText = null, Action<SpriteText> creationParameters = null)
|
||||||
=> createLink(AddText(text, creationParameters), text, tooltipText: tooltipText, action: action);
|
=> createLink(AddText(text, creationParameters), text, tooltipText: tooltipText, action: action);
|
||||||
|
|
||||||
public void AddLink(IEnumerable<SpriteText> text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null)
|
public IEnumerable<Drawable> AddLink(IEnumerable<SpriteText> text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null)
|
||||||
{
|
{
|
||||||
foreach (var t in text)
|
foreach (var t in text)
|
||||||
AddArbitraryDrawable(t);
|
AddArbitraryDrawable(t);
|
||||||
|
|
||||||
createLink(text, null, url, linkType, linkArgument, tooltipText);
|
return createLink(text, null, url, linkType, linkArgument, tooltipText);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createLink(IEnumerable<Drawable> drawables, string text, string url = null, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action action = null)
|
private IEnumerable<Drawable> createLink(IEnumerable<Drawable> drawables, string text, string url = null, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action action = null)
|
||||||
{
|
{
|
||||||
AddInternal(new DrawableLinkCompiler(drawables.OfType<SpriteText>().ToList())
|
AddInternal(new DrawableLinkCompiler(drawables.OfType<SpriteText>().ToList())
|
||||||
{
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
TooltipText = tooltipText ?? (url != text ? url : string.Empty),
|
TooltipText = tooltipText ?? (url != text ? url : string.Empty),
|
||||||
Action = action ?? (() =>
|
Action = action ?? (() =>
|
||||||
{
|
{
|
||||||
@ -121,6 +122,13 @@ namespace osu.Game.Graphics.Containers
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
return drawables;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We want the compilers to always be visible no matter where they are, so RelativeSizeAxes is used.
|
||||||
|
// However due to https://github.com/ppy/osu-framework/issues/2073, it's possible for the compilers to be relative size in the flow's auto-size axes - an unsupported operation.
|
||||||
|
// Since the compilers don't display any content and don't affect the layout, it's simplest to exclude them from the flow.
|
||||||
|
public override IEnumerable<Drawable> FlowingChildren => base.FlowingChildren.Where(c => !(c is DrawableLinkCompiler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
@ -19,6 +20,6 @@ namespace osu.Game.Graphics.Containers
|
|||||||
|
|
||||||
public void AddArbitraryDrawable(Drawable drawable) => AddInternal(drawable);
|
public void AddArbitraryDrawable(Drawable drawable) => AddInternal(drawable);
|
||||||
|
|
||||||
public void AddIcon(FontAwesome icon, Action<SpriteText> creationParameters = null) => AddText(((char)icon).ToString(), creationParameters);
|
public IEnumerable<Drawable> AddIcon(FontAwesome icon, Action<SpriteText> creationParameters = null) => AddText(((char)icon).ToString(), creationParameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@ namespace osu.Game.Graphics.Containers
|
|||||||
private readonly Container content;
|
private readonly Container content;
|
||||||
protected override Container<Drawable> Content => content;
|
protected override Container<Drawable> Content => content;
|
||||||
|
|
||||||
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
||||||
|
|
||||||
private readonly Container sizableContainer;
|
private readonly Container sizableContainer;
|
||||||
|
|
||||||
private Drawable backgroundLayer;
|
private Drawable backgroundLayer;
|
||||||
@ -41,15 +43,44 @@ namespace osu.Game.Graphics.Containers
|
|||||||
this.targetMode = targetMode;
|
this.targetMode = targetMode;
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
InternalChild = sizableContainer = new Container
|
InternalChild = sizableContainer = new AlwaysInputContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
RelativePositionAxes = Axes.Both,
|
RelativePositionAxes = Axes.Both,
|
||||||
CornerRadius = 10,
|
CornerRadius = 10,
|
||||||
Child = content = new DrawSizePreservingFillContainer()
|
Child = content = new ScalingDrawSizePreservingFillContainer(targetMode != ScalingMode.Gameplay)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ScalingDrawSizePreservingFillContainer : DrawSizePreservingFillContainer
|
||||||
|
{
|
||||||
|
private readonly bool applyUIScale;
|
||||||
|
private Bindable<float> uiScale;
|
||||||
|
|
||||||
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
||||||
|
|
||||||
|
public ScalingDrawSizePreservingFillContainer(bool applyUIScale)
|
||||||
|
{
|
||||||
|
this.applyUIScale = applyUIScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuConfigManager osuConfig)
|
||||||
|
{
|
||||||
|
if (applyUIScale)
|
||||||
|
{
|
||||||
|
uiScale = osuConfig.GetBindable<float>(OsuSetting.UIScale);
|
||||||
|
uiScale.BindValueChanged(scaleChanged, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scaleChanged(float value)
|
||||||
|
{
|
||||||
|
this.ScaleTo(new Vector2(value), 500, Easing.Out);
|
||||||
|
this.ResizeTo(new Vector2(1 / value), 500, Easing.Out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
{
|
{
|
||||||
@ -116,5 +147,15 @@ namespace osu.Game.Graphics.Containers
|
|||||||
sizableContainer.MoveTo(targetPosition, 500, Easing.OutQuart);
|
sizableContainer.MoveTo(targetPosition, 500, Easing.OutQuart);
|
||||||
sizableContainer.ResizeTo(targetSize, 500, Easing.OutQuart).OnComplete(_ => { sizableContainer.Masking = requiresMasking; });
|
sizableContainer.ResizeTo(targetSize, 500, Easing.OutQuart).OnComplete(_ => { sizableContainer.Masking = requiresMasking; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class AlwaysInputContainer : Container
|
||||||
|
{
|
||||||
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
||||||
|
|
||||||
|
public AlwaysInputContainer()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,12 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
AccentColour = colours.Pink;
|
AccentColour = colours.Pink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
CurrentNumber.BindValueChanged(updateTooltipText, true);
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool OnHover(HoverEvent e)
|
protected override bool OnHover(HoverEvent e)
|
||||||
{
|
{
|
||||||
Nub.Glowing = true;
|
Nub.Glowing = true;
|
||||||
|
@ -160,7 +160,6 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Text = (value as IHasDescription)?.Description ?? (value as Enum)?.GetDescription() ?? value.ToString(),
|
Text = (value as IHasDescription)?.Description ?? (value as Enum)?.GetDescription() ?? value.ToString(),
|
||||||
TextSize = 14,
|
TextSize = 14,
|
||||||
Font = @"Exo2.0-Bold", // Font should only turn bold when active?
|
|
||||||
},
|
},
|
||||||
Bar = new Box
|
Bar = new Box
|
||||||
{
|
{
|
||||||
@ -173,6 +172,8 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
},
|
},
|
||||||
new HoverClickSounds()
|
new HoverClickSounds()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Active.BindValueChanged(val => Text.Font = val ? @"Exo2.0-Bold" : @"Exo2.0", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnActivated() => fadeActive();
|
protected override void OnActivated() => fadeActive();
|
||||||
|
@ -46,7 +46,6 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Text = (value as Enum)?.GetDescription() ?? value.ToString(),
|
Text = (value as Enum)?.GetDescription() ?? value.ToString(),
|
||||||
TextSize = 14,
|
TextSize = 14,
|
||||||
Font = @"Exo2.0-Bold",
|
|
||||||
},
|
},
|
||||||
box = new Box
|
box = new Box
|
||||||
{
|
{
|
||||||
@ -59,6 +58,8 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
},
|
},
|
||||||
new HoverClickSounds()
|
new HoverClickSounds()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Active.BindValueChanged(val => Text.Font = val ? @"Exo2.0-Bold" : @"Exo2.0", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -101,6 +101,9 @@ namespace osu.Game.Online.API
|
|||||||
//todo: replace this with a ping request.
|
//todo: replace this with a ping request.
|
||||||
log.Add(@"In a failing state, waiting a bit before we try again...");
|
log.Add(@"In a failing state, waiting a bit before we try again...");
|
||||||
Thread.Sleep(5000);
|
Thread.Sleep(5000);
|
||||||
|
|
||||||
|
if (!IsLoggedIn) goto case APIState.Connecting;
|
||||||
|
|
||||||
if (queue.Count == 0)
|
if (queue.Count == 0)
|
||||||
{
|
{
|
||||||
log.Add(@"Queueing a ping request");
|
log.Add(@"Queueing a ping request");
|
||||||
|
@ -41,7 +41,6 @@ namespace osu.Game.Online.Chat
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly List<LocalEchoMessage> pendingMessages = new List<LocalEchoMessage>();
|
private readonly List<LocalEchoMessage> pendingMessages = new List<LocalEchoMessage>();
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An event that fires when new messages arrived.
|
/// An event that fires when new messages arrived.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -221,14 +221,19 @@ namespace osu.Game
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var databasedSet = BeatmapManager.QueryBeatmapSet(s => s.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID);
|
var databasedSet = beatmap.OnlineBeatmapSetID != null ?
|
||||||
|
BeatmapManager.QueryBeatmapSet(s => s.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID) :
|
||||||
|
BeatmapManager.QueryBeatmapSet(s => s.Hash == beatmap.Hash);
|
||||||
|
|
||||||
|
if (databasedSet != null)
|
||||||
|
{
|
||||||
// Use first beatmap available for current ruleset, else switch ruleset.
|
// Use first beatmap available for current ruleset, else switch ruleset.
|
||||||
var first = databasedSet.Beatmaps.Find(b => b.Ruleset == ruleset.Value) ?? databasedSet.Beatmaps.First();
|
var first = databasedSet.Beatmaps.Find(b => b.Ruleset == ruleset.Value) ?? databasedSet.Beatmaps.First();
|
||||||
|
|
||||||
ruleset.Value = first.Ruleset;
|
ruleset.Value = first.Ruleset;
|
||||||
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(first);
|
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(first);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (currentScreen)
|
switch (currentScreen)
|
||||||
{
|
{
|
||||||
@ -359,8 +364,11 @@ namespace osu.Game
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
mainContent = new DrawSizePreservingFillContainer(),
|
overlayContent = new Container
|
||||||
overlayContent = new Container { RelativeSizeAxes = Axes.Both, Depth = float.MinValue },
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
floatingOverlayContent = new Container { RelativeSizeAxes = Axes.Both, Depth = float.MinValue },
|
||||||
idleTracker = new IdleTracker(6000)
|
idleTracker = new IdleTracker(6000)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -379,32 +387,32 @@ namespace osu.Game
|
|||||||
CloseAllOverlays(false);
|
CloseAllOverlays(false);
|
||||||
intro?.ChildScreen?.MakeCurrent();
|
intro?.ChildScreen?.MakeCurrent();
|
||||||
},
|
},
|
||||||
}, overlayContent.Add);
|
}, floatingOverlayContent.Add);
|
||||||
|
|
||||||
loadComponentSingleFile(volume = new VolumeOverlay(), overlayContent.Add);
|
loadComponentSingleFile(volume = new VolumeOverlay(), floatingOverlayContent.Add);
|
||||||
loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add);
|
loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add);
|
||||||
|
|
||||||
loadComponentSingleFile(screenshotManager, Add);
|
loadComponentSingleFile(screenshotManager, Add);
|
||||||
|
|
||||||
//overlay elements
|
//overlay elements
|
||||||
loadComponentSingleFile(direct = new DirectOverlay { Depth = -1 }, mainContent.Add);
|
loadComponentSingleFile(direct = new DirectOverlay { Depth = -1 }, overlayContent.Add);
|
||||||
loadComponentSingleFile(social = new SocialOverlay { Depth = -1 }, mainContent.Add);
|
loadComponentSingleFile(social = new SocialOverlay { Depth = -1 }, overlayContent.Add);
|
||||||
loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal);
|
loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal);
|
||||||
loadComponentSingleFile(chatOverlay = new ChatOverlay { Depth = -1 }, mainContent.Add);
|
loadComponentSingleFile(chatOverlay = new ChatOverlay { Depth = -1 }, overlayContent.Add);
|
||||||
loadComponentSingleFile(settings = new MainSettings
|
loadComponentSingleFile(settings = new MainSettings
|
||||||
{
|
{
|
||||||
GetToolbarHeight = () => ToolbarOffset,
|
GetToolbarHeight = () => ToolbarOffset,
|
||||||
Depth = -1
|
Depth = -1
|
||||||
}, overlayContent.Add);
|
}, floatingOverlayContent.Add);
|
||||||
loadComponentSingleFile(userProfile = new UserProfileOverlay { Depth = -2 }, mainContent.Add);
|
loadComponentSingleFile(userProfile = new UserProfileOverlay { Depth = -2 }, overlayContent.Add);
|
||||||
loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay { Depth = -3 }, mainContent.Add);
|
loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay { Depth = -3 }, overlayContent.Add);
|
||||||
loadComponentSingleFile(musicController = new MusicController
|
loadComponentSingleFile(musicController = new MusicController
|
||||||
{
|
{
|
||||||
Depth = -5,
|
Depth = -5,
|
||||||
Position = new Vector2(0, Toolbar.HEIGHT),
|
Position = new Vector2(0, Toolbar.HEIGHT),
|
||||||
Anchor = Anchor.TopRight,
|
Anchor = Anchor.TopRight,
|
||||||
Origin = Anchor.TopRight,
|
Origin = Anchor.TopRight,
|
||||||
}, overlayContent.Add);
|
}, floatingOverlayContent.Add);
|
||||||
|
|
||||||
loadComponentSingleFile(notifications = new NotificationOverlay
|
loadComponentSingleFile(notifications = new NotificationOverlay
|
||||||
{
|
{
|
||||||
@ -412,22 +420,22 @@ namespace osu.Game
|
|||||||
Depth = -4,
|
Depth = -4,
|
||||||
Anchor = Anchor.TopRight,
|
Anchor = Anchor.TopRight,
|
||||||
Origin = Anchor.TopRight,
|
Origin = Anchor.TopRight,
|
||||||
}, overlayContent.Add);
|
}, floatingOverlayContent.Add);
|
||||||
|
|
||||||
loadComponentSingleFile(accountCreation = new AccountCreationOverlay
|
loadComponentSingleFile(accountCreation = new AccountCreationOverlay
|
||||||
{
|
{
|
||||||
Depth = -6,
|
Depth = -6,
|
||||||
}, overlayContent.Add);
|
}, floatingOverlayContent.Add);
|
||||||
|
|
||||||
loadComponentSingleFile(dialogOverlay = new DialogOverlay
|
loadComponentSingleFile(dialogOverlay = new DialogOverlay
|
||||||
{
|
{
|
||||||
Depth = -7,
|
Depth = -7,
|
||||||
}, overlayContent.Add);
|
}, floatingOverlayContent.Add);
|
||||||
|
|
||||||
loadComponentSingleFile(externalLinkOpener = new ExternalLinkOpener
|
loadComponentSingleFile(externalLinkOpener = new ExternalLinkOpener
|
||||||
{
|
{
|
||||||
Depth = -8,
|
Depth = -8,
|
||||||
}, overlayContent.Add);
|
}, floatingOverlayContent.Add);
|
||||||
|
|
||||||
dependencies.Cache(idleTracker);
|
dependencies.Cache(idleTracker);
|
||||||
dependencies.Cache(settings);
|
dependencies.Cache(settings);
|
||||||
@ -646,10 +654,10 @@ namespace osu.Game
|
|||||||
|
|
||||||
public bool OnReleased(GlobalAction action) => false;
|
public bool OnReleased(GlobalAction action) => false;
|
||||||
|
|
||||||
private Container mainContent;
|
|
||||||
|
|
||||||
private Container overlayContent;
|
private Container overlayContent;
|
||||||
|
|
||||||
|
private Container floatingOverlayContent;
|
||||||
|
|
||||||
private OsuScreen currentScreen;
|
private OsuScreen currentScreen;
|
||||||
private FrameworkConfigManager frameworkConfig;
|
private FrameworkConfigManager frameworkConfig;
|
||||||
private ScalingContainer screenContainer;
|
private ScalingContainer screenContainer;
|
||||||
@ -693,6 +701,7 @@ namespace osu.Game
|
|||||||
Beatmap.Disabled = applyBeatmapRulesetRestrictions;
|
Beatmap.Disabled = applyBeatmapRulesetRestrictions;
|
||||||
|
|
||||||
screenContainer.Padding = new MarginPadding { Top = ToolbarOffset };
|
screenContainer.Padding = new MarginPadding { Top = ToolbarOffset };
|
||||||
|
overlayContent.Padding = new MarginPadding { Top = ToolbarOffset };
|
||||||
|
|
||||||
MenuCursorContainer.CanShowCursor = currentScreen?.CursorVisible ?? false;
|
MenuCursorContainer.CanShowCursor = currentScreen?.CursorVisible ?? false;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
|
|||||||
{
|
{
|
||||||
public class DownloadButton : HeaderButton, IHasTooltip
|
public class DownloadButton : HeaderButton, IHasTooltip
|
||||||
{
|
{
|
||||||
public string TooltipText => Enabled ? null : "You gotta be an osu!supporter to download for now 'yo";
|
public string TooltipText => "Download this beatmap";
|
||||||
|
|
||||||
private readonly IBindable<User> localUser = new Bindable<User>();
|
private readonly IBindable<User> localUser = new Bindable<User>();
|
||||||
|
|
||||||
@ -101,12 +101,9 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons
|
|||||||
private void load(APIAccess api)
|
private void load(APIAccess api)
|
||||||
{
|
{
|
||||||
localUser.BindTo(api.LocalUser);
|
localUser.BindTo(api.LocalUser);
|
||||||
localUser.BindValueChanged(userChanged, true);
|
|
||||||
Enabled.BindValueChanged(enabledChanged, true);
|
Enabled.BindValueChanged(enabledChanged, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void userChanged(User user) => Enabled.Value = user.IsSupporter;
|
|
||||||
|
|
||||||
private void enabledChanged(bool enabled) => this.FadeColour(enabled ? Color4.White : Color4.Gray, 200, Easing.OutQuint);
|
private void enabledChanged(bool enabled) => this.FadeColour(enabled ? Color4.White : Color4.Gray, 200, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,6 @@ namespace osu.Game.Overlays.Chat.Tabs
|
|||||||
CloseButton.FadeIn(TRANSITION_LENGTH, Easing.OutQuint);
|
CloseButton.FadeIn(TRANSITION_LENGTH, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override void FadeInactive()
|
protected override void FadeInactive()
|
||||||
{
|
{
|
||||||
base.FadeInactive();
|
base.FadeInactive();
|
||||||
|
@ -18,7 +18,6 @@ namespace osu.Game.Overlays.KeyBinding
|
|||||||
Add(new InGameKeyBindingsSubsection(manager));
|
Add(new InGameKeyBindingsSubsection(manager));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class DefaultBindingsSubsection : KeyBindingsSubsection
|
private class DefaultBindingsSubsection : KeyBindingsSubsection
|
||||||
{
|
{
|
||||||
protected override string Header => string.Empty;
|
protected override string Header => string.Empty;
|
||||||
|
@ -176,7 +176,6 @@ namespace osu.Game.Overlays.Mods
|
|||||||
section.DeselectTypes(modTypes, immediate);
|
section.DeselectTypes(modTypes, immediate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private SampleChannel sampleOn, sampleOff;
|
private SampleChannel sampleOn, sampleOff;
|
||||||
|
|
||||||
private void modButtonPressed(Mod selectedMod)
|
private void modButtonPressed(Mod selectedMod)
|
||||||
|
@ -49,7 +49,6 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
|
|||||||
Api.Queue(request);
|
Api.Queue(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
@ -63,9 +63,16 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y
|
AutoSizeAxes = Axes.Y
|
||||||
},
|
},
|
||||||
|
new SettingsSlider<float, UIScaleSlider>
|
||||||
|
{
|
||||||
|
LabelText = "UI Scaling",
|
||||||
|
TransferValueOnCommit = true,
|
||||||
|
Bindable = osuConfig.GetBindable<float>(OsuSetting.UIScale),
|
||||||
|
KeyboardStep = 0.01f
|
||||||
|
},
|
||||||
new SettingsEnumDropdown<ScalingMode>
|
new SettingsEnumDropdown<ScalingMode>
|
||||||
{
|
{
|
||||||
LabelText = "Scaling",
|
LabelText = "Screen Scaling",
|
||||||
Bindable = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling),
|
Bindable = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling),
|
||||||
},
|
},
|
||||||
scalingSettings = new FillFlowContainer<SettingsSlider<float>>
|
scalingSettings = new FillFlowContainer<SettingsSlider<float>>
|
||||||
@ -202,6 +209,11 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class UIScaleSlider : OsuSliderBar<float>
|
||||||
|
{
|
||||||
|
public override string TooltipText => base.TooltipText + "x";
|
||||||
|
}
|
||||||
|
|
||||||
private class ResolutionSettingsDropdown : SettingsDropdown<Size>
|
private class ResolutionSettingsDropdown : SettingsDropdown<Size>
|
||||||
{
|
{
|
||||||
protected override OsuDropdown<Size> CreateDropdown() => new ResolutionDropdownControl { Items = Items };
|
protected override OsuDropdown<Size> CreateDropdown() => new ResolutionDropdownControl { Items = Items };
|
||||||
|
@ -5,7 +5,6 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Input.Events;
|
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
|
||||||
@ -78,66 +77,15 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
|
|
||||||
private class SensitivitySetting : SettingsSlider<double, SensitivitySlider>
|
private class SensitivitySetting : SettingsSlider<double, SensitivitySlider>
|
||||||
{
|
{
|
||||||
public override Bindable<double> Bindable
|
|
||||||
{
|
|
||||||
get { return ((SensitivitySlider)Control).Sensitivity; }
|
|
||||||
|
|
||||||
set
|
|
||||||
{
|
|
||||||
BindableDouble doubleValue = (BindableDouble)value;
|
|
||||||
|
|
||||||
// create a second layer of bindable so we can only handle state changes when not being dragged.
|
|
||||||
((SensitivitySlider)Control).Sensitivity = doubleValue;
|
|
||||||
|
|
||||||
// this bindable will still act as the "interactive" bindable displayed during a drag.
|
|
||||||
base.Bindable = new BindableDouble(doubleValue.Value)
|
|
||||||
{
|
|
||||||
Default = doubleValue.Default,
|
|
||||||
MinValue = doubleValue.MinValue,
|
|
||||||
MaxValue = doubleValue.MaxValue
|
|
||||||
};
|
|
||||||
|
|
||||||
// one-way binding to update the sliderbar with changes from external actions.
|
|
||||||
doubleValue.DisabledChanged += disabled => base.Bindable.Disabled = disabled;
|
|
||||||
doubleValue.ValueChanged += newValue => base.Bindable.Value = newValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SensitivitySetting()
|
public SensitivitySetting()
|
||||||
{
|
{
|
||||||
KeyboardStep = 0.01f;
|
KeyboardStep = 0.01f;
|
||||||
|
TransferValueOnCommit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SensitivitySlider : OsuSliderBar<double>
|
private class SensitivitySlider : OsuSliderBar<double>
|
||||||
{
|
{
|
||||||
public Bindable<double> Sensitivity;
|
|
||||||
|
|
||||||
public SensitivitySlider()
|
|
||||||
{
|
|
||||||
Current.ValueChanged += newValue =>
|
|
||||||
{
|
|
||||||
if (!isDragging && Sensitivity != null)
|
|
||||||
Sensitivity.Value = newValue;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool isDragging;
|
|
||||||
|
|
||||||
protected override bool OnDragStart(DragStartEvent e)
|
|
||||||
{
|
|
||||||
isDragging = true;
|
|
||||||
return base.OnDragStart(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool OnDragEnd(DragEndEvent e)
|
|
||||||
{
|
|
||||||
isDragging = false;
|
|
||||||
Current.TriggerChange();
|
|
||||||
|
|
||||||
return base.OnDragEnd(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string TooltipText => Current.Disabled ? "Enable raw input to adjust sensitivity" : Current.Value.ToString(@"0.##x");
|
public override string TooltipText => Current.Disabled ? "Enable raw input to adjust sensitivity" : Current.Value.ToString(@"0.##x");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,16 @@ namespace osu.Game.Overlays.Settings.Sections
|
|||||||
LabelText = "Adjust gameplay cursor size based on current beatmap",
|
LabelText = "Adjust gameplay cursor size based on current beatmap",
|
||||||
Bindable = config.GetBindable<bool>(OsuSetting.AutoCursorSize)
|
Bindable = config.GetBindable<bool>(OsuSetting.AutoCursorSize)
|
||||||
},
|
},
|
||||||
|
new SettingsCheckbox
|
||||||
|
{
|
||||||
|
LabelText = "Beatmap skins",
|
||||||
|
Bindable = config.GetBindable<bool>(OsuSetting.BeatmapSkins)
|
||||||
|
},
|
||||||
|
new SettingsCheckbox
|
||||||
|
{
|
||||||
|
LabelText = "Beatmap hitsounds",
|
||||||
|
Bindable = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
skins.ItemAdded += itemAdded;
|
skins.ItemAdded += itemAdded;
|
||||||
|
@ -26,6 +26,8 @@ namespace osu.Game.Overlays.Settings
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> FilterTerms => base.FilterTerms.Concat(Control.Items.Select(i => i.ToString()));
|
||||||
|
|
||||||
protected sealed override Drawable CreateControl() => CreateDropdown();
|
protected sealed override Drawable CreateControl() => CreateDropdown();
|
||||||
|
|
||||||
protected virtual OsuDropdown<T> CreateDropdown() => new DropdownControl { Items = Items };
|
protected virtual OsuDropdown<T> CreateDropdown() => new DropdownControl { Items = Items };
|
||||||
|
@ -72,7 +72,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> FilterTerms => new[] { LabelText };
|
public virtual IEnumerable<string> FilterTerms => new[] { LabelText };
|
||||||
|
|
||||||
public bool MatchingFilter
|
public bool MatchingFilter
|
||||||
{
|
{
|
||||||
|
@ -124,7 +124,6 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
|||||||
// osu-stable treated the first span of the slider as a repeat, but no repeats are happening
|
// osu-stable treated the first span of the slider as a repeat, but no repeats are happening
|
||||||
repeatCount = Math.Max(0, repeatCount - 1);
|
repeatCount = Math.Max(0, repeatCount - 1);
|
||||||
|
|
||||||
|
|
||||||
if (split.Length > 7)
|
if (split.Length > 7)
|
||||||
length = Convert.ToDouble(split[7], CultureInfo.InvariantCulture);
|
length = Convert.ToDouble(split[7], CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
|
@ -250,14 +250,14 @@ namespace osu.Game.Rulesets.UI
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
{
|
{
|
||||||
KeyBindingInputManager.Children = new Drawable[]
|
KeyBindingInputManager.AddRange(new Drawable[]
|
||||||
{
|
{
|
||||||
content = new Container
|
content = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
Playfield
|
Playfield
|
||||||
};
|
});
|
||||||
|
|
||||||
if (Cursor != null)
|
if (Cursor != null)
|
||||||
KeyBindingInputManager.Add(Cursor);
|
KeyBindingInputManager.Add(Cursor);
|
||||||
|
@ -27,14 +27,6 @@ namespace osu.Game.Rulesets.UI
|
|||||||
public abstract class RulesetInputManager<T> : PassThroughInputManager, ICanAttachKeyCounter, IHasReplayHandler
|
public abstract class RulesetInputManager<T> : PassThroughInputManager, ICanAttachKeyCounter, IHasReplayHandler
|
||||||
where T : struct
|
where T : struct
|
||||||
{
|
{
|
||||||
public class RulesetKeyBindingContainer : DatabasedKeyBindingContainer<T>
|
|
||||||
{
|
|
||||||
public RulesetKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
|
|
||||||
: base(ruleset, variant, unique)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override InputState CreateInitialState()
|
protected override InputState CreateInitialState()
|
||||||
{
|
{
|
||||||
var state = base.CreateInitialState();
|
var state = base.CreateInitialState();
|
||||||
@ -251,6 +243,14 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
protected virtual RulesetKeyBindingContainer CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
|
protected virtual RulesetKeyBindingContainer CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
|
||||||
=> new RulesetKeyBindingContainer(ruleset, variant, unique);
|
=> new RulesetKeyBindingContainer(ruleset, variant, unique);
|
||||||
|
|
||||||
|
public class RulesetKeyBindingContainer : DatabasedKeyBindingContainer<T>
|
||||||
|
{
|
||||||
|
public RulesetKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique)
|
||||||
|
: base(ruleset, variant, unique)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -109,12 +109,12 @@ namespace osu.Game.Scoring.Legacy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateAccuracy(score.ScoreInfo);
|
CalculateAccuracy(score.ScoreInfo);
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void calculateAccuracy(ScoreInfo score)
|
protected void CalculateAccuracy(ScoreInfo score)
|
||||||
{
|
{
|
||||||
int countMiss = score.Statistics[HitResult.Miss];
|
int countMiss = score.Statistics[HitResult.Miss];
|
||||||
int count50 = score.Statistics[HitResult.Meh];
|
int count50 = score.Statistics[HitResult.Meh];
|
||||||
|
@ -2,10 +2,14 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Backgrounds
|
namespace osu.Game.Screens.Backgrounds
|
||||||
{
|
{
|
||||||
@ -16,11 +20,21 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
|
|
||||||
private string backgroundName => $@"Menu/menu-background-{currentDisplay % background_count + 1}";
|
private string backgroundName => $@"Menu/menu-background-{currentDisplay % background_count + 1}";
|
||||||
|
|
||||||
|
private Bindable<User> user;
|
||||||
|
private Bindable<Skin> skin;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load(IAPIProvider api, SkinManager skinManager)
|
||||||
{
|
{
|
||||||
|
user = api.LocalUser.GetBoundCopy();
|
||||||
|
skin = skinManager.CurrentSkin.GetBoundCopy();
|
||||||
|
|
||||||
|
user.ValueChanged += _ => Next();
|
||||||
|
skin.ValueChanged += _ => Next();
|
||||||
|
|
||||||
currentDisplay = RNG.Next(0, background_count);
|
currentDisplay = RNG.Next(0, background_count);
|
||||||
display(new Background(backgroundName));
|
|
||||||
|
Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void display(Background newBackground)
|
private void display(Background newBackground)
|
||||||
@ -39,8 +53,33 @@ namespace osu.Game.Screens.Backgrounds
|
|||||||
nextTask?.Cancel();
|
nextTask?.Cancel();
|
||||||
nextTask = Scheduler.AddDelayed(() =>
|
nextTask = Scheduler.AddDelayed(() =>
|
||||||
{
|
{
|
||||||
LoadComponentAsync(new Background(backgroundName) { Depth = currentDisplay }, display);
|
Background background;
|
||||||
|
|
||||||
|
if (user.Value?.IsSupporter ?? false)
|
||||||
|
background = new SkinnedBackground(skin.Value, backgroundName);
|
||||||
|
else
|
||||||
|
background = new Background(backgroundName);
|
||||||
|
|
||||||
|
background.Depth = currentDisplay;
|
||||||
|
|
||||||
|
LoadComponentAsync(background, display);
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class SkinnedBackground : Background
|
||||||
|
{
|
||||||
|
private readonly Skin skin;
|
||||||
|
|
||||||
|
public SkinnedBackground(Skin skin, string fallbackTextureName) : base(fallbackTextureName)
|
||||||
|
{
|
||||||
|
this.skin = skin;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
Sprite.Texture = skin.GetTexture("menu-background") ?? Sprite.Texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ namespace osu.Game.Screens.Edit.Components
|
|||||||
|
|
||||||
public TimeInfoContainer()
|
public TimeInfoContainer()
|
||||||
{
|
{
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
trackTimer = new OsuSpriteText
|
trackTimer = new OsuSpriteText
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
@ -24,7 +28,10 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
public override bool CursorVisible => false;
|
public override bool CursorVisible => false;
|
||||||
|
|
||||||
private const float icon_y = -0.09f;
|
private readonly List<Drawable> supporterDrawables = new List<Drawable>();
|
||||||
|
private Drawable heart;
|
||||||
|
|
||||||
|
private const float icon_y = -85;
|
||||||
|
|
||||||
public Disclaimer()
|
public Disclaimer()
|
||||||
{
|
{
|
||||||
@ -42,7 +49,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Icon = FontAwesome.fa_warning,
|
Icon = FontAwesome.fa_warning,
|
||||||
Size = new Vector2(30),
|
Size = new Vector2(30),
|
||||||
RelativePositionAxes = Axes.Both,
|
|
||||||
Y = icon_y,
|
Y = icon_y,
|
||||||
},
|
},
|
||||||
textFlow = new LinkFlowContainer
|
textFlow = new LinkFlowContainer
|
||||||
@ -51,8 +57,9 @@ namespace osu.Game.Screens.Menu
|
|||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Padding = new MarginPadding(50),
|
Padding = new MarginPadding(50),
|
||||||
TextAnchor = Anchor.TopCentre,
|
TextAnchor = Anchor.TopCentre,
|
||||||
|
Y = -110,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.TopCentre,
|
||||||
Spacing = new Vector2(0, 2),
|
Spacing = new Vector2(0, 2),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -68,14 +75,37 @@ namespace osu.Game.Screens.Menu
|
|||||||
t.Font = @"Exo2.0-SemiBold";
|
t.Font = @"Exo2.0-SemiBold";
|
||||||
});
|
});
|
||||||
|
|
||||||
textFlow.AddParagraph("Don't expect everything to work perfectly.");
|
textFlow.AddParagraph("Things may not work as expected", t => t.TextSize = 20);
|
||||||
textFlow.AddParagraph("");
|
textFlow.NewParagraph();
|
||||||
textFlow.AddParagraph("Detailed bug reports are welcomed via github issues.");
|
|
||||||
textFlow.AddParagraph("");
|
|
||||||
|
|
||||||
textFlow.AddText("Visit ");
|
Action<SpriteText> format = t =>
|
||||||
textFlow.AddLink("discord.gg/ppy", "https://discord.gg/ppy");
|
{
|
||||||
textFlow.AddText(" if you want to help out or follow progress!");
|
t.TextSize = 15;
|
||||||
|
t.Font = @"Exo2.0-SemiBold";
|
||||||
|
};
|
||||||
|
|
||||||
|
textFlow.AddParagraph("Detailed bug reports are welcomed via github issues.", format);
|
||||||
|
textFlow.NewParagraph();
|
||||||
|
|
||||||
|
textFlow.AddText("Visit ", format);
|
||||||
|
textFlow.AddLink("discord.gg/ppy", "https://discord.gg/ppy", creationParameters:format);
|
||||||
|
textFlow.AddText(" to help out or follow progress!", format);
|
||||||
|
|
||||||
|
textFlow.NewParagraph();
|
||||||
|
textFlow.NewParagraph();
|
||||||
|
textFlow.NewParagraph();
|
||||||
|
|
||||||
|
supporterDrawables.AddRange(textFlow.AddText("Consider becoming an ", format));
|
||||||
|
supporterDrawables.AddRange(textFlow.AddLink("osu!supporter", "https://osu.ppy.sh/home/support", creationParameters: format));
|
||||||
|
supporterDrawables.AddRange(textFlow.AddText(" to help support the game", format));
|
||||||
|
|
||||||
|
supporterDrawables.Add(heart = textFlow.AddIcon(FontAwesome.fa_heart, t =>
|
||||||
|
{
|
||||||
|
t.Padding = new MarginPadding { Left = 5 };
|
||||||
|
t.TextSize = 12;
|
||||||
|
t.Colour = colours.Pink;
|
||||||
|
t.Origin = Anchor.Centre;
|
||||||
|
}).First());
|
||||||
|
|
||||||
iconColour = colours.Yellow;
|
iconColour = colours.Yellow;
|
||||||
}
|
}
|
||||||
@ -90,8 +120,15 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
base.OnEntering(last);
|
base.OnEntering(last);
|
||||||
|
|
||||||
icon.Delay(1500).FadeColour(iconColour, 200, Easing.OutQuint);
|
icon.Delay(1000).FadeColour(iconColour, 200, Easing.OutQuint);
|
||||||
icon.Delay(1500).MoveToY(icon_y * 1.1f, 100, Easing.OutCirc).Then().MoveToY(icon_y, 100, Easing.InCirc);
|
icon.Delay(1000)
|
||||||
|
.MoveToY(icon_y * 1.1f, 160, Easing.OutCirc)
|
||||||
|
.RotateTo(-10, 160, Easing.OutCirc)
|
||||||
|
.Then()
|
||||||
|
.MoveToY(icon_y, 160, Easing.InCirc)
|
||||||
|
.RotateTo(0, 160, Easing.InCirc);
|
||||||
|
|
||||||
|
supporterDrawables.ForEach(d => d.FadeOut().Delay(2000).FadeIn(500));
|
||||||
|
|
||||||
Content
|
Content
|
||||||
.FadeInFromZero(500)
|
.FadeInFromZero(500)
|
||||||
@ -99,6 +136,8 @@ namespace osu.Game.Screens.Menu
|
|||||||
.FadeOut(250)
|
.FadeOut(250)
|
||||||
.ScaleTo(0.9f, 250, Easing.InQuint)
|
.ScaleTo(0.9f, 250, Easing.InQuint)
|
||||||
.Finally(d => Push(intro));
|
.Finally(d => Push(intro));
|
||||||
|
|
||||||
|
heart.FlashColour(Color4.White, 750, Easing.OutQuint).Loop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osuTK.Graphics.ES30;
|
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Batches;
|
using osu.Framework.Graphics.Batches;
|
||||||
@ -150,7 +149,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
private class VisualiserSharedData
|
private class VisualiserSharedData
|
||||||
{
|
{
|
||||||
public readonly LinearBatch<TexturedVertex2D> VertexBatch = new LinearBatch<TexturedVertex2D>(100 * 4, 10, PrimitiveType.Quads);
|
public readonly QuadBatch<TexturedVertex2D> VertexBatch = new QuadBatch<TexturedVertex2D>(100, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class VisualisationDrawNode : DrawNode
|
private class VisualisationDrawNode : DrawNode
|
||||||
|
@ -93,10 +93,14 @@ namespace osu.Game.Screens.Multi.Lounge.Components
|
|||||||
Host.BindValueChanged(v =>
|
Host.BindValueChanged(v =>
|
||||||
{
|
{
|
||||||
hostText.Clear();
|
hostText.Clear();
|
||||||
|
flagContainer.Clear();
|
||||||
|
|
||||||
|
if (v != null)
|
||||||
|
{
|
||||||
hostText.AddText("hosted by ");
|
hostText.AddText("hosted by ");
|
||||||
hostText.AddLink(v.Username, null, LinkAction.OpenUserProfile, v.Id.ToString(), "Open profile", s => s.Font = "Exo2.0-BoldItalic");
|
hostText.AddLink(v.Username, null, LinkAction.OpenUserProfile, v.Id.ToString(), "Open profile", s => s.Font = "Exo2.0-BoldItalic");
|
||||||
|
|
||||||
flagContainer.Child = new DrawableFlag(v.Country) { RelativeSizeAxes = Axes.Both };
|
flagContainer.Child = new DrawableFlag(v.Country) { RelativeSizeAxes = Axes.Both };
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ParticipantCount.BindValueChanged(v => summary.Text = $"{v:#,0}{" participant".Pluralize(v == 1)}");
|
ParticipantCount.BindValueChanged(v => summary.Text = $"{v:#,0}{" participant".Pluralize(v == 1)}");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Linq;
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
@ -13,8 +13,9 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Drawables;
|
using osu.Game.Beatmaps.Drawables;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Screens.Multi.Components;
|
using osu.Game.Screens.Multi.Components;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
@ -37,11 +38,10 @@ namespace osu.Game.Screens.Multi.Lounge.Components
|
|||||||
private Box statusStrip;
|
private Box statusStrip;
|
||||||
private UpdateableBeatmapBackgroundSprite background;
|
private UpdateableBeatmapBackgroundSprite background;
|
||||||
private ParticipantCountDisplay participantCount;
|
private ParticipantCountDisplay participantCount;
|
||||||
private FillFlowContainer topFlow, participantsFlow;
|
|
||||||
private OsuSpriteText name, status;
|
private OsuSpriteText name, status;
|
||||||
private BeatmapTypeInfo beatmapTypeInfo;
|
private BeatmapTypeInfo beatmapTypeInfo;
|
||||||
private ScrollContainer participantsScroll;
|
|
||||||
private ParticipantInfo participantInfo;
|
private ParticipantInfo participantInfo;
|
||||||
|
private MatchParticipants participants;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private BeatmapManager beatmaps { get; set; }
|
private BeatmapManager beatmaps { get; set; }
|
||||||
@ -58,7 +58,19 @@ namespace osu.Game.Screens.Multi.Lounge.Components
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = OsuColour.FromHex(@"343138"),
|
Colour = OsuColour.FromHex(@"343138"),
|
||||||
},
|
},
|
||||||
topFlow = new FillFlowContainer
|
new GridContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
RowDimensions = new[]
|
||||||
|
{
|
||||||
|
new Dimension(GridSizeMode.AutoSize),
|
||||||
|
new Dimension(GridSizeMode.Distributed),
|
||||||
|
},
|
||||||
|
Content = new[]
|
||||||
|
{
|
||||||
|
new Drawable[]
|
||||||
|
{
|
||||||
|
new FillFlowContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
@ -147,52 +159,40 @@ namespace osu.Game.Screens.Multi.Lounge.Components
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
participantsScroll = new OsuScrollContainer
|
|
||||||
{
|
|
||||||
Anchor = Anchor.BottomLeft,
|
|
||||||
Origin = Anchor.BottomLeft,
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Padding = new MarginPadding { Top = contentPadding.Top, Left = 38, Right = 37 },
|
|
||||||
Children = new[]
|
|
||||||
{
|
|
||||||
participantsFlow = new FillFlowContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
AutoSizeAxes = Axes.Y,
|
|
||||||
LayoutDuration = transition_duration,
|
|
||||||
Spacing = new Vector2(5f),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
new Drawable[]
|
||||||
|
{
|
||||||
|
participants = new MatchParticipants
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
participantInfo.Host.BindTo(bindings.Host);
|
participantInfo.Host.BindTo(bindings.Host);
|
||||||
participantInfo.ParticipantCount.BindTo(bindings.ParticipantCount);
|
participantInfo.ParticipantCount.BindTo(bindings.ParticipantCount);
|
||||||
participantInfo.Participants.BindTo(bindings.Participants);
|
participantInfo.Participants.BindTo(bindings.Participants);
|
||||||
|
|
||||||
participantCount.Participants.BindTo(bindings.Participants);
|
participantCount.Participants.BindTo(bindings.Participants);
|
||||||
participantCount.ParticipantCount.BindTo(bindings.ParticipantCount);
|
participantCount.ParticipantCount.BindTo(bindings.ParticipantCount);
|
||||||
participantCount.MaxParticipants.BindTo(bindings.MaxParticipants);
|
participantCount.MaxParticipants.BindTo(bindings.MaxParticipants);
|
||||||
|
|
||||||
beatmapTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap);
|
beatmapTypeInfo.Beatmap.BindTo(bindings.CurrentBeatmap);
|
||||||
beatmapTypeInfo.Ruleset.BindTo(bindings.CurrentRuleset);
|
beatmapTypeInfo.Ruleset.BindTo(bindings.CurrentRuleset);
|
||||||
beatmapTypeInfo.Type.BindTo(bindings.Type);
|
beatmapTypeInfo.Type.BindTo(bindings.Type);
|
||||||
background.Beatmap.BindTo(bindings.CurrentBeatmap);
|
background.Beatmap.BindTo(bindings.CurrentBeatmap);
|
||||||
|
|
||||||
bindings.Status.BindValueChanged(displayStatus);
|
bindings.Status.BindValueChanged(displayStatus);
|
||||||
bindings.Participants.BindValueChanged(p => participantsFlow.ChildrenEnumerable = p.Select(u => new UserTile(u)));
|
|
||||||
bindings.Name.BindValueChanged(n => name.Text = n);
|
bindings.Name.BindValueChanged(n => name.Text = n);
|
||||||
|
|
||||||
Room.BindValueChanged(updateRoom, true);
|
Room.BindValueChanged(updateRoom, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRoom(Room room)
|
private void updateRoom(Room room)
|
||||||
{
|
{
|
||||||
bindings.Room = room;
|
bindings.Room = room;
|
||||||
|
participants.Room = room;
|
||||||
|
|
||||||
if (room != null)
|
if (room != null)
|
||||||
{
|
{
|
||||||
participantsFlow.FadeIn(transition_duration);
|
|
||||||
participantCount.FadeIn(transition_duration);
|
participantCount.FadeIn(transition_duration);
|
||||||
beatmapTypeInfo.FadeIn(transition_duration);
|
beatmapTypeInfo.FadeIn(transition_duration);
|
||||||
name.FadeIn(transition_duration);
|
name.FadeIn(transition_duration);
|
||||||
@ -200,7 +200,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
participantsFlow.FadeOut(transition_duration);
|
|
||||||
participantCount.FadeOut(transition_duration);
|
participantCount.FadeOut(transition_duration);
|
||||||
beatmapTypeInfo.FadeOut(transition_duration);
|
beatmapTypeInfo.FadeOut(transition_duration);
|
||||||
name.FadeOut(transition_duration);
|
name.FadeOut(transition_duration);
|
||||||
@ -210,13 +209,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void UpdateAfterChildren()
|
|
||||||
{
|
|
||||||
base.UpdateAfterChildren();
|
|
||||||
|
|
||||||
participantsScroll.Height = DrawHeight - topFlow.DrawHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void displayStatus(RoomStatus s)
|
private void displayStatus(RoomStatus s)
|
||||||
{
|
{
|
||||||
status.Text = s.Message;
|
status.Text = s.Message;
|
||||||
@ -226,7 +218,92 @@ namespace osu.Game.Screens.Multi.Lounge.Components
|
|||||||
status.FadeColour(c, transition_duration);
|
status.FadeColour(c, transition_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class UserTile : Container, IHasTooltip
|
private class RoomStatusNoneSelected : RoomStatus
|
||||||
|
{
|
||||||
|
public override string Message => @"No Room Selected";
|
||||||
|
public override Color4 GetAppropriateColour(OsuColour colours) => colours.Gray8;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MatchParticipants : CompositeDrawable
|
||||||
|
{
|
||||||
|
private Room room;
|
||||||
|
private readonly FillFlowContainer fill;
|
||||||
|
|
||||||
|
public Room Room
|
||||||
|
{
|
||||||
|
get { return room; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (room == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
room = value;
|
||||||
|
updateParticipants();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MatchParticipants()
|
||||||
|
{
|
||||||
|
Padding = new MarginPadding { Horizontal = 10 };
|
||||||
|
|
||||||
|
InternalChild = new ScrollContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = fill = new FillFlowContainer
|
||||||
|
{
|
||||||
|
Spacing = new Vector2(10),
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y,
|
||||||
|
Direction = FillDirection.Full,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private APIAccess api { get; set; }
|
||||||
|
|
||||||
|
private GetRoomScoresRequest request;
|
||||||
|
|
||||||
|
private void updateParticipants()
|
||||||
|
{
|
||||||
|
var roomId = room?.RoomID.Value ?? 0;
|
||||||
|
|
||||||
|
request?.Cancel();
|
||||||
|
|
||||||
|
// nice little progressive fade
|
||||||
|
int time = 500;
|
||||||
|
foreach (var c in fill.Children)
|
||||||
|
{
|
||||||
|
c.Delay(500 - time).FadeOut(time, Easing.Out);
|
||||||
|
time = Math.Max(20, time - 20);
|
||||||
|
c.Expire();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roomId == 0) return;
|
||||||
|
|
||||||
|
request = new GetRoomScoresRequest(roomId);
|
||||||
|
request.Success += scores =>
|
||||||
|
{
|
||||||
|
if (roomId != room.RoomID.Value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fill.Clear();
|
||||||
|
foreach (var s in scores)
|
||||||
|
fill.Add(new UserTile(s.User));
|
||||||
|
|
||||||
|
fill.FadeInFromZero(1000, Easing.OutQuint);
|
||||||
|
};
|
||||||
|
|
||||||
|
api.Queue(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
request?.Cancel();
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UserTile : CompositeDrawable, IHasTooltip
|
||||||
{
|
{
|
||||||
private readonly User user;
|
private readonly User user;
|
||||||
|
|
||||||
@ -239,7 +316,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components
|
|||||||
CornerRadius = 5f;
|
CornerRadius = 5f;
|
||||||
Masking = true;
|
Masking = true;
|
||||||
|
|
||||||
Children = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
new Box
|
new Box
|
||||||
{
|
{
|
||||||
@ -254,11 +331,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RoomStatusNoneSelected : RoomStatus
|
|
||||||
{
|
|
||||||
public override string Message => @"No Room Selected";
|
|
||||||
public override Color4 GetAppropriateColour(OsuColour colours) => colours.Gray8;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,17 +16,18 @@ namespace osu.Game.Screens.Multi.Match.Components
|
|||||||
{
|
{
|
||||||
public Action<IEnumerable<APIRoomScoreInfo>> ScoresLoaded;
|
public Action<IEnumerable<APIRoomScoreInfo>> ScoresLoaded;
|
||||||
|
|
||||||
private readonly Room room;
|
public Room Room
|
||||||
|
|
||||||
public MatchLeaderboard(Room room)
|
|
||||||
{
|
{
|
||||||
this.room = room;
|
get => bindings.Room;
|
||||||
|
set => bindings.Room = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly RoomBindings bindings = new RoomBindings();
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
room.RoomID.BindValueChanged(id =>
|
bindings.RoomID.BindValueChanged(id =>
|
||||||
{
|
{
|
||||||
if (id == null)
|
if (id == null)
|
||||||
return;
|
return;
|
||||||
@ -38,10 +39,10 @@ namespace osu.Game.Screens.Multi.Match.Components
|
|||||||
|
|
||||||
protected override APIRequest FetchScores(Action<IEnumerable<APIRoomScoreInfo>> scoresCallback)
|
protected override APIRequest FetchScores(Action<IEnumerable<APIRoomScoreInfo>> scoresCallback)
|
||||||
{
|
{
|
||||||
if (room.RoomID == null)
|
if (bindings.RoomID.Value == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var req = new GetRoomScoresRequest(room.RoomID.Value ?? 0);
|
var req = new GetRoomScoresRequest(bindings.RoomID.Value ?? 0);
|
||||||
|
|
||||||
req.Success += r =>
|
req.Success += r =>
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,8 @@ namespace osu.Game.Screens.Multi.Match
|
|||||||
|
|
||||||
MatchChatDisplay chat;
|
MatchChatDisplay chat;
|
||||||
Components.Header header;
|
Components.Header header;
|
||||||
|
Info info;
|
||||||
|
GridContainer bottomRow;
|
||||||
MatchSettingsOverlay settings;
|
MatchSettingsOverlay settings;
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
@ -61,20 +63,21 @@ namespace osu.Game.Screens.Multi.Match
|
|||||||
Content = new[]
|
Content = new[]
|
||||||
{
|
{
|
||||||
new Drawable[] { header = new Components.Header(room) { Depth = -1 } },
|
new Drawable[] { header = new Components.Header(room) { Depth = -1 } },
|
||||||
new Drawable[] { new Info(room) { OnStart = onStart } },
|
new Drawable[] { info = new Info(room) { OnStart = onStart } },
|
||||||
new Drawable[]
|
new Drawable[]
|
||||||
{
|
{
|
||||||
new GridContainer
|
bottomRow = new GridContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Content = new[]
|
Content = new[]
|
||||||
{
|
{
|
||||||
new Drawable[]
|
new Drawable[]
|
||||||
{
|
{
|
||||||
leaderboard = new MatchLeaderboard(room)
|
leaderboard = new MatchLeaderboard
|
||||||
{
|
{
|
||||||
Padding = new MarginPadding(10),
|
Padding = new MarginPadding(10),
|
||||||
RelativeSizeAxes = Axes.Both
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Room = room
|
||||||
},
|
},
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
@ -108,10 +111,19 @@ namespace osu.Game.Screens.Multi.Match
|
|||||||
header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect { Selected = addPlaylistItem });
|
header.OnRequestSelectBeatmap = () => Push(new MatchSongSelect { Selected = addPlaylistItem });
|
||||||
header.Tabs.Current.ValueChanged += t =>
|
header.Tabs.Current.ValueChanged += t =>
|
||||||
{
|
{
|
||||||
|
const float fade_duration = 500;
|
||||||
if (t is SettingsMatchPage)
|
if (t is SettingsMatchPage)
|
||||||
|
{
|
||||||
settings.Show();
|
settings.Show();
|
||||||
|
info.FadeOut(fade_duration, Easing.OutQuint);
|
||||||
|
bottomRow.FadeOut(fade_duration, Easing.OutQuint);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
settings.Hide();
|
settings.Hide();
|
||||||
|
info.FadeIn(fade_duration, Easing.OutQuint);
|
||||||
|
bottomRow.FadeIn(fade_duration, Easing.OutQuint);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
chat.Exit += Exit;
|
chat.Exit += Exit;
|
||||||
|
@ -103,8 +103,8 @@ namespace osu.Game.Screens.Multi.Ranking.Pages
|
|||||||
public class ResultsMatchLeaderboard : MatchLeaderboard
|
public class ResultsMatchLeaderboard : MatchLeaderboard
|
||||||
{
|
{
|
||||||
public ResultsMatchLeaderboard(Room room)
|
public ResultsMatchLeaderboard(Room room)
|
||||||
: base(room)
|
|
||||||
{
|
{
|
||||||
|
Room = room;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool FadeTop => true;
|
protected override bool FadeTop => true;
|
||||||
|
@ -39,6 +39,7 @@ namespace osu.Game.Screens.Multi
|
|||||||
|
|
||||||
if (room != null)
|
if (room != null)
|
||||||
{
|
{
|
||||||
|
RoomID.UnbindFrom(room.RoomID);
|
||||||
Name.UnbindFrom(room.Name);
|
Name.UnbindFrom(room.Name);
|
||||||
Host.UnbindFrom(room.Host);
|
Host.UnbindFrom(room.Host);
|
||||||
Status.UnbindFrom(room.Status);
|
Status.UnbindFrom(room.Status);
|
||||||
@ -52,10 +53,9 @@ namespace osu.Game.Screens.Multi
|
|||||||
Duration.UnbindFrom(room.Duration);
|
Duration.UnbindFrom(room.Duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
room = value;
|
room = value ?? new Room();
|
||||||
|
|
||||||
if (room != null)
|
RoomID.BindTo(room.RoomID);
|
||||||
{
|
|
||||||
Name.BindTo(room.Name);
|
Name.BindTo(room.Name);
|
||||||
Host.BindTo(room.Host);
|
Host.BindTo(room.Host);
|
||||||
Status.BindTo(room.Status);
|
Status.BindTo(room.Status);
|
||||||
@ -69,7 +69,6 @@ namespace osu.Game.Screens.Multi
|
|||||||
Duration.BindTo(room.Duration);
|
Duration.BindTo(room.Duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void updatePlaylist()
|
private void updatePlaylist()
|
||||||
{
|
{
|
||||||
@ -82,6 +81,7 @@ namespace osu.Game.Screens.Multi
|
|||||||
currentRuleset.Value = playlistItem?.Ruleset;
|
currentRuleset.Value = playlistItem?.Ruleset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public readonly Bindable<int?> RoomID = new Bindable<int?>();
|
||||||
public readonly Bindable<string> Name = new Bindable<string>();
|
public readonly Bindable<string> Name = new Bindable<string>();
|
||||||
public readonly Bindable<User> Host = new Bindable<User>();
|
public readonly Bindable<User> Host = new Bindable<User>();
|
||||||
public readonly Bindable<RoomStatus> Status = new Bindable<RoomStatus>();
|
public readonly Bindable<RoomStatus> Status = new Bindable<RoomStatus>();
|
||||||
|
@ -50,7 +50,7 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
protected override void PopOut() => this.FadeOut(fade_duration);
|
protected override void PopOut() => this.FadeOut(fade_duration);
|
||||||
|
|
||||||
//We want to handle keyboard inputs all the time in order to trigger ToggleVisibility() when not visible
|
//We want to handle keyboard inputs all the time in order to trigger ToggleVisibility() when not visible
|
||||||
public override bool HandleNonPositionalInput => true;
|
public override bool PropagateNonPositionalInputSubTree => true;
|
||||||
|
|
||||||
protected override bool OnKeyDown(KeyDownEvent e)
|
protected override bool OnKeyDown(KeyDownEvent e)
|
||||||
{
|
{
|
||||||
|
@ -24,8 +24,6 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
private const int duration = 100;
|
private const int duration = 100;
|
||||||
|
|
||||||
private readonly Container content;
|
|
||||||
|
|
||||||
public readonly KeyCounterCollection KeyCounter;
|
public readonly KeyCounterCollection KeyCounter;
|
||||||
public readonly RollingCounter<int> ComboCounter;
|
public readonly RollingCounter<int> ComboCounter;
|
||||||
public readonly ScoreCounter ScoreCounter;
|
public readonly ScoreCounter ScoreCounter;
|
||||||
@ -37,6 +35,7 @@ namespace osu.Game.Screens.Play
|
|||||||
public readonly PlayerSettingsOverlay PlayerSettingsOverlay;
|
public readonly PlayerSettingsOverlay PlayerSettingsOverlay;
|
||||||
|
|
||||||
private Bindable<bool> showHud;
|
private Bindable<bool> showHud;
|
||||||
|
private readonly Container visibilityContainer;
|
||||||
private readonly BindableBool replayLoaded = new BindableBool();
|
private readonly BindableBool replayLoaded = new BindableBool();
|
||||||
|
|
||||||
private static bool hasShownNotificationOnce;
|
private static bool hasShownNotificationOnce;
|
||||||
@ -45,18 +44,33 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
Add(content = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
AlwaysPresent = true, // The hud may be hidden but certain elements may need to still be updated
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
ComboCounter = CreateComboCounter(),
|
visibilityContainer = new Container
|
||||||
ScoreCounter = CreateScoreCounter(),
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Y = 30,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
AutoSizeDuration = 200,
|
||||||
|
AutoSizeEasing = Easing.Out,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
AccuracyCounter = CreateAccuracyCounter(),
|
AccuracyCounter = CreateAccuracyCounter(),
|
||||||
|
ScoreCounter = CreateScoreCounter(),
|
||||||
|
ComboCounter = CreateComboCounter(),
|
||||||
|
},
|
||||||
|
},
|
||||||
HealthDisplay = CreateHealthDisplay(),
|
HealthDisplay = CreateHealthDisplay(),
|
||||||
Progress = CreateProgress(),
|
Progress = CreateProgress(),
|
||||||
ModDisplay = CreateModsContainer(),
|
ModDisplay = CreateModsContainer(),
|
||||||
|
}
|
||||||
|
},
|
||||||
PlayerSettingsOverlay = CreatePlayerSettingsOverlay(),
|
PlayerSettingsOverlay = CreatePlayerSettingsOverlay(),
|
||||||
new FillFlowContainer
|
new FillFlowContainer
|
||||||
{
|
{
|
||||||
@ -71,8 +85,7 @@ namespace osu.Game.Screens.Play
|
|||||||
HoldToQuit = CreateHoldForMenuButton(),
|
HoldToQuit = CreateHoldForMenuButton(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
});
|
|
||||||
|
|
||||||
BindProcessor(scoreProcessor);
|
BindProcessor(scoreProcessor);
|
||||||
BindRulesetContainer(rulesetContainer);
|
BindRulesetContainer(rulesetContainer);
|
||||||
@ -91,7 +104,7 @@ namespace osu.Game.Screens.Play
|
|||||||
private void load(OsuConfigManager config, NotificationOverlay notificationOverlay)
|
private void load(OsuConfigManager config, NotificationOverlay notificationOverlay)
|
||||||
{
|
{
|
||||||
showHud = config.GetBindable<bool>(OsuSetting.ShowInterface);
|
showHud = config.GetBindable<bool>(OsuSetting.ShowInterface);
|
||||||
showHud.ValueChanged += hudVisibility => content.FadeTo(hudVisibility ? 1 : 0, duration);
|
showHud.ValueChanged += hudVisibility => visibilityContainer.FadeTo(hudVisibility ? 1 : 0, duration);
|
||||||
showHud.TriggerChange();
|
showHud.TriggerChange();
|
||||||
|
|
||||||
if (!showHud && !hasShownNotificationOnce)
|
if (!showHud && !hasShownNotificationOnce)
|
||||||
@ -159,20 +172,27 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
protected virtual RollingCounter<double> CreateAccuracyCounter() => new PercentageCounter
|
protected virtual RollingCounter<double> CreateAccuracyCounter() => new PercentageCounter
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopRight,
|
|
||||||
Position = new Vector2(0, 35),
|
|
||||||
TextSize = 20,
|
TextSize = 20,
|
||||||
Margin = new MarginPadding { Right = 140 },
|
BypassAutoSizeAxes = Axes.X,
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
Margin = new MarginPadding { Top = 5, Right = 20 },
|
||||||
|
};
|
||||||
|
|
||||||
|
protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6)
|
||||||
|
{
|
||||||
|
TextSize = 40,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
};
|
};
|
||||||
|
|
||||||
protected virtual RollingCounter<int> CreateComboCounter() => new SimpleComboCounter
|
protected virtual RollingCounter<int> CreateComboCounter() => new SimpleComboCounter
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopLeft,
|
|
||||||
Position = new Vector2(0, 35),
|
|
||||||
Margin = new MarginPadding { Left = 140 },
|
|
||||||
TextSize = 20,
|
TextSize = 20,
|
||||||
|
BypassAutoSizeAxes = Axes.X,
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopLeft,
|
||||||
|
Margin = new MarginPadding { Top = 5, Left = 20 },
|
||||||
};
|
};
|
||||||
|
|
||||||
protected virtual HealthDisplay CreateHealthDisplay() => new StandardHealthDisplay
|
protected virtual HealthDisplay CreateHealthDisplay() => new StandardHealthDisplay
|
||||||
@ -191,14 +211,6 @@ namespace osu.Game.Screens.Play
|
|||||||
AudioClock = offsetClock
|
AudioClock = offsetClock
|
||||||
};
|
};
|
||||||
|
|
||||||
protected virtual ScoreCounter CreateScoreCounter() => new ScoreCounter(6)
|
|
||||||
{
|
|
||||||
Anchor = Anchor.TopCentre,
|
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
TextSize = 40,
|
|
||||||
Position = new Vector2(0, 30),
|
|
||||||
};
|
|
||||||
|
|
||||||
protected virtual SongProgress CreateProgress() => new SongProgress
|
protected virtual SongProgress CreateProgress() => new SongProgress
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
|
@ -32,6 +32,7 @@ using osu.Game.Scoring;
|
|||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Storyboards.Drawables;
|
using osu.Game.Storyboards.Drawables;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
{
|
{
|
||||||
@ -82,7 +83,7 @@ namespace osu.Game.Screens.Play
|
|||||||
protected ScoreProcessor ScoreProcessor;
|
protected ScoreProcessor ScoreProcessor;
|
||||||
protected RulesetContainer RulesetContainer;
|
protected RulesetContainer RulesetContainer;
|
||||||
|
|
||||||
private HUDOverlay hudOverlay;
|
protected HUDOverlay HUDOverlay;
|
||||||
private FailOverlay failOverlay;
|
private FailOverlay failOverlay;
|
||||||
|
|
||||||
private DrawableStoryboard storyboard;
|
private DrawableStoryboard storyboard;
|
||||||
@ -199,7 +200,7 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
Child = RulesetContainer.Cursor?.CreateProxy() ?? new Container(),
|
Child = RulesetContainer.Cursor?.CreateProxy() ?? new Container(),
|
||||||
},
|
},
|
||||||
hudOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, offsetClock, adjustableClock)
|
HUDOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, offsetClock, adjustableClock)
|
||||||
{
|
{
|
||||||
Clock = Clock, // hud overlay doesn't want to use the audio clock directly
|
Clock = Clock, // hud overlay doesn't want to use the audio clock directly
|
||||||
ProcessCustomClock = false,
|
ProcessCustomClock = false,
|
||||||
@ -232,8 +233,8 @@ namespace osu.Game.Screens.Play
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
hudOverlay.HoldToQuit.Action = performUserRequestedExit;
|
HUDOverlay.HoldToQuit.Action = performUserRequestedExit;
|
||||||
hudOverlay.KeyCounter.Visible.BindTo(RulesetContainer.HasReplayLoaded);
|
HUDOverlay.KeyCounter.Visible.BindTo(RulesetContainer.HasReplayLoaded);
|
||||||
|
|
||||||
RulesetContainer.IsPaused.BindTo(pauseContainer.IsPaused);
|
RulesetContainer.IsPaused.BindTo(pauseContainer.IsPaused);
|
||||||
|
|
||||||
@ -401,6 +402,7 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
float fadeOutDuration = instant ? 0 : 250;
|
float fadeOutDuration = instant ? 0 : 250;
|
||||||
Content.FadeOut(fadeOutDuration);
|
Content.FadeOut(fadeOutDuration);
|
||||||
|
Background?.FadeColour(Color4.White, fadeOutDuration, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnScroll(ScrollEvent e) => mouseWheelDisabled.Value && !pauseContainer.IsPaused;
|
protected override bool OnScroll(ScrollEvent e) => mouseWheelDisabled.Value && !pauseContainer.IsPaused;
|
||||||
@ -438,7 +440,7 @@ namespace osu.Game.Screens.Play
|
|||||||
.FadeTo(storyboardVisible && BackgroundOpacity > 0 ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint);
|
.FadeTo(storyboardVisible && BackgroundOpacity > 0 ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint);
|
||||||
|
|
||||||
if (storyboardVisible && beatmap.Storyboard.ReplacesBackground)
|
if (storyboardVisible && beatmap.Storyboard.ReplacesBackground)
|
||||||
Background?.FadeTo(0, BACKGROUND_FADE_DURATION, Easing.OutQuint);
|
Background?.FadeColour(Color4.Black, BACKGROUND_FADE_DURATION, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Results CreateResults(ScoreInfo score) => new SoloResults(score);
|
protected virtual Results CreateResults(ScoreInfo score) => new SoloResults(score);
|
||||||
|
@ -164,7 +164,7 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
protected override void InitializeBackgroundElements()
|
protected override void InitializeBackgroundElements()
|
||||||
{
|
{
|
||||||
Background?.FadeTo(1, BACKGROUND_FADE_DURATION, Easing.OutQuint);
|
Background?.FadeColour(Color4.White, BACKGROUND_FADE_DURATION, Easing.OutQuint);
|
||||||
Background?.BlurTo(background_blur, BACKGROUND_FADE_DURATION, Easing.OutQuint);
|
Background?.BlurTo(background_blur, BACKGROUND_FADE_DURATION, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ using osu.Framework.Configuration;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Screens.Backgrounds;
|
using osu.Game.Screens.Backgrounds;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -60,14 +61,14 @@ namespace osu.Game.Screens.Play
|
|||||||
protected virtual void InitializeBackgroundElements() => UpdateBackgroundElements();
|
protected virtual void InitializeBackgroundElements() => UpdateBackgroundElements();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called wen background elements require updates, usually due to a user changing a setting.
|
/// Called when background elements require updates, usually due to a user changing a setting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userChange"></param>
|
/// <param name="userChange"></param>
|
||||||
protected virtual void UpdateBackgroundElements()
|
protected virtual void UpdateBackgroundElements()
|
||||||
{
|
{
|
||||||
if (!IsCurrentScreen) return;
|
if (!IsCurrentScreen) return;
|
||||||
|
|
||||||
Background?.FadeTo(BackgroundOpacity, BACKGROUND_FADE_DURATION, Easing.OutQuint);
|
Background?.FadeColour(OsuColour.Gray(BackgroundOpacity), BACKGROUND_FADE_DURATION, Easing.OutQuint);
|
||||||
Background?.BlurTo(new Vector2((float)BlurLevel.Value * 25), BACKGROUND_FADE_DURATION, Easing.OutQuint);
|
Background?.BlurTo(new Vector2((float)BlurLevel.Value * 25), BACKGROUND_FADE_DURATION, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,10 +46,10 @@ namespace osu.Game.Screens.Play
|
|||||||
State = Visibility.Visible;
|
State = Visibility.Visible;
|
||||||
|
|
||||||
RelativePositionAxes = Axes.Both;
|
RelativePositionAxes = Axes.Both;
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.X;
|
||||||
|
|
||||||
Position = new Vector2(0.5f, 0.7f);
|
Position = new Vector2(0.5f, 0.7f);
|
||||||
Size = new Vector2(1, 0.14f);
|
Size = new Vector2(1, 100);
|
||||||
|
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,6 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
private readonly Container<DrawableCarouselItem> scrollableContent;
|
private readonly Container<DrawableCarouselItem> scrollableContent;
|
||||||
|
|
||||||
|
|
||||||
public Bindable<bool> RightClickScrollingEnabled = new Bindable<bool>();
|
public Bindable<bool> RightClickScrollingEnabled = new Bindable<bool>();
|
||||||
|
|
||||||
public Bindable<RandomSelectAlgorithm> RandomAlgorithm = new Bindable<RandomSelectAlgorithm>();
|
public Bindable<RandomSelectAlgorithm> RandomAlgorithm = new Bindable<RandomSelectAlgorithm>();
|
||||||
|
@ -297,14 +297,14 @@ namespace osu.Game.Screens.Select
|
|||||||
/// <param name="performStartAction">Whether to trigger <see cref="OnStart"/>.</param>
|
/// <param name="performStartAction">Whether to trigger <see cref="OnStart"/>.</param>
|
||||||
public void FinaliseSelection(BeatmapInfo beatmap = null, bool performStartAction = true)
|
public void FinaliseSelection(BeatmapInfo beatmap = null, bool performStartAction = true)
|
||||||
{
|
{
|
||||||
// avoid attempting to continue before a selection has been obtained.
|
|
||||||
// this could happen via a user interaction while the carousel is still in a loading state.
|
|
||||||
if (Carousel.SelectedBeatmap == null) return;
|
|
||||||
|
|
||||||
// if we have a pending filter operation, we want to run it now.
|
// if we have a pending filter operation, we want to run it now.
|
||||||
// it could change selection (ie. if the ruleset has been changed).
|
// it could change selection (ie. if the ruleset has been changed).
|
||||||
Carousel.FlushPendingFilterOperations();
|
Carousel.FlushPendingFilterOperations();
|
||||||
|
|
||||||
|
// avoid attempting to continue before a selection has been obtained.
|
||||||
|
// this could happen via a user interaction while the carousel is still in a loading state.
|
||||||
|
if (Carousel.SelectedBeatmap == null) return;
|
||||||
|
|
||||||
if (beatmap != null)
|
if (beatmap != null)
|
||||||
Carousel.SelectBeatmap(beatmap);
|
Carousel.SelectBeatmap(beatmap);
|
||||||
|
|
||||||
|
@ -21,8 +21,6 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
SampleChannel GetSample(string sampleName);
|
SampleChannel GetSample(string sampleName);
|
||||||
|
|
||||||
TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration where TValue : class;
|
TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration;
|
||||||
|
|
||||||
TValue? GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue?> query) where TConfiguration : SkinConfiguration where TValue : struct;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,9 +101,10 @@ namespace osu.Game.Skinning
|
|||||||
bool hasExtension = filename.Contains('.');
|
bool hasExtension = filename.Contains('.');
|
||||||
|
|
||||||
string lastPiece = filename.Split('/').Last();
|
string lastPiece = filename.Split('/').Last();
|
||||||
|
var legacyName = filename.StartsWith("Gameplay/taiko/") ? "taiko-" + lastPiece : lastPiece;
|
||||||
|
|
||||||
var file = source.Files.Find(f =>
|
var file = source.Files.Find(f =>
|
||||||
string.Equals(hasExtension ? f.Filename : Path.ChangeExtension(f.Filename, null), lastPiece, StringComparison.InvariantCultureIgnoreCase));
|
string.Equals(hasExtension ? f.Filename : Path.ChangeExtension(f.Filename, null), legacyName, StringComparison.InvariantCultureIgnoreCase));
|
||||||
return file?.FileInfo.StoragePath;
|
return file?.FileInfo.StoragePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,9 @@ namespace osu.Game.Skinning
|
|||||||
case @"Author":
|
case @"Author":
|
||||||
skin.SkinInfo.Creator = pair.Value;
|
skin.SkinInfo.Creator = pair.Value;
|
||||||
break;
|
break;
|
||||||
|
case @"CursorExpand":
|
||||||
|
skin.CursorExpand = pair.Value != "0";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -43,22 +43,14 @@ namespace osu.Game.Skinning
|
|||||||
return fallbackSource?.GetSample(sampleName);
|
return fallbackSource?.GetSample(sampleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TValue? GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue?> query) where TConfiguration : SkinConfiguration where TValue : struct
|
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration
|
||||||
{
|
{
|
||||||
TValue? val = null;
|
TValue val;
|
||||||
if ((source as Skin)?.Configuration is TConfiguration conf)
|
if ((source as Skin)?.Configuration is TConfiguration conf)
|
||||||
val = query?.Invoke(conf);
|
if (beatmapSkins && (val = query.Invoke(conf)) != null)
|
||||||
|
return val;
|
||||||
|
|
||||||
return val ?? fallbackSource?.GetValue(query);
|
return fallbackSource == null ? default : fallbackSource.GetValue(query);
|
||||||
}
|
|
||||||
|
|
||||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration where TValue : class
|
|
||||||
{
|
|
||||||
TValue val = null;
|
|
||||||
if ((source as Skin)?.Configuration is TConfiguration conf)
|
|
||||||
val = query?.Invoke(conf);
|
|
||||||
|
|
||||||
return val ?? fallbackSource?.GetValue(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ISkinSource source;
|
private readonly ISkinSource source;
|
||||||
|
@ -22,11 +22,8 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
public abstract Texture GetTexture(string componentName);
|
public abstract Texture GetTexture(string componentName);
|
||||||
|
|
||||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration where TValue : class
|
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration
|
||||||
=> Configuration is TConfiguration conf ? query?.Invoke(conf) : null;
|
=> Configuration is TConfiguration conf ? query.Invoke(conf) : default;
|
||||||
|
|
||||||
public TValue? GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue?> query) where TConfiguration : SkinConfiguration where TValue : struct
|
|
||||||
=> Configuration is TConfiguration conf ? query?.Invoke(conf) : null;
|
|
||||||
|
|
||||||
protected Skin(SkinInfo skin)
|
protected Skin(SkinInfo skin)
|
||||||
{
|
{
|
||||||
|
@ -16,5 +16,7 @@ namespace osu.Game.Skinning
|
|||||||
public Dictionary<string, Color4> CustomColours { get; set; } = new Dictionary<string, Color4>();
|
public Dictionary<string, Color4> CustomColours { get; set; } = new Dictionary<string, Color4>();
|
||||||
|
|
||||||
public string HitCircleFont { get; set; } = "default";
|
public string HitCircleFont { get; set; } = "default";
|
||||||
|
|
||||||
|
public bool? CursorExpand { get; set; } = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,8 +116,6 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
public SampleChannel GetSample(string sampleName) => CurrentSkin.Value.GetSample(sampleName);
|
public SampleChannel GetSample(string sampleName) => CurrentSkin.Value.GetSample(sampleName);
|
||||||
|
|
||||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration where TValue : class => CurrentSkin.Value.GetValue(query);
|
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration => CurrentSkin.Value.GetValue(query);
|
||||||
|
|
||||||
public TValue? GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue?> query) where TConfiguration : SkinConfiguration where TValue : struct => CurrentSkin.Value.GetValue(query);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
Player p = null;
|
Player p = null;
|
||||||
AddStep(ruleset.RulesetInfo.Name, () => p = loadPlayerFor(ruleset));
|
AddStep(ruleset.RulesetInfo.Name, () => p = loadPlayerFor(ruleset));
|
||||||
AddUntilStep(() => ContinueCondition(p));
|
AddCheckSteps(() => p);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -52,7 +52,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
Player p = null;
|
Player p = null;
|
||||||
AddStep(r.Name, () => p = loadPlayerFor(r));
|
AddStep(r.Name, () => p = loadPlayerFor(r));
|
||||||
AddUntilStep(() => ContinueCondition(p));
|
AddCheckSteps(() => p);
|
||||||
|
|
||||||
AddUntilStep(() =>
|
AddUntilStep(() =>
|
||||||
{
|
{
|
||||||
@ -79,7 +79,10 @@ namespace osu.Game.Tests.Visual
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual bool ContinueCondition(Player player) => player.IsLoaded;
|
protected virtual void AddCheckSteps(Func<Player> player)
|
||||||
|
{
|
||||||
|
AddUntilStep(() => player().IsLoaded, "player loaded");
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo);
|
protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo);
|
||||||
|
|
||||||
|
@ -78,6 +78,5 @@ namespace osu.Game.Users
|
|||||||
[JsonProperty(@"country")]
|
[JsonProperty(@"country")]
|
||||||
public int? Country;
|
public int? Country;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Humanizer" Version="2.5.16" />
|
<PackageReference Include="Humanizer" Version="2.5.16" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.0" />
|
<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.Framework" Version="0.0.7939" />
|
<PackageReference Include="ppy.osu.Framework" Version="2019.122.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…
x
Reference in New Issue
Block a user