// SPDX-FileCopyrightText: 2022 Jezithyr // SPDX-FileCopyrightText: 2023 DrSmugleaf // SPDX-FileCopyrightText: 2023 Jezithyr // SPDX-FileCopyrightText: 2023 Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> // SPDX-FileCopyrightText: 2023 metalgearsloth // SPDX-FileCopyrightText: 2024 Aviu00 <93730715+Aviu00@users.noreply.github.com> // SPDX-FileCopyrightText: 2024 Piras314 // SPDX-FileCopyrightText: 2024 username <113782077+whateverusername0@users.noreply.github.com> // SPDX-FileCopyrightText: 2024 whateverusername0 // SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 deltanedas <39013340+deltanedas@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 deltanedas <@deltanedas:kde.org> // SPDX-FileCopyrightText: 2025 gluesniffler <159397573+gluesniffler@users.noreply.github.com> // // SPDX-License-Identifier: AGPL-3.0-or-later using Content.Shared.Body.Components; using Content.Shared.Body.Systems; using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Serialization; // Shitmed Change using Content.Shared.Containers.ItemSlots; using Content.Shared.FixedPoint; using Content.Shared._Shitmed.Medical.Surgery.Tools; using Content.Shared._Shitmed.Targeting; using Robust.Shared.Prototypes; namespace Content.Shared.Body.Part; [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] //[Access(typeof(SharedBodySystem))] // goob edit - all access :godo: public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent // Shitmed Change { // Need to set this on container changes as it may be several transform parents up the hierarchy. /// /// Parent body for this part. /// [DataField, AutoNetworkedField] public EntityUid? Body; // Shitmed Change Start [DataField, AutoNetworkedField] public BodyPartSlot? ParentSlot; /// /// Shitmed Change: Bleeding stacks to give when this body part is severed. /// Doubled for . parts. /// [DataField] public float SeverBleeding = 4f; [DataField] public string ToolName { get; set; } = "A body part"; [DataField] public string SlotId = string.Empty; [DataField, AutoNetworkedField] public bool? Used { get; set; } = null; [DataField] public float Speed { get; set; } = 1f; /// /// Shitmed Change: What's the max health this body part can have? /// [DataField] public float MinIntegrity; /// /// Whether this body part can be severed or not /// [DataField, AutoNetworkedField] public bool CanSever = true; /// /// Shitmed Change: Whether this body part is enabled or not. /// [DataField, AutoNetworkedField] public bool Enabled = true; /// /// Shitmed Change: Whether this body part can be enabled or not. Used for non-functional prosthetics. /// [DataField, AutoNetworkedField] public bool CanEnable = true; /// /// Whether this body part can attach children or not. /// [DataField] public bool CanAttachChildren = true; /// /// Shitmed Change: How long it takes to run another self heal tick on the body part. /// [DataField] public float HealingTime = 30; /// /// Shitmed Change: How long it has been since the last self heal tick on the body part. /// public float HealingTimer; /// /// Shitmed Change: How much health to heal on the body part per tick. /// [DataField] public float SelfHealingAmount = 5; /// /// Shitmed Change: The name of the container for this body part. Used in insertion surgeries. /// [DataField] public string ContainerName { get; set; } = "part_slot"; /// /// Shitmed Change: The slot for item insertion. /// [DataField, AutoNetworkedField] public ItemSlot ItemInsertionSlot = new(); /// /// Shitmed Change: Current species. Dictates things like body part sprites. /// [DataField, AutoNetworkedField] public string Species { get; set; } = ""; /// /// Shitmed Change: The total damage that has to be dealt to a body part /// to make possible severing it. /// [DataField, AutoNetworkedField] public float SeverIntegrity = 90; /// /// Shitmed Change: The ID of the base layer for this body part. /// [DataField, AutoNetworkedField] public string? BaseLayerId; /// /// Shitmed Change: On what TargetIntegrity we should re-enable the part. /// [DataField, AutoNetworkedField] public TargetIntegrity EnableIntegrity = TargetIntegrity.ModeratelyWounded; [DataField, AutoNetworkedField] public Dictionary IntegrityThresholds = new() { { TargetIntegrity.CriticallyWounded, 90 }, { TargetIntegrity.HeavilyWounded, 75 }, { TargetIntegrity.ModeratelyWounded, 60 }, { TargetIntegrity.SomewhatWounded, 40}, { TargetIntegrity.LightlyWounded, 20 }, { TargetIntegrity.Healthy, 10 }, }; [DataField, AutoNetworkedField] public BodyPartType PartType = BodyPartType.Other; // TODO BODY Replace with a simulation of organs /// /// Whether or not the owning will die if all /// s of this type are removed from it. /// [DataField("vital"), AutoNetworkedField] public bool IsVital; [DataField, AutoNetworkedField] public BodyPartSymmetry Symmetry = BodyPartSymmetry.None; /// /// When attached, the part will ensure these components on the entity, and delete them on removal. /// [DataField, AlwaysPushInheritance] public ComponentRegistry? OnAdd; /// /// When removed, the part will ensure these components on the entity, and add them on removal. /// [DataField, AlwaysPushInheritance] public ComponentRegistry? OnRemove; // Shitmed Change End /// /// Child body parts attached to this body part. /// [DataField, AutoNetworkedField] public Dictionary Children = new(); /// /// Organs attached to this body part. /// [DataField, AutoNetworkedField] public Dictionary Organs = new(); /// /// These are only for VV/Debug do not use these for gameplay/systems /// [ViewVariables] private List BodyPartSlotsVV { get { List temp = new(); var containerSystem = IoCManager.Resolve().System(); foreach (var slotId in Children.Keys) { temp.Add((ContainerSlot)containerSystem.GetContainer(Owner, SharedBodySystem.PartSlotContainerIdPrefix + slotId)); } return temp; } } [ViewVariables] private List OrganSlotsVV { get { List temp = new(); var containerSystem = IoCManager.Resolve().System(); foreach (var slotId in Organs.Keys) { temp.Add((ContainerSlot)containerSystem.GetContainer(Owner, SharedBodySystem.OrganSlotContainerIdPrefix + slotId)); } return temp; } } } /// /// Contains metadata about a body part in relation to its slot. /// [NetSerializable, Serializable] [DataRecord] public partial struct BodyPartSlot { public string Id; public BodyPartType Type; public BodyPartSlot(string id, BodyPartType type) { Id = id; Type = type; } }; /// /// Contains metadata about an organ part in relation to its slot. /// [NetSerializable, Serializable] [DataRecord] public partial struct OrganSlot { public string Id; public OrganSlot(string id) { Id = id; } };