1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-06 21:02:59 +08:00

Merge branch 'master' into fullscreen-overlay-surface

This commit is contained in:
Dean Herbert 2019-06-12 00:07:30 +09:00 committed by GitHub
commit a690a67a6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 93 additions and 119 deletions

View File

@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
if (beatmap.HitObjects.Count == 0) if (beatmap.HitObjects.Count == 0)
return new CatchDifficultyAttributes { Mods = mods }; return new CatchDifficultyAttributes { Mods = mods, Skills = skills };
// this is the same as osu!, so there's potential to share the implementation... maybe // 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) / clockRate; double preempt = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / clockRate;
@ -41,7 +41,8 @@ namespace osu.Game.Rulesets.Catch.Difficulty
StarRating = Math.Sqrt(skills[0].DifficultyValue()) * star_scaling_factor, StarRating = Math.Sqrt(skills[0].DifficultyValue()) * star_scaling_factor,
Mods = mods, Mods = mods,
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 = beatmap.HitObjects.Count(h => h is Fruit) + beatmap.HitObjects.OfType<JuiceStream>().SelectMany(j => j.NestedHitObjects).Count(h => !(h is TinyDroplet)) MaxCombo = beatmap.HitObjects.Count(h => h is Fruit) + beatmap.HitObjects.OfType<JuiceStream>().SelectMany(j => j.NestedHitObjects).Count(h => !(h is TinyDroplet)),
Skills = skills
}; };
} }

View File

@ -379,8 +379,8 @@ namespace osu.Game.Rulesets.Catch.UI
X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * speed, 0, 1); X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * speed, 0, 1);
// Correct overshooting. // Correct overshooting.
if (hyperDashDirection > 0 && hyperDashTargetPosition < X || if ((hyperDashDirection > 0 && hyperDashTargetPosition < X) ||
hyperDashDirection < 0 && hyperDashTargetPosition > X) (hyperDashDirection < 0 && hyperDashTargetPosition > X))
{ {
X = hyperDashTargetPosition; X = hyperDashTargetPosition;
SetHyperDashState(); SetHyperDashState();

View File

@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
if (beatmap.HitObjects.Count == 0) if (beatmap.HitObjects.Count == 0)
return new ManiaDifficultyAttributes { Mods = mods }; return new ManiaDifficultyAttributes { Mods = mods, Skills = skills };
return new ManiaDifficultyAttributes return new ManiaDifficultyAttributes
{ {
@ -38,6 +38,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
Mods = mods, Mods = mods,
// Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future // Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future
GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate, GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate,
Skills = skills
}; };
} }

View File

@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
break; break;
if (Vector2Extensions.Distance(stackBaseObject.Position, objectN.Position) < stack_distance if (Vector2Extensions.Distance(stackBaseObject.Position, objectN.Position) < stack_distance
|| stackBaseObject is Slider && Vector2Extensions.Distance(stackBaseObject.EndPosition, objectN.Position) < stack_distance) || (stackBaseObject is Slider && Vector2Extensions.Distance(stackBaseObject.EndPosition, objectN.Position) < stack_distance))
{ {
stackBaseIndex = n; stackBaseIndex = n;

View File

@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
if (beatmap.HitObjects.Count == 0) if (beatmap.HitObjects.Count == 0)
return new OsuDifficultyAttributes { Mods = mods }; return new OsuDifficultyAttributes { Mods = mods, Skills = skills };
double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier; double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier; double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
@ -50,7 +50,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
SpeedStrain = speedRating, 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, OverallDifficulty = (80 - hitWindowGreat) / 6,
MaxCombo = maxCombo MaxCombo = maxCombo,
Skills = skills
}; };
} }

View File

@ -37,11 +37,11 @@ namespace osu.Game.Rulesets.Osu.Mods
if (time < osuHit.HitObject.StartTime - relax_leniency) continue; if (time < osuHit.HitObject.StartTime - relax_leniency) continue;
if (osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime || osuHit.IsHit) if ((osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime) || osuHit.IsHit)
continue; continue;
requiresHit |= osuHit is DrawableHitCircle && osuHit.IsHovered && osuHit.HitObject.HitWindows.CanBeHit(relativetime); requiresHit |= osuHit is DrawableHitCircle && osuHit.IsHovered && osuHit.HitObject.HitWindows.CanBeHit(relativetime);
requiresHold |= osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered) || osuHit is DrawableSpinner; requiresHold |= (osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered)) || osuHit is DrawableSpinner;
} }
if (requiresHit) if (requiresHit)

