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.
using osu.Framework.Allocation;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Objects.Drawables;
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)
: base(hit)
{
this.type = type;
Type = type;
// in order to create nested strong hit
HitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
}
[BackgroundDependencyLoader]
private void load()
{
Result.Type = type;
Result.Type = Type;
}
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.
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Objects.Drawables;
namespace osu.Game.Rulesets.Taiko.Tests
{
public class DrawableTestStrongHit : DrawableHit
public class DrawableTestStrongHit : DrawableTestHit
{
private readonly HitResult type;
private readonly bool hitBoth;
public DrawableTestStrongHit(double startTime, HitResult type = HitResult.Great, bool hitBoth = true)
@ -20,12 +17,8 @@ namespace osu.Game.Rulesets.Taiko.Tests
{
IsStrong = true,
StartTime = startTime,
})
}, type)
{
// in order to create nested strong hit
HitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
this.type = type;
this.hitBoth = hitBoth;
}
@ -33,10 +26,8 @@ namespace osu.Game.Rulesets.Taiko.Tests
{
base.LoadAsyncComplete();
Result.Type = type;
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;

View File

@ -6,7 +6,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Objects.Drawables;
using osu.Game.Rulesets.Taiko.UI;
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))));
}
private Drawable getContentFor(DrawableTaikoHitObject hit)
private Drawable getContentFor(DrawableTestHit hit)
{
return new Container
{
@ -37,7 +36,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
Children = new Drawable[]
{
hit,
new HitExplosion(hit)
new HitExplosion(hit, hit.Type)
{
Anchor = 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)
=> new DrawableTestStrongHit(Time.Current, type, hitBoth);
private DrawableTestHit createStrongHit(HitResult type, bool hitBoth) => new DrawableTestStrongHit(Time.Current, type, hitBoth);
}
}

View File

@ -15,8 +15,14 @@ namespace osu.Game.Rulesets.Taiko.UI
{
internal class DefaultHitExplosion : CircularContainer
{
[Resolved]
private DrawableHitObject judgedObject { get; set; }
private readonly DrawableHitObject judgedObject;
private readonly HitResult result;
public DefaultHitExplosion(DrawableHitObject judgedObject, HitResult result)
{
this.judgedObject = judgedObject;
this.result = result;
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
@ -31,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.UI
Alpha = 0.15f;
Masking = true;
if (judgedObject.Result.Type == HitResult.Miss)
if (result == HitResult.Miss)
return;
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;
[Cached(typeof(DrawableHitObject))]
public readonly DrawableHitObject JudgedObject;
private readonly HitResult result;
private SkinnableDrawable skinnable;
@ -31,9 +31,10 @@ namespace osu.Game.Rulesets.Taiko.UI
public override double LifetimeEnd => skinnable.Drawable.LifetimeEnd;
public HitExplosion(DrawableHitObject judgedObject)
public HitExplosion(DrawableHitObject judgedObject, HitResult result)
{
JudgedObject = judgedObject;
this.result = result;
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
@ -47,14 +48,12 @@ namespace osu.Game.Rulesets.Taiko.UI
[BackgroundDependencyLoader]
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)
{
var resultType = judgedObject.Result?.Type ?? HitResult.Great;
switch (resultType)
switch (result)
{
case HitResult.Miss:
return TaikoSkinComponents.TaikoExplosionMiss;

View File

@ -9,6 +9,7 @@ using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
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;
addExplosion(judgedObject, type);
addExplosion(judgedObject, result.Type, type);
break;
}
}
@ -219,9 +219,9 @@ namespace osu.Game.Rulesets.Taiko.UI
/// 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.
/// </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)
kiaiExplosionContainer.Add(new KiaiHitExplosion(drawableObject, type));
});