SharedBodySystem.Relay.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>
  2. // SPDX-FileCopyrightText: 2025 Aviu00 <93730715+Aviu00@users.noreply.github.com>
  3. // SPDX-FileCopyrightText: 2025 Misandry <mary@thughunt.ing>
  4. // SPDX-FileCopyrightText: 2025 Piras314 <p1r4s@proton.me>
  5. // SPDX-FileCopyrightText: 2025 gus <august.eymann@gmail.com>
  6. //
  7. // SPDX-License-Identifier: AGPL-3.0-or-later
  8. using Content.Shared._Shitmed.DoAfter;
  9. using Content.Shared.Body.Components;
  10. using Content.Shared.Body.Part;
  11. namespace Content.Shared.Body.Systems;
  12. public partial class SharedBodySystem
  13. {
  14. private void InitializeRelay()
  15. {
  16. SubscribeLocalEvent<BodyComponent, GetDoAfterDelayMultiplierEvent>(RelayBodyPartEvent);
  17. }
  18. protected void RefRelayBodyPartEvent<T>(EntityUid uid, BodyComponent component, ref T args) where T : IBodyPartRelayEvent
  19. {
  20. RelayEvent((uid, component), ref args);
  21. }
  22. protected void RelayBodyPartEvent<T>(EntityUid uid, BodyComponent component, T args) where T : IBodyPartRelayEvent
  23. {
  24. RelayEvent((uid, component), args);
  25. }
  26. public void RelayEvent<T>(Entity<BodyComponent> body, ref T args) where T : IBodyPartRelayEvent
  27. {
  28. // this copies the by-ref event if it is a struct
  29. var ev = new BodyPartRelayedEvent<T>(args);
  30. foreach (var part in GetBodyChildrenOfType(body.Owner, args.TargetBodyPart, body.Comp))
  31. {
  32. RaiseLocalEvent(part.Id, ev);
  33. }
  34. // and now we copy it back
  35. args = ev.Args;
  36. }
  37. public void RelayEvent<T>(Entity<BodyComponent> body, T args) where T : IBodyPartRelayEvent
  38. {
  39. var ev = new BodyPartRelayedEvent<T>(args);
  40. foreach (var part in GetBodyChildrenOfType(body.Owner, args.TargetBodyPart, body.Comp))
  41. {
  42. RaiseLocalEvent(part.Id, ev);
  43. }
  44. }
  45. }
  46. public sealed class BodyPartRelayedEvent<TEvent> : EntityEventArgs
  47. {
  48. public TEvent Args;
  49. public BodyPartRelayedEvent(TEvent args)
  50. {
  51. Args = args;
  52. }
  53. }
  54. /// <summary>
  55. /// Events that should be relayed to body parts should implement this interface.
  56. /// </summary>
  57. public interface IBodyPartRelayEvent
  58. {
  59. /// <summary>
  60. /// What body part should this event be relayed to, if any?
  61. /// </summary>
  62. public BodyPartType TargetBodyPart { get; }
  63. }