diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index 2ec4c14932..6e90b7cf3c 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -79,6 +79,7 @@ namespace Content.Client.Entry "Hitscan", "StunOnCollide", "RandomPottedPlant", + "Brain", "CommunicationsConsole", "BarSign", "DroppedBodyPart", diff --git a/Content.Server/Body/Behavior/BrainBehavior.cs b/Content.Server/Body/Behavior/BrainBehavior.cs deleted file mode 100644 index e7f869bf03..0000000000 --- a/Content.Server/Body/Behavior/BrainBehavior.cs +++ /dev/null @@ -1,70 +0,0 @@ -using Content.Server.Ghost; -using Content.Server.Ghost.Components; -using Content.Server.Mind.Components; -using Content.Shared.Body.Components; -using Content.Shared.Body.Part; -using Content.Shared.Movement.Components; -using Robust.Shared.GameObjects; - -namespace Content.Server.Body.Behavior -{ - public class BrainBehavior : MechanismBehavior - { - protected override void OnAddedToBody(SharedBodyComponent body) - { - base.OnAddedToBody(body); - - HandleMind(body.Owner, Owner); - } - - protected override void OnAddedToPart(SharedBodyPartComponent part) - { - base.OnAddedToPart(part); - - HandleMind(part.Owner, Owner); - } - - protected override void OnAddedToPartInBody(SharedBodyComponent body, SharedBodyPartComponent part) - { - base.OnAddedToPartInBody(body, part); - - HandleMind(body.Owner, Owner); - } - - protected override void OnRemovedFromBody(SharedBodyComponent old) - { - base.OnRemovedFromBody(old); - - HandleMind(Part!.Owner, old.Owner); - } - - protected override void OnRemovedFromPart(SharedBodyPartComponent old) - { - base.OnRemovedFromPart(old); - - HandleMind(Owner, old.Owner); - } - - protected override void OnRemovedFromPartInBody(SharedBodyComponent oldBody, SharedBodyPartComponent oldPart) - { - base.OnRemovedFromPartInBody(oldBody, oldPart); - - HandleMind(oldBody.Owner, Owner); - } - - private void HandleMind(IEntity newEntity, IEntity oldEntity) - { - newEntity.EnsureComponent(); - var oldMind = oldEntity.EnsureComponent(); - - if (!newEntity.HasComponent()) - newEntity.AddComponent(); - - // TODO: This is an awful solution. - if (!newEntity.HasComponent()) - newEntity.AddComponent(); - - oldMind.Mind?.TransferTo(newEntity); - } - } -} diff --git a/Content.Server/Body/Components/BrainComponent.cs b/Content.Server/Body/Components/BrainComponent.cs new file mode 100644 index 0000000000..51865cbab7 --- /dev/null +++ b/Content.Server/Body/Components/BrainComponent.cs @@ -0,0 +1,12 @@ +using Content.Server.Body.Systems; +using Robust.Shared.Analyzers; +using Robust.Shared.GameObjects; + +namespace Content.Server.Body.Components +{ + [RegisterComponent, Friend(typeof(BrainSystem))] + public class BrainComponent : Component + { + public override string Name => "Brain"; + } +} diff --git a/Content.Server/Body/Systems/BrainSystem.cs b/Content.Server/Body/Systems/BrainSystem.cs new file mode 100644 index 0000000000..1a38721eed --- /dev/null +++ b/Content.Server/Body/Systems/BrainSystem.cs @@ -0,0 +1,49 @@ +using Content.Server.Body.Components; +using Content.Server.Ghost; +using Content.Server.Ghost.Components; +using Content.Server.Mind.Components; +using Content.Shared.Body.Events; +using Content.Shared.Movement.Components; +using Robust.Shared.GameObjects; + +namespace Content.Server.Body.Systems +{ + public class BrainSystem : EntitySystem + { + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent((uid, component, args) => HandleMind(args.Body.OwnerUid, uid)); + SubscribeLocalEvent((uid, component, args) => HandleMind(args.Part.OwnerUid, uid)); + SubscribeLocalEvent((uid, component, args) => HandleMind(args.Body.OwnerUid, uid)); + SubscribeLocalEvent(OnRemovedFromBody); + SubscribeLocalEvent((uid, component, args) => HandleMind(uid, args.Old.OwnerUid)); + SubscribeLocalEvent((uid, component, args) => HandleMind(args.OldBody.OwnerUid, uid)); + } + + private void OnRemovedFromBody(EntityUid uid, BrainComponent component, RemovedFromBodyEvent args) + { + // This one needs to be special, okay? + if (!EntityManager.TryGetComponent(uid, out MechanismComponent mech)) + return; + + HandleMind(mech.Part!.OwnerUid, args.Old.OwnerUid); + } + + private void HandleMind(EntityUid newEntity, EntityUid oldEntity) + { + EntityManager.EnsureComponent(newEntity); + var oldMind = EntityManager.EnsureComponent(oldEntity); + + if (!EntityManager.HasComponent(newEntity)) + EntityManager.AddComponent(newEntity); + + // TODO: This is an awful solution. + if (!EntityManager.HasComponent(newEntity)) + EntityManager.AddComponent(newEntity); + + oldMind.Mind?.TransferTo(EntityManager.GetEntity(newEntity)); + } + } +} diff --git a/Content.Shared/Body/Components/SharedMechanismComponent.cs b/Content.Shared/Body/Components/SharedMechanismComponent.cs index a66a2dec91..515b233fba 100644 --- a/Content.Shared/Body/Components/SharedMechanismComponent.cs +++ b/Content.Shared/Body/Components/SharedMechanismComponent.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Content.Shared.Body.Behavior; +using Content.Shared.Body.Events; using Content.Shared.Body.Part; using Robust.Shared.GameObjects; using Robust.Shared.IoC; @@ -168,12 +169,14 @@ namespace Content.Shared.Body.Components } } - // TODO BODY Turn these into event listeners so they dont need to be exposed public void AddedToBody(SharedBodyComponent body) { DebugTools.AssertNotNull(Body); DebugTools.AssertNotNull(body); + var ev = new AddedToBodyEvent(body); + Owner.EntityManager.EventBus.RaiseLocalEvent(OwnerUid, ev, false); + foreach (var behavior in _behaviors.Values) { behavior.AddedToBody(body); @@ -187,6 +190,9 @@ namespace Content.Shared.Body.Components Owner.Transform.AttachParent(part.Owner); + var ev = new AddedToPartEvent(part); + Owner.EntityManager.EventBus.RaiseLocalEvent(OwnerUid, ev, false); + foreach (var behavior in _behaviors.Values) { behavior.AddedToPart(part); @@ -202,6 +208,9 @@ namespace Content.Shared.Body.Components Owner.Transform.AttachParent(part.Owner); + var ev = new AddedToPartInBodyEvent(body, part); + Owner.EntityManager.EventBus.RaiseLocalEvent(OwnerUid, ev, false); + foreach (var behavior in _behaviors.Values) { behavior.AddedToPartInBody(body, part); @@ -213,6 +222,9 @@ namespace Content.Shared.Body.Components DebugTools.AssertNull(Body); DebugTools.AssertNotNull(old); + var ev = new RemovedFromBodyEvent(old); + Owner.EntityManager.EventBus.RaiseLocalEvent(OwnerUid, ev, false); + foreach (var behavior in _behaviors.Values) { behavior.RemovedFromBody(old); @@ -226,6 +238,9 @@ namespace Content.Shared.Body.Components Owner.Transform.AttachToGridOrMap(); + var ev = new RemovedFromPartEvent(old); + Owner.EntityManager.EventBus.RaiseLocalEvent(OwnerUid, ev, false); + foreach (var behavior in _behaviors.Values) { behavior.RemovedFromPart(old); @@ -241,6 +256,9 @@ namespace Content.Shared.Body.Components Owner.Transform.AttachToGridOrMap(); + var ev = new RemovedFromPartInBodyEvent(oldBody, oldPart); + Owner.EntityManager.EventBus.RaiseLocalEvent(OwnerUid, ev, false); + foreach (var behavior in _behaviors.Values) { behavior.RemovedFromPartInBody(oldBody, oldPart); diff --git a/Content.Shared/Body/Events/MechanismBodyEvents.cs b/Content.Shared/Body/Events/MechanismBodyEvents.cs new file mode 100644 index 0000000000..2b5a71ea6f --- /dev/null +++ b/Content.Shared/Body/Events/MechanismBodyEvents.cs @@ -0,0 +1,90 @@ +using Content.Shared.Body.Components; +using Robust.Shared.GameObjects; + +namespace Content.Shared.Body.Events +{ + // All of these events are raised on a mechanism entity when added/removed to a body in different + // ways. + + /// + /// Raised on a mechanism when it is added to a body. + /// + public class AddedToBodyEvent : EntityEventArgs + { + public SharedBodyComponent Body; + + public AddedToBodyEvent(SharedBodyComponent body) + { + Body = body; + } + } + + /// + /// Raised on a mechanism when it is added to a body part. + /// + public class AddedToPartEvent : EntityEventArgs + { + public SharedBodyPartComponent Part; + + public AddedToPartEvent(SharedBodyPartComponent part) + { + Part = part; + } + } + + /// + /// Raised on a mechanism when it is added to a body part within a body. + /// + public class AddedToPartInBodyEvent : EntityEventArgs + { + public SharedBodyComponent Body; + public SharedBodyPartComponent Part; + + public AddedToPartInBodyEvent(SharedBodyComponent body, SharedBodyPartComponent part) + { + Body = body; + Part = part; + } + } + + /// + /// Raised on a mechanism when it is removed from a body. + /// + public class RemovedFromBodyEvent : EntityEventArgs + { + public SharedBodyComponent Old; + + public RemovedFromBodyEvent(SharedBodyComponent old) + { + Old = old; + } + } + + /// + /// Raised on a mechanism when it is removed from a body part. + /// + public class RemovedFromPartEvent : EntityEventArgs + { + public SharedBodyPartComponent Old; + + public RemovedFromPartEvent(SharedBodyPartComponent old) + { + Old = old; + } + } + + /// + /// Raised on a mechanism when it is removed from a body part within a body. + /// + public class RemovedFromPartInBodyEvent : EntityEventArgs + { + public SharedBodyComponent OldBody; + public SharedBodyPartComponent OldPart; + + public RemovedFromPartInBodyEvent(SharedBodyComponent oldBody, SharedBodyPartComponent oldPart) + { + OldBody = oldBody; + OldPart = oldPart; + } + } +} diff --git a/Resources/Prototypes/Body/Mechanisms/human.yml b/Resources/Prototypes/Body/Mechanisms/human.yml index ea74357b88..15df4aa3e6 100644 --- a/Resources/Prototypes/Body/Mechanisms/human.yml +++ b/Resources/Prototypes/Body/Mechanisms/human.yml @@ -28,12 +28,11 @@ - type: Mechanism size: 1 compatibility: Biological - behaviors: - - !type:BrainBehavior {} - type: Input context: "ghost" - type: DummyInputMover - type: GhostOnMove + - type: Brain - type: entity id: OrganHumanEyes