1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 10:22:56 +08:00

Merge branch 'master' into editor-beat-snap-always

This commit is contained in:
Bartłomiej Dach 2020-11-30 18:39:22 +01:00 committed by GitHub
commit 5fbe1823a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 54 additions and 41 deletions

View File

@ -30,6 +30,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
public void UpdateResult() => base.UpdateResult(true); public void UpdateResult() => base.UpdateResult(true);
protected override double MaximumJudgementOffset => base.MaximumJudgementOffset * release_window_lenience;
protected override void CheckForResult(bool userTriggered, double timeOffset) protected override void CheckForResult(bool userTriggered, double timeOffset)
{ {
Debug.Assert(HitObject.HitWindows != null); Debug.Assert(HitObject.HitWindows != null);

View File

@ -9,9 +9,7 @@ using osu.Framework.Graphics;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Osu.UI;
using osu.Game.Rulesets.Scoring;
using osuTK; using osuTK;
namespace osu.Game.Rulesets.Osu.Objects.Drawables namespace osu.Game.Rulesets.Osu.Objects.Drawables
@ -61,13 +59,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
PositionBindable.BindTo(HitObject.PositionBindable); PositionBindable.BindTo(HitObject.PositionBindable);
StackHeightBindable.BindTo(HitObject.StackHeightBindable); StackHeightBindable.BindTo(HitObject.StackHeightBindable);
ScaleBindable.BindTo(HitObject.ScaleBindable); ScaleBindable.BindTo(HitObject.ScaleBindable);
// Manually set to reduce the number of future alive objects to a bare minimum.
LifetimeStart = HitObject.StartTime - HitObject.TimePreempt;
// Arbitrary lifetime end to prevent past objects in idle states remaining alive in non-frame-stable contexts.
// An extra 1000ms is added to always overestimate the true lifetime, and a more exact value is set by hit transforms and the following expiry.
LifetimeEnd = HitObject.GetEndTime() + HitObject.HitWindows.WindowFor(HitResult.Miss) + 1000;
} }
protected override void OnFree() protected override void OnFree()

View File

