1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 03:22:55 +08:00

Merge branch 'master' into editor-timeline-hitobject-display

This commit is contained in:
Dan Balasescu 2019-12-09 14:34:55 +09:00 committed by GitHub
commit 5738ef5fab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 112 additions and 64 deletions

20
osu.Desktop/app.manifest Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity version="1.0.0.0" name="osu!" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
<applicationRequestMinimum>
<defaultAssemblyRequest permissionSetReference="Custom" />
<PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
</applicationRequestMinimum>
</security>
</trustInfo>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</asmv1:assembly>

View File

@ -8,6 +8,7 @@
<Title>osu!lazer</Title> <Title>osu!lazer</Title>
<Product>osu!lazer</Product> <Product>osu!lazer</Product>
<ApplicationIcon>lazer.ico</ApplicationIcon> <ApplicationIcon>lazer.ico</ApplicationIcon>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Version>0.0.0</Version> <Version>0.0.0</Version>
<FileVersion>0.0.0</FileVersion> <FileVersion>0.0.0</FileVersion>
</PropertyGroup> </PropertyGroup>

View File

@ -49,7 +49,11 @@ namespace osu.Game.Rulesets.Osu.Skinning
return this.GetAnimation(component.LookupName, true, false); return this.GetAnimation(component.LookupName, true, false);
case OsuSkinComponents.SliderFollowCircle: case OsuSkinComponents.SliderFollowCircle:
return this.GetAnimation("sliderfollowcircle", true, true); var followCircle = this.GetAnimation("sliderfollowcircle", true, true);
if (followCircle != null)
// follow circles are 2x the hitcircle resolution in legacy skins (since they are scaled down from >1x
followCircle.Scale *= 0.5f;
return followCircle;
case OsuSkinComponents.SliderBall: case OsuSkinComponents.SliderBall:
var sliderBallContent = this.GetAnimation("sliderb", true, true, ""); var sliderBallContent = this.GetAnimation("sliderb", true, true, "");

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio; using osu.Framework.Audio;
@ -19,6 +20,7 @@ using osu.Game.Overlays;
using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Screens; using osu.Game.Screens;
@ -55,6 +57,9 @@ namespace osu.Game.Tests.Visual.Gameplay
beforeLoadAction?.Invoke(); beforeLoadAction?.Invoke();
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
foreach (var mod in Mods.Value.OfType<IApplicableToClock>())
mod.ApplyToClock(Beatmap.Value.Track);
InputManager.Child = container = new TestPlayerLoaderContainer( InputManager.Child = container = new TestPlayerLoaderContainer(
loader = new TestPlayerLoader(() => loader = new TestPlayerLoader(() =>
{ {
@ -63,6 +68,24 @@ namespace osu.Game.Tests.Visual.Gameplay
})); }));
} }
/// <summary>
/// When <see cref="PlayerLoader"/> exits early, it has to wait for the player load task
/// to complete before running disposal on player. This previously caused an issue where mod
/// speed adjustments were undone too late, causing cross-screen pollution.
/// </summary>
[Test]
public void TestEarlyExit()
{
AddStep("load dummy beatmap", () => ResetPlayer(false, () => Mods.Value = new[] { new OsuModNightcore() }));
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
AddAssert("mod rate applied", () => Beatmap.Value.Track.Rate != 1);
AddStep("exit loader", () => loader.Exit());
AddUntilStep("wait for not current", () => !loader.IsCurrentScreen());
AddAssert("player did not load", () => !player.IsLoaded);
AddUntilStep("player disposed", () => loader.DisposalTask?.IsCompleted == true);
AddAssert("mod rate still applied", () => Beatmap.Value.Track.Rate != 1);
}
[Test] [Test]
public void TestBlockLoadViaMouseMovement() public void TestBlockLoadViaMouseMovement()
{ {
@ -196,6 +219,8 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
public new VisualSettings VisualSettings => base.VisualSettings; public new VisualSettings VisualSettings => base.VisualSettings;
public new Task DisposalTask => base.DisposalTask;
public TestPlayerLoader(Func<Player> createPlayer) public TestPlayerLoader(Func<Player> createPlayer)
: base(createPlayer) : base(createPlayer)
{ {

View File

@ -168,7 +168,7 @@ namespace osu.Game.Beatmaps.Drawables
difficultyName.Text = beatmap.Version; difficultyName.Text = beatmap.Version;
starRating.Text = $"{beatmap.StarDifficulty:0.##}"; starRating.Text = $"{beatmap.StarDifficulty:0.##}";
difficultyFlow.Colour = colours.ForDifficultyRating(beatmap.DifficultyRating); difficultyFlow.Colour = colours.ForDifficultyRating(beatmap.DifficultyRating, true);
return true; return true;
} }

View File

@ -38,7 +38,7 @@ namespace osu.Game.Graphics
} }
} }
public Color4 ForDifficultyRating(DifficultyRating difficulty) public Color4 ForDifficultyRating(DifficultyRating difficulty, bool useLighterColour = false)
{ {
switch (difficulty) switch (difficulty)
{ {
@ -56,10 +56,10 @@ namespace osu.Game.Graphics
return Pink; return Pink;
case DifficultyRating.Expert: case DifficultyRating.Expert:
return Purple; return useLighterColour ? PurpleLight : Purple;
case DifficultyRating.ExpertPlus: case DifficultyRating.ExpertPlus:
return Gray0; return useLighterColour ? Gray9 : Gray0;
} }
} }