View File

@ -6,7 +6,7 @@ using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.OpenGL.Buffers; using osu.Framework.Graphics.Batches;
using osu.Framework.Graphics.OpenGL.Vertices; using osu.Framework.Graphics.OpenGL.Vertices;
using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shaders;
@ -57,7 +57,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
// InvalidationID 1 forces an update of each part of the cursor trail the first time ApplyState is run on the draw node // InvalidationID 1 forces an update of each part of the cursor trail the first time ApplyState is run on the draw node
// This is to prevent garbage data from being sent to the vertex shader, resulting in visual issues on some platforms // This is to prevent garbage data from being sent to the vertex shader, resulting in visual issues on some platforms
parts[i].InvalidationID = 1; parts[i].InvalidationID = 1;
parts[i].WasUpdated = true;
} }
} }
@ -149,7 +148,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
public Vector2 Position; public Vector2 Position;
public float Time; public float Time;
public long InvalidationID; public long InvalidationID;
public bool WasUpdated;
} }
private class TrailDrawNode : DrawNode private class TrailDrawNode : DrawNode
@ -164,16 +162,13 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
private readonly TrailPart[] parts = new TrailPart[max_sprites]; private readonly TrailPart[] parts = new TrailPart[max_sprites];
private Vector2 size; private Vector2 size;
private readonly VertexBuffer<TexturedTrailVertex> vertexBuffer = new QuadVertexBuffer<TexturedTrailVertex>(max_sprites, BufferUsageHint.DynamicDraw); private readonly VertexBatch<TexturedTrailVertex> vertexBatch = new QuadBatch<TexturedTrailVertex>(max_sprites, 1);
public TrailDrawNode(CursorTrail source) public TrailDrawNode(CursorTrail source)
: base(source) : base(source)
{ {
for (int i = 0; i < max_sprites; i++) for (int i = 0; i < max_sprites; i++)
{
parts[i].InvalidationID = 0; parts[i].InvalidationID = 0;
parts[i].WasUpdated = false;
}
} }
public override void ApplyState() public override void ApplyState()
@ -194,56 +189,29 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
public override void Draw(Action<TexturedVertex2D> vertexAction) public override void Draw(Action<TexturedVertex2D> vertexAction)
{ {
shader.GetUniform<float>("g_FadeClock").UpdateValue(ref time);
int updateStart = -1, updateEnd = 0;
for (int i = 0; i < parts.Length; ++i)
{
if (parts[i].WasUpdated)
{
if (updateStart == -1)
updateStart = i;
updateEnd = i + 1;
int start = i * 4;
int end = start;
Vector2 pos = parts[i].Position;
float localTime = parts[i].Time;
DrawQuad(
texture,
new Quad(pos.X - size.X / 2, pos.Y - size.Y / 2, size.X, size.Y),
DrawColourInfo.Colour,
null,
v => vertexBuffer.Vertices[end++] = new TexturedTrailVertex
{
Position = v.Position,
TexturePosition = v.TexturePosition,
Time = localTime + 1,
Colour = v.Colour,
});
parts[i].WasUpdated = false;
}
else if (updateStart != -1)
{
vertexBuffer.UpdateRange(updateStart * 4, updateEnd * 4);
updateStart = -1;
}
}
// Update all remaining vertices that have been changed.
if (updateStart != -1)
vertexBuffer.UpdateRange(updateStart * 4, updateEnd * 4);
base.Draw(vertexAction); base.Draw(vertexAction);
shader.Bind(); shader.Bind();
shader.GetUniform<float>("g_FadeClock").UpdateValue(ref time);
texture.TextureGL.Bind(); for (int i = 0; i < parts.Length; ++i)
vertexBuffer.Draw(); {
Vector2 pos = parts[i].Position;
float localTime = parts[i].Time;
DrawQuad(
texture,
new Quad(pos.X - size.X / 2, pos.Y - size.Y / 2, size.X, size.Y),
DrawColourInfo.Colour,
null,
v => vertexBatch.Add(new TexturedTrailVertex
{
Position = v.Position,
TexturePosition = v.TexturePosition,
Time = localTime + 1,
Colour = v.Colour,
}));
}
shader.Unbind(); shader.Unbind();
} }
@ -252,7 +220,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);
vertexBuffer.Dispose(); vertexBatch.Dispose();
} }
} }

