| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- using System.Diagnostics.CodeAnalysis;
- using Content.Shared.Disposal;
- using Content.Shared.Disposal.Components;
- using Content.Shared.DragDrop;
- using Content.Shared.Emag.Systems;
- using Robust.Client.GameObjects;
- using Robust.Client.Animations;
- using Robust.Client.Graphics;
- using Robust.Shared.Audio;
- using Robust.Shared.Audio.Systems;
- using Robust.Shared.GameStates;
- using Robust.Shared.Physics.Events;
- using static Content.Shared.Disposal.Components.SharedDisposalUnitComponent;
- namespace Content.Client.Disposal.Systems;
- public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
- {
- [Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
- [Dependency] private readonly AnimationPlayerSystem _animationSystem = default!;
- [Dependency] private readonly SharedAudioSystem _audioSystem = default!;
- private const string AnimationKey = "disposal_unit_animation";
- private const string DefaultFlushState = "disposal-flush";
- private const string DefaultChargeState = "disposal-charging";
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<DisposalUnitComponent, ComponentHandleState>(OnHandleState);
- SubscribeLocalEvent<DisposalUnitComponent, PreventCollideEvent>(OnPreventCollide);
- SubscribeLocalEvent<DisposalUnitComponent, CanDropTargetEvent>(OnCanDragDropOn);
- SubscribeLocalEvent<DisposalUnitComponent, GotEmaggedEvent>(OnEmagged);
- SubscribeLocalEvent<DisposalUnitComponent, ComponentInit>(OnComponentInit);
- SubscribeLocalEvent<DisposalUnitComponent, AppearanceChangeEvent>(OnAppearanceChange);
- }
- private void OnHandleState(EntityUid uid, DisposalUnitComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not DisposalUnitComponentState state)
- return;
- component.FlushSound = state.FlushSound;
- component.State = state.State;
- component.NextPressurized = state.NextPressurized;
- component.AutomaticEngageTime = state.AutomaticEngageTime;
- component.NextFlush = state.NextFlush;
- component.Powered = state.Powered;
- component.Engaged = state.Engaged;
- component.RecentlyEjected.Clear();
- component.RecentlyEjected.AddRange(EnsureEntityList<DisposalUnitComponent>(state.RecentlyEjected, uid));
- }
- public override bool HasDisposals(EntityUid? uid)
- {
- return HasComp<DisposalUnitComponent>(uid);
- }
- public override bool ResolveDisposals(EntityUid uid, [NotNullWhen(true)] ref SharedDisposalUnitComponent? component)
- {
- if (component != null)
- return true;
- TryComp<DisposalUnitComponent>(uid, out var storage);
- component = storage;
- return component != null;
- }
- public override void DoInsertDisposalUnit(EntityUid uid, EntityUid toInsert, EntityUid user, SharedDisposalUnitComponent? disposal = null)
- {
- return;
- }
- private void OnComponentInit(EntityUid uid, SharedDisposalUnitComponent sharedDisposalUnit, ComponentInit args)
- {
- if (!TryComp<SpriteComponent>(uid, out var sprite) || !TryComp<AppearanceComponent>(uid, out var appearance))
- return;
- UpdateState(uid, sharedDisposalUnit, sprite, appearance);
- }
- private void OnAppearanceChange(EntityUid uid, SharedDisposalUnitComponent unit, ref AppearanceChangeEvent args)
- {
- if (args.Sprite == null)
- return;
- UpdateState(uid, unit, args.Sprite, args.Component);
- }
- /// <summary>
- /// Update visuals and tick animation
- /// </summary>
- private void UpdateState(EntityUid uid, SharedDisposalUnitComponent unit, SpriteComponent sprite, AppearanceComponent appearance)
- {
- if (!_appearanceSystem.TryGetData<VisualState>(uid, Visuals.VisualState, out var state, appearance))
- return;
- sprite.LayerSetVisible(DisposalUnitVisualLayers.Unanchored, state == VisualState.UnAnchored);
- sprite.LayerSetVisible(DisposalUnitVisualLayers.Base, state == VisualState.Anchored);
- sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayFlush, state is VisualState.OverlayFlushing or VisualState.OverlayCharging);
- var chargingState = sprite.LayerMapTryGet(DisposalUnitVisualLayers.BaseCharging, out var chargingLayer)
- ? sprite.LayerGetState(chargingLayer)
- : new RSI.StateId(DefaultChargeState);
- // This is a transient state so not too worried about replaying in range.
- if (state == VisualState.OverlayFlushing)
- {
- if (!_animationSystem.HasRunningAnimation(uid, AnimationKey))
- {
- var flushState = sprite.LayerMapTryGet(DisposalUnitVisualLayers.OverlayFlush, out var flushLayer)
- ? sprite.LayerGetState(flushLayer)
- : new RSI.StateId(DefaultFlushState);
- // Setup the flush animation to play
- var anim = new Animation
- {
- Length = unit.FlushDelay,
- AnimationTracks =
- {
- new AnimationTrackSpriteFlick
- {
- LayerKey = DisposalUnitVisualLayers.OverlayFlush,
- KeyFrames =
- {
- // Play the flush animation
- new AnimationTrackSpriteFlick.KeyFrame(flushState, 0),
- // Return to base state (though, depending on how the unit is
- // configured we might get an appearance change event telling
- // us to go to charging state)
- new AnimationTrackSpriteFlick.KeyFrame(chargingState, (float) unit.FlushDelay.TotalSeconds)
- }
- },
- }
- };
- if (unit.FlushSound != null)
- {
- anim.AnimationTracks.Add(
- new AnimationTrackPlaySound
- {
- KeyFrames =
- {
- new AnimationTrackPlaySound.KeyFrame(_audioSystem.ResolveSound(unit.FlushSound), 0)
- }
- });
- }
- _animationSystem.Play(uid, anim, AnimationKey);
- }
- }
- else if (state == VisualState.OverlayCharging)
- sprite.LayerSetState(DisposalUnitVisualLayers.OverlayFlush, chargingState);
- else
- _animationSystem.Stop(uid, AnimationKey);
- if (!_appearanceSystem.TryGetData<HandleState>(uid, Visuals.Handle, out var handleState, appearance))
- handleState = HandleState.Normal;
- sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayEngaged, handleState != HandleState.Normal);
- if (!_appearanceSystem.TryGetData<LightStates>(uid, Visuals.Light, out var lightState, appearance))
- lightState = LightStates.Off;
- sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayCharging,
- (lightState & LightStates.Charging) != 0);
- sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayReady,
- (lightState & LightStates.Ready) != 0);
- sprite.LayerSetVisible(DisposalUnitVisualLayers.OverlayFull,
- (lightState & LightStates.Full) != 0);
- }
- }
- public enum DisposalUnitVisualLayers : byte
- {
- Unanchored,
- Base,
- BaseCharging,
- OverlayFlush,
- OverlayCharging,
- OverlayReady,
- OverlayFull,
- OverlayEngaged
- }
|