1
0

BodySystem.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. using Content.Server.Body.Components;
  2. using Content.Server.Ghost;
  3. using Content.Server.Humanoid;
  4. using Content.Shared.Body.Components;
  5. using Content.Shared.Body.Part;
  6. using Content.Shared.Body.Systems;
  7. using Content.Shared.Humanoid;
  8. using Content.Shared.Mind;
  9. using Content.Shared.Mobs.Systems;
  10. using Content.Shared.Movement.Events;
  11. using Content.Shared.Movement.Systems;
  12. using Robust.Shared.Audio;
  13. using Robust.Shared.Timing;
  14. using System.Numerics;
  15. // Shitmed Change
  16. using System.Linq;
  17. using Content.Shared._Shitmed.Body.Part;
  18. using Content.Shared.Gibbing.Events;
  19. namespace Content.Server.Body.Systems;
  20. public sealed partial class BodySystem : SharedBodySystem
  21. {
  22. [Dependency] private readonly BloodstreamSystem _bloodstream = default!; // Shitmed Change
  23. [Dependency] private readonly GhostSystem _ghostSystem = default!;
  24. [Dependency] private readonly IGameTiming _gameTiming = default!;
  25. [Dependency] private readonly HumanoidAppearanceSystem _humanoidSystem = default!;
  26. [Dependency] private readonly SharedAppearanceSystem _appearance = default!; // Shitmed Change
  27. [Dependency] private readonly MobStateSystem _mobState = default!;
  28. [Dependency] private readonly SharedMindSystem _mindSystem = default!;
  29. public override void Initialize()
  30. {
  31. base.Initialize();
  32. SubscribeLocalEvent<BodyComponent, MoveInputEvent>(OnRelayMoveInput);
  33. SubscribeLocalEvent<BodyComponent, ApplyMetabolicMultiplierEvent>(OnApplyMetabolicMultiplier);
  34. }
  35. private void OnRelayMoveInput(Entity<BodyComponent> ent, ref MoveInputEvent args)
  36. {
  37. // If they haven't actually moved then ignore it.
  38. if ((args.Entity.Comp.HeldMoveButtons &
  39. (MoveButtons.Down | MoveButtons.Left | MoveButtons.Up | MoveButtons.Right)) == 0x0)
  40. {
  41. return;
  42. }
  43. if (_mobState.IsDead(ent) && _mindSystem.TryGetMind(ent, out var mindId, out var mind))
  44. {
  45. mind.TimeOfDeath ??= _gameTiming.RealTime;
  46. _ghostSystem.OnGhostAttempt(mindId, canReturnGlobal: true, mind: mind);
  47. }
  48. }
  49. private void OnApplyMetabolicMultiplier(
  50. Entity<BodyComponent> ent,
  51. ref ApplyMetabolicMultiplierEvent args)
  52. {
  53. foreach (var organ in GetBodyOrgans(ent, ent))
  54. {
  55. RaiseLocalEvent(organ.Id, ref args);
  56. }
  57. }
  58. protected override void AddPart(
  59. Entity<BodyComponent?> bodyEnt,
  60. Entity<BodyPartComponent> partEnt,
  61. string slotId)
  62. {
  63. // TODO: Predict this probably.
  64. base.AddPart(bodyEnt, partEnt, slotId);
  65. if (!TryComp<HumanoidAppearanceComponent>(bodyEnt, out var humanoid))
  66. return;
  67. var layer = partEnt.Comp.ToHumanoidLayers();
  68. if (layer != null)
  69. {
  70. var layers = HumanoidVisualLayersExtension.Sublayers(layer.Value);
  71. _humanoidSystem.SetLayersVisibility(bodyEnt.Owner, layers, visible: true);
  72. }
  73. }
  74. protected override void RemovePart(
  75. Entity<BodyComponent?> bodyEnt,
  76. Entity<BodyPartComponent> partEnt,
  77. string slotId)
  78. {
  79. base.RemovePart(bodyEnt, partEnt, slotId);
  80. if (!TryComp<HumanoidAppearanceComponent>(bodyEnt, out var humanoid))
  81. return;
  82. var layer = partEnt.Comp.ToHumanoidLayers();
  83. if (layer is null)
  84. return;
  85. var layers = HumanoidVisualLayersExtension.Sublayers(layer.Value);
  86. _humanoidSystem.SetLayersVisibility(
  87. bodyEnt, layers, visible: false, permanent: true, humanoid);
  88. _appearance.SetData(bodyEnt, layer, true); // Shitmed Change
  89. }
  90. public override HashSet<EntityUid> GibBody(
  91. EntityUid bodyId,
  92. bool gibOrgans = false,
  93. BodyComponent? body = null,
  94. bool launchGibs = true,
  95. Vector2? splatDirection = null,
  96. float splatModifier = 1,
  97. Angle splatCone = default,
  98. SoundSpecifier? gibSoundOverride = null,
  99. // Shitmed Change
  100. GibType gib = GibType.Gib,
  101. GibContentsOption contents = GibContentsOption.Drop)
  102. {
  103. if (!Resolve(bodyId, ref body, logMissing: false)
  104. || TerminatingOrDeleted(bodyId)
  105. || EntityManager.IsQueuedForDeletion(bodyId))
  106. {
  107. return new HashSet<EntityUid>();
  108. }
  109. var xform = Transform(bodyId);
  110. if (xform.MapUid is null)
  111. return new HashSet<EntityUid>();
  112. var gibs = base.GibBody(bodyId, gibOrgans, body, launchGibs: launchGibs,
  113. splatDirection: splatDirection, splatModifier: splatModifier, splatCone: splatCone,
  114. gib: gib, contents: contents); // Shitmed Change
  115. var ev = new BeingGibbedEvent(gibs);
  116. RaiseLocalEvent(bodyId, ref ev);
  117. QueueDel(bodyId);
  118. return gibs;
  119. }
  120. // Shitmed Change Start
  121. public override HashSet<EntityUid> GibPart(
  122. EntityUid partId,
  123. BodyPartComponent? part = null,
  124. bool launchGibs = true,
  125. Vector2? splatDirection = null,
  126. float splatModifier = 1,
  127. Angle splatCone = default,
  128. SoundSpecifier? gibSoundOverride = null)
  129. {
  130. if (!Resolve(partId, ref part, logMissing: false)
  131. || TerminatingOrDeleted(partId)
  132. || EntityManager.IsQueuedForDeletion(partId))
  133. return new HashSet<EntityUid>();
  134. if (Transform(partId).MapUid is null)
  135. return new HashSet<EntityUid>();
  136. var gibs = base.GibPart(partId, part, launchGibs: launchGibs,
  137. splatDirection: splatDirection, splatModifier: splatModifier, splatCone: splatCone);
  138. var ev = new BeingGibbedEvent(gibs);
  139. RaiseLocalEvent(partId, ref ev);
  140. if (gibs.Any())
  141. QueueDel(partId);
  142. return gibs;
  143. }
  144. public override bool BurnPart(EntityUid partId, BodyPartComponent? part = null)
  145. {
  146. if (!Resolve(partId, ref part, logMissing: false)
  147. || TerminatingOrDeleted(partId)
  148. || EntityManager.IsQueuedForDeletion(partId))
  149. return false;
  150. return base.BurnPart(partId, part);
  151. }
  152. protected override void ApplyPartMarkings(EntityUid target, BodyPartAppearanceComponent component)
  153. {
  154. return;
  155. }
  156. protected override void RemoveBodyMarkings(EntityUid target, BodyPartAppearanceComponent partAppearance, HumanoidAppearanceComponent bodyAppearance)
  157. {
  158. foreach (var (visualLayer, markingList) in partAppearance.Markings)
  159. foreach (var marking in markingList)
  160. _humanoidSystem.RemoveMarking(target, marking.MarkingId, sync: false, humanoid: bodyAppearance);
  161. Dirty(target, bodyAppearance);
  162. }
  163. protected override void PartRemoveDamage(Entity<BodyComponent?> bodyEnt, Entity<BodyPartComponent> partEnt)
  164. {
  165. var bleeding = partEnt.Comp.SeverBleeding;
  166. if (partEnt.Comp.IsVital)
  167. bleeding *= 2f;
  168. _bloodstream.TryModifyBleedAmount(bodyEnt, bleeding);
  169. }
  170. // Shitmed Change End
  171. }