View File

@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{ {
if (beatmap.HitObjects.Count == 0) if (beatmap.HitObjects.Count == 0)
return new TaikoDifficultyAttributes { Mods = mods }; return new TaikoDifficultyAttributes { Mods = mods, Skills = skills };
return new TaikoDifficultyAttributes return new TaikoDifficultyAttributes
{ {
@ -36,6 +36,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
// Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future // Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future
GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate, GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate,
MaxCombo = beatmap.HitObjects.Count(h => h is Hit), MaxCombo = beatmap.HitObjects.Count(h => h is Hit),
Skills = skills
}; };
} }

View File

@ -189,7 +189,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert("pause overlay " + (isShown ? "shown" : "hidden"), () => Player.PauseOverlayVisible == isShown); AddAssert("pause overlay " + (isShown ? "shown" : "hidden"), () => Player.PauseOverlayVisible == isShown);
private void confirmClockRunning(bool isRunning) => private void confirmClockRunning(bool isRunning) =>
AddAssert("clock " + (isRunning ? "running" : "stopped"), () => Player.GameplayClockContainer.GameplayClock.IsRunning == isRunning); AddUntilStep("clock " + (isRunning ? "running" : "stopped"), () => Player.GameplayClockContainer.GameplayClock.IsRunning == isRunning);
protected override bool AllowFail => true; protected override bool AllowFail => true;

View File

@ -192,7 +192,7 @@ namespace osu.Game.Tests.Visual.UserInterface
public CursorContainer Cursor { get; } public CursorContainer Cursor { get; }
public bool ProvidingUserCursor { get; } public bool ProvidingUserCursor { get; }
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) || SmoothTransition && !ProvidingUserCursor; public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) || (SmoothTransition && !ProvidingUserCursor);
private readonly Box background; private readonly Box background;

View File

