mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 21:02:55 +08:00
Merge remote-tracking branch 'origin/master' into osu-default-bindings
This commit is contained in:
commit
2d8e2dc5f7
@ -2,6 +2,9 @@ clone_depth: 1
|
||||
version: '{branch}-{build}'
|
||||
image: Visual Studio 2017
|
||||
configuration: Debug
|
||||
cache:
|
||||
- C:\ProgramData\chocolatey\bin -> appveyor.yml
|
||||
- C:\ProgramData\chocolatey\lib -> appveyor.yml
|
||||
install:
|
||||
- cmd: git submodule update --init --recursive --depth=5
|
||||
- cmd: choco install resharper-clt -y
|
||||
|
@ -12,6 +12,7 @@ using osu.Framework.Platform;
|
||||
using osu.Game;
|
||||
using OpenTK.Input;
|
||||
using Microsoft.Win32;
|
||||
using osu.Desktop.Updater;
|
||||
using osu.Framework.Platform.Windows;
|
||||
|
||||
namespace osu.Desktop
|
||||
@ -38,6 +39,52 @@ namespace osu.Desktop
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
if (!noVersionOverlay)
|
||||
{
|
||||
LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v =>
|
||||
{
|
||||
Add(v);
|
||||
v.State = Visibility.Visible;
|
||||
});
|
||||
|
||||
#if NET_FRAMEWORK
|
||||
Add(new SquirrelUpdateManager());
|
||||
#else
|
||||
Add(new SimpleUpdateManager());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetHost(GameHost host)
|
||||
{
|
||||
base.SetHost(host);
|
||||
var desktopWindow = host.Window as DesktopGameWindow;
|
||||
if (desktopWindow != null)
|
||||
{
|
||||
desktopWindow.CursorState |= CursorState.Hidden;
|
||||
|
||||
desktopWindow.SetIconFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico"));
|
||||
desktopWindow.Title = Name;
|
||||
|
||||
desktopWindow.FileDrop += fileDrop;
|
||||
}
|
||||
}
|
||||
|
||||
private void fileDrop(object sender, FileDropEventArgs e)
|
||||
{
|
||||
var filePaths = new[] { e.FileName };
|
||||
|
||||
var firstExtension = Path.GetExtension(filePaths.First());
|
||||
|
||||
if (filePaths.Any(f => Path.GetExtension(f) != firstExtension)) return;
|
||||
|
||||
Task.Factory.StartNew(() => Import(filePaths), TaskCreationOptions.LongRunning);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A method of accessing an osu-stable install in a controlled fashion.
|
||||
/// </summary>
|
||||
@ -77,45 +124,5 @@ namespace osu.Desktop
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
if (!noVersionOverlay)
|
||||
{
|
||||
LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v =>
|
||||
{
|
||||
Add(v);
|
||||
v.State = Visibility.Visible;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetHost(GameHost host)
|
||||
{
|
||||
base.SetHost(host);
|
||||
var desktopWindow = host.Window as DesktopGameWindow;
|
||||
if (desktopWindow != null)
|
||||
{
|
||||
desktopWindow.CursorState |= CursorState.Hidden;
|
||||
|
||||
desktopWindow.SetIconFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico"));
|
||||
desktopWindow.Title = Name;
|
||||
|
||||
desktopWindow.FileDrop += fileDrop;
|
||||
}
|
||||
}
|
||||
|
||||
private void fileDrop(object sender, FileDropEventArgs e)
|
||||
{
|
||||
var filePaths = new[] { e.FileName };
|
||||
|
||||
var firstExtension = Path.GetExtension(filePaths.First());
|
||||
|
||||
if (filePaths.Any(f => Path.GetExtension(f) != firstExtension)) return;
|
||||
|
||||
Task.Factory.StartNew(() => Import(filePaths), TaskCreationOptions.LongRunning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,10 +91,6 @@ namespace osu.Desktop.Overlays
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if NET_FRAMEWORK
|
||||
Add(new SquirrelUpdateManager());
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.IPC;
|
||||
|
||||
#if NET_FRAMEWORK
|
||||
using System.Runtime;
|
||||
#endif
|
||||
@ -18,10 +19,7 @@ namespace osu.Desktop
|
||||
[STAThread]
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
// required to initialise native SQLite libraries on some platforms.
|
||||
|
||||
if (!RuntimeInfo.IsMono)
|
||||
useMulticoreJit();
|
||||
useMultiCoreJit();
|
||||
|
||||
// Back up the cwd before DesktopGameHost changes it
|
||||
var cwd = Environment.CurrentDirectory;
|
||||
@ -54,7 +52,7 @@ namespace osu.Desktop
|
||||
}
|
||||
}
|
||||
|
||||
private static void useMulticoreJit()
|
||||
private static void useMultiCoreJit()
|
||||
{
|
||||
#if NET_FRAMEWORK
|
||||
var directory = Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Profiles"));
|
||||
|
103
osu.Desktop/Updater/SimpleUpdateManager.cs
Normal file
103
osu.Desktop/Updater/SimpleUpdateManager.cs
Normal file
@ -0,0 +1,103 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.IO.Network;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
|
||||
namespace osu.Desktop.Updater
|
||||
{
|
||||
/// <summary>
|
||||
/// An update manager that shows notifications if a newer release is detected.
|
||||
/// Installation is left up to the user.
|
||||
/// </summary>
|
||||
internal class SimpleUpdateManager : CompositeDrawable
|
||||
{
|
||||
private NotificationOverlay notificationOverlay;
|
||||
private string version;
|
||||
private GameHost host;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(NotificationOverlay notification, OsuGameBase game, GameHost host)
|
||||
{
|
||||
notificationOverlay = notification;
|
||||
|
||||
this.host = host;
|
||||
version = game.Version;
|
||||
|
||||
if (game.IsDeployedBuild)
|
||||
Schedule(() => Task.Run(() => checkForUpdateAsync()));
|
||||
}
|
||||
|
||||
private async void checkForUpdateAsync()
|
||||
{
|
||||
var releases = new JsonWebRequest<GitHubRelease>("https://api.github.com/repos/ppy/osu/releases/latest");
|
||||
await releases.PerformAsync();
|
||||
|
||||
var latest = releases.ResponseObject;
|
||||
|
||||
if (latest.TagName != version)
|
||||
{
|
||||
notificationOverlay.Post(new SimpleNotification
|
||||
{
|
||||
Text = $"A newer release of osu! has been found ({version} → {latest.TagName}).\n\n"
|
||||
+ "Click here to download the new version, which can be installed over the top of your existing installation",
|
||||
Icon = FontAwesome.fa_upload,
|
||||
Activated = () =>
|
||||
{
|
||||
host.OpenUrlExternally(getBestUrl(latest));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private string getBestUrl(GitHubRelease release)
|
||||
{
|
||||
GitHubAsset bestAsset = null;
|
||||
|
||||
switch (RuntimeInfo.OS)
|
||||
{
|
||||
case RuntimeInfo.Platform.Windows:
|
||||
bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".exe"));
|
||||
break;
|
||||
case RuntimeInfo.Platform.MacOsx:
|
||||
bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".app.zip"));
|
||||
break;
|
||||
}
|
||||
|
||||
return bestAsset?.BrowserDownloadUrl ?? release.HtmlUrl;
|
||||
}
|
||||
|
||||
public class GitHubRelease
|
||||
{
|
||||
[JsonProperty("html_url")]
|
||||
public string HtmlUrl { get; set; }
|
||||
|
||||
[JsonProperty("tag_name")]
|
||||
public string TagName { get; set; }
|
||||
|
||||
[JsonProperty("assets")]
|
||||
public List<GitHubAsset> Assets { get; set; }
|
||||
}
|
||||
|
||||
public class GitHubAsset
|
||||
{
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[JsonProperty("browser_download_url")]
|
||||
public string BrowserDownloadUrl { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
|
||||
#if NET_FRAMEWORK
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
@ -16,7 +17,7 @@ using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using Squirrel;
|
||||
|
||||
namespace osu.Desktop.Overlays
|
||||
namespace osu.Desktop.Updater
|
||||
{
|
||||
public class SquirrelUpdateManager : Component
|
||||
{
|
||||
@ -35,7 +36,7 @@ namespace osu.Desktop.Overlays
|
||||
notificationOverlay = notification;
|
||||
|
||||
if (game.IsDeployedBuild)
|
||||
Schedule(() => checkForUpdateAsync());
|
||||
Schedule(() => Task.Run(() => checkForUpdateAsync()));
|
||||
}
|
||||
|
||||
private async void checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null)
|
@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
}
|
||||
|
||||
public void ToggleHyperDash(bool status) => MovableCatcher.SetHyperdashState(status ? 2 : 1);
|
||||
public void ToggleHyperDash(bool status) => MovableCatcher.SetHyperDashState(status ? 2 : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,9 @@ using osu.Game.Rulesets.Catch.Objects;
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseHyperdash : Game.Tests.Visual.TestCasePlayer
|
||||
public class TestCaseHyperDash : Game.Tests.Visual.TestCasePlayer
|
||||
{
|
||||
public TestCaseHyperdash()
|
||||
public TestCaseHyperDash()
|
||||
: base(new CatchRuleset())
|
||||
{
|
||||
}
|
@ -61,12 +61,12 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
return new CatchDifficultyAttributes(mods, 0);
|
||||
|
||||
// this is the same as osu!, so there's potential to share the implementation... maybe
|
||||
double preEmpt = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate;
|
||||
double preempt = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate;
|
||||
double starRating = Math.Sqrt(calculateDifficulty(difficultyHitObjects, timeRate)) * star_scaling_factor;
|
||||
|
||||
return new CatchDifficultyAttributes(mods, starRating)
|
||||
{
|
||||
ApproachRate = preEmpt > 1200.0 ? -(preEmpt - 1800.0) / 120.0 : -(preEmpt - 1200.0) / 150.0 + 5.0,
|
||||
ApproachRate = preempt > 1200.0 ? -(preempt - 1800.0) / 120.0 : -(preempt - 1200.0) / 150.0 + 5.0,
|
||||
MaxCombo = difficultyHitObjects.Count
|
||||
};
|
||||
}
|
||||
|
@ -255,11 +255,11 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
double positionDifference = target.X * CatchPlayfield.BASE_WIDTH - catcherPosition;
|
||||
double velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0);
|
||||
|
||||
SetHyperdashState(Math.Abs(velocity), target.X);
|
||||
SetHyperDashState(Math.Abs(velocity), target.X);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetHyperdashState();
|
||||
SetHyperDashState();
|
||||
}
|
||||
|
||||
return validCatch;
|
||||
@ -270,18 +270,18 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
private float hyperDashTargetPosition;
|
||||
|
||||
/// <summary>
|
||||
/// Whether we are hypderdashing or not.
|
||||
/// Whether we are hyper-dashing or not.
|
||||
/// </summary>
|
||||
public bool HyperDashing => hyperDashModifier != 1;
|
||||
|
||||
/// <summary>
|
||||
/// Set hyperdash state.
|
||||
/// Set hyper-dash state.
|
||||
/// </summary>
|
||||
/// <param name="modifier">The speed multiplier. If this is less or equals to 1, this catcher will be non-hyperdashing state.</param>
|
||||
/// <param name="targetPosition">When this catcher crosses this position, this catcher ends hyperdashing.</param>
|
||||
public void SetHyperdashState(double modifier = 1, float targetPosition = -1)
|
||||
/// <param name="modifier">The speed multiplier. If this is less or equals to 1, this catcher will be non-hyper-dashing state.</param>
|
||||
/// <param name="targetPosition">When this catcher crosses this position, this catcher ends hyper-dashing.</param>
|
||||
public void SetHyperDashState(double modifier = 1, float targetPosition = -1)
|
||||
{
|
||||
const float hyperdash_transition_length = 180;
|
||||
const float hyper_dash_transition_length = 180;
|
||||
|
||||
bool previouslyHyperDashing = HyperDashing;
|
||||
if (modifier <= 1 || X == targetPosition)
|
||||
@ -291,8 +291,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
if (previouslyHyperDashing)
|
||||
{
|
||||
this.FadeColour(Color4.White, hyperdash_transition_length, Easing.OutQuint);
|
||||
this.FadeTo(1, hyperdash_transition_length, Easing.OutQuint);
|
||||
this.FadeColour(Color4.White, hyper_dash_transition_length, Easing.OutQuint);
|
||||
this.FadeTo(1, hyper_dash_transition_length, Easing.OutQuint);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -303,8 +303,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
if (!previouslyHyperDashing)
|
||||
{
|
||||
this.FadeColour(Color4.OrangeRed, hyperdash_transition_length, Easing.OutQuint);
|
||||
this.FadeTo(0.2f, hyperdash_transition_length, Easing.OutQuint);
|
||||
this.FadeColour(Color4.OrangeRed, hyper_dash_transition_length, Easing.OutQuint);
|
||||
this.FadeTo(0.2f, hyper_dash_transition_length, Easing.OutQuint);
|
||||
Trail = true;
|
||||
}
|
||||
}
|
||||
@ -370,7 +370,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
hyperDashDirection < 0 && hyperDashTargetPosition > X)
|
||||
{
|
||||
X = hyperDashTargetPosition;
|
||||
SetHyperdashState();
|
||||
SetHyperDashState();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,9 +21,9 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
dependencies.CacheAs<IScrollingInfo>(new ScrollingInfo { Direction = { Value = direction }});
|
||||
return dependencies;
|
||||
}
|
||||
|
@ -137,9 +137,9 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
};
|
||||
}
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
dependencies.CacheAs<IBindable<ManiaAction>>(new Bindable<ManiaAction>());
|
||||
return dependencies;
|
||||
}
|
||||
|
@ -19,9 +19,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, IBeatmap originalBeatmap)
|
||||
: base(random, hitObject, beatmap, new Pattern(), originalBeatmap)
|
||||
{
|
||||
var endtimeData = HitObject as IHasEndTime;
|
||||
|
||||
endTime = endtimeData?.EndTime ?? 0;
|
||||
endTime = (HitObject as IHasEndTime)?.EndTime ?? 0;
|
||||
}
|
||||
|
||||
public override IEnumerable<Pattern> Generate()
|
||||
|
@ -19,14 +19,14 @@ namespace osu.Game.Rulesets.Mania
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ManiaConfigManager config)
|
||||
private void load()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SettingsEnumDropdown<ManiaScrollingDirection>
|
||||
{
|
||||
LabelText = "Scrolling direction",
|
||||
Bindable = config.GetBindable<ManiaScrollingDirection>(ManiaSetting.ScrollDirection)
|
||||
Bindable = ((ManiaConfigManager)Config).GetBindable<ManiaScrollingDirection>(ManiaSetting.ScrollDirection)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -118,9 +118,9 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
}
|
||||
}
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
dependencies.CacheAs<IBindable<ManiaAction>>(Action);
|
||||
return dependencies;
|
||||
}
|
||||
|
@ -70,19 +70,19 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(ManiaConfigManager config)
|
||||
private void load()
|
||||
{
|
||||
BarLines.ForEach(Playfield.Add);
|
||||
|
||||
config.BindWith(ManiaSetting.ScrollDirection, configDirection);
|
||||
((ManiaConfigManager)Config).BindWith(ManiaSetting.ScrollDirection, configDirection);
|
||||
configDirection.BindValueChanged(d => scrollingInfo.Direction.Value = (ScrollingDirection)d, true);
|
||||
}
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
dependencies.CacheAs<IScrollingInfo>(scrollingInfo = new ScrollingInfo());
|
||||
return dependencies;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
public struct ConvertValue : IEquatable<ConvertValue>
|
||||
{
|
||||
/// <summary>
|
||||
/// A sane value to account for osu!stable using ints everwhere.
|
||||
/// A sane value to account for osu!stable using <see cref="int"/>s everywhere.
|
||||
/// </summary>
|
||||
private const double conversion_lenience = 2;
|
||||
|
||||
|
@ -61,19 +61,19 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
||||
double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
|
||||
double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;
|
||||
|
||||
// Todo: These int casts are temporary to achieve 1:1 results with osu!stable, and should be remoevd in the future
|
||||
// Todo: These int casts are temporary to achieve 1:1 results with osu!stable, and should be removed in the future
|
||||
double hitWindowGreat = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / timeRate;
|
||||
double preEmpt = (int)BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate;
|
||||
double preempt = (int)BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate;
|
||||
|
||||
int maxCombo = beatmap.HitObjects.Count();
|
||||
// Add the ticks + tail of the slider. 1 is subtracted because the "headcircle" would be counted twice (once for the slider itself in the line above)
|
||||
// Add the ticks + tail of the slider. 1 is subtracted because the head circle would be counted twice (once for the slider itself in the line above)
|
||||
maxCombo += beatmap.HitObjects.OfType<Slider>().Sum(s => s.NestedHitObjects.Count - 1);
|
||||
|
||||
return new OsuDifficultyAttributes(mods, starRating)
|
||||
{
|
||||
AimStrain = aimRating,
|
||||
SpeedStrain = speedRating,
|
||||
ApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5,
|
||||
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
|
||||
OverallDifficulty = (80 - hitWindowGreat) / 6,
|
||||
MaxCombo = maxCombo
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
|
||||
public override void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||
{
|
||||
void adjustFadeIn(OsuHitObject h) => h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier;
|
||||
void adjustFadeIn(OsuHitObject h) => h.TimeFadeIn = h.TimePreempt * fade_in_duration_multiplier;
|
||||
|
||||
foreach (var d in drawables.OfType<DrawableOsuHitObject>())
|
||||
{
|
||||
@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
|
||||
var h = d.HitObject;
|
||||
|
||||
var fadeOutStartTime = h.StartTime - h.TimePreempt + h.TimeFadein;
|
||||
var fadeOutStartTime = h.StartTime - h.TimePreempt + h.TimeFadeIn;
|
||||
var fadeOutDuration = h.TimePreempt * fade_out_duration_multiplier;
|
||||
|
||||
// new duration from completed fade in to end (before fading out)
|
||||
|
@ -96,12 +96,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
||||
|
||||
using (fp.BeginAbsoluteSequence(fadeInTime))
|
||||
{
|
||||
fp.FadeIn(currHitObject.TimeFadein);
|
||||
fp.ScaleTo(1, currHitObject.TimeFadein, Easing.Out);
|
||||
fp.FadeIn(currHitObject.TimeFadeIn);
|
||||
fp.ScaleTo(1, currHitObject.TimeFadeIn, Easing.Out);
|
||||
|
||||
fp.MoveTo(pointEndPosition, currHitObject.TimeFadein, Easing.Out);
|
||||
fp.MoveTo(pointEndPosition, currHitObject.TimeFadeIn, Easing.Out);
|
||||
|
||||
fp.Delay(fadeOutTime - fadeInTime).FadeOut(currHitObject.TimeFadein);
|
||||
fp.Delay(fadeOutTime - fadeInTime).FadeOut(currHitObject.TimeFadeIn);
|
||||
}
|
||||
|
||||
fp.Expire(true);
|
||||
|
@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
base.UpdatePreemptState();
|
||||
|
||||
ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadein * 2, HitObject.TimePreempt));
|
||||
ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadeIn * 2, HitObject.TimePreempt));
|
||||
ApproachCircle.ScaleTo(1.1f, HitObject.TimePreempt);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
AccentColour = skin.GetValue<SkinConfiguration, Color4>(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : (Color4?)null) ?? Color4.White;
|
||||
}
|
||||
|
||||
protected virtual void UpdatePreemptState() => this.FadeIn(HitObject.TimeFadein);
|
||||
protected virtual void UpdatePreemptState() => this.FadeIn(HitObject.TimeFadeIn);
|
||||
|
||||
protected virtual void UpdateCurrentState(ArmedState state)
|
||||
{
|
||||
|
@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
Disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton);
|
||||
if (!spmCounter.IsPresent && Disc.Tracking)
|
||||
spmCounter.FadeIn(HitObject.TimeFadein);
|
||||
spmCounter.FadeIn(HitObject.TimeFadeIn);
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||
var spanProgress = slider.ProgressAt(completionProgress);
|
||||
|
||||
double start = 0;
|
||||
double end = SnakingIn ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / slider.TimeFadein, 0, 1) : 1;
|
||||
double end = SnakingIn ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / slider.TimeFadeIn, 0, 1) : 1;
|
||||
|
||||
if (span >= slider.SpanCount() - 1)
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
public event Action<Vector2> PositionChanged;
|
||||
|
||||
public double TimePreempt = 600;
|
||||
public double TimeFadein = 400;
|
||||
public double TimeFadeIn = 400;
|
||||
|
||||
private Vector2 position;
|
||||
|
||||
@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
||||
|
||||
TimePreempt = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450);
|
||||
TimeFadein = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1200, 800, 300);
|
||||
TimeFadeIn = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1200, 800, 300);
|
||||
|
||||
Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
// This is so on repeats ticks don't appear too late to be visually processed by the player.
|
||||
offset = 200;
|
||||
else
|
||||
offset = TimeFadein * 0.66f;
|
||||
offset = TimeFadeIn * 0.66f;
|
||||
|
||||
TimePreempt = (StartTime - SpanStartTime) / 2 + offset;
|
||||
}
|
||||
|
@ -222,10 +222,10 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
{
|
||||
var hitObjects = decoder.Decode(stream).HitObjects;
|
||||
|
||||
Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[0]).Name);
|
||||
Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[1]).Name);
|
||||
Assert.AreEqual("hitnormal2", getTestableSampleInfo(hitObjects[2]).Name);
|
||||
Assert.AreEqual("hitnormal", getTestableSampleInfo(hitObjects[3]).Name);
|
||||
Assert.AreEqual("normal-hitnormal", getTestableSampleInfo(hitObjects[0]).LookupNames.First());
|
||||
Assert.AreEqual("normal-hitnormal", getTestableSampleInfo(hitObjects[1]).LookupNames.First());
|
||||
Assert.AreEqual("normal-hitnormal2", getTestableSampleInfo(hitObjects[2]).LookupNames.First());
|
||||
Assert.AreEqual("normal-hitnormal", getTestableSampleInfo(hitObjects[3]).LookupNames.First());
|
||||
}
|
||||
|
||||
SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(new SampleInfo { Name = "hitnormal" });
|
||||
@ -242,7 +242,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
|
||||
Assert.AreEqual("hit_1.wav", hitObjects[0].Samples[0].LookupNames.First());
|
||||
Assert.AreEqual("hit_2.wav", hitObjects[1].Samples[0].LookupNames.First());
|
||||
Assert.AreEqual("hitnormal2", getTestableSampleInfo(hitObjects[2]).Name);
|
||||
Assert.AreEqual("normal-hitnormal2", getTestableSampleInfo(hitObjects[2]).LookupNames.First());
|
||||
Assert.AreEqual("hit_1.wav", hitObjects[3].Samples[0].LookupNames.First());
|
||||
}
|
||||
|
||||
|
@ -110,8 +110,8 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
private void testInfoLabels(int expectedCount)
|
||||
{
|
||||
AddAssert("check infolabels exists", () => infoWedge.Info.InfoLabelContainer.Children.Any());
|
||||
AddAssert("check infolabels count", () => infoWedge.Info.InfoLabelContainer.Children.Count == expectedCount);
|
||||
AddAssert("check info labels exists", () => infoWedge.Info.InfoLabelContainer.Children.Any());
|
||||
AddAssert("check info labels count", () => infoWedge.Info.InfoLabelContainer.Children.Count == expectedCount);
|
||||
}
|
||||
|
||||
private void testNullBeatmap()
|
||||
@ -121,7 +121,7 @@ namespace osu.Game.Tests.Visual
|
||||
AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == Beatmap.Default.BeatmapInfo.Metadata.Title);
|
||||
AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == Beatmap.Default.BeatmapInfo.Metadata.Artist);
|
||||
AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any());
|
||||
AddAssert("check no infolabels", () => !infoWedge.Info.InfoLabelContainer.Children.Any());
|
||||
AddAssert("check no info labels", () => !infoWedge.Info.InfoLabelContainer.Children.Any());
|
||||
}
|
||||
|
||||
private void selectBeatmap(IBeatmap b)
|
||||
|
@ -1,6 +1,9 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
@ -13,6 +16,13 @@ namespace osu.Game.Tests.Visual
|
||||
[TestFixture]
|
||||
public class TestCaseButtonSystem : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(ButtonSystem),
|
||||
typeof(ButtonArea),
|
||||
typeof(Button)
|
||||
};
|
||||
|
||||
public TestCaseButtonSystem()
|
||||
{
|
||||
OsuLogo logo;
|
||||
@ -30,6 +40,9 @@ namespace osu.Game.Tests.Visual
|
||||
};
|
||||
|
||||
buttons.SetOsuLogo(logo);
|
||||
|
||||
foreach (var s in Enum.GetValues(typeof(ButtonSystemState)).OfType<ButtonSystemState>().Skip(1))
|
||||
AddStep($"State to {s}", () => buttons.State = s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
28
osu.Game.Tests/Visual/TestCaseDisclaimer.cs
Normal file
28
osu.Game.Tests/Visual/TestCaseDisclaimer.cs
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Screens.Menu;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual
|
||||
{
|
||||
public class TestCaseDisclaimer : OsuTestCase
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
new Disclaimer()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -114,7 +114,7 @@ namespace osu.Game.Tests.Visual
|
||||
testMultiplierTextColour(noFailMod, modSelect.LowMultiplierColour);
|
||||
testMultiplierTextColour(hiddenMod, modSelect.HighMultiplierColour);
|
||||
|
||||
testUnimplmentedMod(autoPilotMod);
|
||||
testUnimplementedMod(autoPilotMod);
|
||||
}
|
||||
|
||||
private void testManiaMods(ManiaRuleset ruleset)
|
||||
@ -154,7 +154,7 @@ namespace osu.Game.Tests.Visual
|
||||
checkNotSelected(mod);
|
||||
}
|
||||
|
||||
private void testUnimplmentedMod(Mod mod)
|
||||
private void testUnimplementedMod(Mod mod)
|
||||
{
|
||||
selectNext(mod);
|
||||
checkNotSelected(mod);
|
||||
|
@ -88,7 +88,7 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
private class TestOnScreenDisplay : OnScreenDisplay
|
||||
{
|
||||
protected override void Display(Drawable toDisplay) => toDisplay.FadeIn().ResizeHeightTo(110);
|
||||
protected override void DisplayTemporarily(Drawable toDisplay) => toDisplay.FadeIn().ResizeHeightTo(110);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Menu;
|
||||
using OpenTK.Graphics;
|
||||
@ -23,19 +22,15 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
public TestCaseOsuGame()
|
||||
{
|
||||
var rateAdjustClock = new StopwatchClock(true);
|
||||
var framedClock = new FramedClock(rateAdjustClock);
|
||||
framedClock.ProcessFrame();
|
||||
|
||||
Add(new Box
|
||||
Children = new Drawable[]
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
});
|
||||
|
||||
Add(new Loader());
|
||||
|
||||
AddSliderStep("Playback speed", 0.0, 2.0, 1, v => rateAdjustClock.Rate = v);
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
new Loader()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,9 +14,9 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
private readonly PreviewTrackManager trackManager = new TestPreviewTrackManager();
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
dependencies.CacheAs(trackManager);
|
||||
dependencies.CacheAs<IPreviewTrackOwner>(this);
|
||||
return dependencies;
|
||||
@ -101,9 +101,9 @@ namespace osu.Game.Tests.Visual
|
||||
AddInternal(track);
|
||||
}
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
dependencies.CacheAs<IPreviewTrackOwner>(this);
|
||||
return dependencies;
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ namespace osu.Game.Tests.Visual
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(ToolbarButton),
|
||||
typeof(ToolbarModeSelector),
|
||||
typeof(ToolbarModeButton),
|
||||
typeof(ToolbarRulesetSelector),
|
||||
typeof(ToolbarRulesetButton),
|
||||
typeof(ToolbarNotificationButton),
|
||||
};
|
||||
|
||||
|
@ -53,7 +53,6 @@ namespace osu.Game.Tests.Visual
|
||||
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg",
|
||||
JoinDate = DateTimeOffset.Now.AddDays(-1),
|
||||
LastVisit = DateTimeOffset.Now,
|
||||
Age = 1,
|
||||
ProfileOrder = new[] { "me" },
|
||||
Statistics = new UserStatistics
|
||||
{
|
||||
|
@ -29,6 +29,11 @@ namespace osu.Game.Audio
|
||||
/// </summary>
|
||||
public string Name;
|
||||
|
||||
/// <summary>
|
||||
/// An optional suffix to provide priority lookup. Falls back to non-suffixed <see cref="Name"/>.
|
||||
/// </summary>
|
||||
public string Suffix;
|
||||
|
||||
/// <summary>
|
||||
/// The sample volume.
|
||||
/// </summary>
|
||||
@ -42,9 +47,16 @@ namespace osu.Game.Audio
|
||||
get
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Namespace))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Suffix))
|
||||
yield return $"{Namespace}/{Bank}-{Name}{Suffix}";
|
||||
yield return $"{Namespace}/{Bank}-{Name}";
|
||||
}
|
||||
|
||||
yield return $"{Bank}-{Name}"; // Without namespace as a fallback even when we have a namespace
|
||||
// check non-namespace as a fallback even when we have a namespace
|
||||
if (!string.IsNullOrEmpty(Suffix))
|
||||
yield return $"{Bank}-{Name}{Suffix}";
|
||||
yield return $"{Bank}-{Name}";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ namespace osu.Game.Beatmaps
|
||||
// by setting the model here, we can update the noline set id below.
|
||||
b.BeatmapSet = model;
|
||||
|
||||
fetchAndPopulateOnlineIDs(b);
|
||||
fetchAndPopulateOnlineIDs(b, model.Beatmaps);
|
||||
}
|
||||
|
||||
// check if a set already exists with the same online id, delete if it does.
|
||||
@ -339,6 +339,8 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
var beatmapInfos = new List<BeatmapInfo>();
|
||||
|
||||
bool invalidateOnlineIDs = false;
|
||||
|
||||
foreach (var name in reader.Filenames.Where(f => f.EndsWith(".osu")))
|
||||
{
|
||||
using (var raw = reader.GetStream(name))
|
||||
@ -355,9 +357,18 @@ namespace osu.Game.Beatmaps
|
||||
beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash();
|
||||
beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash();
|
||||
|
||||
// check that no existing beatmap exists that is imported with the same online beatmap ID. if so, give it precedence.
|
||||
if (beatmap.BeatmapInfo.OnlineBeatmapID.HasValue && QueryBeatmap(b => b.OnlineBeatmapID.Value == beatmap.BeatmapInfo.OnlineBeatmapID.Value) != null)
|
||||
beatmap.BeatmapInfo.OnlineBeatmapID = null;
|
||||
if (beatmap.BeatmapInfo.OnlineBeatmapID.HasValue)
|
||||
{
|
||||
var ourId = beatmap.BeatmapInfo.OnlineBeatmapID;
|
||||
|
||||
// check that no existing beatmap in database exists that is imported with the same online beatmap ID. if so, give it precedence.
|
||||
if (QueryBeatmap(b => b.OnlineBeatmapID.Value == ourId) != null)
|
||||
beatmap.BeatmapInfo.OnlineBeatmapID = null;
|
||||
|
||||
// check that no other beatmap in this imported set has a conflicting online beatmap ID. If so, presume *all* are incorrect.
|
||||
if (beatmapInfos.Any(b => b.OnlineBeatmapID == ourId))
|
||||
invalidateOnlineIDs = true;
|
||||
}
|
||||
|
||||
RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);
|
||||
|
||||
@ -375,6 +386,9 @@ namespace osu.Game.Beatmaps
|
||||
}
|
||||
}
|
||||
|
||||
if (invalidateOnlineIDs)
|
||||
beatmapInfos.ForEach(b => b.OnlineBeatmapID = null);
|
||||
|
||||
return beatmapInfos;
|
||||
}
|
||||
|
||||
@ -382,9 +396,10 @@ namespace osu.Game.Beatmaps
|
||||
/// Query the API to populate mising OnlineBeatmapID / OnlineBeatmapSetID properties.
|
||||
/// </summary>
|
||||
/// <param name="beatmap">The beatmap to populate.</param>
|
||||
/// <param name="otherBeatmaps">The other beatmaps contained within this set.</param>
|
||||
/// <param name="force">Whether to re-query if the provided beatmap already has populated values.</param>
|
||||
/// <returns>True if population was successful.</returns>
|
||||
private bool fetchAndPopulateOnlineIDs(BeatmapInfo beatmap, bool force = false)
|
||||
private bool fetchAndPopulateOnlineIDs(BeatmapInfo beatmap, IEnumerable<BeatmapInfo> otherBeatmaps, bool force = false)
|
||||
{
|
||||
if (!force && beatmap.OnlineBeatmapID != null && beatmap.BeatmapSet.OnlineBeatmapSetID != null)
|
||||
return true;
|
||||
@ -404,6 +419,12 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
Logger.Log($"Successfully mapped to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}.", LoggingTarget.Database);
|
||||
|
||||
if (otherBeatmaps.Any(b => b.OnlineBeatmapID == res.OnlineBeatmapID))
|
||||
{
|
||||
Logger.Log("Another beatmap in the same set already mapped to this ID. We'll skip adding it this time.", LoggingTarget.Database);
|
||||
return false;
|
||||
}
|
||||
|
||||
beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID;
|
||||
beatmap.OnlineBeatmapID = res.OnlineBeatmapID;
|
||||
return true;
|
||||
|
@ -14,7 +14,6 @@ namespace osu.Game.Beatmaps
|
||||
public class BeatmapMetadata : IEquatable<BeatmapMetadata>
|
||||
{
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[JsonIgnore]
|
||||
public int ID { get; set; }
|
||||
|
||||
public string Title { get; set; }
|
||||
|
@ -9,14 +9,14 @@ using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Beatmaps.Drawables
|
||||
{
|
||||
public class DifficultyColouredContainer : Container, IHasAccentColour
|
||||
public abstract class DifficultyColouredContainer : Container, IHasAccentColour
|
||||
{
|
||||
public Color4 AccentColour { get; set; }
|
||||
|
||||
private readonly BeatmapInfo beatmap;
|
||||
private OsuColour palette;
|
||||
|
||||
public DifficultyColouredContainer(BeatmapInfo beatmap)
|
||||
protected DifficultyColouredContainer(BeatmapInfo beatmap)
|
||||
{
|
||||
this.beatmap = beatmap;
|
||||
}
|
||||
|
@ -3,10 +3,14 @@
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Beatmaps.Drawables
|
||||
{
|
||||
@ -14,7 +18,8 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
{
|
||||
private readonly BeatmapInfo beatmap;
|
||||
|
||||
public DifficultyIcon(BeatmapInfo beatmap) : base(beatmap)
|
||||
public DifficultyIcon(BeatmapInfo beatmap)
|
||||
: base(beatmap)
|
||||
{
|
||||
if (beatmap == null)
|
||||
throw new ArgumentNullException(nameof(beatmap));
|
||||
@ -28,16 +33,29 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SpriteIcon
|
||||
new CircularContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Scale = new Vector2(0.84f),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = AccentColour,
|
||||
Icon = FontAwesome.fa_circle
|
||||
Masking = true,
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Colour = Color4.Black.Opacity(0.08f),
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 5,
|
||||
},
|
||||
Child = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = AccentColour,
|
||||
},
|
||||
},
|
||||
new ConstrainedIconContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
// the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment)
|
||||
Icon = beatmap.Ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.fa_question_circle_o }
|
||||
|
@ -179,7 +179,7 @@ namespace osu.Game.Beatmaps.Formats
|
||||
var baseInfo = base.ApplyTo(sampleInfo);
|
||||
|
||||
if (CustomSampleBank > 1)
|
||||
baseInfo.Name += CustomSampleBank;
|
||||
baseInfo.Suffix = CustomSampleBank.ToString();
|
||||
|
||||
return baseInfo;
|
||||
}
|
||||
|
@ -26,9 +26,9 @@ namespace osu.Game.Graphics.Containers
|
||||
|
||||
protected readonly Bindable<OverlayActivation> OverlayActivationMode = new Bindable<OverlayActivation>(OverlayActivation.All);
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
dependencies.CacheAs<IPreviewTrackOwner>(this);
|
||||
return dependencies;
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ namespace osu.Game.Graphics.Cursor
|
||||
{
|
||||
}
|
||||
|
||||
protected override double AppearDelay => (1 - CurrentTooltip.Alpha) * base.AppearDelay; // reduce appear delay if the tooltip is already partly visible.
|
||||
|
||||
public class OsuTooltip : Tooltip
|
||||
{
|
||||
private readonly Box background;
|
||||
|
@ -63,7 +63,14 @@ namespace osu.Game.Online.API.Requests.Responses
|
||||
[JsonProperty(@"beatmapset")]
|
||||
private BeatmapMetadata metadata
|
||||
{
|
||||
set => Beatmap.Metadata = value;
|
||||
set
|
||||
{
|
||||
// extract the set ID to its correct place.
|
||||
Beatmap.BeatmapSet = new BeatmapSetInfo { OnlineBeatmapSetID = value.ID };
|
||||
value.ID = 0;
|
||||
|
||||
Beatmap.Metadata = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty(@"statistics")]
|
||||
|
@ -122,8 +122,8 @@ namespace osu.Game
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
|
||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
|
||||
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(FrameworkConfigManager frameworkConfig)
|
||||
|
@ -20,6 +20,7 @@ using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Framework.Graphics.Performance;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Database;
|
||||
@ -30,6 +31,7 @@ using osu.Game.IO;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Skinning;
|
||||
using OpenTK.Input;
|
||||
using DebugUtils = osu.Game.Utils.DebugUtils;
|
||||
|
||||
namespace osu.Game
|
||||
@ -93,11 +95,13 @@ namespace osu.Game
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
|
||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
|
||||
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
private DatabaseContextFactory contextFactory;
|
||||
|
||||
protected override UserInputManager CreateUserInputManager() => new OsuUserInputManager();
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
@ -267,5 +271,31 @@ namespace osu.Game
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
private class OsuUserInputManager : UserInputManager
|
||||
{
|
||||
protected override MouseButtonEventManager CreateButtonManagerFor(MouseButton button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case MouseButton.Right:
|
||||
return new RightMouseManager(button);
|
||||
}
|
||||
|
||||
return base.CreateButtonManagerFor(button);
|
||||
}
|
||||
|
||||
private class RightMouseManager : MouseButtonEventManager
|
||||
{
|
||||
public RightMouseManager(MouseButton button)
|
||||
: base(button)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool EnableDrag => true; // allow right-mouse dragging for absolute scroll in scroll containers.
|
||||
public override bool EnableClick => false;
|
||||
public override bool ChangeFocusOnClick => false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,6 +102,7 @@ namespace osu.Game.Overlays.KeyBinding
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Margin = new MarginPadding(padding),
|
||||
Padding = new MarginPadding { Top = height },
|
||||
Alpha = 0,
|
||||
Colour = colours.YellowDark
|
||||
}
|
||||
@ -267,7 +268,7 @@ namespace osu.Game.Overlays.KeyBinding
|
||||
GetContainingInputManager().ChangeFocus(null);
|
||||
|
||||
pressAKey.FadeOut(300, Easing.OutQuint);
|
||||
pressAKey.Padding = new MarginPadding { Top = height, Bottom = -pressAKey.DrawHeight };
|
||||
pressAKey.BypassAutoSizeAxes |= Axes.Y;
|
||||
}
|
||||
|
||||
protected override void OnFocus(InputState state)
|
||||
@ -276,7 +277,7 @@ namespace osu.Game.Overlays.KeyBinding
|
||||
AutoSizeEasing = Easing.OutQuint;
|
||||
|
||||
pressAKey.FadeIn(300, Easing.OutQuint);
|
||||
pressAKey.Padding = new MarginPadding { Top = height };
|
||||
pressAKey.BypassAutoSizeAxes &= ~Axes.Y;
|
||||
|
||||
updateBindTarget();
|
||||
base.OnFocus(state);
|
||||
|
@ -14,6 +14,8 @@ using osu.Game.Graphics;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics.Transforms;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
|
||||
@ -135,7 +137,7 @@ namespace osu.Game.Overlays
|
||||
/// <exception cref="InvalidOperationException">If <paramref name="configManager"/> is already being tracked from the same <paramref name="source"/>.</exception>
|
||||
public void BeginTracking(object source, ITrackableConfigManager configManager)
|
||||
{
|
||||
if (configManager == null) throw new ArgumentNullException(nameof(configManager));
|
||||
if (configManager == null) throw new ArgumentNullException(nameof(configManager));
|
||||
|
||||
if (trackedConfigManagers.ContainsKey((source, configManager)))
|
||||
throw new InvalidOperationException($"{nameof(configManager)} is already registered.");
|
||||
@ -159,7 +161,7 @@ namespace osu.Game.Overlays
|
||||
/// <exception cref="InvalidOperationException">If <paramref name="configManager"/> is not being tracked from the same <see cref="source"/>.</exception>
|
||||
public void StopTracking(object source, ITrackableConfigManager configManager)
|
||||
{
|
||||
if (configManager == null) throw new ArgumentNullException(nameof(configManager));
|
||||
if (configManager == null) throw new ArgumentNullException(nameof(configManager));
|
||||
|
||||
if (!trackedConfigManagers.TryGetValue((source, configManager), out var existing))
|
||||
throw new InvalidOperationException($"{nameof(configManager)} is not registered.");
|
||||
@ -181,7 +183,7 @@ namespace osu.Game.Overlays
|
||||
if (string.IsNullOrEmpty(textLine3.Text))
|
||||
textLine3.Text = "NO KEY BOUND";
|
||||
|
||||
Display(box);
|
||||
DisplayTemporarily(box);
|
||||
|
||||
int optionCount = 0;
|
||||
int selectedOption = -1;
|
||||
@ -213,15 +215,29 @@ namespace osu.Game.Overlays
|
||||
});
|
||||
}
|
||||
|
||||
protected virtual void Display(Drawable toDisplay)
|
||||
private TransformSequence<Drawable> fadeIn;
|
||||
private ScheduledDelegate fadeOut;
|
||||
|
||||
protected virtual void DisplayTemporarily(Drawable toDisplay)
|
||||
{
|
||||
toDisplay.Animate(
|
||||
b => b.FadeIn(500, Easing.OutQuint),
|
||||
b => b.ResizeHeightTo(height, 500, Easing.OutQuint)
|
||||
).Then(
|
||||
b => b.FadeOutFromOne(1500, Easing.InQuint),
|
||||
b => b.ResizeHeightTo(height_contracted, 1500, Easing.InQuint)
|
||||
);
|
||||
// avoid starting a new fade-in if one is already active.
|
||||
if (fadeIn == null)
|
||||
{
|
||||
fadeIn = toDisplay.Animate(
|
||||
b => b.FadeIn(500, Easing.OutQuint),
|
||||
b => b.ResizeHeightTo(height, 500, Easing.OutQuint)
|
||||
);
|
||||
|
||||
fadeIn.Finally(_ => fadeIn = null);
|
||||
}
|
||||
|
||||
fadeOut?.Cancel();
|
||||
fadeOut = Scheduler.AddDelayed(() =>
|
||||
{
|
||||
toDisplay.Animate(
|
||||
b => b.FadeOutFromOne(1500, Easing.InQuint),
|
||||
b => b.ResizeHeightTo(height_contracted, 1500, Easing.InQuint));
|
||||
}, 500);
|
||||
}
|
||||
|
||||
private class OptionLight : Container
|
||||
|
@ -158,6 +158,13 @@ namespace osu.Game.Overlays.Profile
|
||||
}
|
||||
}
|
||||
},
|
||||
new Box // this is a temporary workaround for incorrect masking behaviour of FillMode.Fill used in UserCoverBackground (see https://github.com/ppy/osu-framework/issues/1675)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 1,
|
||||
Y = cover_height,
|
||||
Colour = OsuColour.Gray(34),
|
||||
},
|
||||
infoTextLeft = new LinkFlowContainer(t => t.TextSize = 14)
|
||||
{
|
||||
X = UserProfileOverlay.CONTENT_X_MARGIN,
|
||||
@ -360,11 +367,6 @@ namespace osu.Game.Overlays.Profile
|
||||
Text = text
|
||||
};
|
||||
|
||||
if (user.Age != null)
|
||||
{
|
||||
infoTextLeft.AddText($"{user.Age} years old ", boldItalic);
|
||||
}
|
||||
|
||||
if (user.Country != null)
|
||||
{
|
||||
infoTextLeft.AddText("From ", lightText);
|
||||
|
@ -9,6 +9,7 @@ using osu.Framework.Localisation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections
|
||||
{
|
||||
/// <summary>
|
||||
@ -32,7 +33,10 @@ namespace osu.Game.Overlays.Profile.Sections
|
||||
{
|
||||
Action = () =>
|
||||
{
|
||||
if (beatmap.BeatmapSet?.OnlineBeatmapSetID != null) beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.BeatmapSet.OnlineBeatmapSetID.Value);
|
||||
if (beatmap.OnlineBeatmapID != null)
|
||||
beatmapSetOverlay?.FetchAndShowBeatmap(beatmap.OnlineBeatmapID.Value);
|
||||
else if (beatmap.BeatmapSet?.OnlineBeatmapSetID != null)
|
||||
beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.BeatmapSet.OnlineBeatmapSetID.Value);
|
||||
};
|
||||
|
||||
Child = new FillFlowContainer
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Configuration;
|
||||
|
||||
namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
@ -14,6 +15,8 @@ namespace osu.Game.Overlays.Settings
|
||||
{
|
||||
private readonly Ruleset ruleset;
|
||||
|
||||
protected IRulesetConfigManager Config;
|
||||
|
||||
protected RulesetSettingsSubsection(Ruleset ruleset)
|
||||
{
|
||||
this.ruleset = ruleset;
|
||||
@ -21,13 +24,13 @@ namespace osu.Game.Overlays.Settings
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
var config = dependencies.Get<RulesetConfigCache>().GetConfigFor(ruleset);
|
||||
if (config != null)
|
||||
dependencies.Cache(config);
|
||||
Config = dependencies.Get<RulesetConfigCache>().GetConfigFor(ruleset);
|
||||
if (Config != null)
|
||||
dependencies.Cache(Config);
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
Action = () => OnHome?.Invoke()
|
||||
},
|
||||
new ToolbarModeSelector()
|
||||
new ToolbarRulesetSelector()
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
|
@ -7,7 +7,7 @@ using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
public class ToolbarModeButton : ToolbarButton
|
||||
public class ToolbarRulesetButton : ToolbarButton
|
||||
{
|
||||
private RulesetInfo ruleset;
|
||||
public RulesetInfo Ruleset
|
@ -16,18 +16,18 @@ using osu.Game.Rulesets;
|
||||
|
||||
namespace osu.Game.Overlays.Toolbar
|
||||
{
|
||||
public class ToolbarModeSelector : Container
|
||||
public class ToolbarRulesetSelector : Container
|
||||
{
|
||||
private const float padding = 10;
|
||||
|
||||
private readonly FillFlowContainer modeButtons;
|
||||
private readonly Drawable modeButtonLine;
|
||||
private ToolbarModeButton activeButton;
|
||||
private ToolbarRulesetButton activeButton;
|
||||
|
||||
private RulesetStore rulesets;
|
||||
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||
|
||||
public ToolbarModeSelector()
|
||||
public ToolbarRulesetSelector()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
|
||||
@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Toolbar
|
||||
this.rulesets = rulesets;
|
||||
foreach (var r in rulesets.AvailableRulesets)
|
||||
{
|
||||
modeButtons.Add(new ToolbarModeButton
|
||||
modeButtons.Add(new ToolbarRulesetButton
|
||||
{
|
||||
Ruleset = r,
|
||||
Action = delegate { ruleset.Value = r; }
|
||||
@ -115,7 +115,7 @@ namespace osu.Game.Overlays.Toolbar
|
||||
|
||||
private void rulesetChanged(RulesetInfo ruleset)
|
||||
{
|
||||
foreach (ToolbarModeButton m in modeButtons.Children.Cast<ToolbarModeButton>())
|
||||
foreach (ToolbarRulesetButton m in modeButtons.Children.Cast<ToolbarRulesetButton>())
|
||||
{
|
||||
bool isActive = m.Ruleset.ID == ruleset.ID;
|
||||
m.Active = isActive;
|
@ -70,7 +70,8 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
protected readonly Ruleset Ruleset;
|
||||
|
||||
private IRulesetConfigManager rulesetConfig;
|
||||
protected IRulesetConfigManager Config { get; private set; }
|
||||
|
||||
private OnScreenDisplay onScreenDisplay;
|
||||
|
||||
/// <summary>
|
||||
@ -85,17 +86,17 @@ namespace osu.Game.Rulesets.UI
|
||||
Cursor = CreateCursor();
|
||||
}
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
onScreenDisplay = dependencies.Get<OnScreenDisplay>();
|
||||
|
||||
rulesetConfig = dependencies.Get<RulesetConfigCache>().GetConfigFor(Ruleset);
|
||||
if (rulesetConfig != null)
|
||||
Config = dependencies.Get<RulesetConfigCache>().GetConfigFor(Ruleset);
|
||||
if (Config != null)
|
||||
{
|
||||
dependencies.Cache(rulesetConfig);
|
||||
onScreenDisplay?.BeginTracking(this, rulesetConfig);
|
||||
dependencies.Cache(Config);
|
||||
onScreenDisplay?.BeginTracking(this, Config);
|
||||
}
|
||||
|
||||
return dependencies;
|
||||
@ -143,10 +144,10 @@ namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (rulesetConfig != null)
|
||||
if (Config != null)
|
||||
{
|
||||
onScreenDisplay?.StopTracking(this, rulesetConfig);
|
||||
rulesetConfig = null;
|
||||
onScreenDisplay?.StopTracking(this, Config);
|
||||
Config = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,23 +222,16 @@ namespace osu.Game.Rulesets.UI
|
||||
mouseDisabled = config.GetBindable<bool>(OsuSetting.MouseDisableButtons);
|
||||
}
|
||||
|
||||
protected override void TransformState(InputState state)
|
||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||
{
|
||||
base.TransformState(state);
|
||||
if (mouseDisabled.Value && (args.Button == MouseButton.Left || args.Button == MouseButton.Right)) return false;
|
||||
return base.OnMouseDown(state, args);
|
||||
}
|
||||
|
||||
// we don't want to transform the state if a replay is present (for now, at least).
|
||||
if (replayInputHandler != null) return;
|
||||
|
||||
var mouse = state.Mouse as Framework.Input.MouseState;
|
||||
|
||||
if (mouse != null)
|
||||
{
|
||||
if (mouseDisabled.Value)
|
||||
{
|
||||
mouse.SetPressed(MouseButton.Left, false);
|
||||
mouse.SetPressed(MouseButton.Right, false);
|
||||
}
|
||||
}
|
||||
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
||||
{
|
||||
if (!CurrentState.Mouse.IsPressed(args.Button)) return false;
|
||||
return base.OnMouseUp(state, args);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -42,8 +42,8 @@ namespace osu.Game.Screens.Edit
|
||||
private DependencyContainer dependencies;
|
||||
private GameHost host;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
=> dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
=> dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, GameHost host)
|
||||
|
@ -35,6 +35,12 @@ namespace osu.Game.Screens.Menu
|
||||
private readonly Box boxHoverLayer;
|
||||
private readonly SpriteIcon icon;
|
||||
private readonly string sampleName;
|
||||
|
||||
/// <summary>
|
||||
/// The menu state for which we are visible for.
|
||||
/// </summary>
|
||||
public ButtonSystemState VisibleState = ButtonSystemState.TopLevel;
|
||||
|
||||
private readonly Action clickAction;
|
||||
private readonly Key triggerKey;
|
||||
private SampleChannel sampleClick;
|
||||
@ -51,7 +57,7 @@ namespace osu.Game.Screens.Menu
|
||||
AutoSizeAxes = Axes.Both;
|
||||
Alpha = 0;
|
||||
|
||||
Vector2 boxSize = new Vector2(ButtonSystem.BUTTON_WIDTH + Math.Abs(extraWidth), ButtonSystem.BUTTON_AREA_HEIGHT);
|
||||
Vector2 boxSize = new Vector2(ButtonSystem.BUTTON_WIDTH + Math.Abs(extraWidth), ButtonArea.BUTTON_AREA_HEIGHT);
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
@ -260,6 +266,7 @@ namespace osu.Game.Screens.Menu
|
||||
this.FadeOut(800);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case ButtonState.Expanded:
|
||||
const int expand_duration = 500;
|
||||
@ -276,6 +283,33 @@ namespace osu.Game.Screens.Menu
|
||||
StateChanged?.Invoke(State);
|
||||
}
|
||||
}
|
||||
|
||||
public ButtonSystemState ButtonSystemState
|
||||
{
|
||||
set
|
||||
{
|
||||
ContractStyle = 0;
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case ButtonSystemState.Initial:
|
||||
State = ButtonState.Contracted;
|
||||
break;
|
||||
case ButtonSystemState.EnteringMode:
|
||||
ContractStyle = 1;
|
||||
State = ButtonState.Contracted;
|
||||
break;
|
||||
default:
|
||||
if (value == VisibleState)
|
||||
State = ButtonState.Expanded;
|
||||
else if (value < VisibleState)
|
||||
State = ButtonState.Contracted;
|
||||
else
|
||||
State = ButtonState.Exploded;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ButtonState
|
||||
|
148
osu.Game/Screens/Menu/ButtonArea.cs
Normal file
148
osu.Game/Screens/Menu/ButtonArea.cs
Normal file
@ -0,0 +1,148 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
public class ButtonArea : Container, IStateful<Visibility>
|
||||
{
|
||||
public FlowContainerWithOrigin Flow;
|
||||
|
||||
protected override Container<Drawable> Content => Flow;
|
||||
|
||||
private readonly ButtonAreaBackground buttonAreaBackground;
|
||||
private Visibility state;
|
||||
|
||||
public const float BUTTON_AREA_HEIGHT = 100;
|
||||
|
||||
public ButtonArea()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
InternalChild = new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Size = new Vector2(1, BUTTON_AREA_HEIGHT),
|
||||
Alpha = 0,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
buttonAreaBackground = new ButtonAreaBackground(),
|
||||
Flow = new FlowContainerWithOrigin
|
||||
{
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(-ButtonSystem.WEDGE_WIDTH, 0),
|
||||
Anchor = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ButtonSystemState ButtonSystemState
|
||||
{
|
||||
set
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case ButtonSystemState.Exit:
|
||||
case ButtonSystemState.Initial:
|
||||
case ButtonSystemState.EnteringMode:
|
||||
State = Visibility.Hidden;
|
||||
break;
|
||||
case ButtonSystemState.TopLevel:
|
||||
case ButtonSystemState.Play:
|
||||
State = Visibility.Visible;
|
||||
break;
|
||||
}
|
||||
|
||||
buttonAreaBackground.ButtonSystemState = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Visibility State
|
||||
{
|
||||
get => state;
|
||||
set
|
||||
{
|
||||
if (value == state) return;
|
||||
|
||||
state = value;
|
||||
InternalChild.FadeTo(state == Visibility.Hidden ? 0 : 1, 300);
|
||||
StateChanged?.Invoke(state);
|
||||
}
|
||||
}
|
||||
|
||||
public event Action<Visibility> StateChanged;
|
||||
|
||||
private class ButtonAreaBackground : Box, IStateful<ButtonAreaBackgroundState>
|
||||
{
|
||||
private ButtonAreaBackgroundState state;
|
||||
|
||||
public ButtonAreaBackground()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
Size = new Vector2(2, 1);
|
||||
Colour = OsuColour.Gray(50);
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
}
|
||||
|
||||
public ButtonAreaBackgroundState State
|
||||
{
|
||||
get => state;
|
||||
set
|
||||
{
|
||||
if (value == state) return;
|
||||
|
||||
state = value;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ButtonAreaBackgroundState.Flat:
|
||||
this.ScaleTo(new Vector2(2, 0), 300, Easing.InSine);
|
||||
break;
|
||||
case ButtonAreaBackgroundState.Normal:
|
||||
this.ScaleTo(Vector2.One, 400, Easing.OutQuint);
|
||||
break;
|
||||
}
|
||||
|
||||
StateChanged?.Invoke(state);
|
||||
}
|
||||
}
|
||||
|
||||
public ButtonSystemState ButtonSystemState
|
||||
{
|
||||
set
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
default:
|
||||
State = ButtonAreaBackgroundState.Normal;
|
||||
break;
|
||||
case ButtonSystemState.Initial:
|
||||
case ButtonSystemState.Exit:
|
||||
case ButtonSystemState.EnteringMode:
|
||||
State = ButtonAreaBackgroundState.Flat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public event Action<ButtonAreaBackgroundState> StateChanged;
|
||||
}
|
||||
|
||||
public enum ButtonAreaBackgroundState
|
||||
{
|
||||
Normal,
|
||||
Flat
|
||||
}
|
||||
}
|
||||
}
|
@ -10,8 +10,8 @@ using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Input.Bindings;
|
||||
@ -22,9 +22,9 @@ using OpenTK.Input;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
public class ButtonSystem : Container, IStateful<MenuState>, IKeyBindingHandler<GlobalAction>
|
||||
public class ButtonSystem : Container, IStateful<ButtonSystemState>, IKeyBindingHandler<GlobalAction>
|
||||
{
|
||||
public event Action<MenuState> StateChanged;
|
||||
public event Action<ButtonSystemState> StateChanged;
|
||||
|
||||
public Action OnEdit;
|
||||
public Action OnExit;
|
||||
@ -33,12 +33,6 @@ namespace osu.Game.Screens.Menu
|
||||
public Action OnSettings;
|
||||
public Action OnMulti;
|
||||
public Action OnChart;
|
||||
public Action OnTest;
|
||||
|
||||
private readonly FlowContainerWithOrigin buttonFlow;
|
||||
|
||||
//todo: make these non-internal somehow.
|
||||
public const float BUTTON_AREA_HEIGHT = 100;
|
||||
|
||||
public const float BUTTON_WIDTH = 140f;
|
||||
public const float WEDGE_WIDTH = 20;
|
||||
@ -54,18 +48,16 @@ namespace osu.Game.Screens.Menu
|
||||
this.logo.Action = onOsuLogo;
|
||||
|
||||
// osuLogo.SizeForFlow relies on loading to be complete.
|
||||
buttonFlow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0);
|
||||
buttonArea.Flow.Position = new Vector2(WEDGE_WIDTH * 2 - (BUTTON_WIDTH + this.logo.SizeForFlow / 4), 0);
|
||||
|
||||
updateLogoState();
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Drawable iconFacade;
|
||||
private readonly Container buttonArea;
|
||||
private readonly Box buttonAreaBackground;
|
||||
private readonly ButtonArea buttonArea;
|
||||
|
||||
private readonly Button backButton;
|
||||
private readonly Button settingsButton;
|
||||
|
||||
private readonly List<Button> buttonsTopLevel = new List<Button>();
|
||||
private readonly List<Button> buttonsPlay = new List<Button>();
|
||||
@ -76,57 +68,35 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
Children = new Drawable[]
|
||||
Child = buttonArea = new ButtonArea();
|
||||
|
||||
buttonArea.AddRange(new[]
|
||||
{
|
||||
buttonArea = new Container
|
||||
new Button(@"settings", string.Empty, FontAwesome.fa_gear, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O),
|
||||
backButton = new Button(@"back", @"button-back-select", FontAwesome.fa_osu_left_o, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel, -WEDGE_WIDTH)
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Size = new Vector2(1, BUTTON_AREA_HEIGHT),
|
||||
Alpha = 0,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
buttonAreaBackground = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Size = new Vector2(2, 1),
|
||||
Colour = OsuColour.Gray(50),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
buttonFlow = new FlowContainerWithOrigin
|
||||
{
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(-WEDGE_WIDTH, 0),
|
||||
Anchor = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new[]
|
||||
{
|
||||
settingsButton = new Button(@"settings", string.Empty, FontAwesome.fa_gear, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O),
|
||||
backButton = new Button(@"back", string.Empty, FontAwesome.fa_osu_left_o, new Color4(51, 58, 94, 255), onBack, -WEDGE_WIDTH),
|
||||
iconFacade = new Container //need a container to make the osu! icon flow properly.
|
||||
{
|
||||
Size = new Vector2(0, BUTTON_AREA_HEIGHT)
|
||||
}
|
||||
},
|
||||
CentreTarget = iconFacade
|
||||
}
|
||||
}
|
||||
VisibleState = ButtonSystemState.Play,
|
||||
},
|
||||
};
|
||||
iconFacade = new Container //need a container to make the osu! icon flow properly.
|
||||
{
|
||||
Size = new Vector2(0, ButtonArea.BUTTON_AREA_HEIGHT)
|
||||
}
|
||||
});
|
||||
|
||||
buttonArea.Flow.CentreTarget = iconFacade;
|
||||
|
||||
buttonsPlay.Add(new Button(@"solo", @"button-solo-select", FontAwesome.fa_user, new Color4(102, 68, 204, 255), () => OnSolo?.Invoke(), WEDGE_WIDTH, Key.P));
|
||||
buttonsPlay.Add(new Button(@"multi", @"button-generic-select", FontAwesome.fa_users, new Color4(94, 63, 186, 255), () => OnMulti?.Invoke(), 0, Key.M));
|
||||
buttonsPlay.Add(new Button(@"chart", @"button-generic-select", FontAwesome.fa_osu_charts, new Color4(80, 53, 160, 255), () => OnChart?.Invoke()));
|
||||
buttonsPlay.ForEach(b => b.VisibleState = ButtonSystemState.Play);
|
||||
|
||||
buttonsTopLevel.Add(new Button(@"play", @"button-play-select", FontAwesome.fa_osu_logo, new Color4(102, 68, 204, 255), onPlay, WEDGE_WIDTH, Key.P));
|
||||
buttonsTopLevel.Add(new Button(@"play", @"button-play-select", FontAwesome.fa_osu_logo, new Color4(102, 68, 204, 255), () => State = ButtonSystemState.Play, WEDGE_WIDTH, Key.P));
|
||||
buttonsTopLevel.Add(new Button(@"osu!editor", @"button-generic-select", FontAwesome.fa_osu_edit_o, new Color4(238, 170, 0, 255), () => OnEdit?.Invoke(), 0, Key.E));
|
||||
buttonsTopLevel.Add(new Button(@"osu!direct", @"button-direct-select", FontAwesome.fa_osu_chevron_down_o, new Color4(165, 204, 0, 255), () => OnDirect?.Invoke(), 0, Key.D));
|
||||
buttonsTopLevel.Add(new Button(@"exit", string.Empty, FontAwesome.fa_osu_cross_o, new Color4(238, 51, 153, 255), onExit, 0, Key.Q));
|
||||
buttonsTopLevel.Add(new Button(@"exit", string.Empty, FontAwesome.fa_osu_cross_o, new Color4(238, 51, 153, 255), () => OnExit?.Invoke(), 0, Key.Q));
|
||||
|
||||
buttonFlow.AddRange(buttonsPlay);
|
||||
buttonFlow.AddRange(buttonsTopLevel);
|
||||
buttonArea.AddRange(buttonsPlay);
|
||||
buttonArea.AddRange(buttonsTopLevel);
|
||||
}
|
||||
|
||||
private OsuGame game;
|
||||
@ -152,14 +122,17 @@ namespace osu.Game.Screens.Menu
|
||||
}
|
||||
}
|
||||
|
||||
public bool OnReleased(GlobalAction action) => false;
|
||||
|
||||
private bool goBack()
|
||||
{
|
||||
switch (State)
|
||||
{
|
||||
case MenuState.TopLevel:
|
||||
State = MenuState.Initial;
|
||||
case ButtonSystemState.TopLevel:
|
||||
State = ButtonSystemState.Initial;
|
||||
sampleBack?.Play();
|
||||
return true;
|
||||
case MenuState.Play:
|
||||
case ButtonSystemState.Play:
|
||||
backButton.TriggerOnClick();
|
||||
return true;
|
||||
default:
|
||||
@ -167,48 +140,30 @@ namespace osu.Game.Screens.Menu
|
||||
}
|
||||
}
|
||||
|
||||
public bool OnReleased(GlobalAction action) => false;
|
||||
|
||||
private void onPlay()
|
||||
{
|
||||
State = MenuState.Play;
|
||||
}
|
||||
|
||||
private void onExit()
|
||||
{
|
||||
OnExit?.Invoke();
|
||||
}
|
||||
|
||||
private void onBack()
|
||||
{
|
||||
sampleBack?.Play();
|
||||
State = MenuState.TopLevel;
|
||||
}
|
||||
|
||||
private bool onOsuLogo()
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
default:
|
||||
return true;
|
||||
case MenuState.Initial:
|
||||
State = MenuState.TopLevel;
|
||||
case ButtonSystemState.Initial:
|
||||
State = ButtonSystemState.TopLevel;
|
||||
return true;
|
||||
case MenuState.TopLevel:
|
||||
case ButtonSystemState.TopLevel:
|
||||
buttonsTopLevel.First().TriggerOnClick();
|
||||
return false;
|
||||
case MenuState.Play:
|
||||
case ButtonSystemState.Play:
|
||||
buttonsPlay.First().TriggerOnClick();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private MenuState state;
|
||||
private ButtonSystemState state = ButtonSystemState.Initial;
|
||||
|
||||
public override bool HandleKeyboardInput => state != MenuState.Exit;
|
||||
public override bool HandleMouseInput => state != MenuState.Exit;
|
||||
public override bool HandleKeyboardInput => state != ButtonSystemState.Exit;
|
||||
public override bool HandleMouseInput => state != ButtonSystemState.Exit;
|
||||
|
||||
public MenuState State
|
||||
public ButtonSystemState State
|
||||
{
|
||||
get { return state; }
|
||||
|
||||
@ -216,71 +171,19 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
if (state == value) return;
|
||||
|
||||
MenuState lastState = state;
|
||||
ButtonSystemState lastState = state;
|
||||
state = value;
|
||||
|
||||
//todo: figure a more elegant way of doing this.
|
||||
buttonsTopLevel.ForEach(b => b.ContractStyle = 0);
|
||||
buttonsPlay.ForEach(b => b.ContractStyle = 0);
|
||||
backButton.ContractStyle = 0;
|
||||
settingsButton.ContractStyle = 0;
|
||||
|
||||
updateLogoState(lastState);
|
||||
|
||||
using (buttonArea.BeginDelayedSequence(lastState == MenuState.Initial ? 150 : 0, true))
|
||||
Logger.Log($"{nameof(ButtonSystem)}'s state changed from {lastState} to {state}");
|
||||
|
||||
using (buttonArea.BeginDelayedSequence(lastState == ButtonSystemState.Initial ? 150 : 0, true))
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case MenuState.Exit:
|
||||
case MenuState.Initial:
|
||||
buttonAreaBackground.ScaleTo(Vector2.One, 500, Easing.Out);
|
||||
buttonArea.FadeOut(300);
|
||||
buttonArea.ButtonSystemState = state;
|
||||
|
||||
foreach (Button b in buttonsTopLevel)
|
||||
b.State = ButtonState.Contracted;
|
||||
|
||||
foreach (Button b in buttonsPlay)
|
||||
b.State = ButtonState.Contracted;
|
||||
|
||||
if (state != MenuState.Exit && lastState == MenuState.TopLevel)
|
||||
sampleBack?.Play();
|
||||
break;
|
||||
case MenuState.TopLevel:
|
||||
buttonAreaBackground.ScaleTo(Vector2.One, 200, Easing.Out);
|
||||
|
||||
buttonArea.FadeIn(300);
|
||||
|
||||
foreach (Button b in buttonsTopLevel)
|
||||
b.State = ButtonState.Expanded;
|
||||
|
||||
foreach (Button b in buttonsPlay)
|
||||
b.State = ButtonState.Contracted;
|
||||
break;
|
||||
case MenuState.Play:
|
||||
foreach (Button b in buttonsTopLevel)
|
||||
b.State = ButtonState.Exploded;
|
||||
|
||||
foreach (Button b in buttonsPlay)
|
||||
b.State = ButtonState.Expanded;
|
||||
break;
|
||||
case MenuState.EnteringMode:
|
||||
buttonAreaBackground.ScaleTo(new Vector2(2, 0), 300, Easing.InSine);
|
||||
|
||||
buttonsTopLevel.ForEach(b => b.ContractStyle = 1);
|
||||
buttonsPlay.ForEach(b => b.ContractStyle = 1);
|
||||
backButton.ContractStyle = 1;
|
||||
settingsButton.ContractStyle = 1;
|
||||
|
||||
foreach (Button b in buttonsTopLevel)
|
||||
b.State = ButtonState.Contracted;
|
||||
|
||||
foreach (Button b in buttonsPlay)
|
||||
b.State = ButtonState.Contracted;
|
||||
break;
|
||||
}
|
||||
|
||||
backButton.State = state == MenuState.Play ? ButtonState.Expanded : ButtonState.Contracted;
|
||||
settingsButton.State = state == MenuState.TopLevel ? ButtonState.Expanded : ButtonState.Contracted;
|
||||
foreach (var b in buttonArea.Children.OfType<Button>())
|
||||
b.ButtonSystemState = state;
|
||||
}
|
||||
|
||||
StateChanged?.Invoke(State);
|
||||
@ -289,14 +192,14 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
private ScheduledDelegate logoDelayedAction;
|
||||
|
||||
private void updateLogoState(MenuState lastState = MenuState.Initial)
|
||||
private void updateLogoState(ButtonSystemState lastState = ButtonSystemState.Initial)
|
||||
{
|
||||
if (logo == null) return;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case MenuState.Exit:
|
||||
case MenuState.Initial:
|
||||
case ButtonSystemState.Exit:
|
||||
case ButtonSystemState.Initial:
|
||||
logoDelayedAction?.Cancel();
|
||||
logoDelayedAction = Scheduler.AddDelayed(() =>
|
||||
{
|
||||
@ -304,7 +207,7 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
if (game != null)
|
||||
{
|
||||
game.OverlayActivationMode.Value = state == MenuState.Exit ? OverlayActivation.Disabled : OverlayActivation.All;
|
||||
game.OverlayActivationMode.Value = state == ButtonSystemState.Exit ? OverlayActivation.Disabled : OverlayActivation.All;
|
||||
game.Toolbar.Hide();
|
||||
}
|
||||
|
||||
@ -315,22 +218,22 @@ namespace osu.Game.Screens.Menu
|
||||
logo.ScaleTo(1, 800, Easing.OutExpo);
|
||||
}, buttonArea.Alpha * 150);
|
||||
break;
|
||||
case MenuState.TopLevel:
|
||||
case MenuState.Play:
|
||||
case ButtonSystemState.TopLevel:
|
||||
case ButtonSystemState.Play:
|
||||
switch (lastState)
|
||||
{
|
||||
case MenuState.TopLevel: // coming from toplevel to play
|
||||
case ButtonSystemState.TopLevel: // coming from toplevel to play
|
||||
break;
|
||||
case MenuState.Initial:
|
||||
case ButtonSystemState.Initial:
|
||||
logo.ClearTransforms(targetMember: nameof(Position));
|
||||
logo.RelativePositionAxes = Axes.None;
|
||||
|
||||
bool impact = logo.Scale.X > 0.6f;
|
||||
|
||||
if (lastState == MenuState.Initial)
|
||||
if (lastState == ButtonSystemState.Initial)
|
||||
logo.ScaleTo(0.5f, 200, Easing.In);
|
||||
|
||||
logo.MoveTo(logoTrackingPosition, lastState == MenuState.EnteringMode ? 0 : 200, Easing.In);
|
||||
logo.MoveTo(logoTrackingPosition, lastState == ButtonSystemState.EnteringMode ? 0 : 200, Easing.In);
|
||||
|
||||
logoDelayedAction?.Cancel();
|
||||
logoDelayedAction = Scheduler.AddDelayed(() =>
|
||||
@ -356,7 +259,7 @@ namespace osu.Game.Screens.Menu
|
||||
}
|
||||
|
||||
break;
|
||||
case MenuState.EnteringMode:
|
||||
case ButtonSystemState.EnteringMode:
|
||||
logoTracking = true;
|
||||
break;
|
||||
}
|
||||
@ -375,7 +278,7 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
if (logo != null)
|
||||
{
|
||||
if (logoTracking)
|
||||
if (logoTracking && iconFacade.IsLoaded)
|
||||
logo.Position = logoTrackingPosition;
|
||||
|
||||
iconFacade.Width = logo.SizeForFlow * 0.5f;
|
||||
@ -383,12 +286,12 @@ namespace osu.Game.Screens.Menu
|
||||
}
|
||||
}
|
||||
|
||||
public enum MenuState
|
||||
public enum ButtonSystemState
|
||||
{
|
||||
Exit,
|
||||
Initial,
|
||||
TopLevel,
|
||||
Play,
|
||||
EnteringMode,
|
||||
Exit,
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,9 @@
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using osu.Game.Overlays;
|
||||
@ -16,96 +15,89 @@ namespace osu.Game.Screens.Menu
|
||||
public class Disclaimer : OsuScreen
|
||||
{
|
||||
private Intro intro;
|
||||
private readonly SpriteIcon icon;
|
||||
private SpriteIcon icon;
|
||||
private Color4 iconColour;
|
||||
private LinkFlowContainer textFlow;
|
||||
|
||||
protected override bool HideOverlaysOnEnter => true;
|
||||
protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled;
|
||||
|
||||
public override bool CursorVisible => false;
|
||||
|
||||
private const float icon_y = -0.09f;
|
||||
|
||||
public Disclaimer()
|
||||
{
|
||||
ValidForResume = false;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 2),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
icon = new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Icon = FontAwesome.fa_warning,
|
||||
Size = new Vector2(30),
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
TextSize = 30,
|
||||
Text = "This is a development build",
|
||||
Margin = new MarginPadding
|
||||
{
|
||||
Bottom = 20
|
||||
},
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = "Don't expect shit to work perfectly as this is very much a work in progress."
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = "Don't report bugs because we are aware. Don't complain about missing features because we are adding them."
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
Text = "Sit back and enjoy. Visit discord.gg/ppy if you want to help out!",
|
||||
Margin = new MarginPadding { Bottom = 20 },
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
TextSize = 12,
|
||||
Text = "oh and yes, you will get seizures.",
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
LoadComponentAsync(intro = new Intro());
|
||||
Children = new Drawable[]
|
||||
{
|
||||
icon = new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Icon = FontAwesome.fa_warning,
|
||||
Size = new Vector2(30),
|
||||
RelativePositionAxes = Axes.Both,
|
||||
Y = icon_y,
|
||||
},
|
||||
textFlow = new LinkFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding(50),
|
||||
TextAnchor = Anchor.TopCentre,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Spacing = new Vector2(0, 2),
|
||||
}
|
||||
};
|
||||
|
||||
textFlow.AddText("This is an ", t =>
|
||||
{
|
||||
t.TextSize = 30;
|
||||
t.Font = @"Exo2.0-Light";
|
||||
});
|
||||
textFlow.AddText("early development build", t =>
|
||||
{
|
||||
t.TextSize = 30;
|
||||
t.Font = @"Exo2.0-SemiBold";
|
||||
});
|
||||
|
||||
textFlow.AddParagraph("Don't expect everything to work perfectly.");
|
||||
textFlow.AddParagraph("");
|
||||
textFlow.AddParagraph("Detailed bug reports are welcomed via github issues.");
|
||||
textFlow.AddParagraph("");
|
||||
|
||||
textFlow.AddText("Visit ");
|
||||
textFlow.AddLink("discord.gg/ppy", "https://discord.gg/ppy");
|
||||
textFlow.AddText(" if you want to help out or follow progress!");
|
||||
|
||||
iconColour = colours.Yellow;
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
LoadComponentAsync(intro = new Intro());
|
||||
}
|
||||
|
||||
protected override void OnEntering(Screen last)
|
||||
{
|
||||
base.OnEntering(last);
|
||||
|
||||
icon.Delay(1500).FadeColour(iconColour, 200);
|
||||
icon.Delay(1500).FadeColour(iconColour, 200, Easing.OutQuint);
|
||||
icon.Delay(1500).MoveToY(icon_y * 1.1f, 100, Easing.OutCirc).Then().MoveToY(icon_y, 100, Easing.InCirc);
|
||||
|
||||
Content
|
||||
.FadeInFromZero(500)
|
||||
.Then(5500)
|
||||
.FadeOut(250)
|
||||
.ScaleTo(0.9f, 250, Easing.InQuint)
|
||||
.Finally(d => Push(intro));
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,9 @@ namespace osu.Game.Screens.Menu
|
||||
{
|
||||
private readonly ButtonSystem buttons;
|
||||
|
||||
protected override bool HideOverlaysOnEnter => buttons.State == MenuState.Initial;
|
||||
protected override bool HideOverlaysOnEnter => buttons.State == ButtonSystemState.Initial;
|
||||
|
||||
protected override bool AllowBackButton => buttons.State != MenuState.Initial;
|
||||
protected override bool AllowBackButton => buttons.State != ButtonSystemState.Initial;
|
||||
|
||||
private readonly BackgroundScreenDefault background;
|
||||
private Screen songSelect;
|
||||
@ -123,7 +123,7 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
if (resuming)
|
||||
{
|
||||
buttons.State = MenuState.TopLevel;
|
||||
buttons.State = ButtonSystemState.TopLevel;
|
||||
|
||||
const float length = 300;
|
||||
|
||||
@ -155,7 +155,7 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
const float length = 400;
|
||||
|
||||
buttons.State = MenuState.EnteringMode;
|
||||
buttons.State = ButtonSystemState.EnteringMode;
|
||||
|
||||
Content.FadeOut(length, Easing.InSine);
|
||||
Content.MoveTo(new Vector2(-800, 0), length, Easing.InSine);
|
||||
@ -175,7 +175,7 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
protected override bool OnExiting(Screen next)
|
||||
{
|
||||
buttons.State = MenuState.Exit;
|
||||
buttons.State = ButtonSystemState.Exit;
|
||||
Content.FadeOut(3000);
|
||||
return base.OnExiting(next);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ using osu.Game.Graphics.Backgrounds;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace osu.Game.Screens.Menu
|
||||
{
|
||||
@ -345,12 +346,16 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||
{
|
||||
if (args.Button != MouseButton.Left) return false;
|
||||
|
||||
logoBounceContainer.ScaleTo(0.9f, 1000, Easing.Out);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
||||
{
|
||||
if (args.Button != MouseButton.Left) return false;
|
||||
|
||||
logoBounceContainer.ScaleTo(1f, 500, Easing.OutElastic);
|
||||
return true;
|
||||
}
|
||||
|
@ -46,7 +46,9 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
public void UpdateRank(ScoreRank newRank)
|
||||
{
|
||||
Rank = newRank;
|
||||
updateTexture();
|
||||
|
||||
if (IsLoaded)
|
||||
updateTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,8 +69,8 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
=> dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
=> dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
protected SongSelect()
|
||||
{
|
||||
@ -138,7 +138,11 @@ namespace osu.Game.Screens.Select
|
||||
Height = filter_height,
|
||||
FilterChanged = c => Carousel.Filter(c),
|
||||
Background = { Width = 2 },
|
||||
Exit = Exit,
|
||||
Exit = () =>
|
||||
{
|
||||
if (IsCurrentScreen)
|
||||
Exit();
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -189,8 +193,6 @@ namespace osu.Game.Screens.Select
|
||||
dependencies.CacheAs(Ruleset);
|
||||
dependencies.CacheAs<IBindable<RulesetInfo>>(Ruleset);
|
||||
|
||||
base.Ruleset.ValueChanged += r => updateSelectedBeatmap(beatmapNoDebounce);
|
||||
|
||||
if (Footer != null)
|
||||
{
|
||||
Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2);
|
||||
@ -218,6 +220,12 @@ namespace osu.Game.Screens.Select
|
||||
Beatmap.BindValueChanged(workingBeatmapChanged);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
base.Ruleset.ValueChanged += r => updateSelectedBeatmap(beatmapNoDebounce);
|
||||
}
|
||||
|
||||
public void Edit(BeatmapInfo beatmap)
|
||||
{
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value);
|
||||
@ -231,6 +239,10 @@ namespace osu.Game.Screens.Select
|
||||
/// <param name="performStartAction">Whether to trigger <see cref="OnStart"/>.</param>
|
||||
public void FinaliseSelection(BeatmapInfo beatmap = null, bool performStartAction = true)
|
||||
{
|
||||
// avoid attempting to continue before a selection has been obtained.
|
||||
// this could happen via a user interaction while the carousel is still in a loading state.
|
||||
if (Carousel.SelectedBeatmap == null) return;
|
||||
|
||||
// if we have a pending filter operation, we want to run it now.
|
||||
// it could change selection (ie. if the ruleset has been changed).
|
||||
Carousel.FlushPendingFilterOperations();
|
||||
|
@ -49,8 +49,8 @@ namespace osu.Game.Screens.Tournament
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
|
||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
|
||||
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures, Storage storage)
|
||||
|
@ -71,9 +71,9 @@ namespace osu.Game.Skinning
|
||||
|
||||
private void onSourceChanged() => SourceChanged?.Invoke();
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
fallbackSource = dependencies.Get<ISkinSource>();
|
||||
dependencies.CacheAs<ISkinSource>(this);
|
||||
|
@ -36,8 +36,8 @@ namespace osu.Game.Storyboards.Drawables
|
||||
public override bool RemoveCompletedTransforms => false;
|
||||
|
||||
private DependencyContainer dependencies;
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) =>
|
||||
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
|
||||
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
public DrawableStoryboard(Storyboard storyboard)
|
||||
{
|
||||
|
69
osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs
Normal file
69
osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs
Normal file
@ -0,0 +1,69 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using System.IO;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Beatmaps;
|
||||
|
||||
namespace osu.Game.Storyboards.Drawables
|
||||
{
|
||||
public class DrawableStoryboardSample : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The amount of time allowable beyond the start time of the sample, for the sample to start.
|
||||
/// </summary>
|
||||
private const double allowable_late_start = 100;
|
||||
|
||||
private readonly StoryboardSample sample;
|
||||
private SampleChannel channel;
|
||||
|
||||
public override bool RemoveWhenNotAlive => false;
|
||||
|
||||
public DrawableStoryboardSample(StoryboardSample sample)
|
||||
{
|
||||
this.sample = sample;
|
||||
LifetimeStart = sample.Time;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IBindableBeatmap beatmap)
|
||||
{
|
||||
// Try first with the full name, then attempt with no path
|
||||
channel = beatmap.Value.Skin.GetSample(sample.Path) ?? beatmap.Value.Skin.GetSample(Path.ChangeExtension(sample.Path, null));
|
||||
|
||||
if (channel != null)
|
||||
channel.Volume.Value = sample.Volume / 100;
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
// TODO: this logic will need to be consolidated with other game samples like hitsounds.
|
||||
if (Time.Current < sample.Time)
|
||||
{
|
||||
// We've rewound before the start time of the sample
|
||||
channel?.Stop();
|
||||
|
||||
// In the case that the user fast-forwards to a point far beyond the start time of the sample,
|
||||
// we want to be able to fall into the if-conditional below (therefore we must not have a life time end)
|
||||
LifetimeStart = sample.Time;
|
||||
LifetimeEnd = double.MaxValue;
|
||||
}
|
||||
else if (Time.Current - Time.Elapsed < sample.Time)
|
||||
{
|
||||
// We've passed the start time of the sample. We only play the sample if we're within an allowable range
|
||||
// from the sample's start, to reduce layering if we've been fast-forwarded far into the future
|
||||
if (Time.Current - sample.Time < allowable_late_start)
|
||||
channel?.Play();
|
||||
|
||||
// In the case that the user rewinds to a point far behind the start time of the sample,
|
||||
// we want to be able to fall into the if-conditional above (therefore we must not have a life time start)
|
||||
LifetimeStart = double.MinValue;
|
||||
LifetimeEnd = sample.Time;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,14 +2,14 @@
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using System;
|
||||
using osu.Game.Storyboards.Drawables;
|
||||
|
||||
namespace osu.Game.Storyboards
|
||||
{
|
||||
public class StoryboardSample : IStoryboardElement
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public bool IsDrawable => false;
|
||||
public bool IsDrawable => true;
|
||||
|
||||
public double Time;
|
||||
public float Volume;
|
||||
@ -21,9 +21,6 @@ namespace osu.Game.Storyboards
|
||||
Volume = volume;
|
||||
}
|
||||
|
||||
public Drawable CreateDrawable()
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
public Drawable CreateDrawable() => new DrawableStoryboardSample(this);
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ namespace osu.Game.Tests.Visual
|
||||
Clock = new EditorClock(new ControlPointInfo(), 5000, BeatDivisor) { IsCoupled = false };
|
||||
}
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
dependencies.Cache(BeatDivisor);
|
||||
dependencies.CacheAs<IFrameBasedClock>(Clock);
|
||||
|
@ -20,9 +20,9 @@ namespace osu.Game.Tests.Visual
|
||||
|
||||
protected DependencyContainer Dependencies { get; private set; }
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
Dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
|
||||
Dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
Dependencies.CacheAs<BindableBeatmap>(beatmap);
|
||||
Dependencies.CacheAs<IBindableBeatmap>(beatmap);
|
||||
|
@ -42,7 +42,9 @@ namespace osu.Game.Users
|
||||
return;
|
||||
|
||||
country = value;
|
||||
sprite.Texture = getFlagTexture();
|
||||
|
||||
if (IsLoaded)
|
||||
sprite.Texture = getFlagTexture();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,6 @@ namespace osu.Game.Users
|
||||
|
||||
public Bindable<UserStatus> Status = new Bindable<UserStatus>();
|
||||
|
||||
[JsonProperty(@"age")]
|
||||
public int? Age;
|
||||
|
||||
//public Team Team;
|
||||
|
||||
[JsonProperty(@"profile_colour")]
|
||||
|
@ -14,11 +14,11 @@
|
||||
<ProjectReference Include="..\osu-resources\osu.Game.Resources\osu.Game.Resources.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="Humanizer" Version="2.3.3" />
|
||||
<PackageReference Include="Humanizer" Version="2.4.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.1.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2018.705.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2018.712.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.17.1" />
|
||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
|
||||
|
@ -23,6 +23,7 @@
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ClassWithVirtualMembersNeverInherited_002EGlobal/@EntryIndexedValue">HINT</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CollectionNeverQueried_002EGlobal/@EntryIndexedValue">SUGGESTION</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CollectionNeverQueried_002ELocal/@EntryIndexedValue">HINT</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CommentTypo/@EntryIndexedValue">HINT</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=CompareOfFloatsByEqualityOperator/@EntryIndexedValue">HINT</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertClosureToMethodGroup/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfDoToWhile/@EntryIndexedValue">WARNING</s:String>
|
||||
@ -43,6 +44,7 @@
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=FieldCanBeMadeReadOnly_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=FieldCanBeMadeReadOnly_002ELocal/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ForCanBeConvertedToForeach/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=IdentifierTypo/@EntryIndexedValue">HINT</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ImpureMethodCallOnReadonlyValueField/@EntryIndexedValue">HINT</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue">ERROR</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InheritdocConsiderUsage/@EntryIndexedValue">HINT</s:String>
|
||||
@ -133,6 +135,7 @@
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E2/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E3/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E4/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue">HINT</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FBuiltInTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SwitchStatementMissingSomeCases/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
@ -666,4 +669,22 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Beatmap/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=beatmaps/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=beatmap_0027s/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=bindable/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Catmull/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Drawables/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=gameplay/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=hitobjects/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=keymods/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kiai/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Leaderboard/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Leaderboards/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Playfield/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=resampler/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ruleset/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=rulesets/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Taiko/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Unranked/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
|
Loading…
Reference in New Issue
Block a user