1
0

MimePowersSystem.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. using Content.Server.Popups;
  2. using Content.Shared.Abilities.Mime;
  3. using Content.Shared.Actions;
  4. using Content.Shared.Actions.Events;
  5. using Content.Shared.Alert;
  6. using Content.Shared.Coordinates.Helpers;
  7. using Content.Shared.Maps;
  8. using Content.Shared.Paper;
  9. using Content.Shared.Physics;
  10. using Robust.Shared.Containers;
  11. using Robust.Shared.Map;
  12. using Robust.Shared.Timing;
  13. using Content.Shared.Speech.Muting;
  14. namespace Content.Server.Abilities.Mime
  15. {
  16. public sealed class MimePowersSystem : EntitySystem
  17. {
  18. [Dependency] private readonly PopupSystem _popupSystem = default!;
  19. [Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
  20. [Dependency] private readonly AlertsSystem _alertsSystem = default!;
  21. [Dependency] private readonly TurfSystem _turf = default!;
  22. [Dependency] private readonly IMapManager _mapMan = default!;
  23. [Dependency] private readonly SharedContainerSystem _container = default!;
  24. [Dependency] private readonly IGameTiming _timing = default!;
  25. public override void Initialize()
  26. {
  27. base.Initialize();
  28. SubscribeLocalEvent<MimePowersComponent, ComponentInit>(OnComponentInit);
  29. SubscribeLocalEvent<MimePowersComponent, InvisibleWallActionEvent>(OnInvisibleWall);
  30. SubscribeLocalEvent<MimePowersComponent, BreakVowAlertEvent>(OnBreakVowAlert);
  31. SubscribeLocalEvent<MimePowersComponent, RetakeVowAlertEvent>(OnRetakeVowAlert);
  32. }
  33. public override void Update(float frameTime)
  34. {
  35. base.Update(frameTime);
  36. // Queue to track whether mimes can retake vows yet
  37. var query = EntityQueryEnumerator<MimePowersComponent>();
  38. while (query.MoveNext(out var uid, out var mime))
  39. {
  40. if (!mime.VowBroken || mime.ReadyToRepent)
  41. continue;
  42. if (_timing.CurTime < mime.VowRepentTime)
  43. continue;
  44. mime.ReadyToRepent = true;
  45. _popupSystem.PopupEntity(Loc.GetString("mime-ready-to-repent"), uid, uid);
  46. }
  47. }
  48. private void OnComponentInit(EntityUid uid, MimePowersComponent component, ComponentInit args)
  49. {
  50. EnsureComp<MutedComponent>(uid);
  51. if (component.PreventWriting)
  52. {
  53. EnsureComp<BlockWritingComponent>(uid, out var illiterateComponent);
  54. illiterateComponent.FailWriteMessage = component.FailWriteMessage;
  55. Dirty(uid, illiterateComponent);
  56. }
  57. _alertsSystem.ShowAlert(uid, component.VowAlert);
  58. _actionsSystem.AddAction(uid, ref component.InvisibleWallActionEntity, component.InvisibleWallAction, uid);
  59. }
  60. /// <summary>
  61. /// Creates an invisible wall in a free space after some checks.
  62. /// </summary>
  63. private void OnInvisibleWall(EntityUid uid, MimePowersComponent component, InvisibleWallActionEvent args)
  64. {
  65. if (!component.Enabled)
  66. return;
  67. if (_container.IsEntityOrParentInContainer(uid))
  68. return;
  69. var xform = Transform(uid);
  70. // Get the tile in front of the mime
  71. var offsetValue = xform.LocalRotation.ToWorldVec();
  72. var coords = xform.Coordinates.Offset(offsetValue).SnapToGrid(EntityManager, _mapMan);
  73. var tile = coords.GetTileRef(EntityManager, _mapMan);
  74. if (tile == null)
  75. return;
  76. // Check if the tile is blocked by a wall or mob, and don't create the wall if so
  77. if (_turf.IsTileBlocked(tile.Value, CollisionGroup.Impassable | CollisionGroup.Opaque))
  78. {
  79. _popupSystem.PopupEntity(Loc.GetString("mime-invisible-wall-failed"), uid, uid);
  80. return;
  81. }
  82. _popupSystem.PopupEntity(Loc.GetString("mime-invisible-wall-popup", ("mime", uid)), uid);
  83. // Make sure we set the invisible wall to despawn properly
  84. Spawn(component.WallPrototype, _turf.GetTileCenter(tile.Value));
  85. // Handle args so cooldown works
  86. args.Handled = true;
  87. }
  88. private void OnBreakVowAlert(Entity<MimePowersComponent> ent, ref BreakVowAlertEvent args)
  89. {
  90. if (args.Handled)
  91. return;
  92. BreakVow(ent, ent);
  93. args.Handled = true;
  94. }
  95. private void OnRetakeVowAlert(Entity<MimePowersComponent> ent, ref RetakeVowAlertEvent args)
  96. {
  97. if (args.Handled)
  98. return;
  99. RetakeVow(ent, ent);
  100. args.Handled = true;
  101. }
  102. /// <summary>
  103. /// Break this mime's vow to not speak.
  104. /// </summary>
  105. public void BreakVow(EntityUid uid, MimePowersComponent? mimePowers = null)
  106. {
  107. if (!Resolve(uid, ref mimePowers))
  108. return;
  109. if (mimePowers.VowBroken)
  110. return;
  111. mimePowers.Enabled = false;
  112. mimePowers.VowBroken = true;
  113. mimePowers.VowRepentTime = _timing.CurTime + mimePowers.VowCooldown;
  114. RemComp<MutedComponent>(uid);
  115. if (mimePowers.PreventWriting)
  116. RemComp<BlockWritingComponent>(uid);
  117. _alertsSystem.ClearAlert(uid, mimePowers.VowAlert);
  118. _alertsSystem.ShowAlert(uid, mimePowers.VowBrokenAlert);
  119. _actionsSystem.RemoveAction(uid, mimePowers.InvisibleWallActionEntity);
  120. }
  121. /// <summary>
  122. /// Retake this mime's vow to not speak.
  123. /// </summary>
  124. public void RetakeVow(EntityUid uid, MimePowersComponent? mimePowers = null)
  125. {
  126. if (!Resolve(uid, ref mimePowers))
  127. return;
  128. if (!mimePowers.ReadyToRepent)
  129. {
  130. _popupSystem.PopupEntity(Loc.GetString("mime-not-ready-repent"), uid, uid);
  131. return;
  132. }
  133. mimePowers.Enabled = true;
  134. mimePowers.ReadyToRepent = false;
  135. mimePowers.VowBroken = false;
  136. AddComp<MutedComponent>(uid);
  137. if (mimePowers.PreventWriting)
  138. {
  139. EnsureComp<BlockWritingComponent>(uid, out var illiterateComponent);
  140. illiterateComponent.FailWriteMessage = mimePowers.FailWriteMessage;
  141. Dirty(uid, illiterateComponent);
  142. }
  143. _alertsSystem.ClearAlert(uid, mimePowers.VowBrokenAlert);
  144. _alertsSystem.ShowAlert(uid, mimePowers.VowAlert);
  145. _actionsSystem.AddAction(uid, ref mimePowers.InvisibleWallActionEntity, mimePowers.InvisibleWallAction, uid);
  146. }
  147. }
  148. }