using System.Diagnostics.CodeAnalysis; using Content.Shared.Body.Components; using Content.Shared.Body.Events; using Content.Shared.Body.Organ; using Content.Shared.Body.Part; using Robust.Shared.Containers; // Shitmed Change using Content.Shared.Damage; using Content.Shared._Shitmed.BodyEffects; using Content.Shared._Shitmed.Body.Organ; namespace Content.Shared.Body.Systems; public partial class SharedBodySystem { // Shitmed Change Start private void InitializeOrgans() { SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnOrganEnableChanged); } private void OnMapInit(Entity ent, ref MapInitEvent args) { if (ent.Comp.OnAdd is not null || ent.Comp.OnRemove is not null) EnsureComp(ent); } // Shitmed Change End private void AddOrgan( Entity organEnt, EntityUid bodyUid, EntityUid parentPartUid) { organEnt.Comp.Body = bodyUid; var addedEv = new OrganAddedEvent(parentPartUid); RaiseLocalEvent(organEnt, ref addedEv); if (organEnt.Comp.Body is not null) { // Shitmed Change Start var addedInBodyEv = new OrganAddedToBodyEvent(bodyUid, parentPartUid); RaiseLocalEvent(organEnt, ref addedInBodyEv); var organEnabledEv = new OrganEnableChangedEvent(true); RaiseLocalEvent(organEnt, ref organEnabledEv); } // Shitmed Change End Dirty(organEnt, organEnt.Comp); } private void RemoveOrgan(Entity organEnt, EntityUid parentPartUid) { var removedEv = new OrganRemovedEvent(parentPartUid); RaiseLocalEvent(organEnt, ref removedEv); if (organEnt.Comp.Body is { Valid: true } bodyUid) { // Shitmed Change Start organEnt.Comp.OriginalBody = organEnt.Comp.Body; var organDisabledEv = new OrganEnableChangedEvent(false); RaiseLocalEvent(organEnt, ref organDisabledEv); // Shitmed Change End var removedInBodyEv = new OrganRemovedFromBodyEvent(bodyUid, parentPartUid); RaiseLocalEvent(organEnt, ref removedInBodyEv); } if (parentPartUid is { Valid: true } && TryComp(parentPartUid, out DamageableComponent? damageable) && damageable.TotalDamage > 200) TrySetOrganUsed(organEnt, true, organEnt.Comp); organEnt.Comp.Body = null; Dirty(organEnt, organEnt.Comp); } /// /// Creates the specified organ slot on the parent entity. /// private OrganSlot? CreateOrganSlot(Entity parentEnt, string slotId) { if (!Resolve(parentEnt, ref parentEnt.Comp, logMissing: false)) return null; Containers.EnsureContainer(parentEnt, GetOrganContainerId(slotId)); var slot = new OrganSlot(slotId); parentEnt.Comp.Organs.Add(slotId, slot); return slot; } /// /// Attempts to create the specified organ slot on the specified parent if it exists. /// public bool TryCreateOrganSlot( EntityUid? parent, string slotId, [NotNullWhen(true)] out OrganSlot? slot, BodyPartComponent? part = null) { slot = null; if (parent is null || !Resolve(parent.Value, ref part, logMissing: false)) { return false; } Containers.EnsureContainer(parent.Value, GetOrganContainerId(slotId)); slot = new OrganSlot(slotId); // Shitmed Change Start if (!part.Organs.ContainsKey(slotId) && !part.Organs.TryAdd(slotId, slot.Value)) return false; return true; // Shitmed Change End } /// /// Returns whether the slotId exists on the partId. /// public bool CanInsertOrgan( EntityUid partId, string slotId, BodyPartComponent? part = null) { return Resolve(partId, ref part) && part.Organs.ContainsKey(slotId); } /// /// Returns whether the specified organ slot exists on the partId. /// public bool CanInsertOrgan( EntityUid partId, OrganSlot slot, BodyPartComponent? part = null) { return CanInsertOrgan(partId, slot.Id, part); } public bool InsertOrgan( EntityUid partId, EntityUid organId, string slotId, BodyPartComponent? part = null, OrganComponent? organ = null) { if (!Resolve(organId, ref organ, logMissing: false) || !Resolve(partId, ref part, logMissing: false) || !CanInsertOrgan(partId, slotId, part)) { return false; } var containerId = GetOrganContainerId(slotId); return Containers.TryGetContainer(partId, containerId, out var container) && Containers.Insert(organId, container); } /// /// Removes the organ if it is inside of a body part. /// public bool RemoveOrgan(EntityUid organId, OrganComponent? organ = null) { if (!Containers.TryGetContainingContainer((organId, null, null), out var container)) return false; var parent = container.Owner; return HasComp(parent) && Containers.Remove(organId, container); } /// /// Tries to add this organ to any matching slot on this body part. /// public bool AddOrganToFirstValidSlot( EntityUid partId, EntityUid organId, BodyPartComponent? part = null, OrganComponent? organ = null) { if (!Resolve(partId, ref part, logMissing: false) || !Resolve(organId, ref organ, logMissing: false)) { return false; } foreach (var slotId in part.Organs.Keys) { InsertOrgan(partId, organId, slotId, part, organ); return true; } return false; } /// /// Returns a list of ValueTuples of and OrganComponent on each organ /// in the given body. /// /// The body entity id to check on. /// The body to check for organs on. /// The component to check for. public List<(T Comp, OrganComponent Organ)> GetBodyOrganComponents( EntityUid uid, BodyComponent? body = null) where T : IComponent { if (!Resolve(uid, ref body)) return new List<(T Comp, OrganComponent Organ)>(); var query = GetEntityQuery(); var list = new List<(T Comp, OrganComponent Organ)>(3); foreach (var organ in GetBodyOrgans(uid, body)) { if (query.TryGetComponent(organ.Id, out var comp)) list.Add((comp, organ.Component)); } return list; } /// /// Tries to get a list of ValueTuples of and OrganComponent on each organs /// in the given body. /// /// The body entity id to check on. /// The list of components. /// The body to check for organs on. /// The component to check for. /// Whether any were found. public bool TryGetBodyOrganComponents( EntityUid uid, [NotNullWhen(true)] out List<(T Comp, OrganComponent Organ)>? comps, BodyComponent? body = null) where T : IComponent { if (!Resolve(uid, ref body)) { comps = null; return false; } comps = GetBodyOrganComponents(uid, body); if (comps.Count != 0) return true; comps = null; return false; } // Shitmed Change Start public bool TrySetOrganUsed(EntityUid organId, bool used, OrganComponent? organ = null) { if (!Resolve(organId, ref organ) || organ.Used == used) return false; organ.Used = used; Dirty(organId, organ); return true; } private void OnOrganEnableChanged(Entity organEnt, ref OrganEnableChangedEvent args) { if (!organEnt.Comp.CanEnable && args.Enabled) return; organEnt.Comp.Enabled = args.Enabled; if (args.Enabled) EnableOrgan(organEnt); else DisableOrgan(organEnt); if (organEnt.Comp.Body is { Valid: true } bodyEnt) RaiseLocalEvent(organEnt, new OrganComponentsModifyEvent(bodyEnt, args.Enabled)); Dirty(organEnt, organEnt.Comp); } private void EnableOrgan(Entity organEnt) { if (!TryComp(organEnt.Comp.Body, out BodyComponent? body)) return; // I hate having to hardcode these checks so much. if (HasComp(organEnt)) { var ev = new OrganEnabledEvent(organEnt); RaiseLocalEvent(organEnt, ref ev); } } private void DisableOrgan(Entity organEnt) { if (!TryComp(organEnt.Comp.Body, out BodyComponent? body)) return; // I hate having to hardcode these checks so much. if (HasComp(organEnt)) { var ev = new OrganDisabledEvent(organEnt); RaiseLocalEvent(organEnt, ref ev); } } // Shitmed Change End }