CardboardBoxSystem.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using Content.Server.Storage.Components;
  2. using Content.Server.Storage.EntitySystems;
  3. using Content.Shared.Access.Components;
  4. using Content.Shared.CardboardBox;
  5. using Content.Shared.CardboardBox.Components;
  6. using Content.Shared.Damage;
  7. using Content.Shared.Interaction;
  8. using Content.Shared.Movement.Components;
  9. using Content.Shared.Movement.Systems;
  10. using Content.Shared.Stealth;
  11. using Content.Shared.Stealth.Components;
  12. using Content.Shared.Storage.Components;
  13. using Robust.Server.GameObjects;
  14. using Robust.Shared.Audio;
  15. using Robust.Shared.Audio.Systems;
  16. using Robust.Shared.Containers;
  17. using Robust.Shared.Player;
  18. using Robust.Shared.Timing;
  19. namespace Content.Server.CardboardBox;
  20. public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
  21. {
  22. [Dependency] private readonly SharedAudioSystem _audio = default!;
  23. [Dependency] private readonly SharedMoverController _mover = default!;
  24. [Dependency] private readonly IGameTiming _timing = default!;
  25. [Dependency] private readonly SharedStealthSystem _stealth = default!;
  26. [Dependency] private readonly DamageableSystem _damageable = default!;
  27. [Dependency] private readonly EntityStorageSystem _storage = default!;
  28. public override void Initialize()
  29. {
  30. base.Initialize();
  31. SubscribeLocalEvent<CardboardBoxComponent, StorageAfterOpenEvent>(AfterStorageOpen);
  32. SubscribeLocalEvent<CardboardBoxComponent, StorageBeforeOpenEvent>(BeforeStorageOpen);
  33. SubscribeLocalEvent<CardboardBoxComponent, StorageAfterCloseEvent>(AfterStorageClosed);
  34. SubscribeLocalEvent<CardboardBoxComponent, GetAdditionalAccessEvent>(OnGetAdditionalAccess);
  35. SubscribeLocalEvent<CardboardBoxComponent, ActivateInWorldEvent>(OnInteracted);
  36. SubscribeLocalEvent<CardboardBoxComponent, EntInsertedIntoContainerMessage>(OnEntInserted);
  37. SubscribeLocalEvent<CardboardBoxComponent, EntRemovedFromContainerMessage>(OnEntRemoved);
  38. SubscribeLocalEvent<CardboardBoxComponent, DamageChangedEvent>(OnDamage);
  39. }
  40. private void OnInteracted(EntityUid uid, CardboardBoxComponent component, ActivateInWorldEvent args)
  41. {
  42. if (args.Handled)
  43. return;
  44. if (!TryComp<EntityStorageComponent>(uid, out var box))
  45. return;
  46. if (!args.Complex)
  47. {
  48. if (box.Open || !box.Contents.Contains(args.User))
  49. return;
  50. }
  51. args.Handled = true;
  52. _storage.ToggleOpen(args.User, uid, box);
  53. if (box.Contents.Contains(args.User) && !box.Open)
  54. {
  55. _mover.SetRelay(args.User, uid);
  56. component.Mover = args.User;
  57. }
  58. }
  59. private void OnGetAdditionalAccess(EntityUid uid, CardboardBoxComponent component, ref GetAdditionalAccessEvent args)
  60. {
  61. if (component.Mover == null)
  62. return;
  63. args.Entities.Add(component.Mover.Value);
  64. }
  65. private void BeforeStorageOpen(EntityUid uid, CardboardBoxComponent component, ref StorageBeforeOpenEvent args)
  66. {
  67. if (component.Quiet)
  68. return;
  69. //Play effect & sound
  70. if (component.Mover != null)
  71. {
  72. if (_timing.CurTime > component.EffectCooldown)
  73. {
  74. RaiseNetworkEvent(new PlayBoxEffectMessage(GetNetEntity(uid), GetNetEntity(component.Mover.Value)));
  75. _audio.PlayPvs(component.EffectSound, uid);
  76. component.EffectCooldown = _timing.CurTime + component.CooldownDuration;
  77. }
  78. }
  79. }
  80. private void AfterStorageOpen(EntityUid uid, CardboardBoxComponent component, ref StorageAfterOpenEvent args)
  81. {
  82. // If this box has a stealth/chameleon effect, disable the stealth effect while the box is open.
  83. _stealth.SetEnabled(uid, false);
  84. }
  85. private void AfterStorageClosed(EntityUid uid, CardboardBoxComponent component, ref StorageAfterCloseEvent args)
  86. {
  87. // If this box has a stealth/chameleon effect, enable the stealth effect.
  88. if (TryComp(uid, out StealthComponent? stealth))
  89. {
  90. _stealth.SetVisibility(uid, stealth.MaxVisibility, stealth);
  91. _stealth.SetEnabled(uid, true, stealth);
  92. }
  93. }
  94. //Relay damage to the mover
  95. private void OnDamage(EntityUid uid, CardboardBoxComponent component, DamageChangedEvent args)
  96. {
  97. if (args.DamageDelta != null && args.DamageIncreased)
  98. {
  99. _damageable.TryChangeDamage(component.Mover, args.DamageDelta, origin: args.Origin);
  100. }
  101. }
  102. private void OnEntInserted(EntityUid uid, CardboardBoxComponent component, EntInsertedIntoContainerMessage args)
  103. {
  104. if (!TryComp(args.Entity, out MobMoverComponent? mover))
  105. return;
  106. if (component.Mover == null)
  107. {
  108. _mover.SetRelay(args.Entity, uid);
  109. component.Mover = args.Entity;
  110. }
  111. }
  112. /// <summary>
  113. /// Through e.g. teleporting, it's possible for the mover to exit the box without opening it.
  114. /// Handle those situations but don't play the sound.
  115. /// </summary>
  116. private void OnEntRemoved(EntityUid uid, CardboardBoxComponent component, EntRemovedFromContainerMessage args)
  117. {
  118. if (args.Entity != component.Mover)
  119. return;
  120. RemComp<RelayInputMoverComponent>(component.Mover.Value);
  121. component.Mover = null;
  122. }
  123. }