mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 10:52:53 +08:00
Merge branch 'master' into disable-keycounter-breaks
This commit is contained in:
commit
90dbb90470
2
.github/ISSUE_TEMPLATE/01-bug-issues.md
vendored
2
.github/ISSUE_TEMPLATE/01-bug-issues.md
vendored
@ -9,6 +9,8 @@ about: Issues regarding encountered bugs.
|
||||
**osu!lazer version:**
|
||||
|
||||
**Logs:**
|
||||
<!--
|
||||
*please attach logs here, which are located at:*
|
||||
- `%AppData%/osu/logs` *(on Windows),*
|
||||
- `~/.local/share/osu/logs` *(on Linux & macOS).*
|
||||
-->
|
||||
|
2
.github/ISSUE_TEMPLATE/02-crash-issues.md
vendored
2
.github/ISSUE_TEMPLATE/02-crash-issues.md
vendored
@ -9,8 +9,10 @@ about: Issues regarding crashes or permanent freezes.
|
||||
**osu!lazer version:**
|
||||
|
||||
**Logs:**
|
||||
<!--
|
||||
*please attach logs here, which are located at:*
|
||||
- `%AppData%/osu/logs` *(on Windows),*
|
||||
- `~/.local/share/osu/logs` *(on Linux & macOS).*
|
||||
-->
|
||||
|
||||
**Computer Specifications:**
|
||||
|
42
.vscode/launch.json
vendored
42
.vscode/launch.json
vendored
@ -11,11 +11,6 @@
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build osu! (Debug)",
|
||||
"linux": {
|
||||
"env": {
|
||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||
}
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
@ -28,11 +23,6 @@
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build osu! (Release)",
|
||||
"linux": {
|
||||
"env": {
|
||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||
}
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
@ -45,11 +35,6 @@
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build tests (Debug)",
|
||||
"linux": {
|
||||
"env": {
|
||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||
}
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
@ -62,11 +47,6 @@
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build tests (Release)",
|
||||
"linux": {
|
||||
"env": {
|
||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||
}
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
@ -80,11 +60,6 @@
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build osu! (Debug)",
|
||||
"linux": {
|
||||
"env": {
|
||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||
}
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
@ -98,11 +73,6 @@
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build osu! (Release)",
|
||||
"linux": {
|
||||
"env": {
|
||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||
}
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
@ -116,11 +86,6 @@
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build tournament tests (Debug)",
|
||||
"linux": {
|
||||
"env": {
|
||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||
}
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
@ -134,11 +99,6 @@
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build tournament tests (Release)",
|
||||
"linux": {
|
||||
"env": {
|
||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||
}
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
@ -169,4 +129,4 @@
|
||||
"externalConsole": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ If you are looking to install or test osu! without setting up a development envi
|
||||
|
||||
**Latest build:**
|
||||
|
||||
| [Windows (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | [macOS 10.12+](https://github.com/ppy/osu/releases/latest/download/osu.app.zip) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.x86_64.AppImage) | [iOS(iOS 10+)](https://osu.ppy.sh/home/testflight) | [Android (5+)](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk)
|
||||
| [Windows (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | [macOS 10.12+](https://github.com/ppy/osu/releases/latest/download/osu.app.zip) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS(iOS 10+)](https://osu.ppy.sh/home/testflight) | [Android (5+)](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk)
|
||||
| ------------- | ------------- | ------------- | ------------- | ------------- |
|
||||
|
||||
- When running on Windows 7 or 8.1, **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/install/dependencies?tabs=netcore31&pivots=os-windows)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs.
|
||||
|
@ -51,7 +51,7 @@
|
||||
<Reference Include="Java.Interop" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.221.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.228.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.304.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.302.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -30,11 +30,6 @@ namespace osu.Android
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Add(new SimpleUpdateManager());
|
||||
}
|
||||
protected override UpdateManager CreateUpdateManager() => new SimpleUpdateManager();
|
||||
}
|
||||
}
|
@ -47,20 +47,25 @@ namespace osu.Desktop
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override UpdateManager CreateUpdateManager()
|
||||
{
|
||||
switch (RuntimeInfo.OS)
|
||||
{
|
||||
case RuntimeInfo.Platform.Windows:
|
||||
return new SquirrelUpdateManager();
|
||||
|
||||
default:
|
||||
return new SimpleUpdateManager();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
if (!noVersionOverlay)
|
||||
{
|
||||
LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, Add);
|
||||
|
||||
if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows)
|
||||
Add(new SquirrelUpdateManager());
|
||||
else
|
||||
Add(new SimpleUpdateManager());
|
||||
}
|
||||
|
||||
LoadComponentAsync(new DiscordRichPresence(), Add);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Catch.UI;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Tests.Visual;
|
||||
using osuTK;
|
||||
|
||||
@ -51,7 +50,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
return beatmap;
|
||||
}
|
||||
|
||||
protected override Player CreatePlayer(Ruleset ruleset)
|
||||
protected override TestPlayer CreatePlayer(Ruleset ruleset)
|
||||
{
|
||||
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
||||
return base.CreatePlayer(ruleset);
|
||||
|
@ -3,8 +3,8 @@
|
||||
|
||||
using System;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Caching;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Layout;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osuTK;
|
||||
@ -22,21 +22,13 @@ namespace osu.Game.Rulesets.Mania.Mods
|
||||
|
||||
private class ManiaFlashlight : Flashlight
|
||||
{
|
||||
private readonly Cached flashlightProperties = new Cached();
|
||||
private readonly LayoutValue flashlightProperties = new LayoutValue(Invalidation.DrawSize);
|
||||
|
||||
public ManiaFlashlight()
|
||||
{
|
||||
FlashlightSize = new Vector2(0, default_flashlight_size);
|
||||
}
|
||||
|
||||
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||
{
|
||||
if ((invalidation & Invalidation.DrawSize) > 0)
|
||||
{
|
||||
flashlightProperties.Invalidate();
|
||||
}
|
||||
|
||||
return base.Invalidate(invalidation, source, shallPropagate);
|
||||
AddLayout(flashlightProperties);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
|
@ -2,13 +2,13 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using osu.Framework.Caching;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Layout;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
@ -65,6 +65,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddLayout(subtractionCache);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
@ -100,15 +102,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Cached subtractionCache = new Cached();
|
||||
|
||||
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||
{
|
||||
if ((invalidation & Invalidation.DrawSize) > 0)
|
||||
subtractionCache.Invalidate();
|
||||
|
||||
return base.Invalidate(invalidation, source, shallPropagate);
|
||||
}
|
||||
private readonly LayoutValue subtractionCache = new LayoutValue(Invalidation.DrawSize);
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
|
@ -115,9 +115,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Y = HIT_TARGET_POSITION + 150,
|
||||
BypassAutoSizeAxes = Axes.Both
|
||||
},
|
||||
topLevelContainer = new Container { RelativeSizeAxes = Axes.Both }
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests.Mods
|
||||
{
|
||||
public class TestSceneOsuModDifficultyAdjust : ModTestScene
|
||||
{
|
||||
public TestSceneOsuModDifficultyAdjust()
|
||||
: base(new OsuRuleset())
|
||||
{
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNoAdjustment() => CreateModTest(new ModTestData
|
||||
{
|
||||
Mod = new OsuModDifficultyAdjust(),
|
||||
Autoplay = true,
|
||||
PassCondition = checkSomeHit
|
||||
});
|
||||
|
||||
[Test]
|
||||
public void TestCircleSize1() => CreateModTest(new ModTestData
|
||||
{
|
||||
Mod = new OsuModDifficultyAdjust { CircleSize = { Value = 1 } },
|
||||
Autoplay = true,
|
||||
PassCondition = () => checkSomeHit() && checkObjectsScale(0.78f)
|
||||
});
|
||||
|
||||
[Test]
|
||||
public void TestCircleSize10() => CreateModTest(new ModTestData
|
||||
{
|
||||
Mod = new OsuModDifficultyAdjust { CircleSize = { Value = 10 } },
|
||||
Autoplay = true,
|
||||
PassCondition = () => checkSomeHit() && checkObjectsScale(0.15f)
|
||||
});
|
||||
|
||||
[Test]
|
||||
public void TestApproachRate1() => CreateModTest(new ModTestData
|
||||
{
|
||||
Mod = new OsuModDifficultyAdjust { ApproachRate = { Value = 1 } },
|
||||
Autoplay = true,
|
||||
PassCondition = () => checkSomeHit() && checkObjectsPreempt(1680)
|
||||
});
|
||||
|
||||
[Test]
|
||||
public void TestApproachRate10() => CreateModTest(new ModTestData
|
||||
{
|
||||
Mod = new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } },
|
||||
Autoplay = true,
|
||||
PassCondition = () => checkSomeHit() && checkObjectsPreempt(450)
|
||||
});
|
||||
|
||||
private bool checkObjectsPreempt(double target)
|
||||
{
|
||||
var objects = Player.ChildrenOfType<DrawableHitCircle>();
|
||||
if (!objects.Any())
|
||||
return false;
|
||||
|
||||
return objects.All(o => o.HitObject.TimePreempt == target);
|
||||
}
|
||||
|
||||
private bool checkObjectsScale(float target)
|
||||
{
|
||||
var objects = Player.ChildrenOfType<DrawableHitCircle>();
|
||||
if (!objects.Any())
|
||||
return false;
|
||||
|
||||
return objects.All(o => Precision.AlmostEquals(o.ChildrenOfType<ShakeContainer>().First().Children.OfType<Container>().Single().Scale.X, target));
|
||||
}
|
||||
|
||||
private bool checkSomeHit()
|
||||
{
|
||||
return Player.ScoreProcessor.JudgedHits >= 2;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,9 +2,12 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
@ -114,6 +117,22 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
assertGroups();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStackedObjects()
|
||||
{
|
||||
addObjectsStep(() => new OsuHitObject[]
|
||||
{
|
||||
new HitCircle { Position = new Vector2(300, 100) },
|
||||
new HitCircle
|
||||
{
|
||||
Position = new Vector2(300, 300),
|
||||
StackHeight = 20
|
||||
},
|
||||
});
|
||||
|
||||
assertDirections();
|
||||
}
|
||||
|
||||
private void addMultipleObjectsStep() => addObjectsStep(() => new OsuHitObject[]
|
||||
{
|
||||
new HitCircle { Position = new Vector2(100, 100) },
|
||||
@ -207,6 +226,33 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
});
|
||||
}
|
||||
|
||||
private void assertDirections()
|
||||
{
|
||||
AddAssert("group directions are correct", () =>
|
||||
{
|
||||
for (int i = 0; i < hitObjectContainer.Count; i++)
|
||||
{
|
||||
DrawableOsuHitObject expectedStart = getObject(i);
|
||||
DrawableOsuHitObject expectedEnd = i < hitObjectContainer.Count - 1 ? getObject(i + 1) : null;
|
||||
|
||||
if (expectedEnd == null)
|
||||
continue;
|
||||
|
||||
var points = getGroup(i).ChildrenOfType<FollowPoint>().ToArray();
|
||||
if (points.Length == 0)
|
||||
continue;
|
||||
|
||||
float expectedDirection = MathF.Atan2(expectedStart.Position.Y - expectedEnd.Position.Y, expectedStart.Position.X - expectedEnd.Position.X);
|
||||
float realDirection = MathF.Atan2(expectedStart.Position.Y - points[^1].Position.Y, expectedStart.Position.X - points[^1].Position.X);
|
||||
|
||||
if (!Precision.AlmostEquals(expectedDirection, realDirection))
|
||||
throw new AssertionException($"Expected group {i} in direction {expectedDirection}, but was {realDirection}.");
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private DrawableOsuHitObject getObject(int index) => hitObjectContainer[index];
|
||||
|
||||
private FollowPointConnection getGroup(int index) => followPointRenderer.Connections[index];
|
||||
|
@ -3,13 +3,13 @@
|
||||
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests
|
||||
{
|
||||
public class TestSceneOsuFlashlight : TestSceneOsuPlayer
|
||||
{
|
||||
protected override Player CreatePlayer(Ruleset ruleset)
|
||||
protected override TestPlayer CreatePlayer(Ruleset ruleset)
|
||||
{
|
||||
SelectedMods.Value = new Mod[] { new OsuModAutoplay(), new OsuModFlashlight(), };
|
||||
|
||||
|
@ -18,7 +18,6 @@ using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Storyboards;
|
||||
using osu.Game.Tests.Visual;
|
||||
@ -56,7 +55,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
private void checkNextHitObject(string skin) =>
|
||||
AddUntilStep($"check skin from {skin}", () =>
|
||||
{
|
||||
var firstObject = ((TestPlayer)Player).DrawableRuleset.Playfield.HitObjectContainer.AliveObjects.OfType<DrawableHitCircle>().FirstOrDefault();
|
||||
var firstObject = Player.DrawableRuleset.Playfield.HitObjectContainer.AliveObjects.OfType<DrawableHitCircle>().FirstOrDefault();
|
||||
|
||||
if (firstObject == null)
|
||||
return false;
|
||||
@ -75,7 +74,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
[Resolved]
|
||||
private AudioManager audio { get; set; }
|
||||
|
||||
protected override Player CreatePlayer(Ruleset ruleset) => new SkinProvidingPlayer(testUserSkin);
|
||||
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new SkinProvidingPlayer(testUserSkin);
|
||||
|
||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) => new CustomSkinWorkingBeatmap(beatmap, storyboard, Clock, audio, testBeatmapSkin);
|
||||
|
||||
|
@ -11,7 +11,6 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||
using osu.Game.Tests.Visual;
|
||||
using osuTK;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -44,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
base.SetUpSteps();
|
||||
|
||||
AddUntilStep("wait for track to start running", () => track.IsRunning);
|
||||
AddStep("retrieve spinner", () => drawableSpinner = (DrawableSpinner)((TestPlayer)Player).DrawableRuleset.Playfield.AllHitObjects.First());
|
||||
AddStep("retrieve spinner", () => drawableSpinner = (DrawableSpinner)Player.DrawableRuleset.Playfield.AllHitObjects.First());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -89,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
{
|
||||
AddStep($"seek to {time}", () => track.Seek(time));
|
||||
|
||||
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, ((TestPlayer)Player).DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
||||
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
||||
}
|
||||
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new Beatmap
|
||||
|
@ -104,8 +104,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
||||
return;
|
||||
}
|
||||
|
||||
Vector2 startPosition = osuStart.EndPosition;
|
||||
Vector2 endPosition = osuEnd.Position;
|
||||
Vector2 startPosition = osuStart.StackedEndPosition;
|
||||
Vector2 endPosition = osuEnd.StackedPosition;
|
||||
double endTime = osuEnd.StartTime;
|
||||
|
||||
Vector2 distanceVector = endPosition - startPosition;
|
||||
|
@ -5,7 +5,6 @@ using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Caching;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Batches;
|
||||
using osu.Framework.Graphics.OpenGL.Vertices;
|
||||
@ -14,6 +13,7 @@ using osu.Framework.Graphics.Shaders;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Layout;
|
||||
using osu.Framework.Timing;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
@ -43,6 +43,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
// -1 signals that the part is unusable, and should not be drawn
|
||||
parts[i].InvalidationID = -1;
|
||||
}
|
||||
|
||||
AddLayout(partSizeCache);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -72,20 +74,12 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Cached<Vector2> partSizeCache = new Cached<Vector2>();
|
||||
private readonly LayoutValue<Vector2> partSizeCache = new LayoutValue<Vector2>(Invalidation.DrawInfo | Invalidation.RequiredParentSizeToFit | Invalidation.Presence);
|
||||
|
||||
private Vector2 partSize => partSizeCache.IsValid
|
||||
? partSizeCache.Value
|
||||
: (partSizeCache.Value = new Vector2(Texture.DisplayWidth, Texture.DisplayHeight) * DrawInfo.Matrix.ExtractScale().Xy);
|
||||
|
||||
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||
{
|
||||
if ((invalidation & (Invalidation.DrawInfo | Invalidation.RequiredParentSizeToFit | Invalidation.Presence)) > 0)
|
||||
partSizeCache.Invalidate();
|
||||
|
||||
return base.Invalidate(invalidation, source, shallPropagate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The amount of time to fade the cursor trail pieces.
|
||||
/// </summary>
|
||||
@ -97,7 +91,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
{
|
||||
base.Update();
|
||||
|
||||
Invalidate(Invalidation.DrawNode, shallPropagate: false);
|
||||
Invalidate(Invalidation.DrawNode);
|
||||
|
||||
const int fade_clock_reset_threshold = 1000000;
|
||||
|
||||
|
@ -1,23 +1,16 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Tests
|
||||
{
|
||||
public class TestSceneSwellJudgements : PlayerTestScene
|
||||
{
|
||||
protected new TestPlayer Player => (TestPlayer)base.Player;
|
||||
|
||||
public TestSceneSwellJudgements()
|
||||
: base(new TaikoRuleset())
|
||||
{
|
||||
@ -49,25 +42,5 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
|
||||
return beatmap;
|
||||
}
|
||||
|
||||
protected override Player CreatePlayer(Ruleset ruleset) => new TestPlayer();
|
||||
|
||||
protected class TestPlayer : Player
|
||||
{
|
||||
public readonly List<JudgementResult> Results = new List<JudgementResult>();
|
||||
|
||||
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||
|
||||
public TestPlayer()
|
||||
: base(false, false)
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
ScoreProcessor.NewJudgement += r => Results.Add(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,9 @@
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||
using osu.Game.Rulesets.Taiko.Mods;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Tests.Visual;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Tests
|
||||
@ -22,10 +20,10 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
|
||||
protected override bool AllowFail => true;
|
||||
|
||||
protected override Player CreatePlayer(Ruleset ruleset)
|
||||
protected override TestPlayer CreatePlayer(Ruleset ruleset)
|
||||
{
|
||||
SelectedMods.Value = SelectedMods.Value.Concat(new[] { new TaikoModSuddenDeath() }).ToArray();
|
||||
return new ScoreAccessiblePlayer();
|
||||
return base.CreatePlayer(ruleset);
|
||||
}
|
||||
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) =>
|
||||
@ -49,20 +47,10 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
AddStep("Setup judgements", () =>
|
||||
{
|
||||
judged = false;
|
||||
((ScoreAccessiblePlayer)Player).ScoreProcessor.NewJudgement += b => judged = true;
|
||||
Player.ScoreProcessor.NewJudgement += b => judged = true;
|
||||
});
|
||||
AddUntilStep("swell judged", () => judged);
|
||||
AddAssert("not failed", () => !Player.HasFailed);
|
||||
}
|
||||
|
||||
private class ScoreAccessiblePlayer : TestPlayer
|
||||
{
|
||||
public ScoreAccessiblePlayer()
|
||||
: base(false, false)
|
||||
{
|
||||
}
|
||||
|
||||
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Caching;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Layout;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
using osu.Game.Rulesets.Taiko.UI;
|
||||
@ -30,13 +30,15 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
||||
|
||||
private class TaikoFlashlight : Flashlight
|
||||
{
|
||||
private readonly Cached flashlightProperties = new Cached();
|
||||
private readonly LayoutValue flashlightProperties = new LayoutValue(Invalidation.DrawSize);
|
||||
private readonly TaikoPlayfield taikoPlayfield;
|
||||
|
||||
public TaikoFlashlight(TaikoPlayfield taikoPlayfield)
|
||||
{
|
||||
this.taikoPlayfield = taikoPlayfield;
|
||||
FlashlightSize = new Vector2(0, getSizeFor(0));
|
||||
|
||||
AddLayout(flashlightProperties);
|
||||
}
|
||||
|
||||
private float getSizeFor(int combo)
|
||||
@ -56,16 +58,6 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
||||
|
||||
protected override string FragmentShader => "CircularFlashlight";
|
||||
|
||||
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||
{
|
||||
if ((invalidation & Invalidation.DrawSize) > 0)
|
||||
{
|
||||
flashlightProperties.Invalidate();
|
||||
}
|
||||
|
||||
return base.Invalidate(invalidation, source, shallPropagate);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual.Background
|
||||
|
||||
private DummySongSelect songSelect;
|
||||
private TestPlayerLoader playerLoader;
|
||||
private TestPlayer player;
|
||||
private LoadBlockingTestPlayer player;
|
||||
private BeatmapManager manager;
|
||||
private RulesetStore rulesets;
|
||||
|
||||
@ -81,7 +81,7 @@ namespace osu.Game.Tests.Visual.Background
|
||||
public void PlayerLoaderSettingsHoverTest()
|
||||
{
|
||||
setupUserSettings();
|
||||
AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new TestPlayer { BlockLoad = true })));
|
||||
AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new LoadBlockingTestPlayer { BlockLoad = true })));
|
||||
AddUntilStep("Wait for Player Loader to load", () => playerLoader?.IsLoaded ?? false);
|
||||
AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent());
|
||||
AddStep("Trigger background preview", () =>
|
||||
@ -268,7 +268,7 @@ namespace osu.Game.Tests.Visual.Background
|
||||
{
|
||||
setupUserSettings();
|
||||
|
||||
AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new TestPlayer(allowPause))));
|
||||
AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new LoadBlockingTestPlayer(allowPause))));
|
||||
|
||||
AddUntilStep("Wait for Player Loader to load", () => playerLoader.IsLoaded);
|
||||
AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
|
||||
@ -347,7 +347,7 @@ namespace osu.Game.Tests.Visual.Background
|
||||
public bool IsBlurCorrect() => ((FadeAccessibleBackground)Background).CurrentBlur == new Vector2(BACKGROUND_BLUR);
|
||||
}
|
||||
|
||||
private class TestPlayer : Visual.TestPlayer
|
||||
private class LoadBlockingTestPlayer : TestPlayer
|
||||
{
|
||||
protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value);
|
||||
|
||||
@ -360,7 +360,7 @@ namespace osu.Game.Tests.Visual.Background
|
||||
public readonly Bindable<bool> ReplacesBackground = new Bindable<bool>();
|
||||
public readonly Bindable<bool> IsPaused = new Bindable<bool>();
|
||||
|
||||
public TestPlayer(bool allowPause = true)
|
||||
public LoadBlockingTestPlayer(bool allowPause = true)
|
||||
: base(allowPause)
|
||||
{
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Storyboards;
|
||||
|
||||
@ -14,25 +13,24 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
[Description("Player instantiated with an autoplay mod.")]
|
||||
public class TestSceneAutoplay : TestSceneAllRulesetPlayers
|
||||
{
|
||||
protected new TestPlayer Player => (TestPlayer)base.Player;
|
||||
|
||||
protected override Player CreatePlayer(Ruleset ruleset)
|
||||
{
|
||||
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
||||
return new ScoreAccessiblePlayer();
|
||||
return new TestPlayer(false, false);
|
||||
}
|
||||
|
||||
protected override void AddCheckSteps()
|
||||
{
|
||||
ScoreAccessiblePlayer scoreAccessiblePlayer = null;
|
||||
|
||||
AddUntilStep("player loaded", () => (scoreAccessiblePlayer = (ScoreAccessiblePlayer)Player) != null);
|
||||
AddUntilStep("score above zero", () => scoreAccessiblePlayer.ScoreProcessor.TotalScore.Value > 0);
|
||||
AddUntilStep("key counter counted keys", () => scoreAccessiblePlayer.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2));
|
||||
AddStep("seek to break time", () => scoreAccessiblePlayer.GameplayClockContainer.Seek(scoreAccessiblePlayer.BreakOverlay.Breaks.First().StartTime));
|
||||
AddUntilStep("score above zero", () => Player.ScoreProcessor.TotalScore.Value > 0);
|
||||
AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2));
|
||||
AddStep("seek to break time", () => Player.GameplayClockContainer.Seek(Player.BreakOverlay.Breaks.First().StartTime));
|
||||
AddUntilStep("wait for seek to complete", () =>
|
||||
scoreAccessiblePlayer.HUDOverlay.Progress.ReferenceClock.CurrentTime >= scoreAccessiblePlayer.BreakOverlay.Breaks.First().StartTime);
|
||||
AddAssert("test keys not counting", () => !scoreAccessiblePlayer.HUDOverlay.KeyCounter.IsCounting);
|
||||
AddStep("rewind", () => scoreAccessiblePlayer.GameplayClockContainer.Seek(-80000));
|
||||
AddUntilStep("key counter reset", () => scoreAccessiblePlayer.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
|
||||
Player.HUDOverlay.Progress.ReferenceClock.CurrentTime >= Player.BreakOverlay.Breaks.First().StartTime);
|
||||
AddAssert("test keys not counting", () => !Player.HUDOverlay.KeyCounter.IsCounting);
|
||||
AddStep("rewind", () => Player.GameplayClockContainer.Seek(-80000));
|
||||
AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
|
||||
}
|
||||
|
||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
|
||||
@ -41,19 +39,5 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
return working;
|
||||
}
|
||||
|
||||
private class ScoreAccessiblePlayer : TestPlayer
|
||||
{
|
||||
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||
public new HUDOverlay HUDOverlay => base.HUDOverlay;
|
||||
public new BreakOverlay BreakOverlay => base.BreakOverlay;
|
||||
|
||||
public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer;
|
||||
|
||||
public ScoreAccessiblePlayer()
|
||||
: base(false, false)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
@ -11,12 +10,8 @@ using osu.Framework.Utils;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Storyboards;
|
||||
using osuTK;
|
||||
|
||||
@ -24,8 +19,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public class TestSceneGameplayRewinding : PlayerTestScene
|
||||
{
|
||||
private RulesetExposingPlayer player => (RulesetExposingPlayer)Player;
|
||||
|
||||
[Resolved]
|
||||
private AudioManager audioManager { get; set; }
|
||||
|
||||
@ -48,13 +41,13 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
AddUntilStep("wait for track to start running", () => track.IsRunning);
|
||||
addSeekStep(3000);
|
||||
AddAssert("all judged", () => player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged));
|
||||
AddUntilStep("key counter counted keys", () => player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses >= 7));
|
||||
AddStep("clear results", () => player.AppliedResults.Clear());
|
||||
AddAssert("all judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged));
|
||||
AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses >= 7));
|
||||
AddStep("clear results", () => Player.Results.Clear());
|
||||
addSeekStep(0);
|
||||
AddAssert("none judged", () => player.DrawableRuleset.Playfield.AllHitObjects.All(h => !h.Judged));
|
||||
AddUntilStep("key counters reset", () => player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
|
||||
AddAssert("no results triggered", () => player.AppliedResults.Count == 0);
|
||||
AddAssert("none judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => !h.Judged));
|
||||
AddUntilStep("key counters reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
|
||||
AddAssert("no results triggered", () => Player.Results.Count == 0);
|
||||
}
|
||||
|
||||
private void addSeekStep(double time)
|
||||
@ -62,13 +55,13 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddStep($"seek to {time}", () => track.Seek(time));
|
||||
|
||||
// Allow a few frames of lenience
|
||||
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
||||
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
||||
}
|
||||
|
||||
protected override Player CreatePlayer(Ruleset ruleset)
|
||||
protected override TestPlayer CreatePlayer(Ruleset ruleset)
|
||||
{
|
||||
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
||||
return new RulesetExposingPlayer();
|
||||
return base.CreatePlayer(ruleset);
|
||||
}
|
||||
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||
@ -89,29 +82,5 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
return beatmap;
|
||||
}
|
||||
|
||||
private class RulesetExposingPlayer : Player
|
||||
{
|
||||
public readonly List<JudgementResult> AppliedResults = new List<JudgementResult>();
|
||||
|
||||
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||
|
||||
public new HUDOverlay HUDOverlay => base.HUDOverlay;
|
||||
|
||||
public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer;
|
||||
|
||||
public new DrawableRuleset DrawableRuleset => base.DrawableRuleset;
|
||||
|
||||
public RulesetExposingPlayer()
|
||||
: base(false, false)
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
ScoreProcessor.NewJudgement += r => AppliedResults.Add(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens.Play;
|
||||
using osuTK;
|
||||
using osuTK.Input;
|
||||
@ -282,14 +281,10 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
protected override bool AllowFail => true;
|
||||
|
||||
protected override Player CreatePlayer(Ruleset ruleset) => new PausePlayer();
|
||||
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new PausePlayer();
|
||||
|
||||
protected class PausePlayer : TestPlayer
|
||||
{
|
||||
public new HealthProcessor HealthProcessor => base.HealthProcessor;
|
||||
|
||||
public new HUDOverlay HUDOverlay => base.HUDOverlay;
|
||||
|
||||
public bool FailOverlayVisible => FailOverlay.State.Value == Visibility.Visible;
|
||||
|
||||
public bool PauseOverlayVisible => PauseOverlay.State.Value == Visibility.Visible;
|
||||
|
@ -9,15 +9,12 @@ using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Play;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
[HeadlessTest] // we alter unsafe properties on the game host to test inactive window state.
|
||||
public class TestScenePauseWhenInactive : PlayerTestScene
|
||||
{
|
||||
protected new TestPlayer Player => (TestPlayer)base.Player;
|
||||
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||
{
|
||||
var beatmap = (Beatmap)base.CreateBeatmap(ruleset);
|
||||
@ -46,6 +43,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddAssert("time of pause is after gameplay start time", () => Player.GameplayClockContainer.GameplayClock.CurrentTime >= Player.DrawableRuleset.GameplayStartTime);
|
||||
}
|
||||
|
||||
protected override Player CreatePlayer(Ruleset ruleset) => new TestPlayer(true, true, true);
|
||||
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(true, true, true);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Utils;
|
||||
@ -307,17 +306,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank;
|
||||
}
|
||||
|
||||
private class TestPlayer : Visual.TestPlayer
|
||||
{
|
||||
public new Bindable<IReadOnlyList<Mod>> Mods => base.Mods;
|
||||
|
||||
public TestPlayer(bool allowPause = true, bool showResults = true)
|
||||
: base(allowPause, showResults)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
protected class SlowLoadPlayer : Visual.TestPlayer
|
||||
protected class SlowLoadPlayer : TestPlayer
|
||||
{
|
||||
public readonly ManualResetEventSlim AllowLoad = new ManualResetEventSlim(false);
|
||||
|
||||
|
@ -62,14 +62,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
var frameworkConfig = host.Dependencies.Get<FrameworkConfigManager>();
|
||||
frameworkConfig.GetBindable<double>(FrameworkSetting.CursorSensitivity).Disabled = false;
|
||||
|
||||
Game = new TestOsuGame(LocalStorage, API);
|
||||
Game.SetHost(host);
|
||||
|
||||
// todo: this can be removed once we can run audio tracks without a device present
|
||||
// see https://github.com/ppy/osu/issues/1302
|
||||
Game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles);
|
||||
|
||||
Add(Game);
|
||||
CreateGame();
|
||||
});
|
||||
|
||||
AddUntilStep("Wait for load", () => Game.IsLoaded);
|
||||
@ -78,6 +71,18 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
ConfirmAtMainMenu();
|
||||
}
|
||||
|
||||
protected void CreateGame()
|
||||
{
|
||||
Game = new TestOsuGame(LocalStorage, API);
|
||||
Game.SetHost(host);
|
||||
|
||||
// todo: this can be removed once we can run audio tracks without a device present
|
||||
// see https://github.com/ppy/osu/issues/1302
|
||||
Game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles);
|
||||
|
||||
Add(Game);
|
||||
}
|
||||
|
||||
protected void PushAndConfirm(Func<Screen> newScreen)
|
||||
{
|
||||
Screen screen = null;
|
||||
@ -97,12 +102,17 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
|
||||
public new SettingsPanel Settings => base.Settings;
|
||||
|
||||
public new MusicController MusicController => base.MusicController;
|
||||
|
||||
public new OsuConfigManager LocalConfig => base.LocalConfig;
|
||||
|
||||
public new Bindable<WorkingBeatmap> Beatmap => base.Beatmap;
|
||||
|
||||
public new Bindable<RulesetInfo> Ruleset => base.Ruleset;
|
||||
|
||||
// if we don't do this, when running under nUnit the version that gets populated is that of nUnit.
|
||||
public override string Version => "test game";
|
||||
|
||||
protected override Loader CreateLoader() => new TestLoader();
|
||||
|
||||
public new void PerformFromScreen(Action<IScreen> action, IEnumerable<Type> validScreens = null) => base.PerformFromScreen(action, validScreens);
|
||||
|
@ -114,6 +114,22 @@ namespace osu.Game.Tests.Visual.Navigation
|
||||
AddAssert("Options overlay was closed", () => Game.Settings.State.Value == Visibility.Hidden);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestWaitForNextTrackInMenu()
|
||||
{
|
||||
bool trackCompleted = false;
|
||||
|
||||
AddUntilStep("Wait for music controller", () => Game.MusicController.IsLoaded);
|
||||
AddStep("Seek close to end", () =>
|
||||
{
|
||||
Game.MusicController.SeekTo(Game.Beatmap.Value.Track.Length - 1000);
|
||||
Game.Beatmap.Value.Track.Completed += () => trackCompleted = true;
|
||||
});
|
||||
|
||||
AddUntilStep("Track was completed", () => trackCompleted);
|
||||
AddUntilStep("Track was restarted", () => Game.Beatmap.Value.Track.IsRunning);
|
||||
}
|
||||
|
||||
private void pushEscape() =>
|
||||
AddStep("Press escape", () => pressAndRelease(Key.Escape));
|
||||
|
||||
|
41
osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs
Normal file
41
osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Configuration;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Navigation
|
||||
{
|
||||
public class TestSettingsMigration : OsuGameTestScene
|
||||
{
|
||||
public override void RecycleLocalStorage()
|
||||
{
|
||||
base.RecycleLocalStorage();
|
||||
|
||||
using (var config = new OsuConfigManager(LocalStorage))
|
||||
{
|
||||
config.Set(OsuSetting.Version, "2020.101.0");
|
||||
config.Set(OsuSetting.DisplayStarsMaximum, 10.0);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDisplayStarsMigration()
|
||||
{
|
||||
AddAssert("config has migrated value", () => Precision.AlmostEquals(Game.LocalConfig.Get<double>(OsuSetting.DisplayStarsMaximum), 10.1));
|
||||
|
||||
AddStep("set value again", () => Game.LocalConfig.Set<double>(OsuSetting.DisplayStarsMaximum, 10));
|
||||
|
||||
AddStep("force save config", () => Game.LocalConfig.Save());
|
||||
|
||||
AddStep("remove game", () => Remove(Game));
|
||||
|
||||
AddStep("create game again", CreateGame);
|
||||
|
||||
AddUntilStep("Wait for load", () => Game.IsLoaded);
|
||||
|
||||
AddAssert("config did not migrate value", () => Precision.AlmostEquals(Game.LocalConfig.Get<double>(OsuSetting.DisplayStarsMaximum), 10));
|
||||
}
|
||||
}
|
||||
}
|
@ -2,9 +2,11 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Users;
|
||||
using osuTK;
|
||||
|
||||
@ -13,13 +15,19 @@ namespace osu.Game.Tests.Visual.Online
|
||||
[TestFixture]
|
||||
public class TestSceneUserPanel : OsuTestScene
|
||||
{
|
||||
private readonly UserPanel peppy;
|
||||
private readonly Bindable<UserActivity> activity = new Bindable<UserActivity>();
|
||||
|
||||
public TestSceneUserPanel()
|
||||
private UserPanel peppy;
|
||||
|
||||
[Resolved]
|
||||
private RulesetStore rulesetStore { get; set; }
|
||||
|
||||
[SetUp]
|
||||
public void SetUp() => Schedule(() =>
|
||||
{
|
||||
UserPanel flyte;
|
||||
|
||||
Add(new FillFlowContainer
|
||||
Child = new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
@ -44,34 +52,38 @@ namespace osu.Game.Tests.Visual.Online
|
||||
SupportLevel = 3,
|
||||
}) { Width = 300 },
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
flyte.Status.Value = new UserStatusOnline();
|
||||
peppy.Status.Value = null;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UserStatusesTests()
|
||||
{
|
||||
AddStep("online", () => { peppy.Status.Value = new UserStatusOnline(); });
|
||||
AddStep(@"do not disturb", () => { peppy.Status.Value = new UserStatusDoNotDisturb(); });
|
||||
AddStep(@"offline", () => { peppy.Status.Value = new UserStatusOffline(); });
|
||||
AddStep(@"null status", () => { peppy.Status.Value = null; });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UserActivitiesTests()
|
||||
{
|
||||
Bindable<UserActivity> activity = new Bindable<UserActivity>();
|
||||
|
||||
peppy.Activity.BindTo(activity);
|
||||
});
|
||||
|
||||
AddStep("idle", () => { activity.Value = null; });
|
||||
AddStep("spectating", () => { activity.Value = new UserActivity.Spectating(); });
|
||||
AddStep("solo", () => { activity.Value = new UserActivity.SoloGame(null, null); });
|
||||
AddStep("choosing", () => { activity.Value = new UserActivity.ChoosingBeatmap(); });
|
||||
AddStep("editing", () => { activity.Value = new UserActivity.Editing(null); });
|
||||
AddStep("modding", () => { activity.Value = new UserActivity.Modding(); });
|
||||
[Test]
|
||||
public void TestUserStatus()
|
||||
{
|
||||
AddStep("online", () => peppy.Status.Value = new UserStatusOnline());
|
||||
AddStep("do not disturb", () => peppy.Status.Value = new UserStatusDoNotDisturb());
|
||||
AddStep("offline", () => peppy.Status.Value = new UserStatusOffline());
|
||||
AddStep("null status", () => peppy.Status.Value = null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUserActivity()
|
||||
{
|
||||
AddStep("set online status", () => peppy.Status.Value = new UserStatusOnline());
|
||||
|
||||
AddStep("idle", () => activity.Value = null);
|
||||
AddStep("spectating", () => activity.Value = new UserActivity.Spectating());
|
||||
AddStep("solo (osu!)", () => activity.Value = soloGameStatusForRuleset(0));
|
||||
AddStep("solo (osu!taiko)", () => activity.Value = soloGameStatusForRuleset(1));
|
||||
AddStep("solo (osu!catch)", () => activity.Value = soloGameStatusForRuleset(2));
|
||||
AddStep("solo (osu!mania)", () => activity.Value = soloGameStatusForRuleset(3));
|
||||
AddStep("choosing", () => activity.Value = new UserActivity.ChoosingBeatmap());
|
||||
AddStep("editing", () => activity.Value = new UserActivity.Editing(null));
|
||||
AddStep("modding", () => activity.Value = new UserActivity.Modding());
|
||||
}
|
||||
|
||||
private UserActivity soloGameStatusForRuleset(int rulesetId) => new UserActivity.SoloGame(null, rulesetStore.GetRuleset(rulesetId));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Tournament.Screens.Editors;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
public class TestSceneSeedingEditorScreen : LadderTestScene
|
||||
{
|
||||
[Cached]
|
||||
private readonly LadderInfo ladder = new LadderInfo();
|
||||
|
||||
public TestSceneSeedingEditorScreen()
|
||||
{
|
||||
var match = TestSceneSeedingScreen.CreateSampleSeededMatch();
|
||||
|
||||
Add(new SeedingEditorScreen(match.Team1.Value)
|
||||
{
|
||||
Width = 0.85f // create room for control panel
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
127
osu.Game.Tournament.Tests/Screens/TestSceneSeedingScreen.cs
Normal file
127
osu.Game.Tournament.Tests/Screens/TestSceneSeedingScreen.cs
Normal file
@ -0,0 +1,127 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Tournament.Screens.TeamIntro;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Tournament.Tests.Screens
|
||||
{
|
||||
public class TestSceneSeedingScreen : LadderTestScene
|
||||
{
|
||||
[Cached]
|
||||
private readonly LadderInfo ladder = new LadderInfo();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
ladder.CurrentMatch.Value = CreateSampleSeededMatch();
|
||||
|
||||
Add(new SeedingScreen
|
||||
{
|
||||
FillMode = FillMode.Fit,
|
||||
FillAspectRatio = 16 / 9f
|
||||
});
|
||||
}
|
||||
|
||||
public static TournamentMatch CreateSampleSeededMatch() => new TournamentMatch
|
||||
{
|
||||
Team1 =
|
||||
{
|
||||
Value = new TournamentTeam
|
||||
{
|
||||
FlagName = { Value = "JP" },
|
||||
FullName = { Value = "Japan" },
|
||||
LastYearPlacing = { Value = 10 },
|
||||
Seed = { Value = "Low" },
|
||||
SeedingResults =
|
||||
{
|
||||
new SeedingResult
|
||||
{
|
||||
Mod = { Value = "NM" },
|
||||
Seed = { Value = 10 },
|
||||
Beatmaps =
|
||||
{
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist" } },
|
||||
Score = 12345672,
|
||||
Seed = { Value = 24 },
|
||||
},
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist" } },
|
||||
Score = 1234567,
|
||||
Seed = { Value = 12 },
|
||||
},
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist" } },
|
||||
Score = 1234567,
|
||||
Seed = { Value = 16 },
|
||||
}
|
||||
}
|
||||
},
|
||||
new SeedingResult
|
||||
{
|
||||
Mod = { Value = "DT" },
|
||||
Seed = { Value = 5 },
|
||||
Beatmaps =
|
||||
{
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist" } },
|
||||
Score = 234567,
|
||||
Seed = { Value = 3 },
|
||||
},
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist" } },
|
||||
Score = 234567,
|
||||
Seed = { Value = 6 },
|
||||
},
|
||||
new SeedingBeatmap
|
||||
{
|
||||
BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata { Title = "Test Title", Artist = "Test Artist" } },
|
||||
Score = 234567,
|
||||
Seed = { Value = 12 },
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Players =
|
||||
{
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 12 } } },
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 16 } } },
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 20 } } },
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 24 } } },
|
||||
new User { Username = "Hello", Statistics = new UserStatistics { Ranks = new UserStatistics.UserRanks { Global = 30 } } },
|
||||
}
|
||||
}
|
||||
},
|
||||
Team2 =
|
||||
{
|
||||
Value = new TournamentTeam
|
||||
{
|
||||
FlagName = { Value = "US" },
|
||||
FullName = { Value = "United States" },
|
||||
Players =
|
||||
{
|
||||
new User { Username = "Hello" },
|
||||
new User { Username = "Hello" },
|
||||
new User { Username = "Hello" },
|
||||
new User { Username = "Hello" },
|
||||
new User { Username = "Hello" },
|
||||
}
|
||||
}
|
||||
},
|
||||
Round =
|
||||
{
|
||||
Value = new TournamentRound { Name = { Value = "Quarterfinals" } }
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ namespace osu.Game.Tournament.Tests.Screens
|
||||
match.Team1.Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "USA");
|
||||
match.Team2.Value = Ladder.Teams.FirstOrDefault(t => t.Acronym.Value == "JPN");
|
||||
match.Round.Value = Ladder.Rounds.FirstOrDefault(g => g.Name.Value == "Finals");
|
||||
match.Completed.Value = true;
|
||||
ladder.CurrentMatch.Value = match;
|
||||
|
||||
Add(new TeamWinScreen
|
||||
|
@ -5,7 +5,6 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@ -35,7 +34,7 @@ namespace osu.Game.Tournament.Components
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = new Color4(54, 54, 54, 255)
|
||||
},
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
|
@ -9,7 +9,6 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Tournament.Models;
|
||||
|
||||
namespace osu.Game.Tournament.Components
|
||||
@ -19,7 +18,7 @@ namespace osu.Game.Tournament.Components
|
||||
public readonly TournamentTeam Team;
|
||||
|
||||
protected readonly Sprite Flag;
|
||||
protected readonly OsuSpriteText AcronymText;
|
||||
protected readonly TournamentSpriteText AcronymText;
|
||||
|
||||
[UsedImplicitly]
|
||||
private Bindable<string> acronym;
|
||||
@ -37,9 +36,9 @@ namespace osu.Game.Tournament.Components
|
||||
FillMode = FillMode.Fit
|
||||
};
|
||||
|
||||
AcronymText = new OsuSpriteText
|
||||
AcronymText = new TournamentSpriteText
|
||||
{
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Regular),
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Regular),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,6 @@ using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osuTK;
|
||||
@ -262,7 +261,7 @@ namespace osu.Game.Tournament.Components
|
||||
static void cp(SpriteText s, Color4 colour)
|
||||
{
|
||||
s.Colour = colour;
|
||||
s.Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 15);
|
||||
s.Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 15);
|
||||
}
|
||||
|
||||
for (var i = 0; i < tuples.Length; i++)
|
||||
@ -278,9 +277,9 @@ namespace osu.Game.Tournament.Components
|
||||
});
|
||||
}
|
||||
|
||||
AddText(new OsuSpriteText { Text = heading }, s => cp(s, OsuColour.Gray(0.33f)));
|
||||
AddText(new TournamentSpriteText { Text = heading }, s => cp(s, OsuColour.Gray(0.33f)));
|
||||
AddText(" ", s => cp(s, OsuColour.Gray(0.33f)));
|
||||
AddText(new OsuSpriteText { Text = content }, s => cp(s, OsuColour.Gray(0.5f)));
|
||||
AddText(new TournamentSpriteText { Text = content }, s => cp(s, OsuColour.Gray(0.5f)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
@ -77,14 +76,14 @@ namespace osu.Game.Tournament.Components
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = new LocalisedString((
|
||||
$"{Beatmap.Metadata.ArtistUnicode ?? Beatmap.Metadata.Artist} - {Beatmap.Metadata.TitleUnicode ?? Beatmap.Metadata.Title}",
|
||||
$"{Beatmap.Metadata.Artist} - {Beatmap.Metadata.Title}")),
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true),
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Bold),
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
@ -95,28 +94,28 @@ namespace osu.Game.Tournament.Components
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = "mapper",
|
||||
Padding = new MarginPadding { Right = 5 },
|
||||
Font = OsuFont.GetFont(italics: true, weight: FontWeight.Regular, size: 14)
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Regular, size: 14)
|
||||
},
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = Beatmap.Metadata.AuthorString,
|
||||
Padding = new MarginPadding { Right = 20 },
|
||||
Font = OsuFont.GetFont(italics: true, weight: FontWeight.Bold, size: 14)
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 14)
|
||||
},
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = "difficulty",
|
||||
Padding = new MarginPadding { Right = 5 },
|
||||
Font = OsuFont.GetFont(italics: true, weight: FontWeight.Regular, size: 14)
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Regular, size: 14)
|
||||
},
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = Beatmap.Version,
|
||||
Font = OsuFont.GetFont(italics: true, weight: FontWeight.Bold, size: 14)
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 14)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
23
osu.Game.Tournament/Models/SeedingBeatmap.cs
Normal file
23
osu.Game.Tournament/Models/SeedingBeatmap.cs
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Beatmaps;
|
||||
|
||||
namespace osu.Game.Tournament.Models
|
||||
{
|
||||
public class SeedingBeatmap
|
||||
{
|
||||
public int ID;
|
||||
|
||||
public BeatmapInfo BeatmapInfo;
|
||||
|
||||
public long Score;
|
||||
|
||||
public Bindable<int> Seed = new BindableInt
|
||||
{
|
||||
MinValue = 1,
|
||||
MaxValue = 64
|
||||
};
|
||||
}
|
||||
}
|
21
osu.Game.Tournament/Models/SeedingResult.cs
Normal file
21
osu.Game.Tournament/Models/SeedingResult.cs
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Bindables;
|
||||
|
||||
namespace osu.Game.Tournament.Models
|
||||
{
|
||||
public class SeedingResult
|
||||
{
|
||||
public List<SeedingBeatmap> Beatmaps = new List<SeedingBeatmap>();
|
||||
|
||||
public Bindable<string> Mod = new Bindable<string>();
|
||||
|
||||
public Bindable<int> Seed = new BindableInt
|
||||
{
|
||||
MinValue = 1,
|
||||
MaxValue = 64
|
||||
};
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Users;
|
||||
@ -29,6 +30,32 @@ namespace osu.Game.Tournament.Models
|
||||
/// </summary>
|
||||
public Bindable<string> Acronym = new Bindable<string>(string.Empty);
|
||||
|
||||
public BindableList<SeedingResult> SeedingResults = new BindableList<SeedingResult>();
|
||||
|
||||
public double AverageRank
|
||||
{
|
||||
get
|
||||
{
|
||||
var ranks = Players.Select(p => p.Statistics?.Ranks.Global)
|
||||
.Where(i => i.HasValue)
|
||||
.Select(i => i.Value)
|
||||
.ToArray();
|
||||
|
||||
if (ranks.Length == 0)
|
||||
return 0;
|
||||
|
||||
return ranks.Average();
|
||||
}
|
||||
}
|
||||
|
||||
public Bindable<string> Seed = new Bindable<string>(string.Empty);
|
||||
|
||||
public Bindable<int> LastYearPlacing = new BindableInt
|
||||
{
|
||||
MinValue = 1,
|
||||
MaxValue = 64
|
||||
};
|
||||
|
||||
[JsonProperty]
|
||||
public BindableList<User> Players { get; set; } = new BindableList<User>();
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 4.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 67 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 67 KiB |
@ -8,7 +8,6 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK;
|
||||
@ -43,7 +42,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
|
||||
Colour = new Color4(54, 54, 54, 255)
|
||||
},
|
||||
// Group name
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
@ -51,7 +50,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
|
||||
Position = new Vector2(0, 7f),
|
||||
|
||||
Text = $"GROUP {name.ToUpperInvariant()}",
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 8),
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 8),
|
||||
Colour = new Color4(255, 204, 34, 255),
|
||||
},
|
||||
teams = new FillFlowContainer<GroupTeam>
|
||||
@ -134,7 +133,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
|
||||
AcronymText.Anchor = Anchor.TopCentre;
|
||||
AcronymText.Origin = Anchor.TopCentre;
|
||||
AcronymText.Text = team.Acronym.Value.ToUpperInvariant();
|
||||
AcronymText.Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 10);
|
||||
AcronymText.Font = OsuFont.Torus.With(weight: FontWeight.Bold, size: 10);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
|
@ -14,7 +14,6 @@ using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Tournament.Screens.Drawings.Components;
|
||||
@ -29,7 +28,7 @@ namespace osu.Game.Tournament.Screens.Drawings
|
||||
|
||||
private ScrollingTeamContainer teamsContainer;
|
||||
private GroupContainer groupsContainer;
|
||||
private OsuSpriteText fullTeamNameText;
|
||||
private TournamentSpriteText fullTeamNameText;
|
||||
|
||||
private readonly List<TournamentTeam> allTeams = new List<TournamentTeam>();
|
||||
|
||||
@ -109,18 +108,18 @@ namespace osu.Game.Tournament.Screens.Drawings
|
||||
RelativeSizeAxes = Axes.X,
|
||||
},
|
||||
// Scrolling team name
|
||||
fullTeamNameText = new OsuSpriteText
|
||||
fullTeamNameText = new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.TopCentre,
|
||||
|
||||
Position = new Vector2(0, 45f),
|
||||
|
||||
Colour = OsuColour.Gray(0.33f),
|
||||
Colour = OsuColour.Gray(0.95f),
|
||||
|
||||
Alpha = 0,
|
||||
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Light, size: 42),
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Light, size: 42),
|
||||
}
|
||||
}
|
||||
},
|
||||
|
288
osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs
Normal file
288
osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs
Normal file
@ -0,0 +1,288 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.Editors
|
||||
{
|
||||
public class SeedingEditorScreen : TournamentEditorScreen<SeedingEditorScreen.SeeingResultRow, SeedingResult>
|
||||
{
|
||||
private readonly TournamentTeam team;
|
||||
|
||||
protected override BindableList<SeedingResult> Storage => team.SeedingResults;
|
||||
|
||||
public SeedingEditorScreen(TournamentTeam team)
|
||||
{
|
||||
this.team = team;
|
||||
}
|
||||
|
||||
public class SeeingResultRow : CompositeDrawable, IModelBacked<SeedingResult>
|
||||
{
|
||||
public SeedingResult Model { get; }
|
||||
|
||||
[Resolved]
|
||||
private LadderInfo ladderInfo { get; set; }
|
||||
|
||||
public SeeingResultRow(TournamentTeam team, SeedingResult round)
|
||||
{
|
||||
Model = round;
|
||||
|
||||
Masking = true;
|
||||
CornerRadius = 10;
|
||||
|
||||
SeedingBeatmapEditor beatmapEditor = new SeedingBeatmapEditor(round)
|
||||
{
|
||||
Width = 0.95f
|
||||
};
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = OsuColour.Gray(0.1f),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Margin = new MarginPadding(5),
|
||||
Padding = new MarginPadding { Right = 160 },
|
||||
Spacing = new Vector2(5),
|
||||
Direction = FillDirection.Full,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SettingsTextBox
|
||||
{
|
||||
LabelText = "Mod",
|
||||
Width = 0.33f,
|
||||
Bindable = Model.Mod
|
||||
},
|
||||
new SettingsSlider<int>
|
||||
{
|
||||
LabelText = "Seed",
|
||||
Width = 0.33f,
|
||||
Bindable = Model.Seed
|
||||
},
|
||||
new SettingsButton
|
||||
{
|
||||
Width = 0.2f,
|
||||
Margin = new MarginPadding(10),
|
||||
Text = "Add beatmap",
|
||||
Action = () => beatmapEditor.CreateNew()
|
||||
},
|
||||
beatmapEditor
|
||||
}
|
||||
},
|
||||
new DangerousSettingsButton
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
RelativeSizeAxes = Axes.None,
|
||||
Width = 150,
|
||||
Text = "Delete result",
|
||||
Action = () =>
|
||||
{
|
||||
Expire();
|
||||
team.SeedingResults.Remove(Model);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
}
|
||||
|
||||
public class SeedingBeatmapEditor : CompositeDrawable
|
||||
{
|
||||
private readonly SeedingResult round;
|
||||
private readonly FillFlowContainer flow;
|
||||
|
||||
public SeedingBeatmapEditor(SeedingResult round)
|
||||
{
|
||||
this.round = round;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
InternalChild = flow = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
LayoutDuration = 200,
|
||||
LayoutEasing = Easing.OutQuint,
|
||||
ChildrenEnumerable = round.Beatmaps.Select(p => new SeedingBeatmapRow(round, p))
|
||||
};
|
||||
}
|
||||
|
||||
public void CreateNew()
|
||||
{
|
||||
var user = new SeedingBeatmap();
|
||||
round.Beatmaps.Add(user);
|
||||
flow.Add(new SeedingBeatmapRow(round, user));
|
||||
}
|
||||
|
||||
public class SeedingBeatmapRow : CompositeDrawable
|
||||
{
|
||||
private readonly SeedingResult result;
|
||||
public SeedingBeatmap Model { get; }
|
||||
|
||||
[Resolved]
|
||||
protected IAPIProvider API { get; private set; }
|
||||
|
||||
private readonly Bindable<string> beatmapId = new Bindable<string>();
|
||||
|
||||
private readonly Bindable<string> score = new Bindable<string>();
|
||||
|
||||
private readonly Container drawableContainer;
|
||||
|
||||
public SeedingBeatmapRow(SeedingResult result, SeedingBeatmap beatmap)
|
||||
{
|
||||
this.result = result;
|
||||
Model = beatmap;
|
||||
|
||||
Margin = new MarginPadding(10);
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
Masking = true;
|
||||
CornerRadius = 5;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = OsuColour.Gray(0.2f),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Margin = new MarginPadding(5),
|
||||
Padding = new MarginPadding { Right = 160 },
|
||||
Spacing = new Vector2(5),
|
||||
Direction = FillDirection.Horizontal,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SettingsNumberBox
|
||||
{
|
||||
LabelText = "Beatmap ID",
|
||||
RelativeSizeAxes = Axes.None,
|
||||
Width = 200,
|
||||
Bindable = beatmapId,
|
||||
},
|
||||
new SettingsSlider<int>
|
||||
{
|
||||
LabelText = "Seed",
|
||||
RelativeSizeAxes = Axes.None,
|
||||
Width = 200,
|
||||
Bindable = beatmap.Seed
|
||||
},
|
||||
new SettingsTextBox
|
||||
{
|
||||
LabelText = "Score",
|
||||
RelativeSizeAxes = Axes.None,
|
||||
Width = 200,
|
||||
Bindable = score,
|
||||
},
|
||||
drawableContainer = new Container
|
||||
{
|
||||
Size = new Vector2(100, 70),
|
||||
},
|
||||
}
|
||||
},
|
||||
new DangerousSettingsButton
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
RelativeSizeAxes = Axes.None,
|
||||
Width = 150,
|
||||
Text = "Delete Beatmap",
|
||||
Action = () =>
|
||||
{
|
||||
Expire();
|
||||
result.Beatmaps.Remove(beatmap);
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(RulesetStore rulesets)
|
||||
{
|
||||
beatmapId.Value = Model.ID.ToString();
|
||||
beatmapId.BindValueChanged(idString =>
|
||||
{
|
||||
int parsed;
|
||||
|
||||
int.TryParse(idString.NewValue, out parsed);
|
||||
|
||||
Model.ID = parsed;
|
||||
|
||||
if (idString.NewValue != idString.OldValue)
|
||||
Model.BeatmapInfo = null;
|
||||
|
||||
if (Model.BeatmapInfo != null)
|
||||
{
|
||||
updatePanel();
|
||||
return;
|
||||
}
|
||||
|
||||
var req = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = Model.ID });
|
||||
|
||||
req.Success += res =>
|
||||
{
|
||||
Model.BeatmapInfo = res.ToBeatmap(rulesets);
|
||||
updatePanel();
|
||||
};
|
||||
|
||||
req.Failure += _ =>
|
||||
{
|
||||
Model.BeatmapInfo = null;
|
||||
updatePanel();
|
||||
};
|
||||
|
||||
API.Queue(req);
|
||||
}, true);
|
||||
|
||||
score.Value = Model.Score.ToString();
|
||||
score.BindValueChanged(str => long.TryParse(str.NewValue, out Model.Score));
|
||||
}
|
||||
|
||||
private void updatePanel()
|
||||
{
|
||||
drawableContainer.Clear();
|
||||
|
||||
if (Model.BeatmapInfo != null)
|
||||
{
|
||||
drawableContainer.Child = new TournamentBeatmapPanel(Model.BeatmapInfo, result.Mod.Value)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Width = 300
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override SeeingResultRow CreateDrawable(SeedingResult model) => new SeeingResultRow(team, model);
|
||||
}
|
||||
}
|
@ -57,6 +57,9 @@ namespace osu.Game.Tournament.Screens.Editors
|
||||
|
||||
private readonly Container drawableContainer;
|
||||
|
||||
[Resolved(canBeNull: true)]
|
||||
private TournamentSceneManager sceneManager { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private LadderInfo ladderInfo { get; set; }
|
||||
|
||||
@ -113,6 +116,18 @@ namespace osu.Game.Tournament.Screens.Editors
|
||||
Width = 0.2f,
|
||||
Bindable = Model.FlagName
|
||||
},
|
||||
new SettingsTextBox
|
||||
{
|
||||
LabelText = "Seed",
|
||||
Width = 0.2f,
|
||||
Bindable = Model.Seed
|
||||
},
|
||||
new SettingsSlider<int>
|
||||
{
|
||||
LabelText = "Last Year Placement",
|
||||
Width = 0.33f,
|
||||
Bindable = Model.LastYearPlacing
|
||||
},
|
||||
new SettingsButton
|
||||
{
|
||||
Width = 0.11f,
|
||||
@ -131,7 +146,17 @@ namespace osu.Game.Tournament.Screens.Editors
|
||||
ladderInfo.Teams.Remove(Model);
|
||||
},
|
||||
},
|
||||
playerEditor
|
||||
playerEditor,
|
||||
new SettingsButton
|
||||
{
|
||||
Width = 0.2f,
|
||||
Margin = new MarginPadding(10),
|
||||
Text = "Edit seeding results",
|
||||
Action = () =>
|
||||
{
|
||||
sceneManager?.SetScreen(new SeedingEditorScreen(team));
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -5,9 +5,9 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
@ -30,7 +30,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
new TournamentLogo(),
|
||||
new RoundDisplay
|
||||
{
|
||||
Y = 10,
|
||||
Y = 5,
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
},
|
||||
@ -51,9 +51,6 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
{
|
||||
private readonly TeamColour teamColour;
|
||||
|
||||
private readonly Color4 red = new Color4(129, 68, 65, 255);
|
||||
private readonly Color4 blue = new Color4(41, 91, 97, 255);
|
||||
|
||||
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();
|
||||
private readonly Bindable<TournamentTeam> currentTeam = new Bindable<TournamentTeam>();
|
||||
private readonly Bindable<int?> currentTeamScore = new Bindable<int?>();
|
||||
@ -106,7 +103,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
|
||||
private void teamChanged(TournamentTeam team)
|
||||
{
|
||||
var colour = teamColour == TeamColour.Red ? red : blue;
|
||||
var colour = teamColour == TeamColour.Red ? TournamentGame.COLOUR_RED : TournamentGame.COLOUR_BLUE;
|
||||
var flip = teamColour != TeamColour.Red;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
@ -169,13 +166,13 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Flag,
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = team?.FullName.Value.ToUpper() ?? "???",
|
||||
X = (flip ? -1 : 1) * 90,
|
||||
Y = -10,
|
||||
Colour = colour,
|
||||
Font = TournamentFont.GetFont(typeface: TournamentTypeface.Aquatico, weight: FontWeight.Regular, size: 20),
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Regular, size: 20),
|
||||
Origin = anchor,
|
||||
Anchor = anchor,
|
||||
},
|
||||
@ -188,10 +185,31 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
{
|
||||
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();
|
||||
|
||||
private readonly TournamentSpriteText text;
|
||||
|
||||
public RoundDisplay()
|
||||
{
|
||||
Width = 200;
|
||||
Height = 20;
|
||||
|
||||
Masking = true;
|
||||
CornerRadius = 10;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = OsuColour.Gray(0.18f),
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
text = new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Colour = Color4.White,
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Regular, size: 16),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -201,20 +219,8 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
currentMatch.BindTo(ladder.CurrentMatch);
|
||||
}
|
||||
|
||||
private void matchChanged(ValueChangedEvent<TournamentMatch> match)
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Colour = Color4.White,
|
||||
Text = match.NewValue.Round.Value?.Name.Value ?? "Unknown Round",
|
||||
Font = TournamentFont.GetFont(typeface: TournamentTypeface.Aquatico, weight: FontWeight.Regular, size: 18),
|
||||
},
|
||||
};
|
||||
}
|
||||
private void matchChanged(ValueChangedEvent<TournamentMatch> match) =>
|
||||
text.Text = match.NewValue.Round.Value?.Name.Value ?? "Unknown Round";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,8 +123,8 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
|
||||
public bool Winning
|
||||
{
|
||||
set => DisplayedCountSpriteText.Font = value
|
||||
? TournamentFont.GetFont(typeface: TournamentTypeface.Aquatico, weight: FontWeight.Regular, size: 60)
|
||||
: TournamentFont.GetFont(typeface: TournamentTypeface.Aquatico, weight: FontWeight.Light, size: 40);
|
||||
? OsuFont.Torus.With(weight: FontWeight.Regular, size: 60)
|
||||
: OsuFont.Torus.With(weight: FontWeight.Light, size: 40);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
@ -26,7 +25,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
{
|
||||
private readonly TournamentMatch match;
|
||||
private readonly bool losers;
|
||||
private OsuSpriteText scoreText;
|
||||
private TournamentSpriteText scoreText;
|
||||
private Box background;
|
||||
|
||||
private readonly Bindable<int?> score = new Bindable<int?>();
|
||||
@ -69,7 +68,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
|
||||
AcronymText.Anchor = AcronymText.Origin = Anchor.CentreLeft;
|
||||
AcronymText.Padding = new MarginPadding { Left = 50 };
|
||||
AcronymText.Font = OsuFont.GetFont(size: 24);
|
||||
AcronymText.Font = OsuFont.Torus.With(size: 24);
|
||||
|
||||
if (match != null)
|
||||
{
|
||||
@ -119,11 +118,11 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
Alpha = 0.8f,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
scoreText = new OsuSpriteText
|
||||
scoreText = new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Font = OsuFont.GetFont(size: 20),
|
||||
Font = OsuFont.Torus.With(size: 20),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -184,7 +183,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
|
||||
background.FadeColour(winner ? colourWinner : colourNormal, winner ? 500 : 0, Easing.OutQuint);
|
||||
|
||||
scoreText.Font = AcronymText.Font = OsuFont.GetFont(weight: winner ? FontWeight.Bold : FontWeight.Regular);
|
||||
scoreText.Font = AcronymText.Font = OsuFont.Torus.With(weight: winner ? FontWeight.Bold : FontWeight.Regular);
|
||||
}
|
||||
|
||||
public MenuItem[] ContextMenuItems
|
||||
|
@ -6,7 +6,6 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@ -22,8 +21,8 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
|
||||
public DrawableTournamentRound(TournamentRound round, bool losers = false)
|
||||
{
|
||||
OsuSpriteText textName;
|
||||
OsuSpriteText textDescription;
|
||||
TournamentSpriteText textName;
|
||||
TournamentSpriteText textDescription;
|
||||
|
||||
AutoSizeAxes = Axes.Both;
|
||||
InternalChild = new FillFlowContainer
|
||||
@ -32,15 +31,15 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
textDescription = new OsuSpriteText
|
||||
textDescription = new TournamentSpriteText
|
||||
{
|
||||
Colour = Color4.Black,
|
||||
Origin = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre
|
||||
},
|
||||
textName = new OsuSpriteText
|
||||
textName = new TournamentSpriteText
|
||||
{
|
||||
Font = OsuFont.GetFont(weight: FontWeight.Bold),
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Bold),
|
||||
Colour = Color4.Black,
|
||||
Origin = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre
|
||||
|
@ -9,7 +9,6 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Game.Screens.Play.PlayerSettings;
|
||||
using osu.Game.Tournament.Components;
|
||||
@ -126,66 +125,5 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private class SettingsTeamDropdown : LadderSettingsDropdown<TournamentTeam>
|
||||
{
|
||||
public SettingsTeamDropdown(BindableList<TournamentTeam> teams)
|
||||
{
|
||||
foreach (var t in teams.Prepend(new TournamentTeam()))
|
||||
add(t);
|
||||
|
||||
teams.CollectionChanged += (_, args) =>
|
||||
{
|
||||
switch (args.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
args.NewItems.Cast<TournamentTeam>().ForEach(add);
|
||||
break;
|
||||
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
args.OldItems.Cast<TournamentTeam>().ForEach(i => Control.RemoveDropdownItem(i));
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private readonly List<IUnbindable> refBindables = new List<IUnbindable>();
|
||||
|
||||
private T boundReference<T>(T obj)
|
||||
where T : IBindable
|
||||
{
|
||||
obj = (T)obj.GetBoundCopy();
|
||||
refBindables.Add(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
private void add(TournamentTeam team)
|
||||
{
|
||||
Control.AddDropdownItem(team);
|
||||
boundReference(team.FullName).BindValueChanged(_ =>
|
||||
{
|
||||
Control.RemoveDropdownItem(team);
|
||||
Control.AddDropdownItem(team);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private class LadderSettingsDropdown<T> : SettingsDropdown<T>
|
||||
{
|
||||
protected override OsuDropdown<T> CreateDropdown() => new DropdownControl();
|
||||
|
||||
private new class DropdownControl : SettingsDropdown<T>.DropdownControl
|
||||
{
|
||||
protected override DropdownMenu CreateMenu() => new Menu();
|
||||
|
||||
private new class Menu : OsuDropdownMenu
|
||||
{
|
||||
public Menu()
|
||||
{
|
||||
MaxHeight = 200;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Overlays.Settings;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
{
|
||||
public class LadderSettingsDropdown<T> : SettingsDropdown<T>
|
||||
{
|
||||
protected override OsuDropdown<T> CreateDropdown() => new DropdownControl();
|
||||
|
||||
private new class DropdownControl : SettingsDropdown<T>.DropdownControl
|
||||
{
|
||||
protected override DropdownMenu CreateMenu() => new Menu();
|
||||
|
||||
private new class Menu : OsuDropdownMenu
|
||||
{
|
||||
public Menu()
|
||||
{
|
||||
MaxHeight = 200;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Game.Tournament.Models;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.Ladder.Components
|
||||
{
|
||||
public class SettingsTeamDropdown : LadderSettingsDropdown<TournamentTeam>
|
||||
{
|
||||
public SettingsTeamDropdown(BindableList<TournamentTeam> teams)
|
||||
{
|
||||
foreach (var t in teams.Prepend(new TournamentTeam()))
|
||||
add(t);
|
||||
|
||||
teams.CollectionChanged += (_, args) =>
|
||||
{
|
||||
switch (args.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
args.NewItems.Cast<TournamentTeam>().ForEach(add);
|
||||
break;
|
||||
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
args.OldItems.Cast<TournamentTeam>().ForEach(i => Control.RemoveDropdownItem(i));
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private readonly List<IUnbindable> refBindables = new List<IUnbindable>();
|
||||
|
||||
private T boundReference<T>(T obj)
|
||||
where T : IBindable
|
||||
{
|
||||
obj = (T)obj.GetBoundCopy();
|
||||
refBindables.Add(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
private void add(TournamentTeam team)
|
||||
{
|
||||
Control.AddDropdownItem(team);
|
||||
boundReference(team.FullName).BindValueChanged(_ =>
|
||||
{
|
||||
Control.RemoveDropdownItem(team);
|
||||
Control.AddDropdownItem(team);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ namespace osu.Game.Tournament.Screens.Ladder
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TourneyVideo(storage.GetStream(@"BG Side Logo - OWC.m4v"))
|
||||
new TourneyVideo(storage.GetStream(@"videos/ladder.m4v"))
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Loop = true,
|
||||
@ -80,7 +80,7 @@ namespace osu.Game.Tournament.Screens.Ladder
|
||||
break;
|
||||
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
foreach (var p in args.NewItems.Cast<TournamentMatch>())
|
||||
foreach (var p in args.OldItems.Cast<TournamentMatch>())
|
||||
{
|
||||
foreach (var d in MatchesContainer.Where(d => d.Match == p))
|
||||
d.Expire();
|
||||
|
@ -9,7 +9,6 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.IPC;
|
||||
@ -56,7 +55,7 @@ namespace osu.Game.Tournament.Screens.MapPool
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = "Current Mode"
|
||||
},
|
||||
|
@ -10,7 +10,6 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Tournament.Screens.Ladder.Components;
|
||||
@ -34,7 +33,7 @@ namespace osu.Game.Tournament.Screens.Schedule
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TourneyVideo(storage.GetStream(@"BG Side Logo - OWC.m4v"))
|
||||
new TourneyVideo(storage.GetStream(@"videos/schedule.m4v"))
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Loop = true,
|
||||
@ -107,20 +106,20 @@ namespace osu.Game.Tournament.Screens.Schedule
|
||||
Height = 0.25f,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Margin = new MarginPadding { Left = -10, Bottom = 10, Top = -5 },
|
||||
Spacing = new Vector2(10, 0),
|
||||
Text = match.NewValue.Round.Value?.Name.Value,
|
||||
Colour = Color4.Black,
|
||||
Font = OsuFont.GetFont(size: 20)
|
||||
Font = OsuFont.Torus.With(size: 20)
|
||||
},
|
||||
new ScheduleMatch(match.NewValue, false),
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = "Start Time " + match.NewValue.Date.Value.ToUniversalTime().ToString("HH:mm UTC"),
|
||||
Colour = Color4.Black,
|
||||
Font = OsuFont.GetFont(size: 20)
|
||||
Font = OsuFont.Torus.With(size: 20)
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -150,7 +149,7 @@ namespace osu.Game.Tournament.Screens.Schedule
|
||||
Alpha = conditional ? 0.6f : 1,
|
||||
Margin = new MarginPadding { Horizontal = 10, Vertical = 5 },
|
||||
});
|
||||
AddInternal(new OsuSpriteText
|
||||
AddInternal(new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomLeft,
|
||||
@ -174,13 +173,13 @@ namespace osu.Game.Tournament.Screens.Schedule
|
||||
Padding = new MarginPadding { Left = 30, Top = 30 };
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
X = 30,
|
||||
Text = title,
|
||||
Colour = Color4.Black,
|
||||
Spacing = new Vector2(10, 0),
|
||||
Font = OsuFont.GetFont(size: 30)
|
||||
Font = OsuFont.Torus.With(size: 30)
|
||||
},
|
||||
content = new FillFlowContainer
|
||||
{
|
||||
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Graphics.UserInterfaceV2;
|
||||
using osu.Game.Online.API;
|
||||
@ -147,7 +146,7 @@ namespace osu.Game.Tournament.Screens
|
||||
|
||||
public Action Action;
|
||||
|
||||
private OsuSpriteText valueText;
|
||||
private TournamentSpriteText valueText;
|
||||
|
||||
protected override Drawable CreateComponent() => new Container
|
||||
{
|
||||
@ -155,7 +154,7 @@ namespace osu.Game.Tournament.Screens
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
valueText = new OsuSpriteText
|
||||
valueText = new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
|
@ -10,7 +10,7 @@ namespace osu.Game.Tournament.Screens.Showcase
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
AddInternal(new TournamentLogo(false));
|
||||
AddInternal(new TournamentLogo());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,20 +11,12 @@ namespace osu.Game.Tournament.Screens.Showcase
|
||||
{
|
||||
public class TournamentLogo : CompositeDrawable
|
||||
{
|
||||
public TournamentLogo(bool includeRoundBackground = true)
|
||||
public TournamentLogo()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Margin = new MarginPadding { Vertical = 5 };
|
||||
|
||||
if (includeRoundBackground)
|
||||
{
|
||||
AutoSizeAxes = Axes.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
Masking = true;
|
||||
Height = 100;
|
||||
}
|
||||
Height = 100;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -32,9 +24,11 @@ namespace osu.Game.Tournament.Screens.Showcase
|
||||
{
|
||||
InternalChild = new Sprite
|
||||
{
|
||||
Texture = textures.Get("game-screen-logo"),
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
FillMode = FillMode.Fit,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Texture = textures.Get("game-screen-logo"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
316
osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
Normal file
316
osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
Normal file
@ -0,0 +1,316 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Tournament.Screens.Ladder.Components;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
{
|
||||
public class SeedingScreen : TournamentScreen, IProvideVideo
|
||||
{
|
||||
private Container mainContainer;
|
||||
|
||||
private readonly Bindable<TournamentMatch> currentMatch = new Bindable<TournamentMatch>();
|
||||
|
||||
private readonly Bindable<TournamentTeam> currentTeam = new Bindable<TournamentTeam>();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(Storage storage)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TourneyVideo(storage.GetStream(@"videos/seeding.m4v"))
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Loop = true,
|
||||
},
|
||||
mainContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new ControlPanel
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TourneyButton
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Text = "Show first team",
|
||||
Action = () => currentTeam.Value = currentMatch.Value.Team1.Value,
|
||||
},
|
||||
new TourneyButton
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Text = "Show second team",
|
||||
Action = () => currentTeam.Value = currentMatch.Value.Team2.Value,
|
||||
},
|
||||
new SettingsTeamDropdown(LadderInfo.Teams)
|
||||
{
|
||||
LabelText = "Show specific team",
|
||||
Bindable = currentTeam,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
currentMatch.BindValueChanged(matchChanged);
|
||||
currentMatch.BindTo(LadderInfo.CurrentMatch);
|
||||
|
||||
currentTeam.BindValueChanged(teamChanged, true);
|
||||
}
|
||||
|
||||
private void teamChanged(ValueChangedEvent<TournamentTeam> team)
|
||||
{
|
||||
if (team.NewValue == null)
|
||||
{
|
||||
mainContainer.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
showTeam(team.NewValue);
|
||||
}
|
||||
|
||||
private void matchChanged(ValueChangedEvent<TournamentMatch> match) =>
|
||||
currentTeam.Value = currentMatch.Value.Team1.Value;
|
||||
|
||||
private void showTeam(TournamentTeam team)
|
||||
{
|
||||
mainContainer.Children = new Drawable[]
|
||||
{
|
||||
new LeftInfo(team) { Position = new Vector2(55, 150), },
|
||||
new RightInfo(team) { Position = new Vector2(500, 150), },
|
||||
};
|
||||
}
|
||||
|
||||
private class RightInfo : CompositeDrawable
|
||||
{
|
||||
public RightInfo(TournamentTeam team)
|
||||
{
|
||||
FillFlowContainer fill;
|
||||
|
||||
Width = 400;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
fill = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
},
|
||||
};
|
||||
|
||||
foreach (var seeding in team.SeedingResults)
|
||||
{
|
||||
fill.Add(new ModRow(seeding.Mod.Value, seeding.Seed.Value));
|
||||
foreach (var beatmap in seeding.Beatmaps)
|
||||
fill.Add(new BeatmapScoreRow(beatmap));
|
||||
}
|
||||
}
|
||||
|
||||
private class BeatmapScoreRow : CompositeDrawable
|
||||
{
|
||||
public BeatmapScoreRow(SeedingBeatmap beatmap)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText { Text = beatmap.BeatmapInfo.Metadata.Title, Colour = Color4.Black, },
|
||||
new TournamentSpriteText { Text = "by", Colour = Color4.Black, Font = OsuFont.Torus.With(weight: FontWeight.Regular) },
|
||||
new TournamentSpriteText { Text = beatmap.BeatmapInfo.Metadata.Artist, Colour = Color4.Black, Font = OsuFont.Torus.With(weight: FontWeight.Regular) },
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(40),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText { Text = beatmap.Score.ToString("#,0"), Colour = Color4.Black, Width = 80 },
|
||||
new TournamentSpriteText { Text = "#" + beatmap.Seed.Value.ToString("#,0"), Colour = Color4.Black, Font = OsuFont.Torus.With(weight: FontWeight.Regular) },
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class ModRow : CompositeDrawable
|
||||
{
|
||||
private readonly string mods;
|
||||
private readonly int seeding;
|
||||
|
||||
public ModRow(string mods, int seeding)
|
||||
{
|
||||
this.mods = mods;
|
||||
this.seeding = seeding;
|
||||
|
||||
Padding = new MarginPadding { Vertical = 10 };
|
||||
|
||||
AutoSizeAxes = Axes.Y;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures)
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Sprite
|
||||
{
|
||||
Texture = textures.Get($"mods/{mods.ToLower()}"),
|
||||
Scale = new Vector2(0.5f)
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Size = new Vector2(50, 16),
|
||||
CornerRadius = 10,
|
||||
Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Text = seeding.ToString("#,0"),
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class LeftInfo : CompositeDrawable
|
||||
{
|
||||
public LeftInfo(TournamentTeam team)
|
||||
{
|
||||
FillFlowContainer fill;
|
||||
|
||||
Width = 200;
|
||||
|
||||
if (team == null) return;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
fill = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TeamDisplay(team) { Margin = new MarginPadding { Bottom = 30 } },
|
||||
new RowDisplay("Average Rank:", $"#{team.AverageRank:#,0}"),
|
||||
new RowDisplay("Seed:", team.Seed.Value),
|
||||
new RowDisplay("Last year's placing:", team.LastYearPlacing.Value > 0 ? $"#{team.LastYearPlacing:#,0}" : "0"),
|
||||
new Container { Margin = new MarginPadding { Bottom = 30 } },
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
foreach (var p in team.Players)
|
||||
fill.Add(new RowDisplay(p.Username, p.Statistics?.Ranks.Global?.ToString("\\##,0") ?? "-"));
|
||||
}
|
||||
|
||||
internal class RowDisplay : CompositeDrawable
|
||||
{
|
||||
public RowDisplay(string left, string right)
|
||||
{
|
||||
AutoSizeAxes = Axes.Y;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
|
||||
var colour = OsuColour.Gray(0.3f);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = left,
|
||||
Colour = colour,
|
||||
Font = OsuFont.Torus.With(size: 22),
|
||||
},
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = right,
|
||||
Colour = colour,
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopLeft,
|
||||
Font = OsuFont.Torus.With(size: 22, weight: FontWeight.Regular),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class TeamDisplay : DrawableTournamentTeam
|
||||
{
|
||||
public TeamDisplay(TournamentTeam team)
|
||||
: base(team)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Flag.RelativeSizeAxes = Axes.None;
|
||||
Flag.Size = new Vector2(300, 200);
|
||||
Flag.Scale = new Vector2(0.3f);
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Flag,
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = team?.FullName.Value ?? "???",
|
||||
Font = OsuFont.Torus.With(size: 32, weight: FontWeight.SemiBold),
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,12 +7,9 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Tournament.Screens.Showcase;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
{
|
||||
@ -29,12 +26,11 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TourneyVideo(storage.GetStream(@"BG Team - Both OWC.m4v"))
|
||||
new TourneyVideo(storage.GetStream(@"videos/teamintro.m4v"))
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Loop = true,
|
||||
},
|
||||
new TournamentLogo(false),
|
||||
mainContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -75,8 +71,9 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Height = 0.25f,
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Y = 180,
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -85,8 +82,6 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
{
|
||||
public RoundDisplay(TournamentMatch match)
|
||||
{
|
||||
var col = OsuColour.Gray(0.33f);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
@ -98,31 +93,13 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
Spacing = new Vector2(0, 10),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Colour = col,
|
||||
Text = "COMING UP NEXT",
|
||||
Spacing = new Vector2(2, 0),
|
||||
Font = OsuFont.GetFont(size: 15, weight: FontWeight.Black)
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Colour = col,
|
||||
Colour = OsuColour.Gray(0.33f),
|
||||
Text = match.Round.Value?.Name.Value ?? "Unknown Round",
|
||||
Spacing = new Vector2(10, 0),
|
||||
Font = OsuFont.GetFont(size: 50, weight: FontWeight.Light)
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Colour = col,
|
||||
Text = match.Date.Value.ToUniversalTime().ToString("dd MMMM HH:mm UTC"),
|
||||
Font = OsuFont.GetFont(size: 20)
|
||||
Font = OsuFont.Torus.With(size: 26, weight: FontWeight.Light)
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -132,21 +109,19 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
|
||||
private class TeamWithPlayers : CompositeDrawable
|
||||
{
|
||||
private readonly Color4 red = new Color4(129, 68, 65, 255);
|
||||
private readonly Color4 blue = new Color4(41, 91, 97, 255);
|
||||
|
||||
public TeamWithPlayers(TournamentTeam team, bool left = false)
|
||||
{
|
||||
FillFlowContainer players;
|
||||
var colour = left ? red : blue;
|
||||
var colour = left ? TournamentGame.COLOUR_RED : TournamentGame.COLOUR_BLUE;
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TeamDisplay(team, left ? "Team Red" : "Team Blue", colour)
|
||||
new TeamDisplay(team)
|
||||
{
|
||||
Anchor = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
Origin = Anchor.Centre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
X = (left ? -1 : 1) * 0.36f,
|
||||
X = (left ? -1 : 1) * 0.3145f,
|
||||
Y = -0.077f,
|
||||
},
|
||||
players = new FillFlowContainer
|
||||
{
|
||||
@ -157,7 +132,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
Anchor = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
Origin = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
X = (left ? -1 : 1) * 0.66f,
|
||||
X = (left ? -1 : 1) * 0.58f,
|
||||
},
|
||||
};
|
||||
|
||||
@ -165,10 +140,10 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
{
|
||||
foreach (var p in team.Players)
|
||||
{
|
||||
players.Add(new OsuSpriteText
|
||||
players.Add(new TournamentSpriteText
|
||||
{
|
||||
Text = p.Username,
|
||||
Font = OsuFont.GetFont(size: 24),
|
||||
Font = OsuFont.Torus.With(size: 24),
|
||||
Colour = colour,
|
||||
Anchor = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
Origin = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
@ -179,7 +154,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
|
||||
private class TeamDisplay : DrawableTournamentTeam
|
||||
{
|
||||
public TeamDisplay(TournamentTeam team, string teamName, Color4 colour)
|
||||
public TeamDisplay(TournamentTeam team)
|
||||
: base(team)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
@ -187,33 +162,24 @@ namespace osu.Game.Tournament.Screens.TeamIntro
|
||||
Flag.Anchor = Flag.Origin = Anchor.TopCentre;
|
||||
Flag.RelativeSizeAxes = Axes.None;
|
||||
Flag.Size = new Vector2(300, 200);
|
||||
Flag.Scale = new Vector2(0.4f);
|
||||
Flag.Margin = new MarginPadding { Bottom = 20 };
|
||||
Flag.Scale = new Vector2(0.32f);
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 5),
|
||||
Spacing = new Vector2(160),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Flag,
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = team?.FullName.Value.ToUpper() ?? "???",
|
||||
Font = TournamentFont.GetFont(TournamentTypeface.Aquatico, 40, FontWeight.Light),
|
||||
Colour = Color4.Black,
|
||||
Text = team?.FullName.Value ?? "???",
|
||||
Font = OsuFont.Torus.With(size: 20, weight: FontWeight.Regular),
|
||||
Colour = OsuColour.Gray(0.2f),
|
||||
Origin = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = teamName.ToUpper(),
|
||||
Font = TournamentFont.GetFont(TournamentTypeface.Aquatico, 20, FontWeight.Regular),
|
||||
Colour = colour,
|
||||
Origin = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -7,10 +7,8 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Tournament.Components;
|
||||
using osu.Game.Tournament.Models;
|
||||
using osu.Game.Tournament.Screens.Showcase;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@ -33,22 +31,18 @@ namespace osu.Game.Tournament.Screens.TeamWin
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
blueWinVideo = new TourneyVideo(storage.GetStream(@"BG Team - Win Blue.m4v"))
|
||||
blueWinVideo = new TourneyVideo(storage.GetStream(@"videos/teamwin-blue.m4v"))
|
||||
{
|
||||
Alpha = 1,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Loop = true,
|
||||
},
|
||||
redWinVideo = new TourneyVideo(storage.GetStream(@"BG Team - Win Red.m4v"))
|
||||
redWinVideo = new TourneyVideo(storage.GetStream(@"videos/teamwin-red.m4v"))
|
||||
{
|
||||
Alpha = 0,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Loop = true,
|
||||
},
|
||||
new TournamentLogo(false)
|
||||
{
|
||||
Y = 40,
|
||||
},
|
||||
mainContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -85,141 +79,99 @@ namespace osu.Game.Tournament.Screens.TeamWin
|
||||
|
||||
mainContainer.Children = new Drawable[]
|
||||
{
|
||||
new TeamFlagDisplay(match.Winner)
|
||||
{
|
||||
Size = new Vector2(300, 200),
|
||||
Scale = new Vector2(0.5f),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
X = -387,
|
||||
},
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.TopLeft,
|
||||
Position = new Vector2(78, -70),
|
||||
Colour = OsuColour.Gray(0.33f),
|
||||
Text = match.Round.Value?.Name.Value ?? "Unknown Round",
|
||||
Font = OsuFont.Torus.With(size: 30, weight: FontWeight.Regular)
|
||||
},
|
||||
new TeamWithPlayers(match.Winner, redWin)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Width = 0.5f,
|
||||
Height = 0.6f,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre
|
||||
Origin = Anchor.TopLeft,
|
||||
Position = new Vector2(78, 0),
|
||||
},
|
||||
new RoundDisplay(match)
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Height = 0.25f,
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private class RoundDisplay : CompositeDrawable
|
||||
{
|
||||
public RoundDisplay(TournamentMatch match)
|
||||
{
|
||||
var col = OsuColour.Gray(0.33f);
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 10),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Colour = col,
|
||||
Text = "WINNER",
|
||||
Font = TournamentFont.GetFont(TournamentTypeface.Aquatico, 15, FontWeight.Regular),
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Colour = col,
|
||||
Text = match.Round.Value?.Name.Value ?? "Unknown Round",
|
||||
Font = TournamentFont.GetFont(TournamentTypeface.Aquatico, 50, FontWeight.Light),
|
||||
Spacing = new Vector2(10, 0),
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Colour = col,
|
||||
Text = match.Date.Value.ToUniversalTime().ToString("dd MMMM HH:mm UTC"),
|
||||
Font = TournamentFont.GetFont(TournamentTypeface.Aquatico, 20, FontWeight.Light),
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class TeamWithPlayers : CompositeDrawable
|
||||
{
|
||||
private readonly Color4 red = new Color4(129, 68, 65, 255);
|
||||
private readonly Color4 blue = new Color4(41, 91, 97, 255);
|
||||
|
||||
public TeamWithPlayers(TournamentTeam team, bool left = false)
|
||||
{
|
||||
var colour = left ? red : blue;
|
||||
FillFlowContainer players;
|
||||
|
||||
var colour = left ? TournamentGame.COLOUR_RED : TournamentGame.COLOUR_BLUE;
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new TeamDisplay(team, left ? "Team Red" : "Team Blue", colour)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Spacing = new Vector2(0, 5),
|
||||
Padding = new MarginPadding(20),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private class TeamDisplay : DrawableTournamentTeam
|
||||
{
|
||||
public TeamDisplay(TournamentTeam team, string teamName, Color4 colour)
|
||||
: base(team)
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
|
||||
Flag.Anchor = Flag.Origin = Anchor.TopCentre;
|
||||
Flag.RelativeSizeAxes = Axes.None;
|
||||
Flag.Size = new Vector2(300, 200);
|
||||
Flag.Scale = new Vector2(0.4f);
|
||||
Flag.Margin = new MarginPadding { Bottom = 20 };
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Flag,
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = team?.FullName.Value.ToUpper() ?? "???",
|
||||
Font = TournamentFont.GetFont(TournamentTypeface.Aquatico, 40, FontWeight.Light),
|
||||
Text = "WINNER",
|
||||
Font = OsuFont.Torus.With(size: 24, weight: FontWeight.SemiBold),
|
||||
Colour = Color4.Black,
|
||||
Origin = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre,
|
||||
},
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = teamName.ToUpper(),
|
||||
Font = OsuFont.GetFont(size: 20),
|
||||
Colour = colour,
|
||||
Origin = Anchor.TopCentre,
|
||||
Anchor = Anchor.TopCentre,
|
||||
}
|
||||
Text = team?.FullName.Value ?? "???",
|
||||
Font = OsuFont.Torus.With(size: 30, weight: FontWeight.SemiBold),
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
players = new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Vertical,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Top = 10 },
|
||||
},
|
||||
}
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
if (team != null)
|
||||
{
|
||||
foreach (var p in team.Players)
|
||||
{
|
||||
players.Add(new TournamentSpriteText
|
||||
{
|
||||
Text = p.Username,
|
||||
Font = OsuFont.Torus.With(size: 24),
|
||||
Colour = colour,
|
||||
Anchor = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
Origin = left ? Anchor.CentreRight : Anchor.CentreLeft,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TeamFlagDisplay : DrawableTournamentTeam
|
||||
{
|
||||
public TeamFlagDisplay(TournamentTeam team)
|
||||
: base(team)
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
Flag
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,75 +0,0 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament
|
||||
{
|
||||
public static class TournamentFont
|
||||
{
|
||||
/// <summary>
|
||||
/// The default font size.
|
||||
/// </summary>
|
||||
public const float DEFAULT_FONT_SIZE = 16;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a <see cref="FontUsage"/>.
|
||||
/// </summary>
|
||||
/// <param name="typeface">The font typeface.</param>
|
||||
/// <param name="size">The size of the text in local space. For a value of 16, a single line will have a height of 16px.</param>
|
||||
/// <param name="weight">The font weight.</param>
|
||||
/// <param name="italics">Whether the font is italic.</param>
|
||||
/// <param name="fixedWidth">Whether all characters should be spaced the same distance apart.</param>
|
||||
/// <returns>The <see cref="FontUsage"/>.</returns>
|
||||
public static FontUsage GetFont(TournamentTypeface typeface = TournamentTypeface.Aquatico, float size = DEFAULT_FONT_SIZE, FontWeight weight = FontWeight.Medium, bool italics = false, bool fixedWidth = false)
|
||||
=> new FontUsage(GetFamilyString(typeface), size, GetWeightString(typeface, weight), italics, fixedWidth);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the string representation of a <see cref="TournamentTypeface"/>.
|
||||
/// </summary>
|
||||
/// <param name="typeface">The <see cref="TournamentTypeface"/>.</param>
|
||||
/// <returns>The string representation.</returns>
|
||||
public static string GetFamilyString(TournamentTypeface typeface)
|
||||
{
|
||||
switch (typeface)
|
||||
{
|
||||
case TournamentTypeface.Aquatico:
|
||||
return "Aquatico";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the string representation of a <see cref="FontWeight"/>.
|
||||
/// </summary>
|
||||
/// <param name="typeface">The <see cref="TournamentTypeface"/>.</param>
|
||||
/// <param name="weight">The <see cref="FontWeight"/>.</param>
|
||||
/// <returns>The string representation of <paramref name="weight"/> in the specified <paramref name="typeface"/>.</returns>
|
||||
public static string GetWeightString(TournamentTypeface typeface, FontWeight weight)
|
||||
=> GetWeightString(GetFamilyString(typeface), weight);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the string representation of a <see cref="FontWeight"/>.
|
||||
/// </summary>
|
||||
/// <param name="family">The family string.</param>
|
||||
/// <param name="weight">The <see cref="FontWeight"/>.</param>
|
||||
/// <returns>The string representation of <paramref name="weight"/> in the specified <paramref name="family"/>.</returns>
|
||||
public static string GetWeightString(string family, FontWeight weight)
|
||||
{
|
||||
string weightString = weight.ToString();
|
||||
|
||||
// Only exo has an explicit "regular" weight, other fonts do not
|
||||
if (weight == FontWeight.Regular && family != GetFamilyString(TournamentTypeface.Aquatico))
|
||||
weightString = string.Empty;
|
||||
|
||||
return weightString;
|
||||
}
|
||||
}
|
||||
|
||||
public enum TournamentTypeface
|
||||
{
|
||||
Aquatico
|
||||
}
|
||||
}
|
@ -3,11 +3,15 @@
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tournament
|
||||
{
|
||||
public class TournamentGame : TournamentGameBase
|
||||
{
|
||||
public static readonly Color4 COLOUR_RED = new Color4(144, 0, 0, 255);
|
||||
public static readonly Color4 COLOUR_BLUE = new Color4(0, 84, 144, 255);
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
@ -18,7 +18,6 @@ using osu.Framework.IO.Stores;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Tournament.IPC;
|
||||
using osu.Game.Tournament.Models;
|
||||
@ -54,9 +53,6 @@ namespace osu.Game.Tournament
|
||||
{
|
||||
Resources.AddStore(new DllResourceStore(typeof(TournamentGameBase).Assembly));
|
||||
|
||||
AddFont(Resources, @"Resources/Fonts/Aquatico-Regular");
|
||||
AddFont(Resources, @"Resources/Fonts/Aquatico-Light");
|
||||
|
||||
Textures.AddStore(new TextureLoaderStore(new ResourceStore<byte[]>(new StorageBackedResourceStore(storage))));
|
||||
|
||||
this.storage = storage;
|
||||
@ -104,10 +100,10 @@ namespace osu.Game.Tournament
|
||||
Colour = Color4.Red,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new OsuSpriteText
|
||||
new TournamentSpriteText
|
||||
{
|
||||
Text = "Please make the window wider",
|
||||
Font = OsuFont.Default.With(weight: "bold"),
|
||||
Font = OsuFont.Torus.With(weight: FontWeight.Bold),
|
||||
Colour = Color4.White,
|
||||
Padding = new MarginPadding(20)
|
||||
}
|
||||
@ -124,10 +120,9 @@ namespace osu.Game.Tournament
|
||||
using (var sr = new StreamReader(stream))
|
||||
ladder = JsonConvert.DeserializeObject<LadderInfo>(sr.ReadToEnd());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (ladder == null)
|
||||
ladder = new LadderInfo();
|
||||
}
|
||||
|
||||
if (ladder.Ruleset.Value == null)
|
||||
ladder.Ruleset.Value = RulesetStore.AvailableRulesets.First();
|
||||
@ -205,9 +200,11 @@ namespace osu.Game.Tournament
|
||||
{
|
||||
foreach (var p in t.Players)
|
||||
{
|
||||
if (p.Username == null || p.Statistics == null)
|
||||
if (string.IsNullOrEmpty(p.Username) || p.Statistics == null)
|
||||
{
|
||||
PopulateUser(p);
|
||||
addedInfo = true;
|
||||
addedInfo = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,6 +240,24 @@ namespace osu.Game.Tournament
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var t in ladder.Teams)
|
||||
{
|
||||
foreach (var s in t.SeedingResults)
|
||||
{
|
||||
foreach (var b in s.Beatmaps)
|
||||
{
|
||||
if (b.BeatmapInfo == null && b.ID > 0)
|
||||
{
|
||||
var req = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = b.ID });
|
||||
req.Perform(API);
|
||||
b.BeatmapInfo = req.Result?.ToBeatmap(RulesetStore);
|
||||
|
||||
addedInfo = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return addedInfo;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ namespace osu.Game.Tournament
|
||||
//Masking = true,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
video = new TourneyVideo(storage.GetStream("BG Logoless - OWC.m4v"))
|
||||
video = new TourneyVideo(storage.GetStream("videos/main.m4v"))
|
||||
{
|
||||
Loop = true,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -80,6 +80,7 @@ namespace osu.Game.Tournament
|
||||
new ShowcaseScreen(),
|
||||
new MapPoolScreen(),
|
||||
new TeamIntroScreen(),
|
||||
new SeedingScreen(),
|
||||
new DrawingsScreen(),
|
||||
new GameplayScreen(),
|
||||
new TeamWinScreen()
|
||||
@ -121,6 +122,7 @@ namespace osu.Game.Tournament
|
||||
new ScreenButton(typeof(LadderScreen)) { Text = "Bracket", RequestSelection = SetScreen },
|
||||
new Separator(),
|
||||
new ScreenButton(typeof(TeamIntroScreen)) { Text = "TeamIntro", RequestSelection = SetScreen },
|
||||
new ScreenButton(typeof(SeedingScreen)) { Text = "Seeding", RequestSelection = SetScreen },
|
||||
new Separator(),
|
||||
new ScreenButton(typeof(MapPoolScreen)) { Text = "MapPool", RequestSelection = SetScreen },
|
||||
new ScreenButton(typeof(GameplayScreen)) { Text = "Gameplay", RequestSelection = SetScreen },
|
||||
@ -146,8 +148,20 @@ namespace osu.Game.Tournament
|
||||
private Drawable currentScreen;
|
||||
private ScheduledDelegate scheduledHide;
|
||||
|
||||
private Drawable temporaryScreen;
|
||||
|
||||
public void SetScreen(Drawable screen)
|
||||
{
|
||||
currentScreen?.Hide();
|
||||
currentScreen = null;
|
||||
|
||||
screens.Add(temporaryScreen = screen);
|
||||
}
|
||||
|
||||
public void SetScreen(Type screenType)
|
||||
{
|
||||
temporaryScreen?.Expire();
|
||||
|
||||
var target = screens.FirstOrDefault(s => s.GetType() == screenType);
|
||||
|
||||
if (target == null || currentScreen == target) return;
|
||||
|
16
osu.Game.Tournament/TournamentSpriteText.cs
Normal file
16
osu.Game.Tournament/TournamentSpriteText.cs
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Tournament
|
||||
{
|
||||
public class TournamentSpriteText : OsuSpriteText
|
||||
{
|
||||
public TournamentSpriteText()
|
||||
{
|
||||
Font = OsuFont.Torus;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Configuration.Tracking;
|
||||
using osu.Framework.Extensions;
|
||||
@ -126,6 +127,35 @@ namespace osu.Game.Configuration
|
||||
public OsuConfigManager(Storage storage)
|
||||
: base(storage)
|
||||
{
|
||||
Migrate();
|
||||
}
|
||||
|
||||
public void Migrate()
|
||||
{
|
||||
// arrives as 2020.123.0
|
||||
var rawVersion = Get<string>(OsuSetting.Version);
|
||||
|
||||
if (rawVersion.Length < 6)
|
||||
return;
|
||||
|
||||
var pieces = rawVersion.Split('.');
|
||||
|
||||
// on a fresh install or when coming from a non-release build, execution will end here.
|
||||
// we don't want to run migrations in such cases.
|
||||
if (!int.TryParse(pieces[0], out int year)) return;
|
||||
if (!int.TryParse(pieces[1], out int monthDay)) return;
|
||||
|
||||
int combined = (year * 10000) + monthDay;
|
||||
|
||||
if (combined < 20200305)
|
||||
{
|
||||
// the maximum value of this setting was changed.
|
||||
// if we don't manually increase this, it causes song select to filter out beatmaps the user expects to see.
|
||||
var maxStars = (BindableDouble)GetOriginalBindable<double>(OsuSetting.DisplayStarsMaximum);
|
||||
|
||||
if (maxStars.Value == 10)
|
||||
maxStars.Value = maxStars.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
public override TrackedSettings CreateTrackedSettings() => new TrackedSettings
|
||||
|
@ -129,7 +129,7 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
{
|
||||
base.Update();
|
||||
|
||||
Invalidate(Invalidation.DrawNode, shallPropagate: false);
|
||||
Invalidate(Invalidation.DrawNode);
|
||||
|
||||
if (CreateNewTriangles)
|
||||
addTriangles(false);
|
||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Layout;
|
||||
|
||||
namespace osu.Game.Graphics.Containers
|
||||
{
|
||||
@ -142,15 +143,17 @@ namespace osu.Game.Graphics.Containers
|
||||
|
||||
public void ScrollToTop() => scrollContainer.ScrollTo(0);
|
||||
|
||||
public override void InvalidateFromChild(Invalidation invalidation, Drawable source = null)
|
||||
protected override bool OnInvalidate(Invalidation invalidation, InvalidationSource source)
|
||||
{
|
||||
base.InvalidateFromChild(invalidation, source);
|
||||
var result = base.OnInvalidate(invalidation, source);
|
||||
|
||||
if ((invalidation & Invalidation.DrawSize) != 0)
|
||||
if (source == InvalidationSource.Child && (invalidation & Invalidation.DrawSize) != 0)
|
||||
{
|
||||
if (source == ExpandableHeader) //We need to recalculate the positions if the ExpandableHeader changed its size
|
||||
lastKnownScroll = -1;
|
||||
lastKnownScroll = -1;
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private float lastKnownScroll;
|
||||
|
@ -17,7 +17,9 @@ namespace osu.Game.Graphics
|
||||
/// </summary>
|
||||
public static FontUsage Default => GetFont();
|
||||
|
||||
public static FontUsage Numeric => GetFont(Typeface.Venera, weight: FontWeight.Regular);
|
||||
public static FontUsage Numeric => GetFont(Typeface.Venera, weight: FontWeight.Bold);
|
||||
|
||||
public static FontUsage Torus => GetFont(Typeface.Torus, weight: FontWeight.Regular);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a <see cref="FontUsage"/>.
|
||||
@ -45,6 +47,9 @@ namespace osu.Game.Graphics
|
||||
|
||||
case Typeface.Venera:
|
||||
return "Venera";
|
||||
|
||||
case Typeface.Torus:
|
||||
return "Torus";
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -65,16 +70,7 @@ namespace osu.Game.Graphics
|
||||
/// <param name="family">The family string.</param>
|
||||
/// <param name="weight">The <see cref="FontWeight"/>.</param>
|
||||
/// <returns>The string representation of <paramref name="weight"/> in the specified <paramref name="family"/>.</returns>
|
||||
public static string GetWeightString(string family, FontWeight weight)
|
||||
{
|
||||
string weightString = weight.ToString();
|
||||
|
||||
// Only exo has an explicit "regular" weight, other fonts do not
|
||||
if (family != GetFamilyString(Typeface.Exo) && weight == FontWeight.Regular)
|
||||
weightString = string.Empty;
|
||||
|
||||
return weightString;
|
||||
}
|
||||
public static string GetWeightString(string family, FontWeight weight) => weight.ToString();
|
||||
}
|
||||
|
||||
public static class OsuFontExtensions
|
||||
@ -102,15 +98,39 @@ namespace osu.Game.Graphics
|
||||
{
|
||||
Exo,
|
||||
Venera,
|
||||
Torus
|
||||
}
|
||||
|
||||
public enum FontWeight
|
||||
{
|
||||
Light,
|
||||
Regular,
|
||||
Medium,
|
||||
SemiBold,
|
||||
Bold,
|
||||
Black
|
||||
/// <summary>
|
||||
/// Equivalent to weight 300.
|
||||
/// </summary>
|
||||
Light = 300,
|
||||
|
||||
/// <summary>
|
||||
/// Equivalent to weight 400.
|
||||
/// </summary>
|
||||
Regular = 400,
|
||||
|
||||
/// <summary>
|
||||
/// Equivalent to weight 500.
|
||||
/// </summary>
|
||||
Medium = 500,
|
||||
|
||||
/// <summary>
|
||||
/// Equivalent to weight 600.
|
||||
/// </summary>
|
||||
SemiBold = 600,
|
||||
|
||||
/// <summary>
|
||||
/// Equivalent to weight 700.
|
||||
/// </summary>
|
||||
Bold = 700,
|
||||
|
||||
/// <summary>
|
||||
/// Equivalent to weight 900.
|
||||
/// </summary>
|
||||
Black = 900
|
||||
}
|
||||
}
|
||||
|
@ -13,17 +13,17 @@ namespace osu.Game.Graphics.UserInterface
|
||||
/// </summary>
|
||||
public class ExpandingBar : Circle
|
||||
{
|
||||
private bool isCollapsed;
|
||||
private bool expanded = true;
|
||||
|
||||
public bool IsCollapsed
|
||||
public bool Expanded
|
||||
{
|
||||
get => isCollapsed;
|
||||
get => expanded;
|
||||
set
|
||||
{
|
||||
if (value == isCollapsed)
|
||||
if (value == expanded)
|
||||
return;
|
||||
|
||||
isCollapsed = value;
|
||||
expanded = value;
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
@ -83,19 +83,21 @@ namespace osu.Game.Graphics.UserInterface
|
||||
updateState();
|
||||
}
|
||||
|
||||
public void Collapse() => IsCollapsed = true;
|
||||
public void Collapse() => Expanded = false;
|
||||
|
||||
public void Expand() => IsCollapsed = false;
|
||||
public void Expand() => Expanded = true;
|
||||
|
||||
private void updateState()
|
||||
{
|
||||
float newSize = IsCollapsed ? CollapsedSize : ExpandedSize;
|
||||
Easing easingType = IsCollapsed ? Easing.Out : Easing.OutElastic;
|
||||
float newSize = expanded ? ExpandedSize : CollapsedSize;
|
||||
Easing easingType = expanded ? Easing.OutElastic : Easing.Out;
|
||||
|
||||
if (RelativeSizeAxes == Axes.X)
|
||||
this.ResizeHeightTo(newSize, 400, easingType);
|
||||
else
|
||||
this.ResizeWidthTo(newSize, 400, easingType);
|
||||
|
||||
this.FadeTo(expanded ? 1 : 0.5f, 100, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Caching;
|
||||
using osuTK;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Lines;
|
||||
using osu.Framework.Layout;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Graphics.UserInterface
|
||||
@ -83,17 +83,11 @@ namespace osu.Game.Graphics.UserInterface
|
||||
PathRadius = 1
|
||||
}
|
||||
});
|
||||
|
||||
AddLayout(pathCached);
|
||||
}
|
||||
|
||||
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||
{
|
||||
if ((invalidation & Invalidation.DrawSize) > 0)
|
||||
pathCached.Invalidate();
|
||||
|
||||
return base.Invalidate(invalidation, source, shallPropagate);
|
||||
}
|
||||
|
||||
private readonly Cached pathCached = new Cached();
|
||||
private readonly LayoutValue pathCached = new LayoutValue(Invalidation.DrawSize);
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
|
@ -31,8 +31,9 @@ namespace osu.Game.Input.Bindings
|
||||
/// <param name="ruleset">A reference to identify the current <see cref="Ruleset"/>. Used to lookup mappings. Null for global mappings.</param>
|
||||
/// <param name="variant">An optional variant for the specified <see cref="Ruleset"/>. Used when a ruleset has more than one possible keyboard layouts.</param>
|
||||
/// <param name="simultaneousMode">Specify how to deal with multiple matches of <see cref="KeyCombination"/>s and <typeparamref name="T"/>s.</param>
|
||||
public DatabasedKeyBindingContainer(RulesetInfo ruleset = null, int? variant = null, SimultaneousBindingMode simultaneousMode = SimultaneousBindingMode.None)
|
||||
: base(simultaneousMode)
|
||||
/// <param name="matchingMode">Specify how to deal with exact <see cref="KeyCombination"/> matches.</param>
|
||||
public DatabasedKeyBindingContainer(RulesetInfo ruleset = null, int? variant = null, SimultaneousBindingMode simultaneousMode = SimultaneousBindingMode.None, KeyCombinationMatchingMode matchingMode = KeyCombinationMatchingMode.Any)
|
||||
: base(simultaneousMode, matchingMode)
|
||||
{
|
||||
this.ruleset = ruleset;
|
||||
this.variant = variant;
|
||||
|
@ -15,6 +15,7 @@ namespace osu.Game.Input.Bindings
|
||||
private readonly Drawable handler;
|
||||
|
||||
public GlobalActionContainer(OsuGameBase game)
|
||||
: base(matchingMode: KeyCombinationMatchingMode.Modifiers)
|
||||
{
|
||||
if (game is IKeyBindingHandler<GlobalAction>)
|
||||
handler = game;
|
||||
@ -38,6 +39,9 @@ namespace osu.Game.Input.Bindings
|
||||
new KeyBinding(InputKey.Escape, GlobalAction.Back),
|
||||
new KeyBinding(InputKey.ExtraMouseButton1, GlobalAction.Back),
|
||||
|
||||
new KeyBinding(InputKey.Up, GlobalAction.SelectPrevious),
|
||||
new KeyBinding(InputKey.Down, GlobalAction.SelectNext),
|
||||
|
||||
new KeyBinding(InputKey.Space, GlobalAction.Select),
|
||||
new KeyBinding(InputKey.Enter, GlobalAction.Select),
|
||||
new KeyBinding(InputKey.KeypadEnter, GlobalAction.Select),
|
||||
@ -54,10 +58,11 @@ namespace osu.Game.Input.Bindings
|
||||
|
||||
public IEnumerable<KeyBinding> AudioControlKeyBindings => new[]
|
||||
{
|
||||
new KeyBinding(InputKey.Up, GlobalAction.IncreaseVolume),
|
||||
new KeyBinding(InputKey.MouseWheelUp, GlobalAction.IncreaseVolume),
|
||||
new KeyBinding(InputKey.Down, GlobalAction.DecreaseVolume),
|
||||
new KeyBinding(InputKey.MouseWheelDown, GlobalAction.DecreaseVolume),
|
||||
new KeyBinding(new[] { InputKey.Alt, InputKey.Up }, GlobalAction.IncreaseVolume),
|
||||
new KeyBinding(new[] { InputKey.Alt, InputKey.MouseWheelUp }, GlobalAction.IncreaseVolume),
|
||||
new KeyBinding(new[] { InputKey.Alt, InputKey.Down }, GlobalAction.DecreaseVolume),
|
||||
new KeyBinding(new[] { InputKey.Alt, InputKey.MouseWheelDown }, GlobalAction.DecreaseVolume),
|
||||
|
||||
new KeyBinding(InputKey.F4, GlobalAction.ToggleMute),
|
||||
|
||||
new KeyBinding(InputKey.TrackPrevious, GlobalAction.MusicPrev),
|
||||
@ -141,5 +146,11 @@ namespace osu.Game.Input.Bindings
|
||||
|
||||
[Description("Toggle now playing overlay")]
|
||||
ToggleNowPlaying,
|
||||
|
||||
[Description("Previous Selection")]
|
||||
SelectPrevious,
|
||||
|
||||
[Description("Next Selection")]
|
||||
SelectNext,
|
||||
}
|
||||
}
|
||||
|
506
osu.Game/Migrations/20200302094919_RefreshVolumeBindings.Designer.cs
generated
Normal file
506
osu.Game/Migrations/20200302094919_RefreshVolumeBindings.Designer.cs
generated
Normal file
@ -0,0 +1,506 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Game.Migrations
|
||||
{
|
||||
[DbContext(typeof(OsuDbContext))]
|
||||
[Migration("20200302094919_RefreshVolumeBindings")]
|
||||
partial class RefreshVolumeBindings
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.2.6-servicing-10079");
|
||||
|
||||
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b =>
|
||||
{
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<float>("ApproachRate");
|
||||
|
||||
b.Property<float>("CircleSize");
|
||||
|
||||
b.Property<float>("DrainRate");
|
||||
|
||||
b.Property<float>("OverallDifficulty");
|
||||
|
||||
b.Property<double>("SliderMultiplier");
|
||||
|
||||
b.Property<double>("SliderTickRate");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.ToTable("BeatmapDifficulty");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
|
||||
{
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<double>("AudioLeadIn");
|
||||
|
||||
b.Property<double>("BPM");
|
||||
|
||||
b.Property<int>("BaseDifficultyID");
|
||||
|
||||
b.Property<int>("BeatDivisor");
|
||||
|
||||
b.Property<int>("BeatmapSetInfoID");
|
||||
|
||||
b.Property<bool>("Countdown");
|
||||
|
||||
b.Property<double>("DistanceSpacing");
|
||||
|
||||
b.Property<int>("GridSize");
|
||||
|
||||
b.Property<string>("Hash");
|
||||
|
||||
b.Property<bool>("Hidden");
|
||||
|
||||
b.Property<double>("Length");
|
||||
|
||||
b.Property<bool>("LetterboxInBreaks");
|
||||
|
||||
b.Property<string>("MD5Hash");
|
||||
|
||||
b.Property<int?>("MetadataID");
|
||||
|
||||
b.Property<int?>("OnlineBeatmapID");
|
||||
|
||||
b.Property<string>("Path");
|
||||
|
||||
b.Property<int>("RulesetID");
|
||||
|
||||
b.Property<bool>("SpecialStyle");
|
||||
|
||||
b.Property<float>("StackLeniency");
|
||||
|
||||
b.Property<double>("StarDifficulty");
|
||||
|
||||
b.Property<int>("Status");
|
||||
|
||||
b.Property<string>("StoredBookmarks");
|
||||
|
||||
b.Property<double>("TimelineZoom");
|
||||
|
||||
b.Property<string>("Version");
|
||||
|
||||
b.Property<bool>("WidescreenStoryboard");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("BaseDifficultyID");
|
||||
|
||||
b.HasIndex("BeatmapSetInfoID");
|
||||
|
||||
b.HasIndex("Hash");
|
||||
|
||||
b.HasIndex("MD5Hash");
|
||||
|
||||
b.HasIndex("MetadataID");
|
||||
|
||||
b.HasIndex("OnlineBeatmapID")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("RulesetID");
|
||||
|
||||
b.ToTable("BeatmapInfo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapMetadata", b =>
|
||||
{
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Artist");
|
||||
|
||||
b.Property<string>("ArtistUnicode");
|
||||
|
||||
b.Property<string>("AudioFile");
|
||||
|
||||
b.Property<string>("AuthorString")
|
||||
.HasColumnName("Author");
|
||||
|
||||
b.Property<string>("BackgroundFile");
|
||||
|
||||
b.Property<int>("PreviewTime");
|
||||
|
||||
b.Property<string>("Source");
|
||||
|
||||
b.Property<string>("Tags");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("TitleUnicode");
|
||||
|
||||
b.Property<string>("VideoFile");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.ToTable("BeatmapMetadata");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
|
||||
{
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("BeatmapSetInfoID");
|
||||
|
||||
b.Property<int>("FileInfoID");
|
||||
|
||||
b.Property<string>("Filename")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("BeatmapSetInfoID");
|
||||
|
||||
b.HasIndex("FileInfoID");
|
||||
|
||||
b.ToTable("BeatmapSetFileInfo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
|
||||
{
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTimeOffset>("DateAdded");
|
||||
|
||||
b.Property<bool>("DeletePending");
|
||||
|
||||
b.Property<string>("Hash");
|
||||
|
||||
b.Property<int?>("MetadataID");
|
||||
|
||||
b.Property<int?>("OnlineBeatmapSetID");
|
||||
|
||||
b.Property<bool>("Protected");
|
||||
|
||||
b.Property<int>("Status");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("DeletePending");
|
||||
|
||||
b.HasIndex("Hash")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("MetadataID");
|
||||
|
||||
b.HasIndex("OnlineBeatmapSetID")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("BeatmapSetInfo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
|
||||
{
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Key")
|
||||
.HasColumnName("Key");
|
||||
|
||||
b.Property<int?>("RulesetID");
|
||||
|
||||
b.Property<int?>("SkinInfoID");
|
||||
|
||||
b.Property<string>("StringValue")
|
||||
.HasColumnName("Value");
|
||||
|
||||
b.Property<int?>("Variant");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("SkinInfoID");
|
||||
|
||||
b.HasIndex("RulesetID", "Variant");
|
||||
|
||||
b.ToTable("Settings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.IO.FileInfo", b =>
|
||||
{
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Hash");
|
||||
|
||||
b.Property<int>("ReferenceCount");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("Hash")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("ReferenceCount");
|
||||
|
||||
b.ToTable("FileInfo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b =>
|
||||
{
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("IntAction")
|
||||
.HasColumnName("Action");
|
||||
|
||||
b.Property<string>("KeysString")
|
||||
.HasColumnName("Keys");
|
||||
|
||||
b.Property<int?>("RulesetID");
|
||||
|
||||
b.Property<int?>("Variant");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("IntAction");
|
||||
|
||||
b.HasIndex("RulesetID", "Variant");
|
||||
|
||||
b.ToTable("KeyBinding");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b =>
|
||||
{
|
||||
b.Property<int?>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("Available");
|
||||
|
||||
b.Property<string>("InstantiationInfo");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<string>("ShortName");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("Available");
|
||||
|
||||
b.HasIndex("ShortName")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("RulesetInfo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b =>
|
||||
{
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("FileInfoID");
|
||||
|
||||
b.Property<string>("Filename")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<int?>("ScoreInfoID");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("FileInfoID");
|
||||
|
||||
b.HasIndex("ScoreInfoID");
|
||||
|
||||
b.ToTable("ScoreFileInfo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b =>
|
||||
{
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<double>("Accuracy")
|
||||
.HasColumnType("DECIMAL(1,4)");
|
||||
|
||||
b.Property<int>("BeatmapInfoID");
|
||||
|
||||
b.Property<int>("Combo");
|
||||
|
||||
b.Property<DateTimeOffset>("Date");
|
||||
|
||||
b.Property<bool>("DeletePending");
|
||||
|
||||
b.Property<string>("Hash");
|
||||
|
||||
b.Property<int>("MaxCombo");
|
||||
|
||||
b.Property<string>("ModsJson")
|
||||
.HasColumnName("Mods");
|
||||
|
||||
b.Property<long?>("OnlineScoreID");
|
||||
|
||||
b.Property<double?>("PP");
|
||||
|
||||
b.Property<int>("Rank");
|
||||
|
||||
b.Property<int>("RulesetID");
|
||||
|
||||
b.Property<string>("StatisticsJson")
|
||||
.HasColumnName("Statistics");
|
||||
|
||||
b.Property<long>("TotalScore");
|
||||
|
||||
b.Property<long?>("UserID")
|
||||
.HasColumnName("UserID");
|
||||
|
||||
b.Property<string>("UserString")
|
||||
.HasColumnName("User");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("BeatmapInfoID");
|
||||
|
||||
b.HasIndex("OnlineScoreID")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("RulesetID");
|
||||
|
||||
b.ToTable("ScoreInfo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b =>
|
||||
{
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("FileInfoID");
|
||||
|
||||
b.Property<string>("Filename")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<int>("SkinInfoID");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("FileInfoID");
|
||||
|
||||
b.HasIndex("SkinInfoID");
|
||||
|
||||
b.ToTable("SkinFileInfo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Skinning.SkinInfo", b =>
|
||||
{
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Creator");
|
||||
|
||||
b.Property<bool>("DeletePending");
|
||||
|
||||
b.Property<string>("Hash");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("ID");
|
||||
|
||||
b.HasIndex("DeletePending");
|
||||
|
||||
b.HasIndex("Hash")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SkinInfo");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapInfo", b =>
|
||||
{
|
||||
b.HasOne("osu.Game.Beatmaps.BeatmapDifficulty", "BaseDifficulty")
|
||||
.WithMany()
|
||||
.HasForeignKey("BaseDifficultyID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo", "BeatmapSet")
|
||||
.WithMany("Beatmaps")
|
||||
.HasForeignKey("BeatmapSetInfoID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
|
||||
.WithMany("Beatmaps")
|
||||
.HasForeignKey("MetadataID");
|
||||
|
||||
b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset")
|
||||
.WithMany()
|
||||
.HasForeignKey("RulesetID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetFileInfo", b =>
|
||||
{
|
||||
b.HasOne("osu.Game.Beatmaps.BeatmapSetInfo")
|
||||
.WithMany("Files")
|
||||
.HasForeignKey("BeatmapSetInfoID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||
.WithMany()
|
||||
.HasForeignKey("FileInfoID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapSetInfo", b =>
|
||||
{
|
||||
b.HasOne("osu.Game.Beatmaps.BeatmapMetadata", "Metadata")
|
||||
.WithMany("BeatmapSets")
|
||||
.HasForeignKey("MetadataID");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Configuration.DatabasedSetting", b =>
|
||||
{
|
||||
b.HasOne("osu.Game.Skinning.SkinInfo")
|
||||
.WithMany("Settings")
|
||||
.HasForeignKey("SkinInfoID");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Scoring.ScoreFileInfo", b =>
|
||||
{
|
||||
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||
.WithMany()
|
||||
.HasForeignKey("FileInfoID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("osu.Game.Scoring.ScoreInfo")
|
||||
.WithMany("Files")
|
||||
.HasForeignKey("ScoreInfoID");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b =>
|
||||
{
|
||||
b.HasOne("osu.Game.Beatmaps.BeatmapInfo", "Beatmap")
|
||||
.WithMany("Scores")
|
||||
.HasForeignKey("BeatmapInfoID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("osu.Game.Rulesets.RulesetInfo", "Ruleset")
|
||||
.WithMany()
|
||||
.HasForeignKey("RulesetID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("osu.Game.Skinning.SkinFileInfo", b =>
|
||||
{
|
||||
b.HasOne("osu.Game.IO.FileInfo", "FileInfo")
|
||||
.WithMany()
|
||||
.HasForeignKey("FileInfoID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("osu.Game.Skinning.SkinInfo")
|
||||
.WithMany("Files")
|
||||
.HasForeignKey("SkinInfoID")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
16
osu.Game/Migrations/20200302094919_RefreshVolumeBindings.cs
Normal file
16
osu.Game/Migrations/20200302094919_RefreshVolumeBindings.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace osu.Game.Migrations
|
||||
{
|
||||
public partial class RefreshVolumeBindings : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.Sql("DELETE FROM KeyBinding WHERE action in (6,7)");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -43,7 +43,7 @@ namespace osu.Game.Migrations
|
||||
b.Property<int>("ID")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("AudioLeadIn");
|
||||
b.Property<double>("AudioLeadIn");
|
||||
|
||||
b.Property<double>("BPM");
|
||||
|
||||
|
@ -58,7 +58,7 @@ namespace osu.Game.Online.Leaderboards
|
||||
Spacing = new Vector2(-3, 0),
|
||||
Padding = new MarginPadding { Top = 5 },
|
||||
Colour = getRankNameColour(),
|
||||
Font = OsuFont.GetFont(Typeface.Venera, 25),
|
||||
Font = OsuFont.Numeric.With(size: 25),
|
||||
Text = getRankName(),
|
||||
ShadowColour = Color4.Black.Opacity(0.3f),
|
||||
ShadowOffset = new Vector2(0, 0.08f),
|
||||
|
@ -25,6 +25,7 @@ using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Beatmaps;
|
||||
@ -42,6 +43,7 @@ using osu.Game.Overlays.Volume;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Select;
|
||||
using osu.Game.Updater;
|
||||
using osu.Game.Utils;
|
||||
using LogLevel = osu.Framework.Logging.LogLevel;
|
||||
|
||||
@ -389,24 +391,35 @@ namespace osu.Game
|
||||
|
||||
protected virtual Loader CreateLoader() => new Loader();
|
||||
|
||||
protected virtual UpdateManager CreateUpdateManager() => new UpdateManager();
|
||||
|
||||
protected override Container CreateScalingContainer() => new ScalingContainer(ScalingMode.Everything);
|
||||
|
||||
#region Beatmap progression
|
||||
|
||||
private void beatmapChanged(ValueChangedEvent<WorkingBeatmap> beatmap)
|
||||
{
|
||||
var nextBeatmap = beatmap.NewValue;
|
||||
if (nextBeatmap?.Track != null)
|
||||
nextBeatmap.Track.Completed += currentTrackCompleted;
|
||||
|
||||
var oldBeatmap = beatmap.OldValue;
|
||||
if (oldBeatmap?.Track != null)
|
||||
oldBeatmap.Track.Completed -= currentTrackCompleted;
|
||||
beatmap.OldValue?.CancelAsyncLoad();
|
||||
|
||||
updateModDefaults();
|
||||
|
||||
oldBeatmap?.CancelAsyncLoad();
|
||||
nextBeatmap?.BeginAsyncLoad();
|
||||
var newBeatmap = beatmap.NewValue;
|
||||
|
||||
if (newBeatmap != null)
|
||||
{
|
||||
newBeatmap.Track.Completed += () => Scheduler.AddOnce(() => trackCompleted(newBeatmap));
|
||||
newBeatmap.BeginAsyncLoad();
|
||||
}
|
||||
|
||||
void trackCompleted(WorkingBeatmap b)
|
||||
{
|
||||
// the source of track completion is the audio thread, so the beatmap may have changed before firing.
|
||||
if (Beatmap.Value != b)
|
||||
return;
|
||||
|
||||
if (!Beatmap.Value.Track.Looping && !Beatmap.Disabled)
|
||||
MusicController.NextTrack();
|
||||
}
|
||||
}
|
||||
|
||||
private void modsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
|
||||
@ -427,12 +440,6 @@ namespace osu.Game
|
||||
}
|
||||
}
|
||||
|
||||
private void currentTrackCompleted() => Schedule(() =>
|
||||
{
|
||||
if (!Beatmap.Value.Track.Looping && !Beatmap.Disabled)
|
||||
musicController.NextTrack();
|
||||
});
|
||||
|
||||
#endregion
|
||||
|
||||
private ScheduledDelegate performFromMainMenuTask;
|
||||
@ -584,7 +591,7 @@ namespace osu.Game
|
||||
|
||||
loadComponentSingleFile(new OnScreenDisplay(), Add, true);
|
||||
|
||||
loadComponentSingleFile(musicController = new MusicController(), Add, true);
|
||||
loadComponentSingleFile(MusicController = new MusicController(), Add, true);
|
||||
|
||||
loadComponentSingleFile(notifications = new NotificationOverlay
|
||||
{
|
||||
@ -627,6 +634,7 @@ namespace osu.Game
|
||||
chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible;
|
||||
|
||||
Add(externalLinkOpener = new ExternalLinkOpener());
|
||||
Add(CreateUpdateManager()); // dependency on notification overlay
|
||||
|
||||
// side overlays which cancel each other.
|
||||
var singleDisplaySideOverlays = new OverlayContainer[] { Settings, notifications };
|
||||
@ -805,6 +813,13 @@ namespace osu.Game
|
||||
return d;
|
||||
}
|
||||
|
||||
protected override bool OnScroll(ScrollEvent e)
|
||||
{
|
||||
// forward any unhandled mouse scroll events to the volume control.
|
||||
volume.Adjust(GlobalAction.IncreaseVolume, e.ScrollDelta.Y, e.IsPrecise);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OnPressed(GlobalAction action)
|
||||
{
|
||||
if (introScreen == null) return false;
|
||||
@ -885,7 +900,7 @@ namespace osu.Game
|
||||
|
||||
private ScalingContainer screenContainer;
|
||||
|
||||
private MusicController musicController;
|
||||
protected MusicController MusicController { get; private set; }
|
||||
|
||||
protected override bool OnExiting()
|
||||
{
|
||||
@ -943,7 +958,7 @@ namespace osu.Game
|
||||
{
|
||||
OverlayActivationMode.Value = newOsuScreen.InitialOverlayActivationMode;
|
||||
|
||||
musicController.AllowRateAdjustments = newOsuScreen.AllowRateAdjustments;
|
||||
MusicController.AllowRateAdjustments = newOsuScreen.AllowRateAdjustments;
|
||||
|
||||
if (newOsuScreen.HideOverlaysOnEnter)
|
||||
CloseAllOverlays();
|
||||
|
@ -97,7 +97,7 @@ namespace osu.Game
|
||||
|
||||
public bool IsDeployedBuild => AssemblyVersion.Major > 0;
|
||||
|
||||
public string Version
|
||||
public virtual string Version
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -157,9 +157,14 @@ namespace osu.Game
|
||||
AddFont(Resources, @"Fonts/Exo2.0-Black");
|
||||
AddFont(Resources, @"Fonts/Exo2.0-BlackItalic");
|
||||
|
||||
AddFont(Resources, @"Fonts/Venera");
|
||||
AddFont(Resources, @"Fonts/Torus-SemiBold");
|
||||
AddFont(Resources, @"Fonts/Torus-Bold");
|
||||
AddFont(Resources, @"Fonts/Torus-Regular");
|
||||
AddFont(Resources, @"Fonts/Torus-Light");
|
||||
|
||||
AddFont(Resources, @"Fonts/Venera-Light");
|
||||
AddFont(Resources, @"Fonts/Venera-Medium");
|
||||
AddFont(Resources, @"Fonts/Venera-Bold");
|
||||
AddFont(Resources, @"Fonts/Venera-Black");
|
||||
|
||||
runMigrations();
|
||||
|
||||
@ -206,6 +211,10 @@ namespace osu.Game
|
||||
Audio.Tracks.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8));
|
||||
|
||||
Beatmap = new NonNullableBindable<WorkingBeatmap>(defaultBeatmap);
|
||||
|
||||
// ScheduleAfterChildren is safety against something in the current frame accessing the previous beatmap's track
|
||||
// and potentially causing a reload of it after just unloading.
|
||||
// Note that the reason for this being added *has* been resolved, so it may be feasible to removed this if required.
|
||||
Beatmap.BindValueChanged(b => ScheduleAfterChildren(() =>
|
||||
{
|
||||
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)
|
||||
|
@ -59,7 +59,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
|
||||
if (online.Ranked.HasValue)
|
||||
{
|
||||
fields.Add(new Field("ranked", online.Ranked.Value, OsuFont.GetFont(weight: FontWeight.Bold)));
|
||||
fields.Add(new Field(online.Status.ToString().ToLowerInvariant(), online.Ranked.Value, OsuFont.GetFont(weight: FontWeight.Bold)));
|
||||
}
|
||||
else if (online.LastUpdated.HasValue)
|
||||
{
|
||||
|
@ -4,9 +4,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
@ -22,6 +24,8 @@ namespace osu.Game.Overlays.Changelog
|
||||
|
||||
private const string listing_string = "listing";
|
||||
|
||||
private Box streamsBackground;
|
||||
|
||||
public ChangelogHeader()
|
||||
{
|
||||
TabControl.AddItem(listing_string);
|
||||
@ -40,6 +44,12 @@ namespace osu.Game.Overlays.Changelog
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
{
|
||||
streamsBackground.Colour = colourProvider.Background5;
|
||||
}
|
||||
|
||||
private ChangelogHeaderTitle title;
|
||||
|
||||
private void showBuild(ValueChangedEvent<APIChangelogBuild> e)
|
||||
@ -72,7 +82,21 @@ namespace osu.Game.Overlays.Changelog
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Streams = new UpdateStreamBadgeArea(),
|
||||
streamsBackground = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Horizontal = 65,
|
||||
Vertical = 20
|
||||
},
|
||||
Child = Streams = new UpdateStreamBadgeArea()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -26,7 +26,6 @@ namespace osu.Game.Overlays.Changelog
|
||||
|
||||
private readonly APIUpdateStream stream;
|
||||
|
||||
private Container fadeContainer;
|
||||
private FillFlowContainer<SpriteText> text;
|
||||
private ExpandingBar expandingBar;
|
||||
|
||||
@ -44,47 +43,39 @@ namespace osu.Game.Overlays.Changelog
|
||||
|
||||
AddRange(new Drawable[]
|
||||
{
|
||||
fadeContainer = new Container
|
||||
text = new FillFlowContainer<SpriteText>
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Margin = new MarginPadding { Top = 6 },
|
||||
Children = new[]
|
||||
{
|
||||
text = new FillFlowContainer<SpriteText>
|
||||
new OsuSpriteText
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Margin = new MarginPadding { Top = 6 },
|
||||
Children = new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = stream.DisplayName,
|
||||
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black),
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = stream.LatestBuild.DisplayVersion,
|
||||
Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular),
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = stream.LatestBuild.Users > 0 ? $"{"user".ToQuantity(stream.LatestBuild.Users, "N0")} online" : null,
|
||||
Font = OsuFont.GetFont(size: 10),
|
||||
Colour = colourProvider.Foreground1
|
||||
},
|
||||
}
|
||||
Text = stream.DisplayName,
|
||||
Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black),
|
||||
},
|
||||
expandingBar = new ExpandingBar
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Colour = stream.Colour,
|
||||
ExpandedSize = 4,
|
||||
CollapsedSize = 2,
|
||||
IsCollapsed = true
|
||||
Text = stream.LatestBuild.DisplayVersion,
|
||||
Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular),
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = stream.LatestBuild.Users > 0 ? $"{"user".ToQuantity(stream.LatestBuild.Users, "N0")} online" : null,
|
||||
Font = OsuFont.GetFont(size: 10),
|
||||
Colour = colourProvider.Foreground1
|
||||
},
|
||||
}
|
||||
},
|
||||
expandingBar = new ExpandingBar
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Colour = stream.Colour,
|
||||
ExpandedSize = 4,
|
||||
CollapsedSize = 2,
|
||||
Expanded = true
|
||||
},
|
||||
new HoverClickSounds()
|
||||
});
|
||||
|
||||
@ -109,38 +100,41 @@ namespace osu.Game.Overlays.Changelog
|
||||
|
||||
private void updateState()
|
||||
{
|
||||
// Expand based on the local state
|
||||
bool shouldExpand = Active.Value || IsHovered;
|
||||
// highlighted regardless if we are hovered
|
||||
bool textHighlighted = IsHovered;
|
||||
bool barExpanded = IsHovered;
|
||||
|
||||
// Expand based on whether no build is selected and the badge area is hovered
|
||||
shouldExpand |= SelectedTab.Value == null && !externalDimRequested;
|
||||
|
||||
if (shouldExpand)
|
||||
if (SelectedTab.Value == null)
|
||||
{
|
||||
expandingBar.Expand();
|
||||
fadeContainer.FadeTo(1, transition_duration);
|
||||
// at listing, all badges are highlighted when user is not hovering any badge.
|
||||
textHighlighted |= !userHoveringArea;
|
||||
barExpanded |= !userHoveringArea;
|
||||
}
|
||||
else
|
||||
{
|
||||
expandingBar.Collapse();
|
||||
fadeContainer.FadeTo(0.5f, transition_duration);
|
||||
// bar is always expanded when active
|
||||
barExpanded |= Active.Value;
|
||||
|
||||
// text is highlighted only when hovered or active (but not if in selection mode)
|
||||
textHighlighted |= Active.Value && !userHoveringArea;
|
||||
}
|
||||
|
||||
text.FadeTo(externalDimRequested && !IsHovered ? 0.5f : 1, transition_duration);
|
||||
expandingBar.Expanded = barExpanded;
|
||||
text.FadeTo(textHighlighted ? 1 : 0.5f, transition_duration, Easing.OutQuint);
|
||||
}
|
||||
|
||||
private bool externalDimRequested;
|
||||
private bool userHoveringArea;
|
||||
|
||||
public void EnableDim()
|
||||
public bool UserHoveringArea
|
||||
{
|
||||
externalDimRequested = true;
|
||||
updateState();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == userHoveringArea)
|
||||
return;
|
||||
|
||||
public void DisableDim()
|
||||
{
|
||||
externalDimRequested = false;
|
||||
updateState();
|
||||
userHoveringArea = value;
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,25 +6,16 @@ using osu.Framework.Input.Events;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Allocation;
|
||||
|
||||
namespace osu.Game.Overlays.Changelog
|
||||
{
|
||||
public class UpdateStreamBadgeArea : TabControl<APIUpdateStream>
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
public UpdateStreamBadgeArea()
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
AddInternal(new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colourProvider.Background5,
|
||||
});
|
||||
}
|
||||
|
||||
public void Populate(List<APIUpdateStream> streams)
|
||||
@ -36,7 +27,7 @@ namespace osu.Game.Overlays.Changelog
|
||||
protected override bool OnHover(HoverEvent e)
|
||||
{
|
||||
foreach (var streamBadge in TabContainer.Children.OfType<UpdateStreamBadge>())
|
||||
streamBadge.EnableDim();
|
||||
streamBadge.UserHoveringArea = true;
|
||||
|
||||
return base.OnHover(e);
|
||||
}
|
||||
@ -44,26 +35,17 @@ namespace osu.Game.Overlays.Changelog
|
||||
protected override void OnHoverLost(HoverLostEvent e)
|
||||
{
|
||||
foreach (var streamBadge in TabContainer.Children.OfType<UpdateStreamBadge>())
|
||||
streamBadge.DisableDim();
|
||||
streamBadge.UserHoveringArea = false;
|
||||
|
||||
base.OnHoverLost(e);
|
||||
}
|
||||
|
||||
protected override TabFillFlowContainer CreateTabFlow()
|
||||
protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer
|
||||
{
|
||||
var flow = base.CreateTabFlow();
|
||||
|
||||
flow.RelativeSizeAxes = Axes.X;
|
||||
flow.AutoSizeAxes = Axes.Y;
|
||||
flow.AllowMultiline = true;
|
||||
flow.Padding = new MarginPadding
|
||||
{
|
||||
Vertical = 20,
|
||||
Horizontal = 85,
|
||||
};
|
||||
|
||||
return flow;
|
||||
}
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
AllowMultiline = true,
|
||||
};
|
||||
|
||||
protected override Dropdown<APIUpdateStream> CreateDropdown() => null;
|
||||
|
||||
|
@ -80,7 +80,7 @@ namespace osu.Game.Overlays.SearchableList
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding { Horizontal = WIDTH_PADDING, Bottom = 50 },
|
||||
Padding = new MarginPadding { Horizontal = 10, Bottom = 50 },
|
||||
Direction = FillDirection.Vertical,
|
||||
},
|
||||
},
|
||||
|
@ -14,8 +14,25 @@ namespace osu.Game.Overlays.Volume
|
||||
public Func<GlobalAction, bool> ActionRequested;
|
||||
public Func<GlobalAction, float, bool, bool> ScrollActionRequested;
|
||||
|
||||
public bool OnPressed(GlobalAction action) => ActionRequested?.Invoke(action) ?? false;
|
||||
public bool OnScroll(GlobalAction action, float amount, bool isPrecise) => ScrollActionRequested?.Invoke(action, amount, isPrecise) ?? false;
|
||||
public bool OnPressed(GlobalAction action)
|
||||
{
|
||||
// if nothing else handles selection actions in the game, it's safe to let volume be adjusted.
|
||||
switch (action)
|
||||
{
|
||||
case GlobalAction.SelectPrevious:
|
||||
action = GlobalAction.IncreaseVolume;
|
||||
break;
|
||||
|
||||
case GlobalAction.SelectNext:
|
||||
action = GlobalAction.DecreaseVolume;
|
||||
break;
|
||||
}
|
||||
|
||||
return ActionRequested?.Invoke(action) ?? false;
|
||||
}
|
||||
|
||||
public bool OnScroll(GlobalAction action, float amount, bool isPrecise) =>
|
||||
ScrollActionRequested?.Invoke(action, amount, isPrecise) ?? false;
|
||||
|
||||
public void OnReleased(GlobalAction action)
|
||||
{
|
||||
|
@ -11,16 +11,18 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Volume
|
||||
{
|
||||
public class VolumeMeter : Container
|
||||
public class VolumeMeter : Container, IKeyBindingHandler<GlobalAction>
|
||||
{
|
||||
private CircularProgress volumeCircle;
|
||||
private CircularProgress volumeCircleGlow;
|
||||
@ -260,5 +262,28 @@ namespace osu.Game.Overlays.Volume
|
||||
{
|
||||
this.ScaleTo(1f, transition_length, Easing.OutExpo);
|
||||
}
|
||||
|
||||
public bool OnPressed(GlobalAction action)
|
||||
{
|
||||
if (!IsHovered)
|
||||
return false;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case GlobalAction.SelectPrevious:
|
||||
adjust(1, false);
|
||||
return true;
|
||||
|
||||
case GlobalAction.SelectNext:
|
||||
adjust(-1, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnReleased(GlobalAction action)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Caching;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Layout;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
|
||||
@ -19,11 +20,13 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
[Resolved]
|
||||
private IScrollingInfo scrollingInfo { get; set; }
|
||||
|
||||
private readonly Cached initialStateCache = new Cached();
|
||||
private readonly LayoutValue initialStateCache = new LayoutValue(Invalidation.RequiredParentSizeToFit | Invalidation.DrawInfo);
|
||||
|
||||
public ScrollingHitObjectContainer()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
AddLayout(initialStateCache);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
@ -55,14 +58,6 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
return result;
|
||||
}
|
||||
|
||||
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||
{
|
||||
if ((invalidation & (Invalidation.RequiredParentSizeToFit | Invalidation.DrawInfo)) > 0)
|
||||
initialStateCache.Invalidate();
|
||||
|
||||
return base.Invalidate(invalidation, source, shallPropagate);
|
||||
}
|
||||
|
||||
private float scrollLength;
|
||||
|
||||
protected override void Update()
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Caching;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Layout;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osuTK;
|
||||
@ -51,7 +51,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
[Resolved]
|
||||
private BindableBeatDivisor beatDivisor { get; set; }
|
||||
|
||||
private readonly Cached gridCache = new Cached();
|
||||
private readonly LayoutValue gridCache = new LayoutValue(Invalidation.RequiredParentSizeToFit);
|
||||
private readonly double? endTime;
|
||||
|
||||
/// <summary>
|
||||
@ -67,6 +67,8 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
StartTime = startTime;
|
||||
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
AddLayout(gridCache);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
@ -92,14 +94,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
gridCache.Invalidate();
|
||||
}
|
||||
|
||||
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||
{
|
||||
if ((invalidation & Invalidation.RequiredParentSizeToFit) > 0)
|
||||
gridCache.Invalidate();
|
||||
|
||||
return base.Invalidate(invalidation, source, shallPropagate);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
@ -150,7 +150,7 @@ namespace osu.Game.Screens.Menu
|
||||
frequencyAmplitudes[i] = 0;
|
||||
}
|
||||
|
||||
Invalidate(Invalidation.DrawNode, shallPropagate: false);
|
||||
Invalidate(Invalidation.DrawNode);
|
||||
}
|
||||
|
||||
protected override DrawNode CreateDrawNode() => new VisualisationDrawNode(this);
|
||||
|
@ -246,10 +246,11 @@ namespace osu.Game.Screens.Multi
|
||||
FillMode = FillMode.Fill,
|
||||
Beatmap = { BindTarget = Beatmap }
|
||||
},
|
||||
new Container
|
||||
new FillFlowContainer
|
||||
{
|
||||
Depth = -1,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
// This makes the gradient not be perfectly horizontal, but diagonal at a ~40° angle
|
||||
Shear = new Vector2(0.8f, 0),
|
||||
Alpha = 0.5f,
|
||||
@ -259,7 +260,6 @@ namespace osu.Game.Screens.Multi
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
Width = 0.4f,
|
||||
},
|
||||
@ -267,26 +267,20 @@ namespace osu.Game.Screens.Multi
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientHorizontal(Color4.Black, new Color4(0f, 0f, 0f, 0.9f)),
|
||||
Width = 0.05f,
|
||||
X = 0.4f,
|
||||
},
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.9f), new Color4(0f, 0f, 0f, 0.1f)),
|
||||
Width = 0.2f,
|
||||
X = 0.45f,
|
||||
},
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.1f), new Color4(0, 0, 0, 0)),
|
||||
Width = 0.05f,
|
||||
X = 0.65f,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -123,6 +123,10 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
public void Restart()
|
||||
{
|
||||
// The Reset() call below causes speed adjustments to be reset in an async context, leading to deadlocks.
|
||||
// The deadlock can be prevented by resetting the track synchronously before entering the async context.
|
||||
track.ResetSpeedAdjustments();
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
track.Reset();
|
||||
|
@ -12,7 +12,6 @@ using osu.Game.Graphics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osuTK.Input;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Input.Bindings;
|
||||
@ -204,35 +203,24 @@ namespace osu.Game.Screens.Play
|
||||
InternalButtons[selectionIndex].Selected.Value = true;
|
||||
}
|
||||
|
||||
protected override bool OnKeyDown(KeyDownEvent e)
|
||||
{
|
||||
if (!e.Repeat)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Up:
|
||||
if (selectionIndex == -1 || selectionIndex == 0)
|
||||
setSelected(InternalButtons.Count - 1);
|
||||
else
|
||||
setSelected(selectionIndex - 1);
|
||||
return true;
|
||||
|
||||
case Key.Down:
|
||||
if (selectionIndex == -1 || selectionIndex == InternalButtons.Count - 1)
|
||||
setSelected(0);
|
||||
else
|
||||
setSelected(selectionIndex + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnKeyDown(e);
|
||||
}
|
||||
|
||||
public bool OnPressed(GlobalAction action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case GlobalAction.SelectPrevious:
|
||||
if (selectionIndex == -1 || selectionIndex == 0)
|
||||
setSelected(InternalButtons.Count - 1);
|
||||
else
|
||||
setSelected(selectionIndex - 1);
|
||||
return true;
|
||||
|
||||
case GlobalAction.SelectNext:
|
||||
if (selectionIndex == -1 || selectionIndex == InternalButtons.Count - 1)
|
||||
setSelected(0);
|
||||
else
|
||||
setSelected(selectionIndex + 1);
|
||||
return true;
|
||||
|
||||
case GlobalAction.Back:
|
||||
BackAction.Invoke();
|
||||
return true;
|
||||
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Caching;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@ -14,6 +13,7 @@ using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Layout;
|
||||
using osu.Framework.Threading;
|
||||
|
||||
namespace osu.Game.Screens.Play
|
||||
@ -22,6 +22,11 @@ namespace osu.Game.Screens.Play
|
||||
{
|
||||
private BufferedContainer<Column> columns;
|
||||
|
||||
public SquareGraph()
|
||||
{
|
||||
AddLayout(layout);
|
||||
}
|
||||
|
||||
public int ColumnCount => columns?.Children.Count ?? 0;
|
||||
|
||||
private int progress;
|
||||
@ -68,14 +73,7 @@ namespace osu.Game.Screens.Play
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||
{
|
||||
if ((invalidation & Invalidation.DrawSize) > 0)
|
||||
layout.Invalidate();
|
||||
return base.Invalidate(invalidation, source, shallPropagate);
|
||||
}
|
||||
|
||||
private readonly Cached layout = new Cached();
|
||||
private readonly LayoutValue layout = new LayoutValue(Invalidation.DrawSize);
|
||||
private ScheduledDelegate scheduledCreate;
|
||||
|
||||
protected override void Update()
|
||||
|
@ -16,15 +16,17 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Caching;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Screens.Select.Carousel;
|
||||
|
||||
namespace osu.Game.Screens.Select
|
||||
{
|
||||
public class BeatmapCarousel : CompositeDrawable
|
||||
public class BeatmapCarousel : CompositeDrawable, IKeyBindingHandler<GlobalAction>
|
||||
{
|
||||
private const float bleed_top = FilterControl.HEIGHT;
|
||||
private const float bleed_bottom = Footer.HEIGHT;
|
||||
@ -435,41 +437,38 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
protected override bool OnKeyDown(KeyDownEvent e)
|
||||
{
|
||||
// allow for controlling volume when alt is held.
|
||||
// this is required as the VolumeControlReceptor uses OnPressed, which is
|
||||
// executed after all OnKeyDown events.
|
||||
if (e.AltPressed)
|
||||
return base.OnKeyDown(e);
|
||||
|
||||
int direction = 0;
|
||||
bool skipDifficulties = false;
|
||||
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Up:
|
||||
direction = -1;
|
||||
break;
|
||||
|
||||
case Key.Down:
|
||||
direction = 1;
|
||||
break;
|
||||
|
||||
case Key.Left:
|
||||
direction = -1;
|
||||
skipDifficulties = true;
|
||||
break;
|
||||
SelectNext(-1, true);
|
||||
return true;
|
||||
|
||||
case Key.Right:
|
||||
direction = 1;
|
||||
skipDifficulties = true;
|
||||
break;
|
||||
SelectNext(1, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (direction == 0)
|
||||
return base.OnKeyDown(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
SelectNext(direction, skipDifficulties);
|
||||
return true;
|
||||
public bool OnPressed(GlobalAction action)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case GlobalAction.SelectNext:
|
||||
SelectNext(1, false);
|
||||
return true;
|
||||
|
||||
case GlobalAction.SelectPrevious:
|
||||
SelectNext(-1, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnReleased(GlobalAction action)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
|
@ -159,11 +159,11 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
Origin = Anchor.Centre,
|
||||
FillMode = FillMode.Fill,
|
||||
},
|
||||
// Todo: This should be a fill flow, but has invalidation issues (see https://github.com/ppy/osu-framework/issues/223)
|
||||
new Container
|
||||
new FillFlowContainer
|
||||
{
|
||||
Depth = -1,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
// This makes the gradient not be perfectly horizontal, but diagonal at a ~40° angle
|
||||
Shear = new Vector2(0.8f, 0),
|
||||
Alpha = 0.5f,
|
||||
@ -173,7 +173,6 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
Width = 0.4f,
|
||||
},
|
||||
@ -181,26 +180,20 @@ namespace osu.Game.Screens.Select.Carousel
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientHorizontal(Color4.Black, new Color4(0f, 0f, 0f, 0.9f)),
|
||||
Width = 0.05f,
|
||||
X = 0.4f,
|
||||
},
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.9f), new Color4(0f, 0f, 0f, 0.1f)),
|
||||
Width = 0.2f,
|
||||
X = 0.45f,
|
||||
},
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.1f), new Color4(0, 0, 0, 0)),
|
||||
Width = 0.05f,
|
||||
X = 0.65f,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user