AirlockSystem.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. using Content.Client.Wires.Visualizers;
  2. using Content.Shared.Doors.Components;
  3. using Content.Shared.Doors.Systems;
  4. using Content.Shared.Power;
  5. using Robust.Client.Animations;
  6. using Robust.Client.GameObjects;
  7. namespace Content.Client.Doors;
  8. public sealed class AirlockSystem : SharedAirlockSystem
  9. {
  10. [Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
  11. public override void Initialize()
  12. {
  13. base.Initialize();
  14. SubscribeLocalEvent<AirlockComponent, ComponentStartup>(OnComponentStartup);
  15. SubscribeLocalEvent<AirlockComponent, AppearanceChangeEvent>(OnAppearanceChange);
  16. }
  17. private void OnComponentStartup(EntityUid uid, AirlockComponent comp, ComponentStartup args)
  18. {
  19. // Has to be on component startup because we don't know what order components initialize in and running this before DoorComponent inits _will_ crash.
  20. if(!TryComp<DoorComponent>(uid, out var door))
  21. return;
  22. if (comp.OpenUnlitVisible) // Otherwise there are flashes of the fallback sprite between clicking on the door and the door closing animation starting.
  23. {
  24. door.OpenSpriteStates.Add((DoorVisualLayers.BaseUnlit, comp.OpenSpriteState));
  25. door.ClosedSpriteStates.Add((DoorVisualLayers.BaseUnlit, comp.ClosedSpriteState));
  26. }
  27. ((Animation)door.OpeningAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick()
  28. {
  29. LayerKey = DoorVisualLayers.BaseUnlit,
  30. KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.OpeningSpriteState, 0f) },
  31. }
  32. );
  33. ((Animation)door.ClosingAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick()
  34. {
  35. LayerKey = DoorVisualLayers.BaseUnlit,
  36. KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.ClosingSpriteState, 0f) },
  37. }
  38. );
  39. door.DenyingAnimation = new Animation()
  40. {
  41. Length = TimeSpan.FromSeconds(comp.DenyAnimationTime),
  42. AnimationTracks =
  43. {
  44. new AnimationTrackSpriteFlick()
  45. {
  46. LayerKey = DoorVisualLayers.BaseUnlit,
  47. KeyFrames = { new AnimationTrackSpriteFlick.KeyFrame(comp.DenySpriteState, 0f) },
  48. }
  49. }
  50. };
  51. if(!comp.AnimatePanel)
  52. return;
  53. ((Animation)door.OpeningAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick()
  54. {
  55. LayerKey = WiresVisualLayers.MaintenancePanel,
  56. KeyFrames = {new AnimationTrackSpriteFlick.KeyFrame(comp.OpeningPanelSpriteState, 0f)},
  57. });
  58. ((Animation)door.ClosingAnimation).AnimationTracks.Add(new AnimationTrackSpriteFlick
  59. {
  60. LayerKey = WiresVisualLayers.MaintenancePanel,
  61. KeyFrames = {new AnimationTrackSpriteFlick.KeyFrame(comp.ClosingPanelSpriteState, 0f)},
  62. });
  63. }
  64. private void OnAppearanceChange(EntityUid uid, AirlockComponent comp, ref AppearanceChangeEvent args)
  65. {
  66. if (args.Sprite == null)
  67. return;
  68. var boltedVisible = false;
  69. var emergencyLightsVisible = false;
  70. var unlitVisible = false;
  71. if (!_appearanceSystem.TryGetData<DoorState>(uid, DoorVisuals.State, out var state, args.Component))
  72. state = DoorState.Closed;
  73. if (_appearanceSystem.TryGetData<bool>(uid, PowerDeviceVisuals.Powered, out var powered, args.Component)
  74. && powered)
  75. {
  76. boltedVisible = _appearanceSystem.TryGetData<bool>(uid, DoorVisuals.BoltLights, out var lights, args.Component)
  77. && lights && (state == DoorState.Closed || state == DoorState.Welded);
  78. emergencyLightsVisible = _appearanceSystem.TryGetData<bool>(uid, DoorVisuals.EmergencyLights, out var eaLights, args.Component) && eaLights;
  79. unlitVisible =
  80. (state == DoorState.Closing
  81. || state == DoorState.Opening
  82. || state == DoorState.Denying
  83. || (state == DoorState.Open && comp.OpenUnlitVisible)
  84. || (_appearanceSystem.TryGetData<bool>(uid, DoorVisuals.ClosedLights, out var closedLights, args.Component) && closedLights))
  85. && !boltedVisible && !emergencyLightsVisible;
  86. }
  87. args.Sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, unlitVisible);
  88. args.Sprite.LayerSetVisible(DoorVisualLayers.BaseBolted, boltedVisible);
  89. if (comp.EmergencyAccessLayer)
  90. {
  91. args.Sprite.LayerSetVisible(
  92. DoorVisualLayers.BaseEmergencyAccess,
  93. emergencyLightsVisible
  94. && state != DoorState.Open
  95. && state != DoorState.Opening
  96. && state != DoorState.Closing
  97. && !boltedVisible
  98. );
  99. }
  100. switch (state)
  101. {
  102. case DoorState.Open:
  103. args.Sprite.LayerSetState(DoorVisualLayers.BaseUnlit, comp.ClosingSpriteState);
  104. args.Sprite.LayerSetAnimationTime(DoorVisualLayers.BaseUnlit, 0);
  105. break;
  106. case DoorState.Closed:
  107. args.Sprite.LayerSetState(DoorVisualLayers.BaseUnlit, comp.OpeningSpriteState);
  108. args.Sprite.LayerSetAnimationTime(DoorVisualLayers.BaseUnlit, 0);
  109. break;
  110. }
  111. }
  112. }