From 9eaa1cb5cdeda76fcb943905baacab808bddffa2 Mon Sep 17 00:00:00 2001 From: Damnae Date: Sun, 10 Sep 2017 21:25:23 +0200 Subject: [PATCH] Fix sprites not being visible when all their commands are inside loops. --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 2 +- osu.Game/Storyboards/SpriteDefinition.cs | 55 ++++++++++--------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index d538960a37..e436a43989 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -324,7 +324,7 @@ namespace osu.Game.Beatmaps.Formats else { if (depth < 2) - timelineGroup = spriteDefinition; + timelineGroup = spriteDefinition?.TimelineGroup; var commandType = split[0]; switch (commandType) diff --git a/osu.Game/Storyboards/SpriteDefinition.cs b/osu.Game/Storyboards/SpriteDefinition.cs index c410fd8807..1e1718a255 100644 --- a/osu.Game/Storyboards/SpriteDefinition.cs +++ b/osu.Game/Storyboards/SpriteDefinition.cs @@ -10,14 +10,26 @@ using System.Linq; namespace osu.Game.Storyboards { - public class SpriteDefinition : CommandTimelineGroup, IElementDefinition + public class SpriteDefinition : IElementDefinition { + private readonly List loops = new List(); + private readonly List triggers = new List(); + public string Path { get; set; } public Anchor Origin; public Vector2 InitialPosition; - private readonly List loops = new List(); - private readonly List triggers = new List(); + public readonly CommandTimelineGroup TimelineGroup = new CommandTimelineGroup(); + + public double StartTime => Math.Min( + TimelineGroup.HasCommands ? TimelineGroup.CommandsStartTime : double.MaxValue, + loops.Any(l => l.HasCommands) ? loops.Where(l => l.HasCommands).Min(l => l.StartTime) : double.MaxValue); + + public double EndTime => Math.Max( + TimelineGroup.HasCommands ? TimelineGroup.CommandsEndTime : double.MinValue, + loops.Any(l => l.HasCommands) ? loops.Where(l => l.HasCommands).Max(l => l.EndTime) : double.MinValue); + + public bool HasCommands => TimelineGroup.HasCommands || loops.Any(l => l.HasCommands); private delegate void DrawablePropertyInitializer(Drawable drawable, T value); private delegate void DrawableTransformer(Drawable drawable, T value, double duration, Easing easing); @@ -46,38 +58,29 @@ namespace osu.Game.Storyboards public virtual Drawable CreateDrawable() => new StoryboardSprite(this); - public override IEnumerable.TypedCommand> GetCommands(CommandTimelineSelector timelineSelector, double offset = 0) - { - var result = base.GetCommands(timelineSelector, offset); - foreach (var loop in loops) - result = result.Concat(loop.GetCommands(timelineSelector, offset)); - return result; - } - public void ApplyTransforms(Drawable drawable, IEnumerable> triggeredGroups = null) { - applyCommands(drawable, triggeredGroups, g => g.X, (d, value) => d.X = value, (d, value, duration, easing) => d.MoveToX(value, duration, easing)); - applyCommands(drawable, triggeredGroups, g => g.Y, (d, value) => d.Y = value, (d, value, duration, easing) => d.MoveToY(value, duration, easing)); - applyCommands(drawable, triggeredGroups, g => g.Scale, (d, value) => d.Scale = value, (d, value, duration, easing) => d.ScaleTo(value, duration, easing)); - applyCommands(drawable, triggeredGroups, g => g.Rotation, (d, value) => d.Rotation = value, (d, value, duration, easing) => d.RotateTo(value, duration, easing)); - applyCommands(drawable, triggeredGroups, g => g.Colour, (d, value) => d.Colour = value, (d, value, duration, easing) => d.FadeColour(value, duration, easing)); - applyCommands(drawable, triggeredGroups, g => g.Alpha, (d, value) => d.Alpha = value, (d, value, duration, easing) => d.FadeTo(value, duration, easing)); - applyCommands(drawable, triggeredGroups, g => g.BlendingMode, (d, value) => d.BlendingMode = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration), false); + applyCommands(drawable, getCommands(g => g.X, triggeredGroups), (d, value) => d.X = value, (d, value, duration, easing) => d.MoveToX(value, duration, easing)); + applyCommands(drawable, getCommands(g => g.Y, triggeredGroups), (d, value) => d.Y = value, (d, value, duration, easing) => d.MoveToY(value, duration, easing)); + applyCommands(drawable, getCommands(g => g.Scale, triggeredGroups), (d, value) => d.Scale = value, (d, value, duration, easing) => d.ScaleTo(value, duration, easing)); + applyCommands(drawable, getCommands(g => g.Rotation, triggeredGroups), (d, value) => d.Rotation = value, (d, value, duration, easing) => d.RotateTo(value, duration, easing)); + applyCommands(drawable, getCommands(g => g.Colour, triggeredGroups), (d, value) => d.Colour = value, (d, value, duration, easing) => d.FadeColour(value, duration, easing)); + applyCommands(drawable, getCommands(g => g.Alpha, triggeredGroups), (d, value) => d.Alpha = value, (d, value, duration, easing) => d.FadeTo(value, duration, easing)); + applyCommands(drawable, getCommands(g => g.BlendingMode, triggeredGroups), (d, value) => d.BlendingMode = value, (d, value, duration, easing) => d.TransformBlendingMode(value, duration), false); var flippable = drawable as IFlippable; if (flippable != null) { - applyCommands(drawable, triggeredGroups, g => g.FlipH, (d, value) => flippable.FlipH = value, (d, value, duration, easing) => flippable.TransformFlipH(value, duration), false); - applyCommands(drawable, triggeredGroups, g => g.FlipV, (d, value) => flippable.FlipV = value, (d, value, duration, easing) => flippable.TransformFlipV(value, duration), false); + applyCommands(drawable, getCommands(g => g.FlipH, triggeredGroups), (d, value) => flippable.FlipH = value, (d, value, duration, easing) => flippable.TransformFlipH(value, duration), false); + applyCommands(drawable, getCommands(g => g.FlipV, triggeredGroups), (d, value) => flippable.FlipV = value, (d, value, duration, easing) => flippable.TransformFlipV(value, duration), false); } } - private void applyCommands(Drawable drawable, IEnumerable> triggeredGroups, - CommandTimelineSelector timelineSelector, DrawablePropertyInitializer initializeProperty, DrawableTransformer transform, bool alwaysInitialize = true) + private void applyCommands(Drawable drawable, IEnumerable.TypedCommand> commands, DrawablePropertyInitializer initializeProperty, DrawableTransformer transform, bool alwaysInitialize = true) where T : struct { var initialized = false; - foreach (var command in getAggregatedCommands(timelineSelector, triggeredGroups).OrderBy(l => l)) + foreach (var command in commands.OrderBy(l => l)) { if (!initialized) { @@ -93,9 +96,11 @@ namespace osu.Game.Storyboards } } - private IEnumerable.TypedCommand> getAggregatedCommands(CommandTimelineSelector timelineSelector, IEnumerable> triggeredGroups) + private IEnumerable.TypedCommand> getCommands(CommandTimelineSelector timelineSelector, IEnumerable> triggeredGroups) { - var commands = GetCommands(timelineSelector); + var commands = TimelineGroup.GetCommands(timelineSelector); + foreach (var loop in loops) + commands = commands.Concat(loop.GetCommands(timelineSelector)); if (triggeredGroups != null) foreach (var pair in triggeredGroups) commands = commands.Concat(pair.Item1.GetCommands(timelineSelector, pair.Item2));