View File

@ -63,7 +63,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
return; return;
for (int i = 0; i < value.Count; i++) for (int i = 0; i < value.Count; i++)
backgroundFlow.Add(new ScoreTableRowBackground(i)); backgroundFlow.Add(new ScoreTableRowBackground(i, value[i]));
Columns = createHeaders(value[0]); Columns = createHeaders(value[0]);
Content = value.Select((s, i) => createContent(i, s)).ToArray().ToRectangular(); Content = value.Select((s, i) => createContent(i, s)).ToArray().ToRectangular();

View File

@ -7,6 +7,8 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Online.API;
using osu.Game.Scoring;
namespace osu.Game.Overlays.BeatmapSet.Scores namespace osu.Game.Overlays.BeatmapSet.Scores
{ {
@ -17,8 +19,14 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
private readonly Box hoveredBackground; private readonly Box hoveredBackground;
private readonly Box background; private readonly Box background;
public ScoreTableRowBackground(int index) private readonly int index;
private readonly ScoreInfo score;
public ScoreTableRowBackground(int index, ScoreInfo score)
{ {
this.index = index;
this.score = score;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
Height = 25; Height = 25;
@ -37,16 +45,21 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
Alpha = 0, Alpha = 0,
}, },
}; };
if (index % 2 != 0)
background.Alpha = 0;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours, IAPIProvider api)
{ {
hoveredBackground.Colour = colours.Gray4; var isOwnScore = api.LocalUser.Value.Id == score.UserID;
if (isOwnScore)
background.Colour = colours.GreenDarker;
else if (index % 2 == 0)
background.Colour = colours.Gray3; background.Colour = colours.Gray3;
else
background.Alpha = 0;
hoveredBackground.Colour = isOwnScore ? colours.GreenDark : colours.Gray4;
} }
protected override bool OnHover(HoverEvent e) protected override bool OnHover(HoverEvent e)

View File

@ -167,10 +167,6 @@ namespace osu.Game.Overlays.Mods
{ {
switch (e.Button) switch (e.Button)
{ {
case MouseButton.Left:
SelectNext(1);
break;
case MouseButton.Right: case MouseButton.Right:
SelectNext(-1); SelectNext(-1);
break; break;
@ -180,6 +176,13 @@ namespace osu.Game.Overlays.Mods
return true; return true;
} }
protected override bool OnClick(ClickEvent e)
{
SelectNext(1);
return true;
}
/// <summary> /// <summary>
/// Select the next available mod in a specified direction. /// Select the next available mod in a specified direction.
/// </summary> /// </summary>

View File

@ -3,16 +3,14 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Input.Bindings; using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings;
using osu.Game.Screens.Ranking;
using osuTK; using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays namespace osu.Game.Overlays
{ {
@ -36,21 +34,21 @@ namespace osu.Game.Overlays
protected override bool DimMainContent => false; // dimming is handled by main overlay protected override bool DimMainContent => false; // dimming is handled by main overlay
private class BackButton : OsuClickableContainer, IKeyBindingHandler<GlobalAction> private class BackButton : OsuButton
{ {
private AspectContainer aspect;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
Size = new Vector2(Sidebar.DEFAULT_WIDTH); Size = new Vector2(Sidebar.DEFAULT_WIDTH);
Children = new Drawable[]
BackgroundColour = Color4.Black;
AddRange(new Drawable[]
{ {
aspect = new AspectContainer new Container
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Y,
Children = new Drawable[] Children = new Drawable[]
{ {
new SpriteIcon new SpriteIcon
@ -71,34 +69,8 @@ namespace osu.Game.Overlays
}, },
} }
} }
}; });
} }
protected override bool OnMouseDown(MouseDownEvent e)
{
aspect.ScaleTo(0.75f, 2000, Easing.OutQuint);
return base.OnMouseDown(e);
}
protected override bool OnMouseUp(MouseUpEvent e)
{
aspect.ScaleTo(1, 1000, Easing.OutElastic);
return base.OnMouseUp(e);
}
public bool OnPressed(GlobalAction action)
{
switch (action)
{
case GlobalAction.Back:
Click();
return true;
}
return false;
}
public bool OnReleased(GlobalAction action) => false;
} }
} }
} }

View File

@ -214,10 +214,13 @@ namespace osu.Game.Screens.Play
base.Update(); base.Update();
} }
private bool speedAdjustmentsApplied;
private void updateRate() private void updateRate()
{ {
if (sourceClock == null) return; if (sourceClock == null) return;
speedAdjustmentsApplied = true;
sourceClock.ResetSpeedAdjustments(); sourceClock.ResetSpeedAdjustments();
if (sourceClock is IHasTempoAdjust tempo) if (sourceClock is IHasTempoAdjust tempo)
@ -238,8 +241,13 @@ namespace osu.Game.Screens.Play
} }
private void removeSourceClockAdjustments() private void removeSourceClockAdjustments()
{
if (speedAdjustmentsApplied)
{ {
sourceClock.ResetSpeedAdjustments(); sourceClock.ResetSpeedAdjustments();
speedAdjustmentsApplied = false;
}
(sourceClock as IAdjustableAudioComponent)?.RemoveAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust); (sourceClock as IAdjustableAudioComponent)?.RemoveAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust);
} }
} }

