1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 10:12:54 +08:00

Merge branch 'master' into fix-argon-health-bar-flash

This commit is contained in:
Dean Herbert 2023-10-11 00:19:51 +09:00
commit b9dbc8139b
No known key found for this signature in database
28 changed files with 204 additions and 101 deletions

View File

@ -15,7 +15,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon
[BackgroundDependencyLoader]
private void load()
{
RelativeSizeAxes = Axes.Both;
Anchor = Anchor.TopCentre;
Origin = Anchor.Centre;
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
InternalChildren = new Drawable[]
{

View File

@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Rulesets.Catch.UI;
using osuTK;
namespace osu.Game.Rulesets.Catch.Skinning.Default
{
@ -22,6 +23,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default
public DefaultCatcher()
{
Anchor = Anchor.TopCentre;
RelativeSizeAxes = Axes.Both;
InternalChild = sprite = new Sprite
{
@ -32,6 +34,15 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default
};
}
protected override void Update()
{
base.Update();
// matches stable's origin position since we're using the same catcher sprite.
// see LegacyCatcher for more information.
OriginPosition = new Vector2(DrawWidth / 2, 16f);
}
[BackgroundDependencyLoader]
private void load(TextureStore store, Bindable<CatcherAnimationState> currentState)
{

View File

@ -0,0 +1,33 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osuTK;
namespace osu.Game.Rulesets.Catch.Skinning.Legacy
{
public abstract partial class LegacyCatcher : CompositeDrawable
{
protected LegacyCatcher()
{
Anchor = Anchor.TopCentre;
Origin = Anchor.TopCentre;
// in stable, catcher sprites are displayed in their raw size. stable also has catcher sprites displayed with the following scale factors applied:
// 1. 0.5x, affecting all sprites in the playfield, computed here based on lazer's catch playfield dimensions (see WIDTH/HEIGHT constants in CatchPlayfield),
// source: https://github.com/peppy/osu-stable-reference/blob/1531237b63392e82c003c712faa028406073aa8f/osu!/GameplayElements/HitObjectManager.cs#L483-L494
// 2. 0.7x, a constant scale applied to all catcher sprites on construction.
AutoSizeAxes = Axes.Both;
Scale = new Vector2(0.5f * 0.7f);
}
protected override void Update()
{
base.Update();
// stable sets the Y origin position of the catcher to 16px in order for the catching range and OD scaling to align with the top of the catcher's plate in the default skin.
OriginPosition = new Vector2(DrawWidth / 2, 16f);
}
}
}

View File

@ -7,14 +7,12 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Skinning;
using osuTK;
namespace osu.Game.Rulesets.Catch.Skinning.Legacy
{
public partial class LegacyCatcherNew : CompositeDrawable
public partial class LegacyCatcherNew : LegacyCatcher
{
[Resolved]
private Bindable<CatcherAnimationState> currentState { get; set; } = null!;
@ -23,25 +21,12 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
private Drawable currentDrawable = null!;
public LegacyCatcherNew()
{
RelativeSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load(ISkinSource skin)
{
foreach (var state in Enum.GetValues<CatcherAnimationState>())
{
AddInternal(drawables[state] = getDrawableFor(state).With(d =>
{
d.Anchor = Anchor.TopCentre;
d.Origin = Anchor.TopCentre;
d.RelativeSizeAxes = Axes.Both;
d.Size = Vector2.One;
d.FillMode = FillMode.Fit;
d.Alpha = 0;
}));
AddInternal(drawables[state] = getDrawableFor(state).With(d => d.Alpha = 0));
}
currentDrawable = drawables[CatcherAnimationState.Idle];

View File

@ -3,30 +3,21 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Skinning;
using osuTK;
namespace osu.Game.Rulesets.Catch.Skinning.Legacy
{
public partial class LegacyCatcherOld : CompositeDrawable
public partial class LegacyCatcherOld : LegacyCatcher
{
public LegacyCatcherOld()
{
RelativeSizeAxes = Axes.Both;
AutoSizeAxes = Axes.Both;
}
[BackgroundDependencyLoader]
private void load(ISkinSource skin)
{
InternalChild = (skin.GetAnimation(@"fruit-ryuuta", true, true, true) ?? Empty()).With(d =>
{
d.Anchor = Anchor.TopCentre;
d.Origin = Anchor.TopCentre;
d.RelativeSizeAxes = Axes.Both;
d.Size = Vector2.One;
d.FillMode = FillMode.Fit;
});
InternalChild = skin.GetAnimation(@"fruit-ryuuta", true, true, true) ?? Empty();
}
}
}

View File

@ -17,12 +17,13 @@ namespace osu.Game.Rulesets.Catch.UI
public CatchPlayfieldAdjustmentContainer()
{
// because we are using centre anchor/origin, we will need to limit visibility in the future
// to ensure tall windows do not get a readability advantage.
// it may be possible to bake the catch-specific offsets (-100..340 mentioned below) into new values
// which are compatible with TopCentre alignment.
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Anchor = Anchor.TopCentre;
Origin = Anchor.TopCentre;
// playfields in stable are positioned vertically at three fourths the difference between the playfield height and the window height in stable.
// we can match that in lazer by using relative coordinates for Y and considering window height to be 1, and playfield height to be 0.8.
RelativePositionAxes = Axes.Y;
Y = (1 - playfield_size_adjust) / 4 * 3;
Size = new Vector2(playfield_size_adjust);
@ -42,18 +43,28 @@ namespace osu.Game.Rulesets.Catch.UI
/// </summary>
private partial class ScalingContainer : Container
{
public ScalingContainer()
{
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
}
protected override void Update()
{
base.Update();
// in stable, fruit fall vertically from -100 to 340.
// to emulate this, we want to make our playfield 440 gameplay pixels high.
// we then offset it -100 vertically in the position set below.
const float stable_v_offset_ratio = 440 / 384f;
// in stable, fruit fall vertically from 100 pixels above the playfield top down to the catcher's Y position (i.e. -100 to 340),
// see: https://github.com/peppy/osu-stable-reference/blob/1531237b63392e82c003c712faa028406073aa8f/osu!/GameplayElements/HitObjects/Fruits/HitCircleFruits.cs#L65
// we already have the playfield positioned similar to stable (see CatchPlayfieldAdjustmentContainer constructor),
// so we only need to increase this container's height 100 pixels above the playfield, and offset it to have the bottom at 340 rather than 384.
const float stable_fruit_start_position = -100;
const float stable_catcher_y_position = 340;
const float playfield_v_size_adjustment = (stable_catcher_y_position - stable_fruit_start_position) / CatchPlayfield.HEIGHT;
const float playfield_v_catcher_offset = stable_catcher_y_position - CatchPlayfield.HEIGHT;
Scale = new Vector2(Parent.ChildSize.X / CatchPlayfield.WIDTH);
Position = new Vector2(0, -100 * stable_v_offset_ratio + Scale.X);
Size = Vector2.Divide(new Vector2(1, stable_v_offset_ratio), Scale);
Scale = new Vector2(Parent!.ChildSize.X / CatchPlayfield.WIDTH);
Position = new Vector2(0f, playfield_v_catcher_offset * Scale.Y);
Size = Vector2.Divide(new Vector2(1, playfield_v_size_adjustment), Scale);
}
}
}

View File

@ -29,6 +29,13 @@ namespace osu.Game.Rulesets.Catch.UI
/// <summary>
/// The size of the catcher at 1x scale.
/// </summary>
/// <remarks>
/// This is mainly used to compute catching range, the actual catcher size may differ based on skin implementation and sprite textures.
/// This is also equivalent to the "catcherWidth" property in osu-stable when the game field and beatmap difficulty are set to default values.
/// </remarks>
/// <seealso cref="CatchPlayfield.WIDTH"/>
/// <seealso cref="CatchPlayfield.HEIGHT"/>
/// <seealso cref="IBeatmapDifficultyInfo.DEFAULT_DIFFICULTY"/>
public const float BASE_SIZE = 106.75f;
/// <summary>

View File

@ -6,7 +6,6 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Catch.Skinning.Default;
using osu.Game.Skinning;
using osuTK;
namespace osu.Game.Rulesets.Catch.UI
{
@ -26,8 +25,8 @@ namespace osu.Game.Rulesets.Catch.UI
: base(new CatchSkinComponentLookup(CatchSkinComponents.Catcher), _ => new DefaultCatcher())
{
Anchor = Anchor.TopCentre;
// Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling.
OriginPosition = new Vector2(0.5f, 0.06f) * Catcher.BASE_SIZE;
Origin = Anchor.TopCentre;
CentreComponent = false;
}
}
}

View File

@ -8,6 +8,8 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Caching;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Pooling;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Rulesets.Edit;
@ -23,7 +25,7 @@ namespace osu.Game.Rulesets.Mania.Edit
/// <summary>
/// A grid which displays coloured beat divisor lines in proximity to the selection or placement cursor.
/// </summary>
public partial class ManiaBeatSnapGrid : Component
public partial class ManiaBeatSnapGrid : CompositeComponent
{
private const double visible_range = 750;
@ -53,6 +55,8 @@ namespace osu.Game.Rulesets.Mania.Edit
private readonly List<ScrollingHitObjectContainer> grids = new List<ScrollingHitObjectContainer>();
private readonly DrawablePool<DrawableGridLine> linesPool = new DrawablePool<DrawableGridLine>(50);
private readonly Cached lineCache = new Cached();
private (double start, double end)? selectionTimeRange;
@ -60,6 +64,8 @@ namespace osu.Game.Rulesets.Mania.Edit
[BackgroundDependencyLoader]
private void load(HitObjectComposer composer)
{
AddInternal(linesPool);
foreach (var stage in ((ManiaPlayfield)composer.Playfield).Stages)
{
foreach (var column in stage.Columns)
@ -85,17 +91,10 @@ namespace osu.Game.Rulesets.Mania.Edit
}
}
private readonly Stack<DrawableGridLine> availableLines = new Stack<DrawableGridLine>();
private void createLines()
{
foreach (var grid in grids)
{
foreach (var line in grid.Objects.OfType<DrawableGridLine>())
availableLines.Push(line);
grid.Clear();
}
if (selectionTimeRange == null)
return;
@ -131,10 +130,13 @@ namespace osu.Game.Rulesets.Mania.Edit
foreach (var grid in grids)
{
if (!availableLines.TryPop(out var line))
line = new DrawableGridLine();
var line = linesPool.Get();
line.Apply(new HitObject
{
StartTime = time
});
line.HitObject.StartTime = time;
line.Colour = colour;
grid.Add(line);

View File

@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
private DrawableHitObject drawableObject { get; set; } = null!;
public LegacyApproachCircle()
: base("Gameplay/osu/approachcircle", OsuHitObject.OBJECT_DIMENSIONS)
: base("Gameplay/osu/approachcircle", OsuHitObject.OBJECT_DIMENSIONS * 2)
{
}

View File

@ -15,6 +15,9 @@ using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Containers;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
@ -26,6 +29,7 @@ using osu.Game.Screens;
using osu.Game.Screens.Play;
using osu.Game.Screens.Ranking;
using osu.Game.Tests.Resources;
using osu.Game.Users;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
@ -98,6 +102,7 @@ namespace osu.Game.Tests.Visual.Gameplay
{
DateTimeOffset? getLastPlayed() => Realm.Run(r => r.Find<BeatmapInfo>(Beatmap.Value.BeatmapInfo.ID)?.LastPlayed);
AddStep("reset last played", () => Realm.Write(r => r.Find<BeatmapInfo>(Beatmap.Value.BeatmapInfo.ID)!.LastPlayed = null));
AddAssert("last played is null", () => getLastPlayed() == null);
CreateTest();
@ -150,6 +155,40 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("score in database", () => Realm.Run(r => r.Find<ScoreInfo>(Player.Score.ScoreInfo.ID) != null));
}
[Test]
public void TestGuestScoreIsStoredAsGuest()
{
AddStep("set up API", () => ((DummyAPIAccess)API).HandleRequest = req =>
{
switch (req)
{
case GetUserRequest userRequest:
userRequest.TriggerSuccess(new APIUser
{
Username = "Guest",
CountryCode = CountryCode.JP,
Id = 1234
});
return true;
default:
return false;
}
});
AddStep("log out", () => API.Logout());
CreateTest();
AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning);
AddStep("log back in", () => API.Login("username", "password"));
AddStep("seek to completion", () => Player.GameplayClockContainer.Seek(Player.DrawableRuleset.Objects.Last().GetEndTime()));
AddUntilStep("results displayed", () => Player.GetChildScreen() is ResultsScreen);
AddUntilStep("score in database", () => Realm.Run(r => r.Find<ScoreInfo>(Player.Score.ScoreInfo.ID) != null));
AddAssert("score is not associated with online user", () => Realm.Run(r => r.Find<ScoreInfo>(Player.Score.ScoreInfo.ID))!.UserID == APIUser.SYSTEM_USER_ID);
}
[Test]
public void TestReplayExport()
{

View File

@ -11,6 +11,7 @@ using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Rulesets.Osu;
using osu.Game.Screens.OnlinePlay.Multiplayer;
using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual.Multiplayer
{
@ -28,6 +29,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
});
AddStep("Start track playing", () =>
{
Beatmap.Value.Track.Start();
});
AddStep("initialise gameplay", () =>
{
Stack.Push(player = new MultiplayerPlayer(MultiplayerClient.ServerAPIRoom, new PlaylistItem(Beatmap.Value.BeatmapInfo)
@ -37,7 +43,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
});
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen() && player.IsLoaded);
AddAssert("gameplay clock is paused", () => player.ChildrenOfType<GameplayClockContainer>().Single().IsPaused.Value);
AddAssert("gameplay clock is not running", () => !player.ChildrenOfType<GameplayClockContainer>().Single().IsRunning);
AddStep("start gameplay", () => ((IMultiplayerClient)MultiplayerClient).GameplayStarted());
AddUntilStep("gameplay clock is not paused", () => !player.ChildrenOfType<GameplayClockContainer>().Single().IsPaused.Value);
AddAssert("gameplay clock is running", () => player.ChildrenOfType<GameplayClockContainer>().Single().IsRunning);
}
[Test]

View File

@ -190,6 +190,9 @@ namespace osu.Game.Scoring
/// </summary>
private void populateUserDetails(ScoreInfo model)
{
if (model.RealmUser.OnlineID == APIUser.SYSTEM_USER_ID)
return;
string username = model.RealmUser.Username;
if (usernameLookupCache.TryGetValue(username, out var existing))

View File

@ -148,6 +148,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
loadingDisplay.Show();
client.ChangeState(MultiplayerUserState.ReadyForGameplay);
}
// This will pause the clock, pending the gameplay started callback from the server.
GameplayClockContainer.Reset();
}
private void failAndBail(string message = null)

View File

@ -138,12 +138,16 @@ namespace osu.Game.Screens.Play
/// Resets this <see cref="GameplayClockContainer"/> and the source to an initial state ready for gameplay.
/// </summary>
/// <param name="time">The time to seek to on resetting. If <c>null</c>, the existing <see cref="StartTime"/> will be used.</param>
/// <param name="startClock">Whether to start the clock immediately, if not already started.</param>
/// <param name="startClock">Whether to start the clock immediately. If <c>false</c> and the clock was already paused, the clock will remain paused after this call.
/// </param>
public void Reset(double? time = null, bool startClock = false)
{
bool wasPaused = isPaused.Value;
Stop();
// The intention of the Reset method is to get things into a known sane state.
// As such, we intentionally stop the underlying clock directly here, bypassing Stop/StopGameplayClock.
// This is to avoid any kind of isPaused state checks and frequency ramping (as provided by MasterGameplayClockContainer).
GameplayClock.Stop();
if (time != null)
StartTime = time.Value;

View File

@ -15,7 +15,6 @@ using osu.Framework.Layout;
using osu.Framework.Threading;
using osu.Framework.Utils;
using osu.Game.Configuration;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Skinning;
@ -74,7 +73,7 @@ namespace osu.Game.Screens.Play.HUD
return;
glowBarValue = value;
updatePathVertices();
Scheduler.AddOnce(updatePathVertices);
}
}
@ -89,7 +88,7 @@ namespace osu.Game.Screens.Play.HUD
return;
healthBarValue = value;
updatePathVertices();
Scheduler.AddOnce(updatePathVertices);
}
}
@ -139,17 +138,7 @@ namespace osu.Game.Screens.Play.HUD
{
base.LoadComplete();
Current.BindValueChanged(v =>
{
if (v.NewValue >= GlowBarValue)
finishMissDisplay();
double time = v.NewValue > GlowBarValue ? 500 : 250;
this.TransformTo(nameof(HealthBarValue), v.NewValue, time, Easing.OutQuint);
if (resetMissBarDelegate == null)
this.TransformTo(nameof(GlowBarValue), v.NewValue, time, Easing.OutQuint);
}, true);
Current.BindValueChanged(_ => Scheduler.AddOnce(updateCurrent), true);
BarLength.BindValueChanged(l => Width = l.NewValue, true);
BarHeight.BindValueChanged(_ => updatePath());
@ -164,6 +153,17 @@ namespace osu.Game.Screens.Play.HUD
return base.OnInvalidate(invalidation, source);
}
private void updateCurrent()
{
if (Current.Value >= GlowBarValue) finishMissDisplay();
double time = Current.Value > GlowBarValue ? 500 : 250;
// TODO: this should probably use interpolation in update.
this.TransformTo(nameof(HealthBarValue), Current.Value, time, Easing.OutQuint);
if (resetMissBarDelegate == null) this.TransformTo(nameof(GlowBarValue), Current.Value, time, Easing.OutQuint);
}
protected override void Update()
{
base.Update();
@ -172,9 +172,9 @@ namespace osu.Game.Screens.Play.HUD
glowBar.Alpha = (float)Interpolation.DampContinuously(glowBar.Alpha, GlowBarValue > 0 ? 1 : 0, 40, Time.Elapsed);
}
protected override void Flash(JudgementResult result)
protected override void Flash()
{
base.Flash(result);
base.Flash();
mainBar.TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour.Opacity(0.8f))
.TransformTo(nameof(BarPath.GlowColour), main_bar_glow_colour, 300, Easing.OutQuint);
@ -191,9 +191,9 @@ namespace osu.Game.Screens.Play.HUD
}
}
protected override void Miss(JudgementResult result)
protected override void Miss()
{
base.Miss(result);
base.Miss();
if (resetMissBarDelegate != null)
{

View File

@ -8,7 +8,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Game.Graphics;
using osu.Game.Rulesets.Judgements;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Graphics.Shapes;
@ -112,6 +111,13 @@ namespace osu.Game.Screens.Play.HUD
};
}
protected override void Flash()
{
fill.FadeEdgeEffectTo(Math.Min(1, fill.EdgeEffect.Colour.Linear.A + (1f - base_glow_opacity) / glow_max_hits), 50, Easing.OutQuint)
.Delay(glow_fade_delay)
.FadeEdgeEffectTo(base_glow_opacity, glow_fade_time, Easing.OutQuint);
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
@ -119,15 +125,6 @@ namespace osu.Game.Screens.Play.HUD
GlowColour = colours.BlueDarker;
}
protected override void Flash(JudgementResult result) => Scheduler.AddOnce(flash);
private void flash()
{
fill.FadeEdgeEffectTo(Math.Min(1, fill.EdgeEffect.Colour.Linear.A + (1f - base_glow_opacity) / glow_max_hits), 50, Easing.OutQuint)
.Delay(glow_fade_delay)
.FadeEdgeEffectTo(base_glow_opacity, glow_fade_time, Easing.OutQuint);
}
protected override void Update()
{
base.Update();

View File

@ -8,7 +8,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Threading;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
@ -39,17 +38,17 @@ namespace osu.Game.Screens.Play.HUD
/// <summary>
/// Triggered when a <see cref="Judgement"/> is a successful hit, signaling the health display to perform a flash animation (if designed to do so).
/// Calls to this method are debounced.
/// </summary>
/// <param name="result">The judgement result.</param>
protected virtual void Flash(JudgementResult result)
protected virtual void Flash()
{
}
/// <summary>
/// Triggered when a <see cref="Judgement"/> resulted in the player losing health.
/// Calls to this method are debounced.
/// </summary>
/// <param name="result">The judgement result.</param>
protected virtual void Miss(JudgementResult result)
protected virtual void Miss()
{
}
@ -92,7 +91,7 @@ namespace osu.Game.Screens.Play.HUD
{
double newValue = Current.Value + 0.05f;
this.TransformBindableTo(Current, newValue, increase_delay);
Flash(new JudgementResult(new HitObject(), new Judgement()));
Scheduler.AddOnce(Flash);
if (newValue >= 1)
finishInitialAnimation();
@ -101,6 +100,9 @@ namespace osu.Game.Screens.Play.HUD
private void finishInitialAnimation()
{
if (initialIncrease == null)
return;
initialIncrease?.Cancel();
initialIncrease = null;
@ -115,9 +117,9 @@ namespace osu.Game.Screens.Play.HUD
private void onNewJudgement(JudgementResult judgement)
{
if (judgement.IsHit && judgement.Type != HitResult.IgnoreHit)
Flash(judgement);
Scheduler.AddOnce(Flash);
else if (judgement.Judgement.HealthIncreaseFor(judgement) < 0)
Miss(judgement);
Scheduler.AddOnce(Miss);
}
protected override void Dispose(bool isDisposing)

View File

@ -1078,7 +1078,7 @@ namespace osu.Game.Screens.Play
protected virtual void StartGameplay()
{
if (GameplayClockContainer.IsRunning)
throw new InvalidOperationException($"{nameof(StartGameplay)} should not be called when the gameplay clock is already running");
Logger.Error(new InvalidOperationException($"{nameof(StartGameplay)} should not be called when the gameplay clock is already running"), "Clock failure");
GameplayClockContainer.Reset(startClock: true);

View File

@ -11,7 +11,6 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.Utils;
using osu.Game.Rulesets.Judgements;
using osu.Game.Screens.Play.HUD;
using osu.Game.Utils;
using osuTK;
@ -80,7 +79,7 @@ namespace osu.Game.Skinning
marker.Position = fill.Position + new Vector2(fill.DrawWidth, isNewStyle ? fill.DrawHeight / 2 : 0);
}
protected override void Flash(JudgementResult result) => marker.Flash(result);
protected override void Flash() => marker.Flash();
private static Texture getTexture(ISkin skin, string name) => skin?.GetTexture($"scorebar-{name}");
@ -238,7 +237,7 @@ namespace osu.Game.Skinning
});
}
public override void Flash(JudgementResult result)
public override void Flash()
{
bulgeMain();
@ -257,7 +256,7 @@ namespace osu.Game.Skinning
{
public Bindable<double> Current { get; } = new Bindable<double>();
public virtual void Flash(JudgementResult result)
public virtual void Flash()
{
}
}