1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-11 03:32:55 +08:00

Merge pull request #23582 from peppy/placement-blueprint-timeline-combo-fixes

Fix timeline blueprint display not showing correct combo number / colour during placement
This commit is contained in:
Bartłomiej Dach 2023-05-20 15:02:55 +02:00 committed by GitHub
commit afdddb0195
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 41 deletions

View File

@ -1,10 +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.
#nullable disable
using System; using System;
using JetBrains.Annotations;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
@ -24,9 +21,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners
private bool isPlacingEnd; private bool isPlacingEnd;
[Resolved(CanBeNull = true)] [Resolved]
[CanBeNull] private IBeatSnapProvider? beatSnapProvider { get; set; }
private IBeatSnapProvider beatSnapProvider { get; set; }
public SpinnerPlacementBlueprint() public SpinnerPlacementBlueprint()
: base(new Spinner { Position = OsuPlayfield.BASE_SIZE / 2 }) : base(new Spinner { Position = OsuPlayfield.BASE_SIZE / 2 })

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System.Linq; using System.Linq;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
@ -22,34 +20,17 @@ namespace osu.Game.Beatmaps
public virtual void PreProcess() public virtual void PreProcess()
{ {
IHasComboInformation lastObj = null; IHasComboInformation? lastObj = null;
bool isFirst = true;
foreach (var obj in Beatmap.HitObjects.OfType<IHasComboInformation>()) foreach (var obj in Beatmap.HitObjects.OfType<IHasComboInformation>())
{ {
if (isFirst) if (lastObj == null)
{ {
obj.NewCombo = true;
// first hitobject should always be marked as a new combo for sanity. // first hitobject should always be marked as a new combo for sanity.
isFirst = false; obj.NewCombo = true;
}
obj.ComboIndex = lastObj?.ComboIndex ?? 0;
obj.ComboIndexWithOffsets = lastObj?.ComboIndexWithOffsets ?? 0;
obj.IndexInCurrentCombo = (lastObj?.IndexInCurrentCombo + 1) ?? 0;
if (obj.NewCombo)
{
obj.IndexInCurrentCombo = 0;
obj.ComboIndex++;
obj.ComboIndexWithOffsets += obj.ComboOffset + 1;
if (lastObj != null)
lastObj.LastInCombo = true;
} }
obj.UpdateComboInformation(lastObj);
lastObj = obj; lastObj = obj;
} }
} }

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -16,6 +14,7 @@ using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Input.Bindings; using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Screens.Edit; using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose;
using osuTK; using osuTK;
@ -38,16 +37,18 @@ namespace osu.Game.Rulesets.Edit
/// </summary> /// </summary>
public readonly HitObject HitObject; public readonly HitObject HitObject;
[Resolved(canBeNull: true)] [Resolved]
protected EditorClock EditorClock { get; private set; } protected EditorClock EditorClock { get; private set; } = null!;
[Resolved] [Resolved]
private EditorBeatmap beatmap { get; set; } private EditorBeatmap beatmap { get; set; } = null!;
private Bindable<double> startTimeBindable; private Bindable<double> startTimeBindable = null!;
private HitObject? getPreviousHitObject() => beatmap.HitObjects.TakeWhile(h => h.StartTime <= startTimeBindable.Value).LastOrDefault();
[Resolved] [Resolved]
private IPlacementHandler placementHandler { get; set; } private IPlacementHandler placementHandler { get; set; } = null!;
/// <summary> /// <summary>
/// Whether this blueprint is currently in a state that can be committed. /// Whether this blueprint is currently in a state that can be committed.
@ -86,7 +87,7 @@ namespace osu.Game.Rulesets.Edit
protected void BeginPlacement(bool commitStart = false) protected void BeginPlacement(bool commitStart = false)
{ {
// Take the hitnormal sample of the last hit object // Take the hitnormal sample of the last hit object
var lastHitNormal = beatmap.HitObjects.LastOrDefault(h => h.GetEndTime() < HitObject.StartTime)?.Samples?.FirstOrDefault(o => o.Name == HitSampleInfo.HIT_NORMAL); var lastHitNormal = getPreviousHitObject()?.Samples?.FirstOrDefault(o => o.Name == HitSampleInfo.HIT_NORMAL);
if (lastHitNormal != null) if (lastHitNormal != null)
HitObject.Samples[0] = lastHitNormal; HitObject.Samples[0] = lastHitNormal;
@ -148,7 +149,12 @@ namespace osu.Game.Rulesets.Edit
public virtual void UpdateTimeAndPosition(SnapResult result) public virtual void UpdateTimeAndPosition(SnapResult result)
{ {
if (PlacementActive == PlacementState.Waiting) if (PlacementActive == PlacementState.Waiting)
HitObject.StartTime = result.Time ?? EditorClock?.CurrentTime ?? Time.Current; {
HitObject.StartTime = result.Time ?? EditorClock.CurrentTime;
if (HitObject is IHasComboInformation comboInformation)
comboInformation.UpdateComboInformation(getPreviousHitObject() as IHasComboInformation);
}
} }
/// <summary> /// <summary>

View File

@ -1,8 +1,6 @@
// 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.
#nullable disable
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Game.Skinning; using osu.Game.Skinning;
using osuTK.Graphics; using osuTK.Graphics;
@ -65,5 +63,26 @@ namespace osu.Game.Rulesets.Objects.Types
{ {
return skin.GetConfig<SkinComboColourLookup, Color4>(new SkinComboColourLookup(comboIndex, combo))?.Value ?? Color4.White; return skin.GetConfig<SkinComboColourLookup, Color4>(new SkinComboColourLookup(comboIndex, combo))?.Value ?? Color4.White;
} }
/// <summary>
/// Given the previous object in the beatmap, update relevant combo information.
/// </summary>
/// <param name="lastObj">The previous hitobject, or null if this is the first object in the beatmap.</param>
void UpdateComboInformation(IHasComboInformation? lastObj)
{
ComboIndex = lastObj?.ComboIndex ?? 0;
ComboIndexWithOffsets = lastObj?.ComboIndexWithOffsets ?? 0;
IndexInCurrentCombo = (lastObj?.IndexInCurrentCombo + 1) ?? 0;
if (NewCombo || lastObj == null)
{
IndexInCurrentCombo = 0;
ComboIndex++;
ComboIndexWithOffsets += ComboOffset + 1;
if (lastObj != null)
lastObj.LastInCombo = true;
}
}
} }
} }

View File

@ -83,8 +83,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{ {
placementBlueprint = CreateBlueprintFor(obj.NewValue).AsNonNull(); placementBlueprint = CreateBlueprintFor(obj.NewValue).AsNonNull();
placementBlueprint.Colour = Color4.MediumPurple; placementBlueprint.Colour = OsuColour.Gray(0.9f);
// TODO: this is out of order, causing incorrect stacking height.
SelectionBlueprints.Add(placementBlueprint); SelectionBlueprints.Add(placementBlueprint);
} }
} }