1
0

PAISystem.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. using Content.Server.Ghost.Roles;
  2. using Content.Server.Ghost.Roles.Components;
  3. using Content.Server.Instruments;
  4. using Content.Server.Kitchen.Components;
  5. using Content.Shared.Interaction.Events;
  6. using Content.Shared.Mind.Components;
  7. using Content.Shared.PAI;
  8. using Content.Shared.Popups;
  9. using Robust.Shared.Random;
  10. using System.Text;
  11. using Robust.Shared.Player;
  12. namespace Content.Server.PAI;
  13. public sealed class PAISystem : SharedPAISystem
  14. {
  15. [Dependency] private readonly InstrumentSystem _instrumentSystem = default!;
  16. [Dependency] private readonly IRobustRandom _random = default!;
  17. [Dependency] private readonly MetaDataSystem _metaData = default!;
  18. [Dependency] private readonly SharedPopupSystem _popup = default!;
  19. [Dependency] private readonly ToggleableGhostRoleSystem _toggleableGhostRole = default!;
  20. /// <summary>
  21. /// Possible symbols that can be part of a scrambled pai's name.
  22. /// </summary>
  23. private static readonly char[] SYMBOLS = new[] { '#', '~', '-', '@', '&', '^', '%', '$', '*', ' '};
  24. public override void Initialize()
  25. {
  26. base.Initialize();
  27. SubscribeLocalEvent<PAIComponent, UseInHandEvent>(OnUseInHand);
  28. SubscribeLocalEvent<PAIComponent, MindAddedMessage>(OnMindAdded);
  29. SubscribeLocalEvent<PAIComponent, MindRemovedMessage>(OnMindRemoved);
  30. SubscribeLocalEvent<PAIComponent, BeingMicrowavedEvent>(OnMicrowaved);
  31. }
  32. private void OnUseInHand(EntityUid uid, PAIComponent component, UseInHandEvent args)
  33. {
  34. // Not checking for Handled because ToggleableGhostRoleSystem already marks it as such.
  35. if (!TryComp<MindContainerComponent>(uid, out var mind) || !mind.HasMind)
  36. component.LastUser = args.User;
  37. }
  38. private void OnMindAdded(EntityUid uid, PAIComponent component, MindAddedMessage args)
  39. {
  40. if (component.LastUser == null)
  41. return;
  42. // Ownership tag
  43. var val = Loc.GetString("pai-system-pai-name", ("owner", component.LastUser));
  44. // TODO Identity? People shouldn't dox-themselves by carrying around a PAI.
  45. // But having the pda's name permanently be "old lady's PAI" is weird.
  46. // Changing the PAI's identity in a way that ties it to the owner's identity also seems weird.
  47. // Cause then you could remotely figure out information about the owner's equipped items.
  48. _metaData.SetEntityName(uid, val);
  49. }
  50. private void OnMindRemoved(EntityUid uid, PAIComponent component, MindRemovedMessage args)
  51. {
  52. // Mind was removed, shutdown the PAI.
  53. PAITurningOff(uid);
  54. }
  55. private void OnMicrowaved(EntityUid uid, PAIComponent comp, BeingMicrowavedEvent args)
  56. {
  57. // name will always be scrambled whether it gets bricked or not, this is the reward
  58. ScrambleName(uid, comp);
  59. // randomly brick it
  60. if (_random.Prob(comp.BrickChance))
  61. {
  62. _popup.PopupEntity(Loc.GetString(comp.BrickPopup), uid, PopupType.LargeCaution);
  63. _toggleableGhostRole.Wipe(uid);
  64. RemComp<PAIComponent>(uid);
  65. RemComp<ToggleableGhostRoleComponent>(uid);
  66. }
  67. else
  68. {
  69. // you are lucky...
  70. _popup.PopupEntity(Loc.GetString(comp.ScramblePopup), uid, PopupType.Large);
  71. }
  72. }
  73. private void ScrambleName(EntityUid uid, PAIComponent comp)
  74. {
  75. // create a new random name
  76. var len = _random.Next(6, 18);
  77. var name = new StringBuilder(len);
  78. for (int i = 0; i < len; i++)
  79. {
  80. name.Append(_random.Pick(SYMBOLS));
  81. }
  82. // add 's pAI to the scrambled name
  83. var val = Loc.GetString("pai-system-pai-name-raw", ("name", name.ToString()));
  84. _metaData.SetEntityName(uid, val);
  85. }
  86. public void PAITurningOff(EntityUid uid)
  87. {
  88. // Close the instrument interface if it was open
  89. // before closing
  90. if (HasComp<ActiveInstrumentComponent>(uid))
  91. {
  92. _instrumentSystem.ToggleInstrumentUi(uid, uid);
  93. }
  94. // Stop instrument
  95. if (TryComp<InstrumentComponent>(uid, out var instrument))
  96. _instrumentSystem.Clean(uid, instrument);
  97. if (TryComp(uid, out MetaDataComponent? metadata))
  98. {
  99. var proto = metadata.EntityPrototype;
  100. if (proto != null)
  101. _metaData.SetEntityName(uid, proto.Name);
  102. }
  103. }
  104. }