SharedCryostorageSystem.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. using Content.Shared.Administration.Logs;
  2. using Content.Shared.CCVar;
  3. using Content.Shared.DragDrop;
  4. using Content.Shared.GameTicking;
  5. using Content.Shared.Mind;
  6. using Content.Shared.Mind.Components;
  7. using Content.Shared.Mobs.Systems;
  8. using Robust.Shared.Configuration;
  9. using Robust.Shared.Containers;
  10. using Robust.Shared.Map;
  11. using Robust.Shared.Timing;
  12. namespace Content.Shared.Bed.Cryostorage;
  13. /// <summary>
  14. /// This handles <see cref="CryostorageComponent"/>
  15. /// </summary>
  16. public abstract class SharedCryostorageSystem : EntitySystem
  17. {
  18. [Dependency] protected readonly ISharedAdminLogManager AdminLog = default!;
  19. [Dependency] private readonly IConfigurationManager _configuration = default!;
  20. [Dependency] protected readonly IGameTiming Timing = default!;
  21. [Dependency] private readonly IMapManager _mapManager = default!;
  22. [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
  23. [Dependency] protected readonly SharedMindSystem Mind = default!;
  24. [Dependency] private readonly MobStateSystem _mobState = default!;
  25. protected EntityUid? PausedMap { get; private set; }
  26. protected bool CryoSleepRejoiningEnabled;
  27. /// <inheritdoc/>
  28. public override void Initialize()
  29. {
  30. SubscribeLocalEvent<CryostorageComponent, EntInsertedIntoContainerMessage>(OnInsertedContainer);
  31. SubscribeLocalEvent<CryostorageComponent, EntRemovedFromContainerMessage>(OnRemovedContainer);
  32. SubscribeLocalEvent<CryostorageComponent, ContainerIsInsertingAttemptEvent>(OnInsertAttempt);
  33. SubscribeLocalEvent<CryostorageComponent, ComponentShutdown>(OnShutdownContainer);
  34. SubscribeLocalEvent<CryostorageComponent, CanDropTargetEvent>(OnCanDropTarget);
  35. SubscribeLocalEvent<CryostorageContainedComponent, EntGotRemovedFromContainerMessage>(OnRemovedContained);
  36. SubscribeLocalEvent<CryostorageContainedComponent, ComponentShutdown>(OnShutdownContained);
  37. SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
  38. Subs.CVar(_configuration, CCVars.GameCryoSleepRejoining, OnCvarChanged, true);
  39. }
  40. private void OnCvarChanged(bool value)
  41. {
  42. CryoSleepRejoiningEnabled = value;
  43. }
  44. protected virtual void OnInsertedContainer(Entity<CryostorageComponent> ent, ref EntInsertedIntoContainerMessage args)
  45. {
  46. var (_, comp) = ent;
  47. if (args.Container.ID != comp.ContainerId)
  48. return;
  49. _appearance.SetData(ent, CryostorageVisuals.Full, true);
  50. if (!Timing.IsFirstTimePredicted)
  51. return;
  52. var containedComp = EnsureComp<CryostorageContainedComponent>(args.Entity);
  53. var delay = Mind.TryGetMind(args.Entity, out _, out _) ? comp.GracePeriod : comp.NoMindGracePeriod;
  54. containedComp.GracePeriodEndTime = Timing.CurTime + delay;
  55. containedComp.Cryostorage = ent;
  56. Dirty(args.Entity, containedComp);
  57. }
  58. private void OnRemovedContainer(Entity<CryostorageComponent> ent, ref EntRemovedFromContainerMessage args)
  59. {
  60. var (_, comp) = ent;
  61. if (args.Container.ID != comp.ContainerId)
  62. return;
  63. _appearance.SetData(ent, CryostorageVisuals.Full, args.Container.ContainedEntities.Count > 0);
  64. }
  65. private void OnInsertAttempt(Entity<CryostorageComponent> ent, ref ContainerIsInsertingAttemptEvent args)
  66. {
  67. var (_, comp) = ent;
  68. if (args.Container.ID != comp.ContainerId)
  69. return;
  70. if (_mobState.IsIncapacitated(args.EntityUid))
  71. {
  72. args.Cancel();
  73. return;
  74. }
  75. if (!HasComp<CanEnterCryostorageComponent>(args.EntityUid) || !TryComp<MindContainerComponent>(args.EntityUid, out var mindContainer))
  76. {
  77. args.Cancel();
  78. return;
  79. }
  80. if (Mind.TryGetMind(args.EntityUid, out _, out var mindComp, mindContainer) &&
  81. (mindComp.PreventSuicide || mindComp.PreventGhosting))
  82. {
  83. args.Cancel();
  84. }
  85. }
  86. private void OnShutdownContainer(Entity<CryostorageComponent> ent, ref ComponentShutdown args)
  87. {
  88. var comp = ent.Comp;
  89. foreach (var stored in comp.StoredPlayers)
  90. {
  91. if (TryComp<CryostorageContainedComponent>(stored, out var containedComponent))
  92. {
  93. containedComponent.Cryostorage = null;
  94. Dirty(stored, containedComponent);
  95. }
  96. }
  97. comp.StoredPlayers.Clear();
  98. Dirty(ent, comp);
  99. }
  100. private void OnCanDropTarget(Entity<CryostorageComponent> ent, ref CanDropTargetEvent args)
  101. {
  102. if (args.Dragged == args.User)
  103. return;
  104. if (!Mind.TryGetMind(args.Dragged, out _, out var mindComp) || mindComp.Session?.AttachedEntity != args.Dragged)
  105. return;
  106. args.CanDrop = false;
  107. args.Handled = true;
  108. }
  109. private void OnRemovedContained(Entity<CryostorageContainedComponent> ent, ref EntGotRemovedFromContainerMessage args)
  110. {
  111. var (uid, comp) = ent;
  112. if (!IsInPausedMap(uid))
  113. RemCompDeferred(ent, comp);
  114. }
  115. private void OnShutdownContained(Entity<CryostorageContainedComponent> ent, ref ComponentShutdown args)
  116. {
  117. var comp = ent.Comp;
  118. CompOrNull<CryostorageComponent>(comp.Cryostorage)?.StoredPlayers.Remove(ent);
  119. ent.Comp.Cryostorage = null;
  120. Dirty(ent, comp);
  121. }
  122. private void OnRoundRestart(RoundRestartCleanupEvent _)
  123. {
  124. DeletePausedMap();
  125. }
  126. private void DeletePausedMap()
  127. {
  128. if (PausedMap == null || !Exists(PausedMap))
  129. return;
  130. EntityManager.DeleteEntity(PausedMap.Value);
  131. PausedMap = null;
  132. }
  133. protected void EnsurePausedMap()
  134. {
  135. if (PausedMap != null && Exists(PausedMap))
  136. return;
  137. var map = _mapManager.CreateMap();
  138. _mapManager.SetMapPaused(map, true);
  139. PausedMap = _mapManager.GetMapEntityId(map);
  140. }
  141. public bool IsInPausedMap(Entity<TransformComponent?> entity)
  142. {
  143. var (_, comp) = entity;
  144. comp ??= Transform(entity);
  145. return comp.MapUid != null && comp.MapUid == PausedMap;
  146. }
  147. }