using Content.Shared.DragDrop; using Robust.Shared.Containers; namespace Content.Shared.Body; /// /// System responsible for coordinating entities with and their entities with . /// This system is primarily responsible for event relaying and the relationships between a body and its organs. /// It is not responsible for player-facing body features, e.g. "blood" or "breathing." /// Such features should be implemented in systems relying on the various events raised by this class. /// /// /// /// /// /// public sealed partial class BodySystem : EntitySystem { [Dependency] private readonly SharedContainerSystem _container = default!; private EntityQuery _bodyQuery; private EntityQuery _organQuery; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnBodyInit); SubscribeLocalEvent(OnBodyShutdown); SubscribeLocalEvent(OnCanDrag); SubscribeLocalEvent(OnBodyEntInserted); SubscribeLocalEvent(OnBodyEntRemoved); _bodyQuery = GetEntityQuery(); _organQuery = GetEntityQuery(); InitializeRelay(); } private void OnBodyInit(Entity ent, ref ComponentInit args) { ent.Comp.Organs = _container.EnsureContainer(ent, BodyComponent.ContainerID); } private void OnBodyShutdown(Entity ent, ref ComponentShutdown args) { if (ent.Comp.Organs is { } organs) _container.ShutdownContainer(organs); } private void OnBodyEntInserted(Entity ent, ref EntInsertedIntoContainerMessage args) { if (args.Container.ID != BodyComponent.ContainerID) return; if (!_organQuery.TryComp(args.Entity, out var organ)) return; var body = new OrganInsertedIntoEvent(args.Entity); RaiseLocalEvent(ent, ref body); var ev = new OrganGotInsertedEvent(ent); RaiseLocalEvent(args.Entity, ref ev); if (organ.Body != ent) { organ.Body = ent; Dirty(args.Entity, organ); } } private void OnBodyEntRemoved(Entity ent, ref EntRemovedFromContainerMessage args) { if (args.Container.ID != BodyComponent.ContainerID) return; if (!_organQuery.TryComp(args.Entity, out var organ)) return; var body = new OrganRemovedFromEvent(args.Entity); RaiseLocalEvent(ent, ref body); var ev = new OrganGotRemovedEvent(ent); RaiseLocalEvent(args.Entity, ref ev); if (organ.Body == null) return; organ.Body = null; Dirty(args.Entity, organ); } private void OnCanDrag(Entity ent, ref CanDragEvent args) { args.Handled = true; } }