View File

@ -55,7 +55,9 @@ namespace osu.Game.Screens.Play
protected override bool PlayResumeSound => false; protected override bool PlayResumeSound => false;
private Task loadTask; protected Task LoadTask { get; private set; }
protected Task DisposalTask { get; private set; }
private InputManager inputManager; private InputManager inputManager;
private IdleTracker idleTracker; private IdleTracker idleTracker;
@ -159,7 +161,7 @@ namespace osu.Game.Screens.Play
player.RestartCount = restartCount; player.RestartCount = restartCount;
player.RestartRequested = restartRequested; player.RestartRequested = restartRequested;
loadTask = LoadComponentAsync(player, _ => info.Loading = false); LoadTask = LoadComponentAsync(player, _ => info.Loading = false);
} }
private void contentIn() private void contentIn()
@ -250,7 +252,7 @@ namespace osu.Game.Screens.Play
{ {
if (!this.IsCurrentScreen()) return; if (!this.IsCurrentScreen()) return;
loadTask = null; LoadTask = null;
//By default, we want to load the player and never be returned to. //By default, we want to load the player and never be returned to.
//Note that this may change if the player we load requested a re-run. //Note that this may change if the player we load requested a re-run.
@ -301,7 +303,7 @@ namespace osu.Game.Screens.Play
if (isDisposing) if (isDisposing)
{ {
// if the player never got pushed, we should explicitly dispose it. // if the player never got pushed, we should explicitly dispose it.
loadTask?.ContinueWith(_ => player.Dispose()); DisposalTask = LoadTask?.ContinueWith(_ => player.Dispose());
} }
} }

View File

@ -29,13 +29,13 @@ namespace osu.Game.Skinning
/// <param name="defaultImplementation">A function to create the default skin implementation of this element.</param> /// <param name="defaultImplementation">A function to create the default skin implementation of this element.</param>
/// <param name="allowFallback">A conditional to decide whether to allow fallback to the default implementation if a skinned element is not present.</param> /// <param name="allowFallback">A conditional to decide whether to allow fallback to the default implementation if a skinned element is not present.</param>
/// <param name="confineMode">How (if at all) the <see cref="Drawable"/> should be resize to fit within our own bounds.</param> /// <param name="confineMode">How (if at all) the <see cref="Drawable"/> should be resize to fit within our own bounds.</param>
public SkinnableDrawable(ISkinComponent component, Func<ISkinComponent, Drawable> defaultImplementation, Func<ISkinSource, bool> allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) public SkinnableDrawable(ISkinComponent component, Func<ISkinComponent, Drawable> defaultImplementation, Func<ISkinSource, bool> allowFallback = null, ConfineMode confineMode = ConfineMode.NoScaling)
: this(component, allowFallback, confineMode) : this(component, allowFallback, confineMode)
{ {
createDefault = defaultImplementation; createDefault = defaultImplementation;
} }
protected SkinnableDrawable(ISkinComponent component, Func<ISkinSource, bool> allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) protected SkinnableDrawable(ISkinComponent component, Func<ISkinSource, bool> allowFallback = null, ConfineMode confineMode = ConfineMode.NoScaling)
: base(allowFallback) : base(allowFallback)
{ {
this.component = component; this.component = component;

View File

@ -19,7 +19,7 @@ namespace osu.Game.Skinning
[Resolved] [Resolved]
private TextureStore textures { get; set; } private TextureStore textures { get; set; }
public SkinnableSprite(string textureName, Func<ISkinSource, bool> allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) public SkinnableSprite(string textureName, Func<ISkinSource, bool> allowFallback = null, ConfineMode confineMode = ConfineMode.NoScaling)
: base(new SpriteComponent(textureName), allowFallback, confineMode) : base(new SpriteComponent(textureName), allowFallback, confineMode)
{ {
} }

View File

@ -8,7 +8,7 @@ namespace osu.Game.Skinning
{ {
public class SkinnableSpriteText : SkinnableDrawable, IHasText public class SkinnableSpriteText : SkinnableDrawable, IHasText
{ {
public SkinnableSpriteText(ISkinComponent component, Func<ISkinComponent, SpriteText> defaultImplementation, Func<ISkinSource, bool> allowFallback = null, ConfineMode confineMode = ConfineMode.ScaleDownToFit) public SkinnableSpriteText(ISkinComponent component, Func<ISkinComponent, SpriteText> defaultImplementation, Func<ISkinSource, bool> allowFallback = null, ConfineMode confineMode = ConfineMode.NoScaling)
: base(component, defaultImplementation, allowFallback, confineMode) : base(component, defaultImplementation, allowFallback, confineMode)
{ {
} }