using Content.Shared.Chemistry.Components; using Robust.Client.Animations; using Robust.Client.GameObjects; using Robust.Shared.Timing; namespace Content.Client.Chemistry.Visualizers; /// /// The system responsible for ensuring plays the animation it's meant to when the foam dissolves. /// public sealed class FoamVisualizerSystem : VisualizerSystem { [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly SpriteSystem _sprite = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnComponentInit); SubscribeLocalEvent(OnAnimationComplete); } public override void Update(float frameTime) { base.Update(frameTime); if (!_timing.IsFirstTimePredicted) return; var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var comp, out var smoke)) { if (_timing.CurTime < comp.StartTime + TimeSpan.FromSeconds(smoke.Duration) - TimeSpan.FromSeconds(comp.AnimationTime)) continue; // Despawn animation. if (TryComp(uid, out AnimationPlayerComponent? animPlayer) && !AnimationSystem.HasRunningAnimation(uid, animPlayer, FoamVisualsComponent.AnimationKey)) { AnimationSystem.Play((uid, animPlayer), comp.Animation, FoamVisualsComponent.AnimationKey); } } } /// /// Generates the animation used by foam visuals when the foam dissolves. /// private void OnComponentInit(EntityUid uid, FoamVisualsComponent comp, ComponentInit args) { comp.StartTime = _timing.CurTime; comp.Animation = new Animation { Length = TimeSpan.FromSeconds(comp.AnimationTime), AnimationTracks = { new AnimationTrackSpriteFlick { LayerKey = FoamVisualLayers.Base, KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.AnimationState, 0f) } } } }; } private void OnAnimationComplete(EntityUid uid, FoamVisualsComponent component, AnimationCompletedEvent args) { if (args.Key != FoamVisualsComponent.AnimationKey) return; if (TryComp(uid, out var sprite)) _sprite.SetVisible((uid, sprite), false); } } public enum FoamVisualLayers : byte { Base }