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

Merge pull request #24508 from OliBomby/judge-fix

Fix hit animation not synchronizing when editing hit objects
This commit is contained in:
Bartłomiej Dach 2023-08-22 10:21:42 +02:00 committed by GitHub
commit 71ec29041b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 6 deletions

View File

@ -26,6 +26,8 @@ namespace osu.Game.Rulesets.Catch.Tests
AddSliderStep("start time", 500, 600, 0, x => AddSliderStep("start time", 500, 600, 0, x =>
{ {
drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = x; drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = x;
drawableFruit.RefreshStateTransforms();
drawableBanana.RefreshStateTransforms();
}); });
} }
@ -44,6 +46,8 @@ namespace osu.Game.Rulesets.Catch.Tests
AddStep("Initialize start time", () => AddStep("Initialize start time", () =>
{ {
drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = initial_start_time; drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = initial_start_time;
drawableFruit.RefreshStateTransforms();
drawableBanana.RefreshStateTransforms();
fruitRotation = drawableFruit.DisplayRotation; fruitRotation = drawableFruit.DisplayRotation;
bananaRotation = drawableBanana.DisplayRotation; bananaRotation = drawableBanana.DisplayRotation;
@ -54,6 +58,8 @@ namespace osu.Game.Rulesets.Catch.Tests
AddStep("change start time", () => AddStep("change start time", () =>
{ {
drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = another_start_time; drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = another_start_time;
drawableFruit.RefreshStateTransforms();
drawableBanana.RefreshStateTransforms();
}); });
AddAssert("fruit rotation is changed", () => drawableFruit.DisplayRotation != fruitRotation); AddAssert("fruit rotation is changed", () => drawableFruit.DisplayRotation != fruitRotation);
@ -64,6 +70,8 @@ namespace osu.Game.Rulesets.Catch.Tests
AddStep("reset start time", () => AddStep("reset start time", () =>
{ {
drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = initial_start_time; drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = initial_start_time;
drawableFruit.RefreshStateTransforms();
drawableBanana.RefreshStateTransforms();
}); });
AddAssert("rotation and size restored", () => AddAssert("rotation and size restored", () =>

View File

@ -260,7 +260,6 @@ namespace osu.Game.Rulesets.Objects.Drawables
} }
StartTimeBindable.BindTo(HitObject.StartTimeBindable); StartTimeBindable.BindTo(HitObject.StartTimeBindable);
StartTimeBindable.BindValueChanged(onStartTimeChanged);
if (HitObject is IHasComboInformation combo) if (HitObject is IHasComboInformation combo)
{ {
@ -311,9 +310,6 @@ namespace osu.Game.Rulesets.Objects.Drawables
samplesBindable.UnbindFrom(HitObject.SamplesBindable); samplesBindable.UnbindFrom(HitObject.SamplesBindable);
// Changes in start time trigger state updates. When a new hitobject is applied, OnApply() automatically performs a state update anyway.
StartTimeBindable.ValueChanged -= onStartTimeChanged;
// When a new hitobject is applied, the samples will be cleared before re-populating. // When a new hitobject is applied, the samples will be cleared before re-populating.
// In order to stop this needless update, the event is unbound and re-bound as late as possible in Apply(). // In order to stop this needless update, the event is unbound and re-bound as late as possible in Apply().
samplesBindable.CollectionChanged -= onSamplesChanged; samplesBindable.CollectionChanged -= onSamplesChanged;
@ -333,6 +329,8 @@ namespace osu.Game.Rulesets.Objects.Drawables
Entry.NestedEntries.RemoveAll(nestedEntry => nestedEntry is SyntheticHitObjectEntry); Entry.NestedEntries.RemoveAll(nestedEntry => nestedEntry is SyntheticHitObjectEntry);
ClearNestedHitObjects(); ClearNestedHitObjects();
// Changes to `HitObject` properties trigger default application, which triggers `State` updates.
// When a new hitobject is applied, `OnApply()` automatically performs a state update.
HitObject.DefaultsApplied -= onDefaultsApplied; HitObject.DefaultsApplied -= onDefaultsApplied;
entry.RevertResult -= onRevertResult; entry.RevertResult -= onRevertResult;
@ -375,8 +373,6 @@ namespace osu.Game.Rulesets.Objects.Drawables
private void onSamplesChanged(object sender, NotifyCollectionChangedEventArgs e) => LoadSamples(); private void onSamplesChanged(object sender, NotifyCollectionChangedEventArgs e) => LoadSamples();
private void onStartTimeChanged(ValueChangedEvent<double> startTime) => updateState(State.Value, true);
private void onNewResult(DrawableHitObject drawableHitObject, JudgementResult result) => OnNewResult?.Invoke(drawableHitObject, result); private void onNewResult(DrawableHitObject drawableHitObject, JudgementResult result) => OnNewResult?.Invoke(drawableHitObject, result);
private void onRevertResult() private void onRevertResult()
@ -394,6 +390,15 @@ namespace osu.Game.Rulesets.Objects.Drawables
Debug.Assert(Entry != null); Debug.Assert(Entry != null);
Apply(Entry); Apply(Entry);
// Applied defaults indicate a change in hit object state.
// We need to update the judgement result time to the new end time
// and update state to ensure the hit object fades out at the correct time.
if (Result is not null)
{
Result.TimeOffset = 0;
updateState(State.Value, true);
}
DefaultsApplied?.Invoke(this); DefaultsApplied?.Invoke(this);
} }