1
0

SharedSolutionContainerSystem.Relays.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. using Content.Shared.Chemistry.Components;
  2. using Content.Shared.Chemistry.Components.SolutionManager;
  3. using Content.Shared.Chemistry.Reaction;
  4. using Content.Shared.FixedPoint;
  5. namespace Content.Shared.Chemistry.EntitySystems;
  6. #region Events
  7. /// <summary>
  8. /// This event alerts system that the solution was changed
  9. /// </summary>
  10. [ByRefEvent]
  11. public record struct SolutionContainerChangedEvent
  12. {
  13. public readonly Solution Solution;
  14. public readonly string SolutionId;
  15. public SolutionContainerChangedEvent(Solution solution, string solutionId)
  16. {
  17. SolutionId = solutionId;
  18. Solution = solution;
  19. }
  20. }
  21. /// <summary>
  22. /// An event raised when more reagents are added to a (managed) solution than it can hold.
  23. /// </summary>
  24. [ByRefEvent]
  25. public record struct SolutionContainerOverflowEvent(EntityUid SolutionEnt, Solution SolutionHolder, Solution Overflow)
  26. {
  27. /// <summary>The entity which contains the solution that has overflowed.</summary>
  28. public readonly EntityUid SolutionEnt = SolutionEnt;
  29. /// <summary>The solution that has overflowed.</summary>
  30. public readonly Solution SolutionHolder = SolutionHolder;
  31. /// <summary>The reagents that have overflowed the solution.</summary>
  32. public readonly Solution Overflow = Overflow;
  33. /// <summary>The volume by which the solution has overflowed.</summary>
  34. public readonly FixedPoint2 OverflowVol = Overflow.Volume;
  35. /// <summary>Whether some subscriber has taken care of the effects of the overflow.</summary>
  36. public bool Handled = false;
  37. }
  38. /// <summary>
  39. /// Ref event used to relay events raised on solution entities to their containers.
  40. /// </summary>
  41. /// <typeparam name="TEvent"></typeparam>
  42. /// <param name="Event">The event that is being relayed.</param>
  43. /// <param name="ContainerEnt">The container entity that the event is being relayed to.</param>
  44. /// <param name="Name">The name of the solution entity that the event is being relayed from.</param>
  45. [ByRefEvent]
  46. public record struct SolutionRelayEvent<TEvent>(TEvent Event, EntityUid ContainerEnt, string Name)
  47. {
  48. public readonly EntityUid ContainerEnt = ContainerEnt;
  49. public readonly string Name = Name;
  50. public TEvent Event = Event;
  51. }
  52. /// <summary>
  53. /// Ref event used to relay events raised on solution containers to their contained solutions.
  54. /// </summary>
  55. /// <typeparam name="TEvent"></typeparam>
  56. /// <param name="Event">The event that is being relayed.</param>
  57. /// <param name="SolutionEnt">The solution entity that the event is being relayed to.</param>
  58. /// <param name="Name">The name of the solution entity that the event is being relayed to.</param>
  59. [ByRefEvent]
  60. public record struct SolutionContainerRelayEvent<TEvent>(TEvent Event, Entity<SolutionComponent> SolutionEnt, string Name)
  61. {
  62. public readonly Entity<SolutionComponent> SolutionEnt = SolutionEnt;
  63. public readonly string Name = Name;
  64. public TEvent Event = Event;
  65. }
  66. #endregion Events
  67. public abstract partial class SharedSolutionContainerSystem
  68. {
  69. protected void InitializeRelays()
  70. {
  71. SubscribeLocalEvent<ContainedSolutionComponent, SolutionChangedEvent>(OnSolutionChanged);
  72. SubscribeLocalEvent<ContainedSolutionComponent, SolutionOverflowEvent>(OnSolutionOverflow);
  73. SubscribeLocalEvent<ContainedSolutionComponent, ReactionAttemptEvent>(RelaySolutionRefEvent);
  74. }
  75. #region Event Handlers
  76. protected virtual void OnSolutionChanged(Entity<ContainedSolutionComponent> entity, ref SolutionChangedEvent args)
  77. {
  78. var (solutionId, solutionComp) = args.Solution;
  79. var solution = solutionComp.Solution;
  80. UpdateAppearance(entity.Comp.Container, (solutionId, solutionComp, entity.Comp));
  81. var relayEvent = new SolutionContainerChangedEvent(solution, entity.Comp.ContainerName);
  82. RaiseLocalEvent(entity.Comp.Container, ref relayEvent);
  83. }
  84. protected virtual void OnSolutionOverflow(Entity<ContainedSolutionComponent> entity, ref SolutionOverflowEvent args)
  85. {
  86. var solution = args.Solution.Comp.Solution;
  87. var overflow = solution.SplitSolution(args.Overflow);
  88. var relayEv = new SolutionContainerOverflowEvent(entity.Owner, solution, overflow)
  89. {
  90. Handled = args.Handled,
  91. };
  92. RaiseLocalEvent(entity.Comp.Container, ref relayEv);
  93. args.Handled = relayEv.Handled;
  94. }
  95. #region Relay Event Handlers
  96. private void RelaySolutionValEvent<TEvent>(EntityUid uid, ContainedSolutionComponent comp, TEvent @event)
  97. {
  98. var relayEvent = new SolutionRelayEvent<TEvent>(@event, uid, comp.ContainerName);
  99. RaiseLocalEvent(comp.Container, ref relayEvent);
  100. }
  101. private void RelaySolutionRefEvent<TEvent>(Entity<ContainedSolutionComponent> entity, ref TEvent @event)
  102. {
  103. var relayEvent = new SolutionRelayEvent<TEvent>(@event, entity.Owner, entity.Comp.ContainerName);
  104. RaiseLocalEvent(entity.Comp.Container, ref relayEvent);
  105. @event = relayEvent.Event;
  106. }
  107. private void RelaySolutionContainerEvent<TEvent>(EntityUid uid, SolutionContainerManagerComponent comp, TEvent @event)
  108. {
  109. foreach (var (name, soln) in EnumerateSolutions((uid, comp)))
  110. {
  111. var relayEvent = new SolutionContainerRelayEvent<TEvent>(@event, soln, name!);
  112. RaiseLocalEvent(soln, ref relayEvent);
  113. }
  114. }
  115. private void RelaySolutionContainerEvent<TEvent>(Entity<SolutionContainerManagerComponent> entity, ref TEvent @event)
  116. {
  117. foreach (var (name, soln) in EnumerateSolutions((entity.Owner, entity.Comp)))
  118. {
  119. var relayEvent = new SolutionContainerRelayEvent<TEvent>(@event, soln, name!);
  120. RaiseLocalEvent(soln, ref relayEvent);
  121. @event = relayEvent.Event;
  122. }
  123. }
  124. #endregion Relay Event Handlers
  125. #endregion Event Handlers
  126. }