diff --git a/Content.Client/Effects/ColorFlashEffectSystem.cs b/Content.Client/Effects/ColorFlashEffectSystem.cs index af0bd4b600dd..0570b4951ecf 100644 --- a/Content.Client/Effects/ColorFlashEffectSystem.cs +++ b/Content.Client/Effects/ColorFlashEffectSystem.cs @@ -2,8 +2,10 @@ using Robust.Client.Animations; using Robust.Client.GameObjects; using Robust.Shared.Animations; +using Robust.Shared.Collections; using Robust.Shared.Player; using Robust.Shared.Timing; +using Robust.Shared.Utility; namespace Content.Client.Effects; @@ -11,13 +13,13 @@ public sealed class ColorFlashEffectSystem : SharedColorFlashEffectSystem { [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly AnimationPlayerSystem _animation = default!; - [Dependency] private readonly IComponentFactory _factory = default!; /// /// It's a little on the long side but given we use multiple colours denoting what happened it makes it easier to register. /// private const float AnimationLength = 0.30f; private const string AnimationKey = "color-flash-effect"; + private ValueList _toRemove = new(); public override void Initialize() { @@ -44,8 +46,28 @@ private void OnEffectAnimationCompleted(EntityUid uid, ColorFlashEffectComponent { sprite.Color = component.Color; } + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = AllEntityQuery(); + _toRemove.Clear(); + + // Can't use deferred removal on animation completion or it will cause issues. + while (query.MoveNext(out var uid, out _)) + { + if (_animation.HasRunningAnimation(uid, AnimationKey)) + continue; - RemCompDeferred(uid); + _toRemove.Add(uid); + } + + foreach (var ent in _toRemove) + { + RemComp(ent); + } } private Animation? GetDamageAnimation(EntityUid uid, Color color, SpriteComponent? sprite = null) @@ -82,51 +104,31 @@ private void OnColorFlashEffect(ColorFlashEffectEvent ev) { var ent = GetEntity(nent); - if (Deleted(ent)) + if (Deleted(ent) || !TryComp(ent, out SpriteComponent? sprite)) { continue; } - if (!TryComp(ent, out AnimationPlayerComponent? player)) - { - player = (AnimationPlayerComponent) _factory.GetComponent(typeof(AnimationPlayerComponent)); - player.Owner = ent; - player.NetSyncEnabled = false; - AddComp(ent, player); - } - - // Need to stop the existing animation first to ensure the sprite color is fixed. - // Otherwise we might lerp to a red colour instead. - if (_animation.HasRunningAnimation(ent, player, AnimationKey)) - { - _animation.Stop(ent, player, AnimationKey); - } - - if (!TryComp(ent, out var sprite)) - { - continue; - } - - if (TryComp(ent, out var effect)) +#if DEBUG + if (!TryComp(ent, out ColorFlashEffectComponent? comp)) { - sprite.Color = effect.Color; + DebugTools.Assert(!_animation.HasRunningAnimation(ent, AnimationKey)); } +#endif + _animation.Stop(ent, AnimationKey); var animation = GetDamageAnimation(ent, color, sprite); if (animation == null) - continue; - - if (!TryComp(ent, out ColorFlashEffectComponent? comp)) { - comp = (ColorFlashEffectComponent) _factory.GetComponent(typeof(ColorFlashEffectComponent)); - comp.Owner = ent; - comp.NetSyncEnabled = false; - AddComp(ent, comp); + continue; } + comp = EnsureComp(ent); + comp.NetSyncEnabled = false; comp.Color = sprite.Color; - _animation.Play((ent, player), animation, AnimationKey); + + _animation.Play(ent, animation, AnimationKey); } } } diff --git a/Content.Client/Gravity/FloatingVisualizerSystem.cs b/Content.Client/Gravity/FloatingVisualizerSystem.cs index f489237d107b..a7cb3333b273 100644 --- a/Content.Client/Gravity/FloatingVisualizerSystem.cs +++ b/Content.Client/Gravity/FloatingVisualizerSystem.cs @@ -57,6 +57,6 @@ private void OnAnimationCompleted(EntityUid uid, FloatingVisualsComponent compon if (args.Key != component.AnimationKey) return; - FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime, !component.CanFloat); + FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime, stop: !component.CanFloat); } }