mirror of
https://github.com/ppy/osu.git
synced 2024-11-13 15:27:30 +08:00
Implement toggling visibility of pass and fail storyboard layers
Closes https://github.com/ppy/osu/issues/6842. This is a rather barebones implementation, just to get this in place somehow at least. The logic is simple - 50% health or above shows pass layer, anything below shows fail layer. This does not match stable logic all across the board because I have no idea how to package that. Stable defines "passing" in like fifty ways: - in mania it's >80% HP (bb57924c15/osu
!/GameModes/Play/Rulesets/Mania/RulesetMania.cs#L333-L336) - in taiko it's >80% *accuracy* (bb57924c15/osu
!/GameModes/Play/Rulesets/Taiko/RulesetTaiko.cs#L486-L492) - there's also the part where "geki additions" will unconditionally set passing state (bb57924c15/osu
!/GameModes/Play/Player.cs#L3561-L3564) - and also the part where at the end of the map, the final passing state is determined by checking whether the user passed more sections than failed (bb57924c15/osu
!/GameModes/Play/Player.cs#L3320) The biggest issues of these are probably the first two, and they can *probably* be fixed, but would require a new member on `Ruleset` and I'm not sure how to make one look, so I'm not doing that at this time pending collection of ideas on how to do that.
This commit is contained in:
parent
2d4121b14a
commit
67ca7e4135
@ -14,8 +14,11 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Storyboards;
|
||||
using osu.Game.Storyboards.Drawables;
|
||||
using osu.Game.Tests.Gameplay;
|
||||
using osu.Game.Tests.Resources;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@ -28,14 +31,14 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
private DrawableStoryboard? storyboard;
|
||||
|
||||
[Cached]
|
||||
private GameplayState testGameplayState = TestGameplayState.Create(new OsuRuleset());
|
||||
|
||||
[Test]
|
||||
public void TestStoryboard()
|
||||
{
|
||||
AddStep("Restart", restart);
|
||||
AddToggleStep("Passing", passing =>
|
||||
{
|
||||
if (storyboard != null) storyboard.Passing = passing;
|
||||
});
|
||||
AddToggleStep("Toggle passing state", passing => testGameplayState.HealthProcessor.Health.Value = passing ? 1 : 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -109,7 +112,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
storyboardContainer.Clock = new FramedClock(Beatmap.Value.Track);
|
||||
|
||||
storyboard = toLoad.CreateDrawable(SelectedMods.Value);
|
||||
storyboard.Passing = false;
|
||||
|
||||
storyboardContainer.Add(storyboard);
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ namespace osu.Game.Screens.Play
|
||||
public readonly Score Score;
|
||||
|
||||
public readonly ScoreProcessor ScoreProcessor;
|
||||
public readonly HealthProcessor HealthProcessor;
|
||||
|
||||
/// <summary>
|
||||
/// The storyboard associated with the beatmap.
|
||||
@ -68,7 +69,14 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
private readonly Bindable<JudgementResult> lastJudgementResult = new Bindable<JudgementResult>();
|
||||
|
||||
public GameplayState(IBeatmap beatmap, Ruleset ruleset, IReadOnlyList<Mod>? mods = null, Score? score = null, ScoreProcessor? scoreProcessor = null, Storyboard? storyboard = null)
|
||||
public GameplayState(
|
||||
IBeatmap beatmap,
|
||||
Ruleset ruleset,
|
||||
IReadOnlyList<Mod>? mods = null,
|
||||
Score? score = null,
|
||||
ScoreProcessor? scoreProcessor = null,
|
||||
HealthProcessor? healthProcessor = null,
|
||||
Storyboard? storyboard = null)
|
||||
{
|
||||
Beatmap = beatmap;
|
||||
Ruleset = ruleset;
|
||||
@ -82,6 +90,7 @@ namespace osu.Game.Screens.Play
|
||||
};
|
||||
Mods = mods ?? Array.Empty<Mod>();
|
||||
ScoreProcessor = scoreProcessor ?? ruleset.CreateScoreProcessor();
|
||||
HealthProcessor = healthProcessor ?? ruleset.CreateHealthProcessor(beatmap.HitObjects[0].StartTime);
|
||||
Storyboard = storyboard ?? new Storyboard();
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ namespace osu.Game.Screens.Play
|
||||
Score.ScoreInfo.Ruleset = ruleset.RulesetInfo;
|
||||
Score.ScoreInfo.Mods = gameplayMods;
|
||||
|
||||
dependencies.CacheAs(GameplayState = new GameplayState(playableBeatmap, ruleset, gameplayMods, Score, ScoreProcessor, Beatmap.Value.Storyboard));
|
||||
dependencies.CacheAs(GameplayState = new GameplayState(playableBeatmap, ruleset, gameplayMods, Score, ScoreProcessor, HealthProcessor, Beatmap.Value.Storyboard));
|
||||
|
||||
var rulesetSkinProvider = new RulesetSkinProvidingContainer(ruleset, playableBeatmap, Beatmap.Value.Skin);
|
||||
|
||||
|
@ -37,20 +37,6 @@ namespace osu.Game.Storyboards.Drawables
|
||||
|
||||
protected override Vector2 DrawScale => new Vector2(Parent!.DrawHeight / 480);
|
||||
|
||||
private bool passing = true;
|
||||
|
||||
public bool Passing
|
||||
{
|
||||
get => passing;
|
||||
set
|
||||
{
|
||||
if (passing == value) return;
|
||||
|
||||
passing = value;
|
||||
updateLayerVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool RemoveCompletedTransforms => false;
|
||||
|
||||
private double? lastEventEndTime;
|
||||
@ -66,6 +52,9 @@ namespace osu.Game.Storyboards.Drawables
|
||||
|
||||
private DependencyContainer dependencies = null!;
|
||||
|
||||
private BindableNumber<double> health = null!;
|
||||
private readonly BindableBool passing = new BindableBool(true);
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) =>
|
||||
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
|
||||
@ -91,8 +80,8 @@ namespace osu.Game.Storyboards.Drawables
|
||||
});
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(IGameplayClock? clock, CancellationToken? cancellationToken)
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IGameplayClock? clock, CancellationToken? cancellationToken, GameplayState? gameplayState)
|
||||
{
|
||||
if (clock != null)
|
||||
Clock = clock;
|
||||
@ -110,6 +99,16 @@ namespace osu.Game.Storyboards.Drawables
|
||||
}
|
||||
|
||||
lastEventEndTime = Storyboard.LatestEventTime;
|
||||
|
||||
health = gameplayState?.HealthProcessor.Health.GetBoundCopy() ?? new BindableDouble(1);
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
health.BindValueChanged(val => passing.Value = val.NewValue >= 0.5, true);
|
||||
passing.BindValueChanged(_ => updateLayerVisibility(), true);
|
||||
}
|
||||
|
||||
protected virtual IResourceStore<byte[]> CreateResourceLookupStore() => new StoryboardResourceLookupStore(Storyboard, realm, host);
|
||||
@ -125,7 +124,7 @@ namespace osu.Game.Storyboards.Drawables
|
||||
private void updateLayerVisibility()
|
||||
{
|
||||
foreach (var layer in Children)
|
||||
layer.Enabled = passing ? layer.Layer.VisibleWhenPassing : layer.Layer.VisibleWhenFailing;
|
||||
layer.Enabled = passing.Value ? layer.Layer.VisibleWhenPassing : layer.Layer.VisibleWhenFailing;
|
||||
}
|
||||
|
||||
private class StoryboardResourceLookupStore : IResourceStore<byte[]>
|
||||
|
@ -27,7 +27,9 @@ namespace osu.Game.Tests.Gameplay
|
||||
var scoreProcessor = ruleset.CreateScoreProcessor();
|
||||
scoreProcessor.ApplyBeatmap(playableBeatmap);
|
||||
|
||||
return new GameplayState(playableBeatmap, ruleset, mods, score, scoreProcessor);
|
||||
var healthProcessor = ruleset.CreateHealthProcessor(beatmap.HitObjects[0].StartTime);
|
||||
|
||||
return new GameplayState(playableBeatmap, ruleset, mods, score, scoreProcessor, healthProcessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user