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

Integrate GameplayBeatmap changes

This commit is contained in:
Bartłomiej Dach 2020-05-11 22:53:05 +02:00
parent 43342c57b8
commit e5821ff2b2
3 changed files with 32 additions and 32 deletions

View File

@ -7,7 +7,6 @@ using System.Linq;
using Humanizer;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Testing;
@ -76,23 +75,14 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
{
AddStep("set beatmap", () => setBeatmap());
// the bindables need to be independent for each content cell to prevent interference,
// as if some of the skins don't implement the animation they'll immediately revert to the previous state from the clear state.
var states = new List<Bindable<TaikoMascotAnimationState>>();
AddStep("create mascot", () => SetContents(() => new DrawableTaikoMascot { RelativeSizeAxes = Axes.Both }));
AddStep("create mascot", () => SetContents(() =>
{
var state = new Bindable<TaikoMascotAnimationState>(TaikoMascotAnimationState.Clear);
states.Add(state);
return new DrawableTaikoMascot { State = { BindTarget = state }, RelativeSizeAxes = Axes.Both };
}));
AddStep("set clear state", () => states.ForEach(state => state.Value = TaikoMascotAnimationState.Clear));
AddStep("miss", () => mascots.ForEach(mascot => mascot.OnNewResult(new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Miss })));
AddStep("set clear state", () => mascots.ForEach(mascot => mascot.State.Value = TaikoMascotAnimationState.Clear));
AddStep("miss", () => mascots.ForEach(mascot => mascot.LastResult.Value = new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Miss }));
AddAssert("skins with animations remain in clear state", () => someMascotsIn(TaikoMascotAnimationState.Clear));
AddUntilStep("state reverts to fail", () => allMascotsIn(TaikoMascotAnimationState.Fail));
AddStep("set clear state again", () => states.ForEach(state => state.Value = TaikoMascotAnimationState.Clear));
AddStep("set clear state again", () => mascots.ForEach(mascot => mascot.State.Value = TaikoMascotAnimationState.Clear));
AddAssert("skins with animations change to clear", () => someMascotsIn(TaikoMascotAnimationState.Clear));
}
@ -220,6 +210,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
playfield.OnNewResult(hit, judgementResult);
}
foreach (var mascot in mascots)
{
mascot.LastResult.Value = judgementResult;
}
}
private bool allMascotsIn(TaikoMascotAnimationState state) => mascots.All(d => d.State.Value == state);

View File

@ -12,14 +12,15 @@ using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics.Containers;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Taiko.Judgements;
using osu.Game.Screens.Play;
namespace osu.Game.Rulesets.Taiko.UI
{
public class DrawableTaikoMascot : BeatSyncedContainer
{
public IBindable<TaikoMascotAnimationState> State => state;
public readonly Bindable<TaikoMascotAnimationState> State;
public readonly Bindable<JudgementResult> LastResult;
private readonly Bindable<TaikoMascotAnimationState> state;
private readonly Dictionary<TaikoMascotAnimationState, TaikoMascotAnimation> animations;
private TaikoMascotAnimation currentAnimation;
@ -30,12 +31,14 @@ namespace osu.Game.Rulesets.Taiko.UI
{
Origin = Anchor = Anchor.BottomLeft;
state = new Bindable<TaikoMascotAnimationState>(startingState);
State = new Bindable<TaikoMascotAnimationState>(startingState);
LastResult = new Bindable<JudgementResult>();
animations = new Dictionary<TaikoMascotAnimationState, TaikoMascotAnimation>();
}
[BackgroundDependencyLoader]
private void load(TextureStore textures)
[BackgroundDependencyLoader(true)]
private void load(TextureStore textures, GameplayBeatmap gameplayBeatmap)
{
InternalChildren = new[]
{
@ -44,6 +47,9 @@ namespace osu.Game.Rulesets.Taiko.UI
animations[TaikoMascotAnimationState.Kiai] = new TaikoMascotAnimation(TaikoMascotAnimationState.Kiai),
animations[TaikoMascotAnimationState.Fail] = new TaikoMascotAnimation(TaikoMascotAnimationState.Fail),
};
if (gameplayBeatmap != null)
((IBindable<JudgementResult>)LastResult).BindTo(gameplayBeatmap.LastJudgementResult);
}
protected override void LoadComplete()
@ -51,16 +57,22 @@ namespace osu.Game.Rulesets.Taiko.UI
base.LoadComplete();
animations.Values.ForEach(animation => animation.Hide());
state.BindValueChanged(mascotStateChanged, true);
State.BindValueChanged(mascotStateChanged, true);
LastResult.BindValueChanged(onNewResult);
}
public void OnNewResult(JudgementResult result)
private void onNewResult(ValueChangedEvent<JudgementResult> resultChangedEvent)
{
var result = resultChangedEvent.NewValue;
if (result == null)
return;
// TODO: missing support for clear/fail state transition at end of beatmap gameplay
if (triggerComboClear(result) || triggerSwellClear(result))
{
state.Value = TaikoMascotAnimationState.Clear;
State.Value = TaikoMascotAnimationState.Clear;
// always consider a clear equivalent to a hit to avoid clear -> miss transitions
lastObjectHit = true;
}
@ -79,7 +91,7 @@ namespace osu.Game.Rulesets.Taiko.UI
protected override void Update()
{
base.Update();
state.Value = getNextState();
State.Value = getNextState();
}
private TaikoMascotAnimationState getNextState()
@ -87,7 +99,7 @@ namespace osu.Game.Rulesets.Taiko.UI
// don't change state if current animation is playing
// (used for clear state - others are manually animated on new beats)
if (currentAnimation != null && !currentAnimation.Completed)
return state.Value;
return State.Value;
if (!lastObjectHit)
return TaikoMascotAnimationState.Fail;

View File

@ -40,8 +40,6 @@ namespace osu.Game.Rulesets.Taiko.UI
private Container hitTargetOffsetContent;
private SkinnableDrawable mascotDrawable;
public TaikoPlayfield(ControlPointInfo controlPoints)
{
this.controlPoints = controlPoints;
@ -127,7 +125,7 @@ namespace osu.Game.Rulesets.Taiko.UI
},
}
},
mascotDrawable = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoDon), _ => Empty())
new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoDon), _ => Empty())
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.TopLeft,
@ -212,11 +210,6 @@ namespace osu.Game.Rulesets.Taiko.UI
addExplosion(judgedObject, type);
break;
}
if (mascotDrawable.Drawable is DrawableTaikoMascot mascot)
{
mascot.OnNewResult(result);
}
}
private void addDrumRollHit(DrawableDrumRollTick drawableTick) =>