diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs index d61ba1b7eb..74a202386e 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs @@ -25,11 +25,63 @@ public partial class SharedBodySystem private void InitializeBody() { + // Body here to handle root body parts. + SubscribeLocalEvent(OnBodyInserted); + SubscribeLocalEvent(OnBodyRemoved); + SubscribeLocalEvent(OnBodyInit); SubscribeLocalEvent(OnBodyMapInit); SubscribeLocalEvent(OnBodyCanDrag); } + private void OnBodyInserted(EntityUid uid, BodyComponent component, EntInsertedIntoContainerMessage args) + { + // Root body part? + var slotId = args.Container.ID; + + if (slotId != BodyRootContainerId) + return; + + var entity = args.Entity; + + if (TryComp(entity, out BodyPartComponent? childPart)) + { + AddPart(uid, entity, slotId, childPart); + RecursiveBodyUpdate(entity, uid, childPart); + } + + if (TryComp(entity, out OrganComponent? organ)) + { + AddOrgan(entity, uid, uid, organ); + } + } + + private void OnBodyRemoved(EntityUid uid, BodyComponent component, EntRemovedFromContainerMessage args) + { + // TODO: lifestage shenanigans + if (TerminatingOrDeleted(uid)) + return; + + // Root body part? + var slotId = args.Container.ID; + + if (slotId != BodyRootContainerId) + return; + + var entity = args.Entity; + + if (TryComp(entity, out BodyPartComponent? childPart)) + { + RemovePart(uid, entity, slotId, childPart); + RecursiveBodyUpdate(entity, null, childPart); + } + + if (TryComp(entity, out OrganComponent? organ)) + { + RemoveOrgan(entity, uid, organ); + } + } + private void OnBodyInit(EntityUid bodyId, BodyComponent body, ComponentInit args) { // Setup the initial container. @@ -177,8 +229,6 @@ public partial class SharedBodySystem yield break; } - yield return (body.RootContainer.ContainedEntity.Value, rootPart); - foreach (var child in GetBodyPartChildren(body.RootContainer.ContainedEntity.Value, rootPart)) { yield return child; diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Organs.cs b/Content.Shared/Body/Systems/SharedBodySystem.Organs.cs index ee4485f32a..6e392b9892 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Organs.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Organs.cs @@ -9,50 +9,26 @@ namespace Content.Shared.Body.Systems; public partial class SharedBodySystem { - private void InitializeOrgans() + private void AddOrgan(EntityUid uid, EntityUid bodyUid, EntityUid parentPartUid, OrganComponent component) { - SubscribeLocalEvent(OnOrganInserted); - SubscribeLocalEvent(OnOrganRemoved); + component.Body = bodyUid; + RaiseLocalEvent(uid, new AddedToPartEvent(parentPartUid)); + + if (component.Body != null) + RaiseLocalEvent(uid, new AddedToPartInBodyEvent(component.Body.Value, parentPartUid)); + + Dirty(uid, component); } - private void OnOrganInserted(EntityUid uid, OrganComponent component, EntGotInsertedIntoContainerMessage args) + private void RemoveOrgan(EntityUid uid, EntityUid parentPartUid, OrganComponent component) { - // No recursive updates for these as you can't insert organs into organsTM. - var parentUid = args.Container.Owner; + RaiseLocalEvent(uid, new RemovedFromPartEvent(parentPartUid)); - if (HasComp(parentUid)) + if (component.Body != null) { - component.Body = parentUid; - Dirty(uid, component); + RaiseLocalEvent(uid, new RemovedFromPartInBodyEvent(component.Body.Value, parentPartUid)); } - // Organ inserted into body part. - if (TryComp(parentUid, out BodyPartComponent? partComp)) - { - RaiseLocalEvent(uid, new AddedToPartEvent(parentUid)); - - if (partComp.Body != null) - { - component.Body = partComp.Body; - RaiseLocalEvent(uid, new AddedToPartInBodyEvent(partComp.Body.Value, parentUid)); - Dirty(uid, component); - } - } - } - - private void OnOrganRemoved(EntityUid uid, OrganComponent component, EntGotRemovedFromContainerMessage args) - { - // Lifestage shenanigans. - if (component.Body != null && TerminatingOrDeleted(component.Body.Value)) - return; - - if (HasComp(args.Container.Owner)) - RaiseLocalEvent(uid, new RemovedFromPartEvent(args.Container.Owner)); - - if (component.Body == null) - return; - - RaiseLocalEvent(uid, new RemovedFromPartInBodyEvent(component.Body.Value, args.Container.Owner)); component.Body = null; Dirty(uid, component); } diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs index 75a52ddbc5..463a4b7661 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Parts.cs @@ -19,99 +19,89 @@ public partial class SharedBodySystem // TODO: This doesn't handle comp removal on child ents. // If you modify this also see the Body partial for root parts. - SubscribeLocalEvent(OnBodyPartInserted); - SubscribeLocalEvent(OnBodyPartRemoved); + SubscribeLocalEvent(OnBodyPartInserted); + SubscribeLocalEvent(OnBodyPartRemoved); } - private void OnBodyPartInserted(EntityUid uid, BodyPartComponent component, EntGotInsertedIntoContainerMessage args) + private void OnBodyPartInserted(EntityUid uid, BodyPartComponent component, EntInsertedIntoContainerMessage args) { - var parentUid = args.Container.Owner; - - if (HasComp(parentUid)) - { - AddPart(parentUid, uid, GetPartSlotContainerId(args.Container.ID), component); - RecursiveBodyUpdate(uid, parentUid, component); - } - // Body part inserted into another body part. - if (TryComp(parentUid, out BodyPartComponent? partComp)) - { - if (partComp.Body == null) - return; + var entity = args.Entity; + var slotId = args.Container.ID; - AddPart(partComp.Body.Value, uid, GetPartSlotContainerId(args.Container.ID), component); - RecursiveBodyUpdate(uid, partComp.Body, component); - } - } - - private void OnBodyPartRemoved(EntityUid uid, BodyPartComponent component, EntGotRemovedFromContainerMessage args) - { if (component.Body != null) { - // Lifestage shenanigans. - if (TerminatingOrDeleted(component.Body.Value)) - return; + if (TryComp(entity, out BodyPartComponent? childPart)) + { + AddPart(component.Body.Value, entity, slotId, childPart); + RecursiveBodyUpdate(entity, component.Body.Value, childPart); + } - RemovePart(component.Body.Value, uid, GetPartSlotContainerId(args.Container.ID), component); - RecursiveBodyUpdate(uid, null, component); + if (TryComp(entity, out OrganComponent? organ)) + { + AddOrgan(entity, component.Body.Value, uid, organ); + } + } + } + + private void OnBodyPartRemoved(EntityUid uid, BodyPartComponent component, EntRemovedFromContainerMessage args) + { + // TODO: lifestage shenanigans + if (TerminatingOrDeleted(uid)) + return; + + // Body part removed from another body part. + var entity = args.Entity; + var slotId = args.Container.ID; + + if (TryComp(entity, out BodyPartComponent? childPart) && childPart.Body != null) + { + RemovePart(childPart.Body.Value, entity, slotId, childPart); + RecursiveBodyUpdate(entity, null, childPart); + } + + if (TryComp(entity, out OrganComponent? organ)) + { + RemoveOrgan(entity, uid, organ); } } - /// - /// Updates body parts recursively for a particular entity, including itself. - /// private void RecursiveBodyUpdate(EntityUid uid, EntityUid? bodyUid, BodyPartComponent component) { - // Recursively iterate all child parts and organs and ensure their body refs are updated. foreach (var children in GetBodyPartChildren(uid, component)) { - if (children.Component.Body == bodyUid) - continue; - - // Raise the body part change event if relevant. - if (Containers.TryGetContainingContainer(children.Id, out var childContainer)) + if (children.Component.Body != bodyUid) { - var slotId = GetPartSlotContainerId(childContainer.ID); + children.Component.Body = bodyUid; + Dirty(children.Id, children.Component); - if (bodyUid != null) + foreach (var slotId in children.Component.Organs.Keys) { - AddPart(bodyUid.Value, children.Id, slotId, children.Component); - } - else if (component.Body != null) - { - RemovePart(component.Body.Value, children.Id, slotId, children.Component); - } - } + var organContainerId = GetOrganContainerId(slotId); - children.Component.Body = bodyUid; - Dirty(children.Id, children.Component); + if (!Containers.TryGetContainer(children.Id, organContainerId, out var container)) + continue; - foreach (var slotId in children.Component.Organs.Keys) - { - var organContainerId = GetOrganContainerId(slotId); - - if (!Containers.TryGetContainer(children.Id, organContainerId, out var container)) - continue; - - foreach (var organ in container.ContainedEntities) - { - if (TryComp(organ, out OrganComponent? organComp)) + foreach (var organ in container.ContainedEntities) { - var oldBody = organComp.Body; - organComp.Body = bodyUid; - - if (bodyUid != null) + if (TryComp(organ, out OrganComponent? organComp)) { - var ev = new AddedToPartInBodyEvent(bodyUid.Value, children.Id); - RaiseLocalEvent(organ, ev); - } - else if (oldBody != null) - { - var ev = new RemovedFromPartInBodyEvent(oldBody.Value, children.Id); - RaiseLocalEvent(organ, ev); - } + var oldBody = organComp.Body; + organComp.Body = bodyUid; - Dirty(organ, organComp); + if (bodyUid != null) + { + var ev = new AddedToPartInBodyEvent(bodyUid.Value, children.Id); + RaiseLocalEvent(organ, ev); + } + else if (oldBody != null) + { + var ev = new RemovedFromPartInBodyEvent(oldBody.Value, children.Id); + RaiseLocalEvent(organ, ev); + } + + Dirty(organ, organComp); + } } } } @@ -126,8 +116,9 @@ public partial class SharedBodySystem BodyComponent? bodyComp = null) { DebugTools.AssertOwner(partUid, component); - component.Body = bodyUid; Dirty(partUid, component); + component.Body = bodyUid; + var ev = new BodyPartAddedEvent(slotId, component); RaiseLocalEvent(bodyUid, ref ev); @@ -143,8 +134,8 @@ public partial class SharedBodySystem { DebugTools.AssertOwner(partUid, component); Resolve(bodyUid, ref bodyComp, false); - component.Body = null; Dirty(partUid, component); + component.Body = null; var ev = new BodyPartRemovedEvent(slotId, component); RaiseLocalEvent(bodyUid, ref ev); @@ -556,13 +547,15 @@ public partial class SharedBodySystem } /// - /// Returns all body part components for this entity not including itself. + /// Returns all body part components for this entity including itself. /// public IEnumerable<(EntityUid Id, BodyPartComponent Component)> GetBodyPartChildren(EntityUid partId, BodyPartComponent? part = null) { if (!Resolve(partId, ref part, false)) yield break; + yield return (partId, part); + foreach (var slotId in part.Children.Keys) { var containerSlotId = GetPartSlotContainerId(slotId); @@ -574,8 +567,6 @@ public partial class SharedBodySystem if (!TryComp(containedEnt, out BodyPartComponent? childPart)) continue; - yield return (containedEnt, childPart); - foreach (var value in GetBodyPartChildren(containedEnt, childPart)) { yield return value; @@ -638,9 +629,6 @@ public partial class SharedBodySystem return false; } - if (childId == parentId) - return true; - foreach (var (foundId, _) in GetBodyPartChildren(parentId, parent)) { if (foundId == childId) diff --git a/Content.Shared/Body/Systems/SharedBodySystem.cs b/Content.Shared/Body/Systems/SharedBodySystem.cs index c10b3e9fca..431503c96e 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.cs @@ -39,7 +39,6 @@ public abstract partial class SharedBodySystem : EntitySystem base.Initialize(); InitializeBody(); - InitializeOrgans(); InitializeParts(); }