Fix some Mind ECS bugs (#17480)
This commit is contained in:
234
Content.IntegrationTests/Tests/Minds/GhostTests.cs
Normal file
234
Content.IntegrationTests/Tests/Minds/GhostTests.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user