1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 14:07:25 +08:00

Fix potential taiko crash on rewind

This commit is contained in:
smoogipoo 2020-09-25 19:25:58 +09:00
parent 8c45786841
commit acfa62bb50
6 changed files with 34 additions and 35 deletions

View File

@ -2,26 +2,31 @@
// 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.Framework.Allocation; using osu.Framework.Allocation;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects.Drawables;
namespace osu.Game.Rulesets.Taiko.Tests namespace osu.Game.Rulesets.Taiko.Tests
{ {
internal class DrawableTestHit : DrawableTaikoHitObject public class DrawableTestHit : DrawableHit
{ {
private readonly HitResult type; public readonly HitResult Type;
public DrawableTestHit(Hit hit, HitResult type = HitResult.Great) public DrawableTestHit(Hit hit, HitResult type = HitResult.Great)
: base(hit) : base(hit)
{ {
this.type = type; Type = type;
// in order to create nested strong hit
HitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
Result.Type = type; Result.Type = Type;
} }
public override bool OnPressed(TaikoAction action) => false; public override bool OnPressed(TaikoAction action) => false;

View File

@ -2,17 +2,14 @@
// 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 System.Linq; using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects.Drawables;
namespace osu.Game.Rulesets.Taiko.Tests namespace osu.Game.Rulesets.Taiko.Tests
{ {
public class DrawableTestStrongHit : DrawableHit public class DrawableTestStrongHit : DrawableTestHit
{ {
private readonly HitResult type;
private readonly bool hitBoth; private readonly bool hitBoth;
public DrawableTestStrongHit(double startTime, HitResult type = HitResult.Great, bool hitBoth = true) public DrawableTestStrongHit(double startTime, HitResult type = HitResult.Great, bool hitBoth = true)
@ -20,12 +17,8 @@ namespace osu.Game.Rulesets.Taiko.Tests
{ {
IsStrong = true, IsStrong = true,
StartTime = startTime, StartTime = startTime,
}) }, type)
{ {
// in order to create nested strong hit
HitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
this.type = type;
this.hitBoth = hitBoth; this.hitBoth = hitBoth;
} }
@ -33,10 +26,8 @@ namespace osu.Game.Rulesets.Taiko.Tests
{ {
base.LoadAsyncComplete(); base.LoadAsyncComplete();
Result.Type = type;
var nestedStrongHit = (DrawableStrongNestedHit)NestedHitObjects.Single(); var nestedStrongHit = (DrawableStrongNestedHit)NestedHitObjects.Single();
nestedStrongHit.Result.Type = hitBoth ? type : HitResult.Miss; nestedStrongHit.Result.Type = hitBoth ? Type : HitResult.Miss;
} }
public override bool OnPressed(TaikoAction action) => false; public override bool OnPressed(TaikoAction action) => false;

View File

@ -6,7 +6,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Objects.Drawables;
using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.Taiko.UI;
namespace osu.Game.Rulesets.Taiko.Tests.Skinning namespace osu.Game.Rulesets.Taiko.Tests.Skinning
@ -29,7 +28,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
AddStep("Good", () => SetContents(() => getContentFor(createStrongHit(HitResult.Good, hitBoth)))); AddStep("Good", () => SetContents(() => getContentFor(createStrongHit(HitResult.Good, hitBoth))));
} }
private Drawable getContentFor(DrawableTaikoHitObject hit) private Drawable getContentFor(DrawableTestHit hit)
{ {
return new Container return new Container
{ {
@ -37,7 +36,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
Children = new Drawable[] Children = new Drawable[]
{ {
hit, hit,
new HitExplosion(hit) new HitExplosion(hit, hit.Type)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,
@ -46,9 +45,8 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
}; };
} }
private DrawableTaikoHitObject createHit(HitResult type) => new DrawableTestHit(new Hit { StartTime = Time.Current }, type); private DrawableTestHit createHit(HitResult type) => new DrawableTestHit(new Hit { StartTime = Time.Current }, type);
private DrawableTaikoHitObject createStrongHit(HitResult type, bool hitBoth) private DrawableTestHit createStrongHit(HitResult type, bool hitBoth) => new DrawableTestStrongHit(Time.Current, type, hitBoth);
=> new DrawableTestStrongHit(Time.Current, type, hitBoth);
} }
} }

View File

@ -15,8 +15,14 @@ namespace osu.Game.Rulesets.Taiko.UI
{ {
internal class DefaultHitExplosion : CircularContainer internal class DefaultHitExplosion : CircularContainer
{ {
[Resolved] private readonly DrawableHitObject judgedObject;
private DrawableHitObject judgedObject { get; set; } private readonly HitResult result;
public DefaultHitExplosion(DrawableHitObject judgedObject, HitResult result)
{
this.judgedObject = judgedObject;
this.result = result;
}
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
@ -31,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.UI
Alpha = 0.15f; Alpha = 0.15f;
Masking = true; Masking = true;
if (judgedObject.Result.Type == HitResult.Miss) if (result == HitResult.Miss)
return; return;
bool isRim = (judgedObject.HitObject as Hit)?.Type == HitType.Rim; bool isRim = (judgedObject.HitObject as Hit)?.Type == HitType.Rim;

View File

@ -22,8 +22,8 @@ namespace osu.Game.Rulesets.Taiko.UI
{ {
public override bool RemoveWhenNotAlive => true; public override bool RemoveWhenNotAlive => true;
[Cached(typeof(DrawableHitObject))]
public readonly DrawableHitObject JudgedObject; public readonly DrawableHitObject JudgedObject;
private readonly HitResult result;
private SkinnableDrawable skinnable; private SkinnableDrawable skinnable;
@ -31,9 +31,10 @@ namespace osu.Game.Rulesets.Taiko.UI
public override double LifetimeEnd => skinnable.Drawable.LifetimeEnd; public override double LifetimeEnd => skinnable.Drawable.LifetimeEnd;
public HitExplosion(DrawableHitObject judgedObject) public HitExplosion(DrawableHitObject judgedObject, HitResult result)
{ {
JudgedObject = judgedObject; JudgedObject = judgedObject;
this.result = result;
Anchor = Anchor.Centre; Anchor = Anchor.Centre;
Origin = Anchor.Centre; Origin = Anchor.Centre;
@ -47,14 +48,12 @@ namespace osu.Game.Rulesets.Taiko.UI
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
Child = skinnable = new SkinnableDrawable(new TaikoSkinComponent(getComponentName(JudgedObject)), _ => new DefaultHitExplosion()); Child = skinnable = new SkinnableDrawable(new TaikoSkinComponent(getComponentName(JudgedObject)), _ => new DefaultHitExplosion(JudgedObject, result));
} }
private TaikoSkinComponents getComponentName(DrawableHitObject judgedObject) private TaikoSkinComponents getComponentName(DrawableHitObject judgedObject)
{ {
var resultType = judgedObject.Result?.Type ?? HitResult.Great; switch (result)
switch (resultType)
{ {
case HitResult.Miss: case HitResult.Miss:
return TaikoSkinComponents.TaikoExplosionMiss; return TaikoSkinComponents.TaikoExplosionMiss;

View File

@ -9,6 +9,7 @@ using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects.Drawables;
@ -206,8 +207,7 @@ namespace osu.Game.Rulesets.Taiko.UI
}); });
var type = (judgedObject.HitObject as Hit)?.Type ?? HitType.Centre; var type = (judgedObject.HitObject as Hit)?.Type ?? HitType.Centre;
addExplosion(judgedObject, result.Type, type);
addExplosion(judgedObject, type);
break; break;
} }
} }
@ -219,9 +219,9 @@ namespace osu.Game.Rulesets.Taiko.UI
/// As legacy skins have different explosions for singular and double strong hits, /// As legacy skins have different explosions for singular and double strong hits,
/// explosion addition is scheduled to ensure that both hits are processed if they occur on the same frame. /// explosion addition is scheduled to ensure that both hits are processed if they occur on the same frame.
/// </remarks> /// </remarks>
private void addExplosion(DrawableHitObject drawableObject, HitType type) => Schedule(() => private void addExplosion(DrawableHitObject drawableObject, HitResult result, HitType type) => Schedule(() =>
{ {
hitExplosionContainer.Add(new HitExplosion(drawableObject)); hitExplosionContainer.Add(new HitExplosion(drawableObject, result));
if (drawableObject.HitObject.Kiai) if (drawableObject.HitObject.Kiai)
kiaiExplosionContainer.Add(new KiaiHitExplosion(drawableObject, type)); kiaiExplosionContainer.Add(new KiaiHitExplosion(drawableObject, type));
}); });