1
0

GhostRoleTests.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #nullable enable
  2. using System.Linq;
  3. using Content.IntegrationTests.Pair;
  4. using Content.Server.Ghost.Roles;
  5. using Content.Server.Ghost.Roles.Components;
  6. using Content.Server.Players;
  7. using Content.Shared.Ghost;
  8. using Content.Shared.Mind;
  9. using Content.Shared.Players;
  10. using Robust.Shared.Console;
  11. using Robust.Shared.GameObjects;
  12. using Robust.Shared.Map;
  13. namespace Content.IntegrationTests.Tests.Minds;
  14. [TestFixture]
  15. public sealed class GhostRoleTests
  16. {
  17. [TestPrototypes]
  18. private const string Prototypes = @"
  19. - type: entity
  20. id: GhostRoleTestEntity
  21. components:
  22. - type: MindContainer
  23. - type: GhostRole
  24. - type: GhostTakeoverAvailable
  25. ";
  26. /// <summary>
  27. /// This is a simple test that just checks if a player can take a ghost role and then regain control of their
  28. /// original entity without encountering errors.
  29. /// </summary>
  30. [Test]
  31. public async Task TakeRoleAndReturn()
  32. {
  33. await using var pair = await PoolManager.GetServerClient(new PoolSettings
  34. {
  35. Dirty = true,
  36. DummyTicker = false,
  37. Connected = true
  38. });
  39. var server = pair.Server;
  40. var client = pair.Client;
  41. var mapData = await pair.CreateTestMap();
  42. var entMan = server.ResolveDependency<IEntityManager>();
  43. var sPlayerMan = server.ResolveDependency<Robust.Server.Player.IPlayerManager>();
  44. var conHost = client.ResolveDependency<IConsoleHost>();
  45. var mindSystem = entMan.System<SharedMindSystem>();
  46. var session = sPlayerMan.Sessions.Single();
  47. var originalMindId = session.ContentData()!.Mind!.Value;
  48. // Spawn player entity & attach
  49. EntityUid originalMob = default;
  50. await server.WaitPost(() =>
  51. {
  52. originalMob = entMan.SpawnEntity(null, mapData.GridCoords);
  53. mindSystem.TransferTo(originalMindId, originalMob, true);
  54. });
  55. // Check player got attached.
  56. await pair.RunTicksSync(10);
  57. Assert.That(session.AttachedEntity, Is.EqualTo(originalMob));
  58. var originalMind = entMan.GetComponent<MindComponent>(originalMindId);
  59. Assert.That(originalMind.OwnedEntity, Is.EqualTo(originalMob));
  60. Assert.That(originalMind.VisitingEntity, Is.Null);
  61. // Use the ghost command
  62. conHost.ExecuteCommand("ghost");
  63. await pair.RunTicksSync(10);
  64. var ghost = session.AttachedEntity;
  65. Assert.That(entMan.HasComponent<GhostComponent>(ghost));
  66. Assert.That(ghost, Is.Not.EqualTo(originalMob));
  67. Assert.That(session.ContentData()?.Mind, Is.EqualTo(originalMindId));
  68. Assert.That(originalMind.OwnedEntity, Is.EqualTo(originalMob), $"Original mob: {originalMob}, Ghost: {ghost}");
  69. Assert.That(originalMind.VisitingEntity, Is.EqualTo(ghost));
  70. // Spawn ghost takeover entity.
  71. EntityUid ghostRole = default;
  72. await server.WaitPost(() => ghostRole = entMan.SpawnEntity("GhostRoleTestEntity", mapData.GridCoords));
  73. // Take the ghost role
  74. await server.WaitPost(() =>
  75. {
  76. var id = entMan.GetComponent<GhostRoleComponent>(ghostRole).Identifier;
  77. entMan.EntitySysManager.GetEntitySystem<GhostRoleSystem>().Takeover(session, id);
  78. });
  79. // Check player got attached to ghost role.
  80. await pair.RunTicksSync(10);
  81. var newMindId = session.ContentData()!.Mind!.Value;
  82. var newMind = entMan.GetComponent<MindComponent>(newMindId);
  83. Assert.That(newMindId, Is.Not.EqualTo(originalMindId));
  84. Assert.That(session.AttachedEntity, Is.EqualTo(ghostRole));
  85. Assert.That(newMind.OwnedEntity, Is.EqualTo(ghostRole));
  86. Assert.That(newMind.VisitingEntity, Is.Null);
  87. // Original mind should be unaffected, but the ghost will have deleted itself.
  88. Assert.That(originalMind.OwnedEntity, Is.EqualTo(originalMob));
  89. Assert.That(originalMind.VisitingEntity, Is.Null);
  90. Assert.That(entMan.Deleted(ghost));
  91. // Ghost again.
  92. conHost.ExecuteCommand("ghost");
  93. await pair.RunTicksSync(10);
  94. var otherGhost = session.AttachedEntity;
  95. Assert.That(entMan.HasComponent<GhostComponent>(otherGhost));
  96. Assert.That(otherGhost, Is.Not.EqualTo(originalMob));
  97. Assert.That(otherGhost, Is.Not.EqualTo(ghostRole));
  98. Assert.That(session.ContentData()?.Mind, Is.EqualTo(newMindId));
  99. Assert.That(newMind.OwnedEntity, Is.EqualTo(ghostRole));
  100. Assert.That(newMind.VisitingEntity, Is.EqualTo(session.AttachedEntity));
  101. // Next, control the original entity again:
  102. await server.WaitPost(() => mindSystem.SetUserId(originalMindId, session.UserId));
  103. await pair.RunTicksSync(10);
  104. Assert.That(session.AttachedEntity, Is.EqualTo(originalMob));
  105. Assert.That(originalMind.OwnedEntity, Is.EqualTo(originalMob));
  106. Assert.That(originalMind.VisitingEntity, Is.Null);
  107. // the ghost-role mind is unaffected, though the ghost will have deleted itself
  108. Assert.That(newMind.OwnedEntity, Is.EqualTo(ghostRole));
  109. Assert.That(newMind.VisitingEntity, Is.Null);
  110. Assert.That(entMan.Deleted(otherGhost));
  111. await pair.CleanReturnAsync();
  112. }
  113. }