@ -1,6 +1,8 @@
// 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.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Objects.Drawables namespace osu.Game.Rulesets.Osu.Objects.Drawables
{ {
public class DrawableSpinnerTick : DrawableOsuHitObject public class DrawableSpinnerTick : DrawableOsuHitObject
@ -17,6 +19,16 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{ {
} }
private DrawableSpinner drawableSpinner;
protected override void OnParentReceived(DrawableHitObject parent)
{
base.OnParentReceived(parent);
drawableSpinner = (DrawableSpinner)parent;
}
protected override double MaximumJudgementOffset => drawableSpinner.HitObject.Duration;
/// <summary> /// <summary>
/// Apply a judgement result. /// Apply a judgement result.
/// </summary> /// </summary>

View File

@ -176,6 +176,8 @@ namespace osu.Game.Rulesets.Osu.UI
public OsuHitObjectLifetimeEntry(HitObject hitObject) public OsuHitObjectLifetimeEntry(HitObject hitObject)
: base(hitObject) : base(hitObject)
{ {
// Prevent past objects in idles states from remaining alive as their end times are skipped in non-frame-stable contexts.
LifetimeEnd = HitObject.GetEndTime() + HitObject.HitWindows.WindowFor(HitResult.Miss);
} }
protected override double InitialLifetimeOffset => ((OsuHitObject)HitObject).TimePreempt; protected override double InitialLifetimeOffset => ((OsuHitObject)HitObject).TimePreempt;

View File

@ -28,6 +28,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
Filled = HitObject.FirstTick Filled = HitObject.FirstTick
}); });
protected override double MaximumJudgementOffset => HitObject.HitWindow;
protected override void CheckForResult(bool userTriggered, double timeOffset) protected override void CheckForResult(bool userTriggered, double timeOffset)
{ {
if (!userTriggered) if (!userTriggered)

View File

@ -6,13 +6,13 @@ using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Notifications;
using osuTK.Graphics;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using System; using System;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Graphics;
namespace osu.Game.Overlays namespace osu.Game.Overlays
{ {
@ -44,8 +44,7 @@ namespace osu.Game.Overlays
new Box new Box
{ {
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = Color4.Black, Colour = OsuColour.Gray(0.05f),
Alpha = 0.6f
}, },
new OsuScrollContainer new OsuScrollContainer
{ {

View File

@ -1,16 +1,15 @@
// 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 osuTK; using System.Collections.Generic;
using osuTK.Graphics; using System.Linq;
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.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using System.Collections.Generic; using osuTK.Graphics;
using System.Linq;
namespace osu.Game.Overlays.Settings namespace osu.Game.Overlays.Settings
{ {
@ -26,7 +25,7 @@ namespace osu.Game.Overlays.Settings
public virtual IEnumerable<string> FilterTerms => new[] { Header }; public virtual IEnumerable<string> FilterTerms => new[] { Header };
private const int header_size = 26; private const int header_size = 26;
private const int header_margin = 25; private const int margin = 20;
private const int border_size = 2; private const int border_size = 2;
public bool MatchingFilter public bool MatchingFilter
@ -38,7 +37,7 @@ namespace osu.Game.Overlays.Settings
protected SettingsSection() protected SettingsSection()
{ {
Margin = new MarginPadding { Top = 20 }; Margin = new MarginPadding { Top = margin };
AutoSizeAxes = Axes.Y; AutoSizeAxes = Axes.Y;
RelativeSizeAxes = Axes.X; RelativeSizeAxes = Axes.X;
@ -46,10 +45,9 @@ namespace osu.Game.Overlays.Settings
{ {
Margin = new MarginPadding Margin = new MarginPadding
{ {
Top = header_size + header_margin Top = header_size
}, },
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 30),
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
}; };
@ -70,7 +68,7 @@ namespace osu.Game.Overlays.Settings
{ {
Padding = new MarginPadding Padding = new MarginPadding
{ {
Top = 20 + border_size, Top = margin + border_size,
Bottom = 10, Bottom = 10,
}, },
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
@ -82,7 +80,11 @@ namespace osu.Game.Overlays.Settings
Font = OsuFont.GetFont(size: header_size), Font = OsuFont.GetFont(size: header_size),
Text = Header, Text = Header,
Colour = colours.Yellow, Colour = colours.Yellow,
Margin = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS, Right = SettingsPanel.CONTENT_MARGINS } Margin = new MarginPadding
{
Left = SettingsPanel.CONTENT_MARGINS,
Right = SettingsPanel.CONTENT_MARGINS
}
}, },
FlowContent FlowContent
} }

View File

@ -39,7 +39,7 @@ namespace osu.Game.Overlays.Settings
FlowContent = new FillFlowContainer FlowContent = new FillFlowContainer
{ {
Direction = FillDirection.Vertical, Direction = FillDirection.Vertical,
Spacing = new Vector2(0, 5), Spacing = new Vector2(0, 8),
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y, AutoSizeAxes = Axes.Y,
}; };
@ -53,7 +53,7 @@ namespace osu.Game.Overlays.Settings
new OsuSpriteText new OsuSpriteText
{ {
Text = Header.ToUpperInvariant(), Text = Header.ToUpperInvariant(),
Margin = new MarginPadding { Bottom = 10, Left = SettingsPanel.CONTENT_MARGINS, Right = SettingsPanel.CONTENT_MARGINS }, Margin = new MarginPadding { Vertical = 30, Left = SettingsPanel.CONTENT_MARGINS, Right = SettingsPanel.CONTENT_MARGINS },
Font = OsuFont.GetFont(weight: FontWeight.Bold), Font = OsuFont.GetFont(weight: FontWeight.Bold),
}, },
FlowContent FlowContent

View File

@ -9,9 +9,9 @@ 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.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osuTK; using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays.Settings namespace osu.Game.Overlays.Settings
{ {
@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Settings
{ {
new Box new Box
{ {
Colour = Color4.Black, Colour = OsuColour.Gray(0.02f),
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
}, },
new SidebarScrollContainer new SidebarScrollContainer

View File

@ -62,7 +62,6 @@ namespace osu.Game.Overlays
switch (state.NewValue) switch (state.NewValue)
{ {
case Visibility.Visible: case Visibility.Visible:
Background.FadeTo(0.9f, 300, Easing.OutQuint);
Sidebar?.FadeColour(Color4.DarkGray, 300, Easing.OutQuint); Sidebar?.FadeColour(Color4.DarkGray, 300, Easing.OutQuint);
SectionsContainer.FadeOut(300, Easing.OutQuint); SectionsContainer.FadeOut(300, Easing.OutQuint);
@ -70,7 +69,6 @@ namespace osu.Game.Overlays
break; break;
case Visibility.Hidden: case Visibility.Hidden:
Background.FadeTo(0.6f, 500, Easing.OutQuint);
Sidebar?.FadeColour(Color4.White, 300, Easing.OutQuint); Sidebar?.FadeColour(Color4.White, 300, Easing.OutQuint);
SectionsContainer.FadeIn(500, Easing.OutQuint); SectionsContainer.FadeIn(500, Easing.OutQuint);

View File

@ -12,6 +12,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; 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.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings;
@ -72,8 +73,8 @@ namespace osu.Game.Overlays
Origin = Anchor.TopRight, Origin = Anchor.TopRight,
Scale = new Vector2(2, 1), // over-extend to the left for transitions Scale = new Vector2(2, 1), // over-extend to the left for transitions
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = Color4.Black, Colour = OsuColour.Gray(0.05f),
Alpha = 0.6f, Alpha = 1,
}, },
SectionsContainer = new SettingsSectionsContainer SectionsContainer = new SettingsSectionsContainer
{ {
@ -214,7 +215,7 @@ namespace osu.Game.Overlays
base.UpdateAfterChildren(); base.UpdateAfterChildren();
// no null check because the usage of this class is strict // no null check because the usage of this class is strict
HeaderBackground.Alpha = -ExpandableHeader.Y / ExpandableHeader.LayoutSize.Y * 0.5f; HeaderBackground.Alpha = -ExpandableHeader.Y / ExpandableHeader.LayoutSize.Y;
} }
} }
} }

View File

@ -710,6 +710,18 @@ namespace osu.Game.Rulesets.Objects.Drawables
UpdateResult(false); UpdateResult(false);
} }
/// <summary>
/// The maximum offset from the end time of <see cref="HitObject"/> at which this <see cref="DrawableHitObject"/> can be judged.
/// The time offset of <see cref="Result"/> will be clamped to this value during <see cref="ApplyResult"/>.
/// <para>
/// Defaults to the miss window of <see cref="HitObject"/>.
/// </para>
/// </summary>
/// <remarks>
/// This does not affect the time offset provided to invocations of <see cref="CheckForResult"/>.
/// </remarks>
protected virtual double MaximumJudgementOffset => HitObject.HitWindows?.WindowFor(HitResult.Miss) ?? 0;
/// <summary> /// <summary>
/// Applies the <see cref="Result"/> of this <see cref="DrawableHitObject"/>, notifying responders such as /// Applies the <see cref="Result"/> of this <see cref="DrawableHitObject"/>, notifying responders such as
/// the <see cref="ScoreProcessor"/> of the <see cref="JudgementResult"/>. /// the <see cref="ScoreProcessor"/> of the <see cref="JudgementResult"/>.
@ -749,14 +761,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
$"{GetType().ReadableName()} applied an invalid hit result (was: {Result.Type}, expected: [{Result.Judgement.MinResult} ... {Result.Judgement.MaxResult}])."); $"{GetType().ReadableName()} applied an invalid hit result (was: {Result.Type}, expected: [{Result.Judgement.MinResult} ... {Result.Judgement.MaxResult}]).");
} }
// Ensure that the judgement is given a valid time offset, because this may not get set by the caller Result.TimeOffset = Math.Min(MaximumJudgementOffset, Time.Current - HitObject.GetEndTime());
var endTime = HitObject.GetEndTime();
Result.TimeOffset = Time.Current - endTime;
double missWindow = HitObject.HitWindows.WindowFor(HitResult.Miss);
if (missWindow > 0)
Result.TimeOffset = Math.Min(Result.TimeOffset, missWindow);
if (Result.HasResult) if (Result.HasResult)
updateState(Result.IsHit ? ArmedState.Hit : ArmedState.Miss); updateState(Result.IsHit ? ArmedState.Hit : ArmedState.Miss);
@ -778,8 +783,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
if (Judged) if (Judged)
return false; return false;
var endTime = HitObject.GetEndTime(); CheckForResult(userTriggered, Time.Current - HitObject.GetEndTime());
CheckForResult(userTriggered, Time.Current - endTime);
return Judged; return Judged;
} }