@ -27,7 +27,7 @@ namespace osu.Game.Graphics.Containers
protected void BeginConfirm() protected void BeginConfirm()
{ {
if (confirming || !AllowMultipleFires && fired) return; if (confirming || (!AllowMultipleFires && fired)) return;
confirming = true; confirming = true;

View File

@ -19,14 +19,14 @@ namespace osu.Game.Graphics.UserInterface
public class OsuAnimatedButton : OsuClickableContainer public class OsuAnimatedButton : OsuClickableContainer
{ {
/// <summary> /// <summary>
/// The colour that should be flashed when the <see cref="IconButton"/> is clicked. /// The colour that should be flashed when the <see cref="OsuAnimatedButton"/> is clicked.
/// </summary> /// </summary>
protected Color4 FlashColour = Color4.White.Opacity(0.3f); protected Color4 FlashColour = Color4.White.Opacity(0.3f);
private Color4 hoverColour = Color4.White.Opacity(0.1f); private Color4 hoverColour = Color4.White.Opacity(0.1f);
/// <summary> /// <summary>
/// The background colour of the <see cref="IconButton"/> while it is hovered. /// The background colour of the <see cref="OsuAnimatedButton"/> while it is hovered.
/// </summary> /// </summary>
protected Color4 HoverColour protected Color4 HoverColour
{ {

View File

@ -6,10 +6,9 @@ using osu.Framework.Audio;
using osu.Framework.Audio.Sample; using osu.Framework.Audio.Sample;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Containers;
using osuTK.Graphics; using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface namespace osu.Game.Graphics.UserInterface
@ -33,27 +32,26 @@ namespace osu.Game.Graphics.UserInterface
public string LabelText public string LabelText
{ {
get => labelSpriteText?.Text;
set set
{ {
if (labelSpriteText != null) if (labelText != null)
labelSpriteText.Text = value; labelText.Text = value;
} }
} }
public MarginPadding LabelPadding public MarginPadding LabelPadding
{ {
get => labelSpriteText?.Padding ?? new MarginPadding(); get => labelText?.Padding ?? new MarginPadding();
set set
{ {
if (labelSpriteText != null) if (labelText != null)
labelSpriteText.Padding = value; labelText.Padding = value;
} }
} }
protected readonly Nub Nub; protected readonly Nub Nub;
private readonly SpriteText labelSpriteText; private readonly OsuTextFlowContainer labelText;
private SampleChannel sampleChecked; private SampleChannel sampleChecked;
private SampleChannel sampleUnchecked; private SampleChannel sampleUnchecked;
@ -62,24 +60,28 @@ namespace osu.Game.Graphics.UserInterface
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
const float nub_padding = 5;
Children = new Drawable[] Children = new Drawable[]
{ {
labelSpriteText = new OsuSpriteText(), labelText = new OsuTextFlowContainer
{
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Padding = new MarginPadding { Right = Nub.EXPANDED_SIZE + nub_padding }
},
Nub = new Nub Nub = new Nub
{ {
Anchor = Anchor.CentreRight, Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight, Origin = Anchor.CentreRight,
Margin = new MarginPadding { Right = 5 }, Margin = new MarginPadding { Right = nub_padding },
}, },
new HoverClickSounds() new HoverClickSounds()
}; };
Nub.Current.BindTo(Current); Nub.Current.BindTo(Current);
Current.DisabledChanged += disabled => Current.DisabledChanged += disabled => labelText.Alpha = Nub.Alpha = disabled ? 0.3f : 1;
{
labelSpriteText.Alpha = Nub.Alpha = disabled ? 0.3f : 1;
};
} }
protected override void LoadComplete() protected override void LoadComplete()

View File

@ -37,7 +37,7 @@ namespace osu.Game.Online.API
public Bindable<User> LocalUser { get; } = new Bindable<User>(createGuestUser()); public Bindable<User> LocalUser { get; } = new Bindable<User>(createGuestUser());
protected bool HasLogin => authentication.Token.Value != null || !string.IsNullOrEmpty(ProvidedUsername) && !string.IsNullOrEmpty(password); protected bool HasLogin => authentication.Token.Value != null || (!string.IsNullOrEmpty(ProvidedUsername) && !string.IsNullOrEmpty(password));
private readonly CancellationTokenSource cancellationToken = new CancellationTokenSource(); private readonly CancellationTokenSource cancellationToken = new CancellationTokenSource();

View File

@ -69,7 +69,7 @@ namespace osu.Game.Online.Chat
if (displayText.Length == 0 || linkText.Length == 0) continue; if (displayText.Length == 0 || linkText.Length == 0) continue;
// Check for encapsulated links // Check for encapsulated links
if (result.Links.Find(l => l.Index <= index && l.Index + l.Length >= index + m.Length || index <= l.Index && index + m.Length >= l.Index + l.Length) == null) if (result.Links.Find(l => (l.Index <= index && l.Index + l.Length >= index + m.Length) || (index <= l.Index && index + m.Length >= l.Index + l.Length)) == null)
{ {
result.Text = result.Text.Remove(index, m.Length).Insert(index, displayText); result.Text = result.Text.Remove(index, m.Length).Insert(index, displayText);

View File

@ -56,7 +56,7 @@ namespace osu.Game.Overlays
private readonly Container channelSelectionContainer; private readonly Container channelSelectionContainer;
private readonly ChannelSelectionOverlay channelSelectionOverlay; private readonly ChannelSelectionOverlay channelSelectionOverlay;
public override bool Contains(Vector2 screenSpacePos) => chatContainer.ReceivePositionalInputAt(screenSpacePos) || channelSelectionOverlay.State.Value == Visibility.Visible && channelSelectionOverlay.ReceivePositionalInputAt(screenSpacePos); public override bool Contains(Vector2 screenSpacePos) => chatContainer.ReceivePositionalInputAt(screenSpacePos) || (channelSelectionOverlay.State.Value == Visibility.Visible && channelSelectionOverlay.ReceivePositionalInputAt(screenSpacePos));
public ChatOverlay() public ChatOverlay()
{ {

View File

@ -14,7 +14,6 @@ namespace osu.Game.Overlays.Settings
public override string LabelText public override string LabelText
{ {
get => checkbox.LabelText;
set => checkbox.LabelText = value; set => checkbox.LabelText = value;
} }
} }

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Difficulty namespace osu.Game.Rulesets.Difficulty
@ -8,6 +9,7 @@ namespace osu.Game.Rulesets.Difficulty
public class DifficultyAttributes public class DifficultyAttributes
{ {
public Mod[] Mods; public Mod[] Mods;
public Skill[] Skills;
public double StarRating; public double StarRating;
@ -15,9 +17,10 @@ namespace osu.Game.Rulesets.Difficulty
{ {
} }
public DifficultyAttributes(Mod[] mods, double starRating) public DifficultyAttributes(Mod[] mods, Skill[] skills, double starRating)
{ {
Mods = mods; Mods = mods;
Skills = skills;
StarRating = starRating; StarRating = starRating;
} }
} }

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Utils; using osu.Game.Rulesets.Difficulty.Utils;
@ -17,7 +18,7 @@ namespace osu.Game.Rulesets.Difficulty.Skills
/// <summary> /// <summary>
/// The peak strain for each <see cref="DifficultyCalculator.SectionLength"/> section of the beatmap. /// The peak strain for each <see cref="DifficultyCalculator.SectionLength"/> section of the beatmap.
/// </summary> /// </summary>
public IList<double> StrainPeaks => strainPeaks; public IReadOnlyList<double> StrainPeaks => strainPeaks;
/// <summary> /// <summary>
/// Strain values are multiplied by this number for the given skill. Used to balance the value of different skills between each other. /// Strain values are multiplied by this number for the given skill. Used to balance the value of different skills between each other.
@ -84,13 +85,12 @@ namespace osu.Game.Rulesets.Difficulty.Skills
/// </summary> /// </summary>
public double DifficultyValue() public double DifficultyValue()
{ {
strainPeaks.Sort((a, b) => b.CompareTo(a)); // Sort from highest to lowest strain.
double difficulty = 0; double difficulty = 0;
double weight = 1; double weight = 1;
// Difficulty is the weighted sum of the highest strains from every section. // Difficulty is the weighted sum of the highest strains from every section.
foreach (double strain in strainPeaks) // We're sorting from highest to lowest strain.
foreach (double strain in strainPeaks.OrderByDescending(d => d))
{ {
difficulty += strain * weight; difficulty += strain * weight;
weight *= DecayWeight; weight *= DecayWeight;

View File

@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Edit
/// </summary> /// </summary>
public readonly DrawableHitObject HitObject; public readonly DrawableHitObject HitObject;
protected override bool ShouldBeAlive => HitObject.IsAlive && HitObject.IsPresent || State == SelectionState.Selected; protected override bool ShouldBeAlive => (HitObject.IsAlive && HitObject.IsPresent) || State == SelectionState.Selected;
public override bool HandlePositionalInput => ShouldBeAlive; public override bool HandlePositionalInput => ShouldBeAlive;
public override bool RemoveWhenNotAlive => false; public override bool RemoveWhenNotAlive => false;

View File

@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
public override bool RemoveCompletedTransforms => false; public override bool RemoveCompletedTransforms => false;
protected override bool RequiresChildrenUpdate => true; protected override bool RequiresChildrenUpdate => true;
public override bool IsPresent => base.IsPresent || State.Value == ArmedState.Idle && Clock?.CurrentTime >= LifetimeStart; public override bool IsPresent => base.IsPresent || (State.Value == ArmedState.Idle && Clock?.CurrentTime >= LifetimeStart);
public readonly Bindable<ArmedState> State = new Bindable<ArmedState>(); public readonly Bindable<ArmedState> State = new Bindable<ArmedState>();

View File

@ -136,9 +136,9 @@ namespace osu.Game.Scoring.Legacy
score.Rank = score.Mods.Any(m => m is ModHidden || m is ModFlashlight) ? ScoreRank.XH : ScoreRank.X; score.Rank = score.Mods.Any(m => m is ModHidden || m is ModFlashlight) ? ScoreRank.XH : ScoreRank.X;
else if (ratio300 > 0.9 && ratio50 <= 0.01 && countMiss == 0) else if (ratio300 > 0.9 && ratio50 <= 0.01 && countMiss == 0)
score.Rank = score.Mods.Any(m => m is ModHidden || m is ModFlashlight) ? ScoreRank.SH : ScoreRank.S; score.Rank = score.Mods.Any(m => m is ModHidden || m is ModFlashlight) ? ScoreRank.SH : ScoreRank.S;
else if (ratio300 > 0.8 && countMiss == 0 || ratio300 > 0.9) else if ((ratio300 > 0.8 && countMiss == 0) || ratio300 > 0.9)
score.Rank = ScoreRank.A; score.Rank = ScoreRank.A;
else if (ratio300 > 0.7 && countMiss == 0 || ratio300 > 0.8) else if ((ratio300 > 0.7 && countMiss == 0) || ratio300 > 0.8)
score.Rank = ScoreRank.B; score.Rank = ScoreRank.B;
else if (ratio300 > 0.6) else if (ratio300 > 0.6)
score.Rank = ScoreRank.C; score.Rank = ScoreRank.C;
@ -159,9 +159,9 @@ namespace osu.Game.Scoring.Legacy
score.Rank = score.Mods.Any(m => m is ModHidden || m is ModFlashlight) ? ScoreRank.XH : ScoreRank.X; score.Rank = score.Mods.Any(m => m is ModHidden || m is ModFlashlight) ? ScoreRank.XH : ScoreRank.X;
else if (ratio300 > 0.9 && ratio50 <= 0.01 && countMiss == 0) else if (ratio300 > 0.9 && ratio50 <= 0.01 && countMiss == 0)
score.Rank = score.Mods.Any(m => m is ModHidden || m is ModFlashlight) ? ScoreRank.SH : ScoreRank.S; score.Rank = score.Mods.Any(m => m is ModHidden || m is ModFlashlight) ? ScoreRank.SH : ScoreRank.S;
else if (ratio300 > 0.8 && countMiss == 0 || ratio300 > 0.9) else if ((ratio300 > 0.8 && countMiss == 0) || ratio300 > 0.9)
score.Rank = ScoreRank.A; score.Rank = ScoreRank.A;
else if (ratio300 > 0.7 && countMiss == 0 || ratio300 > 0.8) else if ((ratio300 > 0.7 && countMiss == 0) || ratio300 > 0.8)
score.Rank = ScoreRank.B; score.Rank = ScoreRank.B;
else if (ratio300 > 0.6) else if (ratio300 > 0.6)
score.Rank = ScoreRank.C; score.Rank = ScoreRank.C;

View File

@ -69,6 +69,7 @@ namespace osu.Game.Screens.Play
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
sourceClock = (IAdjustableClock)beatmap.Track ?? new StopwatchClock(); sourceClock = (IAdjustableClock)beatmap.Track ?? new StopwatchClock();
(sourceClock as IAdjustableAudioComponent)?.AddAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust);
adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
@ -87,6 +88,8 @@ namespace osu.Game.Screens.Play
private double totalOffset => userOffsetClock.Offset + platformOffsetClock.Offset; private double totalOffset => userOffsetClock.Offset + platformOffsetClock.Offset;
private readonly BindableDouble pauseFreqAdjust = new BindableDouble(1);
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuConfigManager config) private void load(OsuConfigManager config)
{ {
@ -122,6 +125,8 @@ namespace osu.Game.Screens.Play
Seek(GameplayClock.CurrentTime); Seek(GameplayClock.CurrentTime);
adjustableClock.Start(); adjustableClock.Start();
IsPaused.Value = false; IsPaused.Value = false;
this.TransformBindableTo(pauseFreqAdjust, 1, 200, Easing.In);
} }
/// <summary> /// <summary>
@ -143,7 +148,8 @@ namespace osu.Game.Screens.Play
public void Stop() public void Stop()
{ {
adjustableClock.Stop(); this.TransformBindableTo(pauseFreqAdjust, 0, 200, Easing.Out).OnComplete(_ => adjustableClock.Stop());
IsPaused.Value = true; IsPaused.Value = true;
} }
@ -175,5 +181,11 @@ namespace osu.Game.Screens.Play
foreach (var mod in mods.OfType<IApplicableToClock>()) foreach (var mod in mods.OfType<IApplicableToClock>())
mod.ApplyToClock(sourceClock); mod.ApplyToClock(sourceClock);
} }
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
(sourceClock as IAdjustableAudioComponent)?.RemoveAdjustment(AdjustableProperty.Frequency, pauseFreqAdjust);
}
} }
} }

View File

@ -275,7 +275,7 @@ namespace osu.Game.Screens.Ranking
currentPage = page.NewValue?.CreatePage(); currentPage = page.NewValue?.CreatePage();
if (currentPage != null) if (currentPage != null)
circleInner.Add(currentPage); LoadComponentAsync(currentPage, circleInner.Add);
}, true); }, true);
} }

