InjectionAnomalySystem.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using Content.Server.Anomaly.Components;
  2. using Content.Shared.Chemistry.EntitySystems;
  3. using Content.Shared.Anomaly.Components;
  4. using Content.Shared.Chemistry.Components.SolutionManager;
  5. using System.Linq;
  6. using Robust.Server.GameObjects;
  7. namespace Content.Server.Anomaly.Effects;
  8. /// <summary>
  9. /// This component allows the anomaly to inject liquid from the SolutionContainer
  10. /// into the surrounding entities with the InjectionSolution component
  11. /// </summary>
  12. ///
  13. /// <see cref="InjectionAnomalyComponent"/>
  14. public sealed class InjectionAnomalySystem : EntitySystem
  15. {
  16. [Dependency] private readonly EntityLookupSystem _lookup = default!;
  17. [Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
  18. [Dependency] private readonly TransformSystem _transform = default!;
  19. private EntityQuery<InjectableSolutionComponent> _injectableQuery;
  20. public override void Initialize()
  21. {
  22. SubscribeLocalEvent<InjectionAnomalyComponent, AnomalyPulseEvent>(OnPulse);
  23. SubscribeLocalEvent<InjectionAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical, before: new[] { typeof(SharedSolutionContainerSystem) });
  24. _injectableQuery = GetEntityQuery<InjectableSolutionComponent>();
  25. }
  26. private void OnPulse(Entity<InjectionAnomalyComponent> entity, ref AnomalyPulseEvent args)
  27. {
  28. PulseScalableEffect(entity, entity.Comp.InjectRadius * args.PowerModifier, entity.Comp.MaxSolutionInjection * args.Severity * args.PowerModifier);
  29. }
  30. private void OnSupercritical(Entity<InjectionAnomalyComponent> entity, ref AnomalySupercriticalEvent args)
  31. {
  32. PulseScalableEffect(entity, entity.Comp.SuperCriticalInjectRadius * args.PowerModifier, entity.Comp.SuperCriticalSolutionInjection * args.PowerModifier);
  33. }
  34. private void PulseScalableEffect(Entity<InjectionAnomalyComponent> entity, float injectRadius, float maxInject)
  35. {
  36. if (!_solutionContainer.TryGetSolution(entity.Owner, entity.Comp.Solution, out _, out var sol))
  37. return;
  38. //We get all the entity in the radius into which the reagent will be injected.
  39. var xformQuery = GetEntityQuery<TransformComponent>();
  40. var xform = xformQuery.GetComponent(entity);
  41. var allEnts = _lookup.GetEntitiesInRange<InjectableSolutionComponent>(_transform.GetMapCoordinates(entity, xform: xform), injectRadius)
  42. .Select(x => x.Owner).ToList();
  43. //for each matching entity found
  44. foreach (var ent in allEnts)
  45. {
  46. if (!_solutionContainer.TryGetInjectableSolution(ent, out var injectable, out _))
  47. continue;
  48. if (_injectableQuery.TryGetComponent(ent, out var injEnt))
  49. {
  50. _solutionContainer.TryTransferSolution(injectable.Value, sol, maxInject);
  51. //Spawn Effect
  52. var uidXform = Transform(ent);
  53. Spawn(entity.Comp.VisualEffectPrototype, uidXform.Coordinates);
  54. }
  55. }
  56. }
  57. }