Refactor mind and ghost deletion code (#3680)

* Refactor mind and ghost deletion code

* Refactor to use EventBus and clean up deletes

* Fix mind eject when being deleted

* Refactor entity manager calls to use IEntity.EntityManager
This commit is contained in:
ShadowCommander
2021-03-31 14:17:22 -07:00
committed by GitHub
parent 4005fbe133
commit 951b0f425a
11 changed files with 86 additions and 31 deletions

View File

@@ -61,15 +61,8 @@ namespace Content.Server.Administration.Commands
DebugTools.AssertNotNull(mind); DebugTools.AssertNotNull(mind);
var oldEntity = mind!.CurrentEntity;
mindComponent.Mind?.TransferTo(null); mindComponent.Mind?.TransferTo(null);
mind.TransferTo(target); mind!.TransferTo(target);
DebugTools.AssertNotNull(oldEntity);
if (oldEntity!.HasComponent<GhostComponent>())
oldEntity.Delete();
} }
} }
} }

View File

@@ -1,4 +1,4 @@
#nullable enable #nullable enable
using System; using System;
using Content.Server.Eui; using Content.Server.Eui;
using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Mobs;
@@ -203,9 +203,6 @@ namespace Content.Server.GameObjects.Components.Medical
{ {
if (message.Sender == _capturedMind) if (message.Sender == _capturedMind)
{ {
//If the captured mind is in a ghost, we want to get rid of it.
_capturedMind.VisitingEntity?.Delete();
//Transfer the mind to the new mob //Transfer the mind to the new mob
_capturedMind.TransferTo(_bodyContainer.ContainedEntity); _capturedMind.TransferTo(_bodyContainer.ContainedEntity);

View File

@@ -1,4 +1,4 @@
#nullable enable #nullable enable
using Content.Server.GameObjects.Components.Observer; using Content.Server.GameObjects.Components.Observer;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Server.Interfaces.GameTicking; using Content.Server.Interfaces.GameTicking;
@@ -22,9 +22,6 @@ namespace Content.Server.GameObjects.Components.Mobs
[RegisterComponent] [RegisterComponent]
public class MindComponent : Component, IExamine public class MindComponent : Component, IExamine
{ {
[DataField("show_examine_info")]
private bool _showExamineInfo;
/// <inheritdoc /> /// <inheritdoc />
public override string Name => "Mind"; public override string Name => "Mind";
@@ -61,6 +58,8 @@ namespace Content.Server.GameObjects.Components.Mobs
/// </summary> /// </summary>
public void InternalEjectMind() public void InternalEjectMind()
{ {
if (!Deleted)
Owner.EntityManager.EventBus.RaiseLocalEvent(Owner.Uid, new MindRemovedMessage());
Mind = null; Mind = null;
} }
@@ -94,7 +93,7 @@ namespace Content.Server.GameObjects.Components.Mobs
Mind!.TransferTo(visiting); Mind!.TransferTo(visiting);
} }
else if(GhostOnShutdown) else if (GhostOnShutdown)
{ {
var spawnPosition = Owner.Transform.Coordinates; var spawnPosition = Owner.Transform.Coordinates;
// Use a regular timer here because the entity has probably been deleted. // Use a regular timer here because the entity has probably been deleted.
@@ -153,4 +152,8 @@ namespace Content.Server.GameObjects.Components.Mobs
} }
} }
} }
public class MindRemovedMessage : EntityEventArgs
{
}
} }

View File

@@ -1,4 +1,5 @@
using Content.Server.Mobs; #nullable enable
using Content.Server.Mobs;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.ViewVariables; using Robust.Shared.ViewVariables;
@@ -18,4 +19,8 @@ namespace Content.Server.GameObjects.Components.Mobs
Mind?.UnVisit(); Mind?.UnVisit();
} }
} }
public class MindUnvisitedMessage : EntityEventArgs
{
}
} }

View File

@@ -28,7 +28,9 @@ namespace Content.Server.GameObjects.Components.Observer
return; return;
} }
Player.ContentData()?.Mind?.TransferTo(_newMob); var mind = Player.ContentData()?.Mind;
mind?.TransferTo(_newMob);
mind?.UnVisit();
Close(); Close();
} }
} }

View File

