1
0

SubFloorHideSystem.cs 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using Content.Shared.Construction.Components;
  2. using Content.Shared.Eye;
  3. using Content.Shared.SubFloor;
  4. using Robust.Server.Player;
  5. using Robust.Shared.Enums;
  6. using Robust.Shared.Map.Components;
  7. using Robust.Shared.Player;
  8. namespace Content.Server.SubFloor;
  9. public sealed class SubFloorHideSystem : SharedSubFloorHideSystem
  10. {
  11. [Dependency] private readonly IPlayerManager _player = default!;
  12. [Dependency] private readonly SharedEyeSystem _eye = default!;
  13. private HashSet<ICommonSession> _showFloors = new();
  14. public override void Initialize()
  15. {
  16. base.Initialize();
  17. SubscribeLocalEvent<SubFloorHideComponent, AnchorAttemptEvent>(OnAnchorAttempt);
  18. SubscribeLocalEvent<SubFloorHideComponent, UnanchorAttemptEvent>(OnUnanchorAttempt);
  19. SubscribeNetworkEvent<ShowSubfloorRequestEvent>(OnShowSubfloor);
  20. SubscribeLocalEvent<GetVisMaskEvent>(OnGetVisibility);
  21. _player.PlayerStatusChanged += OnPlayerStatus;
  22. }
  23. private void OnPlayerStatus(object? sender, SessionStatusEventArgs e)
  24. {
  25. if (e.NewStatus == SessionStatus.Connected)
  26. return;
  27. _showFloors.Remove(e.Session);
  28. if (e.Session.AttachedEntity != null)
  29. _eye.RefreshVisibilityMask(e.Session.AttachedEntity.Value);
  30. }
  31. private void OnGetVisibility(ref GetVisMaskEvent ev)
  32. {
  33. if (!TryComp(ev.Entity, out ActorComponent? actor))
  34. return;
  35. if (_showFloors.Contains(actor.PlayerSession))
  36. {
  37. ev.VisibilityMask |= (int)VisibilityFlags.Subfloor;
  38. }
  39. }
  40. private void OnShowSubfloor(ShowSubfloorRequestEvent ev, EntitySessionEventArgs args)
  41. {
  42. // TODO: Commands are a bit of an eh? for client-only but checking shared perms
  43. var ent = args.SenderSession.AttachedEntity;
  44. if (!TryComp(ent, out EyeComponent? eyeComp))
  45. return;
  46. if (ev.Value)
  47. {
  48. _showFloors.Add(args.SenderSession);
  49. }
  50. else
  51. {
  52. _showFloors.Remove(args.SenderSession);
  53. }
  54. _eye.RefreshVisibilityMask((ent.Value, eyeComp));
  55. RaiseNetworkEvent(new ShowSubfloorRequestEvent()
  56. {
  57. Value = ev.Value,
  58. }, args.SenderSession);
  59. }
  60. private void OnAnchorAttempt(EntityUid uid, SubFloorHideComponent component, AnchorAttemptEvent args)
  61. {
  62. // No teleporting entities through floor tiles when anchoring them.
  63. var xform = Transform(uid);
  64. if (TryComp<MapGridComponent>(xform.GridUid, out var grid)
  65. && HasFloorCover(xform.GridUid.Value, grid, Map.TileIndicesFor(xform.GridUid.Value, grid, xform.Coordinates)))
  66. {
  67. args.Cancel();
  68. }
  69. }
  70. private void OnUnanchorAttempt(EntityUid uid, SubFloorHideComponent component, UnanchorAttemptEvent args)
  71. {
  72. // No un-anchoring things under the floor. Only required for something like vents, which are still interactable
  73. // despite being partially under the floor.
  74. if (component.IsUnderCover)
  75. args.Cancel();
  76. }
  77. }