BodyPartComponent.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. // SPDX-FileCopyrightText: 2022 Jezithyr <Jezithyr@gmail.com>
  2. // SPDX-FileCopyrightText: 2023 DrSmugleaf <DrSmugleaf@users.noreply.github.com>
  3. // SPDX-FileCopyrightText: 2023 Jezithyr <jezithyr@gmail.com>
  4. // SPDX-FileCopyrightText: 2023 Leon Friedrich <60421075+ElectroJr@users.noreply.github.com>
  5. // SPDX-FileCopyrightText: 2023 metalgearsloth <comedian_vs_clown@hotmail.com>
  6. // SPDX-FileCopyrightText: 2024 Aviu00 <93730715+Aviu00@users.noreply.github.com>
  7. // SPDX-FileCopyrightText: 2024 Piras314 <p1r4s@proton.me>
  8. // SPDX-FileCopyrightText: 2024 username <113782077+whateverusername0@users.noreply.github.com>
  9. // SPDX-FileCopyrightText: 2024 whateverusername0 <whateveremail>
  10. // SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>
  11. // SPDX-FileCopyrightText: 2025 deltanedas <39013340+deltanedas@users.noreply.github.com>
  12. // SPDX-FileCopyrightText: 2025 deltanedas <@deltanedas:kde.org>
  13. // SPDX-FileCopyrightText: 2025 gluesniffler <159397573+gluesniffler@users.noreply.github.com>
  14. //
  15. // SPDX-License-Identifier: AGPL-3.0-or-later
  16. using Content.Shared.Body.Components;
  17. using Content.Shared.Body.Systems;
  18. using Robust.Shared.Containers;
  19. using Robust.Shared.GameStates;
  20. using Robust.Shared.Serialization;
  21. // Shitmed Change
  22. using Content.Shared.Containers.ItemSlots;
  23. using Content.Shared.FixedPoint;
  24. using Content.Shared._Shitmed.Medical.Surgery.Tools;
  25. using Content.Shared._Shitmed.Targeting;
  26. using Robust.Shared.Prototypes;
  27. namespace Content.Shared.Body.Part;
  28. [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
  29. //[Access(typeof(SharedBodySystem))] // goob edit - all access :godo:
  30. public sealed partial class BodyPartComponent : Component, ISurgeryToolComponent // Shitmed Change
  31. {
  32. // Need to set this on container changes as it may be several transform parents up the hierarchy.
  33. /// <summary>
  34. /// Parent body for this part.
  35. /// </summary>
  36. [DataField, AutoNetworkedField]
  37. public EntityUid? Body;
  38. // Shitmed Change Start
  39. [DataField, AutoNetworkedField]
  40. public BodyPartSlot? ParentSlot;
  41. /// <summary>
  42. /// Shitmed Change: Bleeding stacks to give when this body part is severed.
  43. /// Doubled for <see cref="IsVital"/>. parts.
  44. /// </summary>
  45. [DataField]
  46. public float SeverBleeding = 4f;
  47. [DataField]
  48. public string ToolName { get; set; } = "A body part";
  49. [DataField]
  50. public string SlotId = string.Empty;
  51. [DataField, AutoNetworkedField]
  52. public bool? Used { get; set; } = null;
  53. [DataField]
  54. public float Speed { get; set; } = 1f;
  55. /// <summary>
  56. /// Shitmed Change: What's the max health this body part can have?
  57. /// </summary>
  58. [DataField]
  59. public float MinIntegrity;
  60. /// <summary>
  61. /// Whether this body part can be severed or not
  62. /// </summary>
  63. [DataField, AutoNetworkedField]
  64. public bool CanSever = true;
  65. /// <summary>
  66. /// Shitmed Change: Whether this body part is enabled or not.
  67. /// </summary>
  68. [DataField, AutoNetworkedField]
  69. public bool Enabled = true;
  70. /// <summary>
  71. /// Shitmed Change: Whether this body part can be enabled or not. Used for non-functional prosthetics.
  72. /// </summary>
  73. [DataField, AutoNetworkedField]
  74. public bool CanEnable = true;
  75. /// <summary>
  76. /// Whether this body part can attach children or not.
  77. /// </summary>
  78. [DataField]
  79. public bool CanAttachChildren = true;
  80. /// <summary>
  81. /// Shitmed Change: How long it takes to run another self heal tick on the body part.
  82. /// </summary>
  83. [DataField]
  84. public float HealingTime = 30;
  85. /// <summary>
  86. /// Shitmed Change: How long it has been since the last self heal tick on the body part.
  87. /// </summary>
  88. public float HealingTimer;
  89. /// <summary>
  90. /// Shitmed Change: How much health to heal on the body part per tick.
  91. /// </summary>
  92. [DataField]
  93. public float SelfHealingAmount = 5;
  94. /// <summary>
  95. /// Shitmed Change: The name of the container for this body part. Used in insertion surgeries.
  96. /// </summary>
  97. [DataField]
  98. public string ContainerName { get; set; } = "part_slot";
  99. /// <summary>
  100. /// Shitmed Change: The slot for item insertion.
  101. /// </summary>
  102. [DataField, AutoNetworkedField]
  103. public ItemSlot ItemInsertionSlot = new();
  104. /// <summary>
  105. /// Shitmed Change: Current species. Dictates things like body part sprites.
  106. /// </summary>
  107. [DataField, AutoNetworkedField]
  108. public string Species { get; set; } = "";
  109. /// <summary>
  110. /// Shitmed Change: The total damage that has to be dealt to a body part
  111. /// to make possible severing it.
  112. /// </summary>
  113. [DataField, AutoNetworkedField]
  114. public float SeverIntegrity = 90;
  115. /// <summary>
  116. /// Shitmed Change: The ID of the base layer for this body part.
  117. /// </summary>
  118. [DataField, AutoNetworkedField]
  119. public string? BaseLayerId;
  120. /// <summary>
  121. /// Shitmed Change: On what TargetIntegrity we should re-enable the part.
  122. /// </summary>
  123. [DataField, AutoNetworkedField]
  124. public TargetIntegrity EnableIntegrity = TargetIntegrity.ModeratelyWounded;
  125. [DataField, AutoNetworkedField]
  126. public Dictionary<TargetIntegrity, float> IntegrityThresholds = new()
  127. {
  128. { TargetIntegrity.CriticallyWounded, 90 },
  129. { TargetIntegrity.HeavilyWounded, 75 },
  130. { TargetIntegrity.ModeratelyWounded, 60 },
  131. { TargetIntegrity.SomewhatWounded, 40},
  132. { TargetIntegrity.LightlyWounded, 20 },
  133. { TargetIntegrity.Healthy, 10 },
  134. };
  135. [DataField, AutoNetworkedField]
  136. public BodyPartType PartType = BodyPartType.Other;
  137. // TODO BODY Replace with a simulation of organs
  138. /// <summary>
  139. /// Whether or not the owning <see cref="Body"/> will die if all
  140. /// <see cref="BodyComponent"/>s of this type are removed from it.
  141. /// </summary>
  142. [DataField("vital"), AutoNetworkedField]
  143. public bool IsVital;
  144. [DataField, AutoNetworkedField]
  145. public BodyPartSymmetry Symmetry = BodyPartSymmetry.None;
  146. /// <summary>
  147. /// When attached, the part will ensure these components on the entity, and delete them on removal.
  148. /// </summary>
  149. [DataField, AlwaysPushInheritance]
  150. public ComponentRegistry? OnAdd;
  151. /// <summary>
  152. /// When removed, the part will ensure these components on the entity, and add them on removal.
  153. /// </summary>
  154. [DataField, AlwaysPushInheritance]
  155. public ComponentRegistry? OnRemove;
  156. // Shitmed Change End
  157. /// <summary>
  158. /// Child body parts attached to this body part.
  159. /// </summary>
  160. [DataField, AutoNetworkedField]
  161. public Dictionary<string, BodyPartSlot> Children = new();
  162. /// <summary>
  163. /// Organs attached to this body part.
  164. /// </summary>
  165. [DataField, AutoNetworkedField]
  166. public Dictionary<string, OrganSlot> Organs = new();
  167. /// <summary>
  168. /// These are only for VV/Debug do not use these for gameplay/systems
  169. /// </summary>
  170. [ViewVariables]
  171. private List<ContainerSlot> BodyPartSlotsVV
  172. {
  173. get
  174. {
  175. List<ContainerSlot> temp = new();
  176. var containerSystem = IoCManager.Resolve<IEntityManager>().System<SharedContainerSystem>();
  177. foreach (var slotId in Children.Keys)
  178. {
  179. temp.Add((ContainerSlot)containerSystem.GetContainer(Owner, SharedBodySystem.PartSlotContainerIdPrefix + slotId));
  180. }
  181. return temp;
  182. }
  183. }
  184. [ViewVariables]
  185. private List<ContainerSlot> OrganSlotsVV
  186. {
  187. get
  188. {
  189. List<ContainerSlot> temp = new();
  190. var containerSystem = IoCManager.Resolve<IEntityManager>().System<SharedContainerSystem>();
  191. foreach (var slotId in Organs.Keys)
  192. {
  193. temp.Add((ContainerSlot)containerSystem.GetContainer(Owner, SharedBodySystem.OrganSlotContainerIdPrefix + slotId));
  194. }
  195. return temp;
  196. }
  197. }
  198. }
  199. /// <summary>
  200. /// Contains metadata about a body part in relation to its slot.
  201. /// </summary>
  202. [NetSerializable, Serializable]
  203. [DataRecord]
  204. public partial struct BodyPartSlot
  205. {
  206. public string Id;
  207. public BodyPartType Type;
  208. public BodyPartSlot(string id, BodyPartType type)
  209. {
  210. Id = id;
  211. Type = type;
  212. }
  213. };
  214. /// <summary>
  215. /// Contains metadata about an organ part in relation to its slot.
  216. /// </summary>
  217. [NetSerializable, Serializable]
  218. [DataRecord]
  219. public partial struct OrganSlot
  220. {
  221. public string Id;
  222. public OrganSlot(string id)
  223. {
  224. Id = id;
  225. }
  226. };