@@ -72,6 +72,26 @@ namespace Content.Server.GameObjects.Components.Observer
base.Shutdown(); base.Shutdown();
} }
public override void OnAdd()
{
base.OnAdd();
if (Owner.TryGetComponent<MindComponent>(out var mind))
{
mind.GhostOnShutdown = false;
}
}
public override void OnRemove()
{
base.OnRemove();
if (Owner.TryGetComponent<MindComponent>(out var mind))
{
mind.GhostOnShutdown = true;
}
}
public override ComponentState GetComponentState(ICommonSession player) => new GhostComponentState(CanReturnToBody); public override ComponentState GetComponentState(ICommonSession player) => new GhostComponentState(CanReturnToBody);
public override void HandleNetworkMessage(ComponentMessage message, INetChannel netChannel, ICommonSession? session = null!) public override void HandleNetworkMessage(ComponentMessage message, INetChannel netChannel, ICommonSession? session = null!)
@@ -92,13 +112,12 @@ namespace Content.Server.GameObjects.Components.Observer
{ {
var o = actor.playerSession.ContentData()!.Mind; var o = actor.playerSession.ContentData()!.Mind;
o?.UnVisit(); o?.UnVisit();
Owner.Delete();
} }
break; break;
} }
case ReturnToCloneComponentMessage _: case ReturnToCloneComponentMessage _:
if (Owner.TryGetComponent(out VisitingMindComponent? mind)) if (Owner.TryGetComponent(out VisitingMindComponent? mind) && mind.Mind != null)
{ {
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new GhostReturnMessage(mind.Mind)); Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new GhostReturnMessage(mind.Mind));
} }

View File

@@ -0,0 +1,44 @@
#nullable enable
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Observer;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using System;
namespace Content.Server.GameObjects.EntitySystems
{
[UsedImplicitly]
public class GhostSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<GhostComponent, MindRemovedMessage>(OnMindRemovedMessage);
SubscribeLocalEvent<GhostComponent, MindUnvisitedMessage>(OnMindUnvisitedMessage);
}
private void OnMindRemovedMessage(EntityUid uid, GhostComponent component, MindRemovedMessage args)
{
if (!EntityManager.TryGetEntity(uid, out var entity))
return;
DeleteEntity(entity);
}
private void OnMindUnvisitedMessage(EntityUid uid, GhostComponent component, MindUnvisitedMessage args)
{
if (!EntityManager.TryGetEntity(uid, out var entity))
return;
DeleteEntity(entity);
}
private void DeleteEntity(IEntity? entity)
{
if (entity?.Deleted == true)
return;
entity?.Delete();
}
}
}

View File

@@ -45,7 +45,6 @@ namespace Content.Server.GameTicking
if (mind.VisitingEntity != null) if (mind.VisitingEntity != null)
{ {
mind.UnVisit(); mind.UnVisit();
mind.VisitingEntity.Delete();
} }
var position = playerEntity?.Transform.Coordinates ?? IoCManager.Resolve<IGameTicker>().GetObserverSpawnPoint(); var position = playerEntity?.Transform.Coordinates ?? IoCManager.Resolve<IGameTicker>().GetObserverSpawnPoint();

View File

@@ -416,13 +416,8 @@ namespace Content.Server.GameTicking
public void Respawn(IPlayerSession targetPlayer) public void Respawn(IPlayerSession targetPlayer)
{ {
var ghost = targetPlayer.AttachedEntity?.GetComponentOrNull<GhostComponent>();
targetPlayer.ContentData()?.WipeMind(); targetPlayer.ContentData()?.WipeMind();
if (ghost?.Deleted == false)
ghost.Owner.Delete();
if (LobbyEnabled) if (LobbyEnabled)
_playerJoinLobby(targetPlayer); _playerJoinLobby(targetPlayer);
else else

View File

@@ -55,13 +55,9 @@ namespace Content.Server.GlobalVerbs
var userMind = player.ContentData()?.Mind; var userMind = player.ContentData()?.Mind;
var targetMind = target.GetComponent<MindComponent>(); var targetMind = target.GetComponent<MindComponent>();
var oldEntity = userMind?.CurrentEntity;
targetMind.Mind?.TransferTo(null); targetMind.Mind?.TransferTo(null);
userMind?.TransferTo(target); userMind?.TransferTo(target);
if (oldEntity != null && oldEntity.HasComponent<GhostComponent>())
oldEntity.Delete();
} }
} }
} }

View File

@@ -313,6 +313,8 @@ namespace Content.Server.Mobs
{ {
oldVisitingEnt.RemoveComponent<VisitingMindComponent>(); oldVisitingEnt.RemoveComponent<VisitingMindComponent>();
} }
oldVisitingEnt.EntityManager.EventBus.RaiseLocalEvent(oldVisitingEnt.Uid, new MindUnvisitedMessage());
} }
public bool TryGetSession([NotNullWhen(true)] out IPlayerSession? session) public bool TryGetSession([NotNullWhen(true)] out IPlayerSession? session)