View File

@ -15,12 +15,10 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.4" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.609.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.609.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.611.1" />
<PackageReference Include="SharpCompress" Version="0.23.0" /> <PackageReference Include="SharpCompress" Version="0.23.0" />
<PackageReference Include="NUnit" Version="3.12.0" /> <PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="4.5.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\osu-framework\osu.Framework\osu.Framework.csproj" />
</ItemGroup>
</Project> </Project>

View File

@ -105,8 +105,8 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.518.0" /> <PackageReference Include="ppy.osu.Game.Resources" Version="2019.518.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.607.0" /> <PackageReference Include="ppy.osu.Framework" Version="2019.611.1" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.607.0" /> <PackageReference Include="ppy.osu.Framework.iOS" Version="2019.611.1" />
<PackageReference Include="SharpCompress" Version="0.22.0" /> <PackageReference Include="SharpCompress" Version="0.22.0" />
<PackageReference Include="NUnit" Version="3.11.0" /> <PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />

12
osu.sln
View File

@ -25,10 +25,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Taiko.Tes
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Osu.Tests", "osu.Game.Rulesets.Osu.Tests\osu.Game.Rulesets.Osu.Tests.csproj", "{DECCCC75-67AD-4C3D-BB84-FD0E01323511}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Osu.Tests", "osu.Game.Rulesets.Osu.Tests\osu.Game.Rulesets.Osu.Tests.csproj", "{DECCCC75-67AD-4C3D-BB84-FD0E01323511}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Framework", "..\osu-framework\osu.Framework\osu.Framework.csproj", "{C7D2DA3C-97BF-403C-9F75-115C8A64DAC1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Framework.NativeLibs", "..\osu-framework\osu.Framework.NativeLibs\osu.Framework.NativeLibs.csproj", "{35AD7F4C-81DC-4060-BFD1-C376DC4C4801}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -83,14 +79,6 @@ Global
{DECCCC75-67AD-4C3D-BB84-FD0E01323511}.Debug|Any CPU.Build.0 = Debug|Any CPU {DECCCC75-67AD-4C3D-BB84-FD0E01323511}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DECCCC75-67AD-4C3D-BB84-FD0E01323511}.Release|Any CPU.ActiveCfg = Release|Any CPU {DECCCC75-67AD-4C3D-BB84-FD0E01323511}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DECCCC75-67AD-4C3D-BB84-FD0E01323511}.Release|Any CPU.Build.0 = Release|Any CPU {DECCCC75-67AD-4C3D-BB84-FD0E01323511}.Release|Any CPU.Build.0 = Release|Any CPU
{C7D2DA3C-97BF-403C-9F75-115C8A64DAC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C7D2DA3C-97BF-403C-9F75-115C8A64DAC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C7D2DA3C-97BF-403C-9F75-115C8A64DAC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C7D2DA3C-97BF-403C-9F75-115C8A64DAC1}.Release|Any CPU.Build.0 = Release|Any CPU
{35AD7F4C-81DC-4060-BFD1-C376DC4C4801}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35AD7F4C-81DC-4060-BFD1-C376DC4C4801}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35AD7F4C-81DC-4060-BFD1-C376DC4C4801}.Release|Any CPU.ActiveCfg = Release|Any CPU
{35AD7F4C-81DC-4060-BFD1-C376DC4C4801}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE