Fix some Mind ECS bugs (#17480)

This commit is contained in:
Leon Friedrich
2023-06-20 16:29:26 +12:00
committed by GitHub
parent 41244b74aa
commit 9fc4fc6ac2
18 changed files with 767 additions and 248 deletions

View File

@@ -4,6 +4,7 @@ using System.Threading.Tasks;
using Content.Client.Construction;
using Content.Client.Examine;
using Content.Server.Body.Systems;
using Content.Server.Mind;
using Content.Server.Mind.Components;
using Content.Server.Players;
using Content.Server.Stack;
@@ -184,7 +185,7 @@ public abstract partial class InteractionTest
{
// Fuck you mind system I want an hour of my life back
// Mind system is a time vampire
ServerSession.ContentData()?.WipeMind();
SEntMan.System<MindSystem>().WipeMind(ServerSession.ContentData()?.Mind);
old = cPlayerMan.LocalPlayer.ControlledEntity;
Player = SEntMan.SpawnEntity(PlayerPrototype, PlayerCoords);

View File

@@ -0,0 +1,234 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameTicking;
using Content.Server.Ghost.Components;
using Content.Server.Mind;
using Content.Server.Mind.Components;
using Content.Server.Players;
using NUnit.Framework;
using Robust.Server.Console;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Network;
namespace Content.IntegrationTests.Tests.Minds;
[TestFixture]
public sealed class GhostTests
{
/// <summary>
/// Test that a ghost gets created when the player entity is deleted.
/// 1. Delete mob
/// 2. Assert is ghost
/// </summary>
[Test]
public async Task TestGhostOnDelete()
{
// Client is needed to spawn session
await using var pairTracker = await PoolManager.GetServerClient();
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>();
var playerMan = server.ResolveDependency<IPlayerManager>();
IPlayerSession player = playerMan.ServerSessions.Single();
await server.WaitAssertion(() =>
{
Assert.That(player.AttachedEntity, Is.Not.EqualTo(null));
entMan.DeleteEntity(player.AttachedEntity!.Value);
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() =>
{
// Is player a ghost?
Assert.That(player.AttachedEntity, Is.Not.EqualTo(null));
var entity = player.AttachedEntity!.Value;
Assert.That(entMan.HasComponent<GhostComponent>(entity));
});
await pairTracker.CleanReturnAsync();
}
/// <summary>
/// Test that when the original mob gets deleted, the visited ghost does not get deleted.
/// And that the visited ghost becomes the main mob.
/// 1. Visit ghost
/// 2. Delete original mob
/// 3. Assert is ghost
/// 4. Assert was not deleted
/// 5. Assert is main mob
/// </summary>
[Test]
public async Task TestOriginalDeletedWhileGhostingKeepsGhost()
{
// Client is needed to spawn session
await using var pairTracker = await PoolManager.GetServerClient();
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>();
var playerMan = server.ResolveDependency<IPlayerManager>();
var gameTicker = entMan.EntitySysManager.GetEntitySystem<GameTicker>();
var mindSystem = entMan.EntitySysManager.GetEntitySystem<MindSystem>();
IPlayerSession player = playerMan.ServerSessions.Single();
EntityUid originalEntity = default!;
EntityUid ghost = default!;
await server.WaitAssertion(() =>
{
Assert.That(player.AttachedEntity, Is.Not.EqualTo(null));
originalEntity = player.AttachedEntity!.Value;
Assert.That(mindSystem.TryGetMind(player.UserId, out var mind), "could not find mind");
ghost = entMan.SpawnEntity("MobObserver", MapCoordinates.Nullspace);
mindSystem.Visit(mind, ghost);
Assert.That(player.AttachedEntity, Is.EqualTo(ghost));
Assert.That(entMan.HasComponent<GhostComponent>(player.AttachedEntity), "player is not a ghost");
Assert.That(mind.VisitingEntity, Is.EqualTo(player.AttachedEntity));
Assert.That(mind.OwnedEntity, Is.EqualTo(originalEntity));
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() => entMan.DeleteEntity(originalEntity));
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() =>
{
// Is player a ghost?
Assert.That(!entMan.Deleted(ghost), "ghost has been deleted");
Assert.That(player.AttachedEntity, Is.EqualTo(ghost));
Assert.That(entMan.HasComponent<GhostComponent>(player.AttachedEntity));
Assert.That(mindSystem.TryGetMind(player.UserId, out var mind), "could not find mind");
Assert.That(mind.UserId, Is.EqualTo(player.UserId));
Assert.That(mind.Session, Is.EqualTo(player));
Assert.IsNull(mind.VisitingEntity);
Assert.That(mind.OwnedEntity, Is.EqualTo(ghost));
});
await pairTracker.CleanReturnAsync();
}
/// <summary>
/// Test that ghosts can become admin ghosts without issue
/// 1. Become a ghost
/// 2. visit an admin ghost
/// 3. original ghost is deleted, player is an admin ghost.
/// </summary>
[Test]
public async Task TestGhostToAghost()
{
// Client is needed to spawn session
await using var pairTracker = await PoolManager.GetServerClient();
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>();
var playerMan = server.ResolveDependency<IPlayerManager>();
var serverConsole = server.ResolveDependency<IServerConsoleHost>();
IPlayerSession player = playerMan.ServerSessions.Single();
EntityUid ghost = default!;
await server.WaitAssertion(() =>
{
Assert.That(player.AttachedEntity, Is.Not.EqualTo(null));
entMan.DeleteEntity(player.AttachedEntity!.Value);
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() =>
{
// Is player a ghost?
Assert.That(player.AttachedEntity, Is.Not.EqualTo(null));
ghost = player.AttachedEntity!.Value;
Assert.That(entMan.HasComponent<GhostComponent>(ghost));
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() =>
{
serverConsole.ExecuteCommand(player, "aghost");
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() =>
{
Assert.That(entMan.Deleted(ghost));
Assert.That(player.AttachedEntity, Is.Not.EqualTo(ghost));
Assert.That(entMan.HasComponent<GhostComponent>(player.AttachedEntity!.Value));
var mind = player.ContentData()?.Mind;
Assert.NotNull(mind);
Assert.Null(mind.VisitingEntity);
});
await pairTracker.CleanReturnAsync();
}
/// <summary>
/// Test ghost getting deleted while player is connected spawns another ghost
/// 1. become ghost
/// 2. delete ghost
/// 3. new ghost is spawned
/// </summary>
[Test]
public async Task TestGhostDeletedSpawnsNewGhost()
{
// Client is needed to spawn session
await using var pairTracker = await PoolManager.GetServerClient();
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>();
var playerMan = server.ResolveDependency<IPlayerManager>();
var serverConsole = server.ResolveDependency<IServerConsoleHost>();
IPlayerSession player = playerMan.ServerSessions.Single();
EntityUid ghost = default!;
await server.WaitAssertion(() =>
{
Assert.That(player.AttachedEntity, Is.Not.EqualTo(null));
entMan.DeleteEntity(player.AttachedEntity!.Value);
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() =>
{
// Is player a ghost?
Assert.That(player.AttachedEntity, Is.Not.EqualTo(null));
ghost = player.AttachedEntity!.Value;
Assert.That(entMan.HasComponent<GhostComponent>(ghost));
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() =>
{
serverConsole.ExecuteCommand(player, "aghost");
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() =>
{
Assert.That(entMan.Deleted(ghost));
Assert.That(player.AttachedEntity, Is.Not.EqualTo(ghost));
Assert.That(entMan.HasComponent<GhostComponent>(player.AttachedEntity!.Value));
});
await pairTracker.CleanReturnAsync();
}
}

View File

@@ -2,6 +2,7 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Mind;
using Content.Server.Players;
using NUnit.Framework;
using Robust.Server.GameObjects;
using Robust.Server.Player;
@@ -16,6 +17,11 @@ namespace Content.IntegrationTests.Tests.Minds
[TestFixture]
public sealed class MindEntityDeletionTest
{
// This test will do the following:
// - spawn a player
// - visit some entity
// - delete the entity being visited
// - assert that player returns to original entity
[Test]
public async Task TestDeleteVisiting()
{
@@ -50,95 +56,34 @@ namespace Content.IntegrationTests.Tests.Minds
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() =>
{
entMan.DeleteEntity(visitEnt);
if (mind.VisitingEntity != null)
{
Assert.Fail("Mind VisitingEntity was not null");
return;
}
// This used to throw so make sure it doesn't.
entMan.DeleteEntity(playerEnt);
});
await server.WaitPost(() => entMan.DeleteEntity(visitEnt));
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitPost(() =>
{
mapManager.DeleteMap(map.MapId);
});
await pairTracker.CleanReturnAsync();
}
[Test]
public async Task TestGhostOnDelete()
{
// Has to be a non-dummy ticker so we have a proper map.
await using var pairTracker = await PoolManager.GetServerClient();
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>();
var playerMan = server.ResolveDependency<IPlayerManager>();
var mapManager = server.ResolveDependency<IMapManager>();
var mindSystem = entMan.EntitySysManager.GetEntitySystem<MindSystem>();
var map = await PoolManager.CreateTestMap(pairTracker);
EntityUid playerEnt = default;
Mind mind = default!;
await server.WaitAssertion(() =>
{
var player = playerMan.ServerSessions.Single();
var pos = new MapCoordinates(Vector2.Zero, map.MapId);
playerEnt = entMan.SpawnEntity(null, pos);
mind = mindSystem.CreateMind(player.UserId);
mindSystem.TransferTo(mind, playerEnt);
Assert.That(mind.CurrentEntity, Is.EqualTo(playerEnt));
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitPost(() =>
{
entMan.DeleteEntity(playerEnt);
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() =>
{
Assert.That(entMan.EntityExists(mind.CurrentEntity!.Value), Is.True);
});
await server.WaitPost(() =>
{
mapManager.DeleteMap(map.MapId);
});
Assert.IsNull(mind.VisitingEntity);
Assert.That(entMan.EntityExists(mind.OwnedEntity));
Assert.That(mind.OwnedEntity, Is.EqualTo(playerEnt));
// This used to throw so make sure it doesn't.
await server.WaitPost(() => entMan.DeleteEntity(mind.OwnedEntity!.Value));
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitPost(() => mapManager.DeleteMap(map.MapId));
await pairTracker.CleanReturnAsync();
}
// this is a variant of TestGhostOnDelete that just deletes the whole map.
[Test]
public async Task TestGhostOnDeleteMap()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings { NoClient = true });
await using var pairTracker = await PoolManager.GetServerClient();
var server = pairTracker.Pair.Server;
var testMap = await PoolManager.CreateTestMap(pairTracker);
var coordinates = testMap.GridCoords;
var entMan = server.ResolveDependency<IServerEntityManager>();
var mapManager = server.ResolveDependency<IMapManager>();
var playerMan = server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
var mindSystem = entMan.EntitySysManager.GetEntitySystem<MindSystem>();
@@ -149,8 +94,7 @@ namespace Content.IntegrationTests.Tests.Minds
await server.WaitAssertion(() =>
{
playerEnt = entMan.SpawnEntity(null, coordinates);
mind = mindSystem.CreateMind(null);
mind = player.ContentData()!.Mind!;
mindSystem.TransferTo(mind, playerEnt);
Assert.That(mind.CurrentEntity, Is.EqualTo(playerEnt));

View File

@@ -0,0 +1,134 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Ghost.Components;
using Content.Server.Mind;
using Content.Server.Players;
using NUnit.Framework;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Enums;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Network;
using IPlayerManager = Robust.Server.Player.IPlayerManager;
namespace Content.IntegrationTests.Tests.Minds;
// This partial class contains misc helper functions for other tests.
[TestFixture]
public sealed partial class MindTests
{
public async Task<EntityUid> BecomeGhost(Pair pair, bool visit = false)
{
var entMan = pair.Server.ResolveDependency<IServerEntityManager>();
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var mindSys = entMan.System<MindSystem>();
EntityUid ghostUid = default;
Mind mind = default!;
var player = playerMan.ServerSessions.Single();
await pair.Server.WaitAssertion(() =>
{
var oldUid = player.AttachedEntity;
ghostUid = entMan.SpawnEntity("MobObserver", MapCoordinates.Nullspace);
mind = mindSys.GetMind(player.UserId);
Assert.NotNull(mind);
if (visit)
{
mindSys.Visit(mind, ghostUid);
return;
}
mindSys.TransferTo(mind, ghostUid);
if (oldUid != null)
entMan.DeleteEntity(oldUid.Value);
});
await PoolManager.RunTicksSync(pair, 5);
Assert.That(entMan.HasComponent<GhostComponent>(ghostUid));
Assert.That(player.AttachedEntity == ghostUid);
Assert.That(mind.CurrentEntity == ghostUid);
if (!visit)
Assert.Null(mind.VisitingEntity);
return ghostUid;
}
public async Task<EntityUid> VisitGhost(Pair pair, bool visit = false)
{
return await BecomeGhost(pair, visit: true);
}
/// <summary>
/// Get the player's current mind and check that the entities exists.
/// </summary>
public Mind GetMind(Pair pair)
{
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var entMan = pair.Server.ResolveDependency<IEntityManager>();
var player = playerMan.ServerSessions.SingleOrDefault();
Assert.NotNull(player);
var mind = player.ContentData()!.Mind;
Assert.NotNull(mind);
Assert.That(player.AttachedEntity, Is.EqualTo(mind.CurrentEntity));
Assert.That(entMan.EntityExists(mind.OwnedEntity));
Assert.That(entMan.EntityExists(mind.CurrentEntity));
return mind;
}
public async Task Disconnect(Pair pair)
{
var netManager = pair.Client.ResolveDependency<IClientNetManager>();
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
var mind = player.ContentData()!.Mind;
await pair.Client.WaitAssertion(() =>
{
netManager.ClientDisconnect("Disconnect command used.");
});
await PoolManager.RunTicksSync(pair, 5);
Assert.That(player.Status == SessionStatus.Disconnected);
Assert.NotNull(mind.UserId);
Assert.Null(mind.Session);
}
public async Task Connect(Pair pair, string username)
{
var netManager = pair.Client.ResolveDependency<IClientNetManager>();
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
Assert.That(!playerMan.ServerSessions.Any());
await Task.WhenAll(pair.Client.WaitIdleAsync(), pair.Client.WaitIdleAsync());
pair.Client.SetConnectTarget(pair.Server);
await pair.Client.WaitPost(() => netManager.ClientConnect(null!, 0, username));
await PoolManager.RunTicksSync(pair, 5);
var player = playerMan.ServerSessions.Single();
Assert.That(player.Status == SessionStatus.InGame);
}
public async Task<IPlayerSession> DisconnectReconnect(Pair pair)
{
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
var name = player.Name;
var id = player.UserId;
await Disconnect(pair);
await Connect(pair, name);
// Session has changed
var newSession = playerMan.ServerSessions.Single();
Assert.That(newSession != player);
Assert.That(newSession.UserId == id);
return newSession;
}
}

View File

@@ -0,0 +1,157 @@
using System.Linq;
using System.Threading.Tasks;
using Content.Server.Ghost.Components;
using Content.Server.Mind;
using NUnit.Framework;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
namespace Content.IntegrationTests.Tests.Minds;
[TestFixture]
public sealed partial class MindTests
{
// This test will do the following:
// - attach a player to a ghost (not visiting)
// - disconnect
// - reconnect
// - assert that they spawned in as a new entity
[Test]
public async Task TestGhostsCanReconnect()
{
await using var pairTracker = await PoolManager.GetServerClient();
var pair = pairTracker.Pair;
var entMan = pair.Server.ResolveDependency<IEntityManager>();
await PoolManager.RunTicksSync(pair, 5);
var mind = GetMind(pair);
var ghost = await BecomeGhost(pair);
await DisconnectReconnect(pair);
// Player in control of a NEW entity
var newMind = GetMind(pair);
Assert.That(newMind != mind);
Assert.That(entMan.Deleted(ghost));
Assert.Null(newMind.VisitingEntity);
await pairTracker.CleanReturnAsync();
}
// This test will do the following:
// - disconnect a player
// - delete their original entity
// - reconnect
// - assert that they spawned in as a new entity
[Test]
public async Task TestDeletedCanReconnect()
{
await using var pairTracker = await PoolManager.GetServerClient();
var pair = pairTracker.Pair;
var entMan = pair.Server.ResolveDependency<IEntityManager>();
await PoolManager.RunTicksSync(pair, 5);
var mind = GetMind(pair);
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
var name = player.Name;
var user = player.UserId;
Assert.NotNull(mind.OwnedEntity);
var entity = mind.OwnedEntity.Value;
// Player is not a ghost
Assert.That(!entMan.HasComponent<GhostComponent>(mind.CurrentEntity));
// Disconnect
await Disconnect(pair);
// Delete entity
Assert.That(entMan.EntityExists(entity));
await pair.Server.WaitPost(() => entMan.DeleteEntity(entity));
Assert.That(entMan.Deleted(entity));
Assert.IsNull(mind.OwnedEntity);
// Reconnect
await Connect(pair, name);
player = playerMan.ServerSessions.Single();
Assert.That(user == player.UserId);
// Player is now a new entity
var newMind = GetMind(pair);
Assert.That(newMind != mind);
Assert.Null(mind.UserId);
Assert.Null(mind.CurrentEntity);
Assert.NotNull(newMind.OwnedEntity);
Assert.That(entMan.EntityExists(newMind.OwnedEntity));
await pairTracker.CleanReturnAsync();
}
// This test will do the following:
// - visit a ghost
// - disconnect
// - reconnect
// - assert that they return to their original entity
[Test]
public async Task TestVisitingGhostReconnect()
{
await using var pairTracker = await PoolManager.GetServerClient();
var pair = pairTracker.Pair;
var entMan = pair.Server.ResolveDependency<IEntityManager>();
await PoolManager.RunTicksSync(pair, 5);
var mind = GetMind(pair);
var original = mind.CurrentEntity;
var ghost = await VisitGhost(pair);
await DisconnectReconnect(pair);
// Player now controls their original mob, mind was preserved
Assert.That(mind == GetMind(pair));
Assert.That(mind.CurrentEntity == original);
Assert.That(!entMan.Deleted(original));
Assert.That(entMan.Deleted(ghost));
await pairTracker.CleanReturnAsync();
}
// This test will do the following:
// - visit a normal (non-ghost) entity,
// - disconnect
// - reconnect
// - assert that they return to the visited entity.
[Test]
public async Task TestVisitingReconnect()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{ ExtraPrototypes = Prototypes });
var pair = pairTracker.Pair;
var entMan = pair.Server.ResolveDependency<IEntityManager>();
var mindSys = entMan.System<MindSystem>();
await PoolManager.RunTicksSync(pair, 5);
var mind = GetMind(pair);
// Make player visit a new mob
var original = mind.CurrentEntity;
EntityUid visiting = default;
await pair.Server.WaitAssertion(() =>
{
visiting = entMan.SpawnEntity("MindTestEntity", MapCoordinates.Nullspace);
mindSys.Visit(mind, visiting);
});
await PoolManager.RunTicksSync(pair, 5);
await DisconnectReconnect(pair);
// Player is back in control of the visited mob, mind was preserved
Assert.That(mind == GetMind(pair));
Assert.That(!entMan.Deleted(original));
Assert.That(!entMan.Deleted(visiting));
Assert.That(mind.CurrentEntity == visiting);
Assert.That(mind.CurrentEntity == visiting);
await pairTracker.CleanReturnAsync();
}
}

View File

@@ -28,7 +28,7 @@ using IPlayerManager = Robust.Server.Player.IPlayerManager;
namespace Content.IntegrationTests.Tests.Minds;
[TestFixture]
public sealed class MindTests
public sealed partial class MindTests
{
private const string Prototypes = @"
- type: entity
@@ -125,7 +125,7 @@ public sealed class MindTests
var mind = mindSystem.CreateMind(null);
mindSystem.TransferTo(mind, entity);
Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mind));
var mind2 = mindSystem.CreateMind(null);
mindSystem.TransferTo(mind2, entity);
Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mind2));
@@ -220,32 +220,44 @@ public sealed class MindTests
[Test]
public async Task TestOwningPlayerCanBeChanged()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings{ NoClient = true });
await using var pairTracker = await PoolManager.GetServerClient();
var server = pairTracker.Pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>();
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
var mindSystem = entMan.EntitySysManager.GetEntitySystem<MindSystem>();
var originalMind = GetMind(pairTracker.Pair);
var userId = originalMind.UserId;
Mind mind = default!;
await server.WaitAssertion(() =>
{
var mindSystem = entMan.EntitySysManager.GetEntitySystem<MindSystem>();
var entity = entMan.SpawnEntity(null, new MapCoordinates());
var mindComp = entMan.EnsureComponent<MindContainerComponent>(entity);
entMan.DirtyEntity(entity);
var mind = mindSystem.CreateMind(null);
mind = mindSystem.CreateMind(null);
mindSystem.TransferTo(mind, entity);
Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mind));
var newUserId = new NetUserId(Guid.NewGuid());
Assert.That(mindComp.HasMind);
CatchPlayerDataException(() =>
mindSystem.ChangeOwningPlayer(mindComp.Mind!, newUserId));
Assert.That(mind.UserId, Is.EqualTo(newUserId));
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await server.WaitAssertion(() =>
{
mindSystem.SetUserId(mind, userId);
Assert.That(mind.UserId, Is.EqualTo(userId));
Assert.That(originalMind.UserId, Is.EqualTo(null));
mindSystem.SetUserId(originalMind, userId);
Assert.That(mind.UserId, Is.EqualTo(null));
Assert.That(originalMind.UserId, Is.EqualTo(userId));
});
await PoolManager.RunTicksSync(pairTracker.Pair, 5);
await pairTracker.CleanReturnAsync();
}
@@ -275,26 +287,26 @@ public sealed class MindTests
Assert.That(!mindSystem.HasRole<Job>(mind));
var traitorRole = new TraitorRole(mind, new AntagPrototype());
mindSystem.AddRole(mind, traitorRole);
Assert.That(mindSystem.HasRole<TraitorRole>(mind));
Assert.That(!mindSystem.HasRole<Job>(mind));
var jobRole = new Job(mind, new JobPrototype());
mindSystem.AddRole(mind, jobRole);
Assert.That(mindSystem.HasRole<TraitorRole>(mind));
Assert.That(mindSystem.HasRole<Job>(mind));
mindSystem.RemoveRole(mind, traitorRole);
Assert.That(!mindSystem.HasRole<TraitorRole>(mind));
Assert.That(mindSystem.HasRole<Job>(mind));
mindSystem.RemoveRole(mind, jobRole);
Assert.That(!mindSystem.HasRole<TraitorRole>(mind));
Assert.That(!mindSystem.HasRole<Job>(mind));
});
@@ -353,7 +365,7 @@ public sealed class MindTests
MakeSentientCommand.MakeSentient(mob, IoCManager.Resolve<IEntityManager>());
mobMind = mindSystem.CreateMind(player.UserId, "Mindy McThinker the Second");
mindSystem.ChangeOwningPlayer(mobMind, player.UserId);
mindSystem.SetUserId(mobMind, player.UserId);
mindSystem.TransferTo(mobMind, mob);
});