diff --git a/Content.Server/Fluids/EntitySystems/DrainSystem.cs b/Content.Server/Fluids/EntitySystems/DrainSystem.cs index 80f3a38f61..a731fa1c8a 100644 --- a/Content.Server/Fluids/EntitySystems/DrainSystem.cs +++ b/Content.Server/Fluids/EntitySystems/DrainSystem.cs @@ -1,7 +1,9 @@ +using Content.Server.Chemistry.Components.SolutionManager; using Content.Server.Fluids.Components; using Content.Server.Chemistry.EntitySystems; using Content.Shared.FixedPoint; using Content.Shared.Audio; +using Robust.Shared.Collections; namespace Content.Server.Fluids.EntitySystems { @@ -11,10 +13,14 @@ namespace Content.Server.Fluids.EntitySystems [Dependency] private readonly SolutionContainerSystem _solutionSystem = default!; [Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!; - public override void Update(float frameTime) { base.Update(frameTime); + var managerQuery = GetEntityQuery(); + var xformQuery = GetEntityQuery(); + var puddleQuery = GetEntityQuery(); + var puddles = new ValueList<(EntityUid Entity, string Solution)>(); + foreach (var drain in EntityQuery()) { drain.Accumulator += frameTime; @@ -24,27 +30,33 @@ namespace Content.Server.Fluids.EntitySystems } drain.Accumulator -= drain.DrainFrequency; - /// Best to do this one every second rather than once every tick... - _solutionSystem.TryGetSolution(drain.Owner, DrainComponent.SolutionName, out var drainSolution); + if (!managerQuery.TryGetComponent(drain.Owner, out var manager)) + continue; + + // Best to do this one every second rather than once every tick... + _solutionSystem.TryGetSolution(drain.Owner, DrainComponent.SolutionName, out var drainSolution, manager); if (drainSolution is null) - return; + continue; - /// Remove a bit from the buffer + // Remove a bit from the buffer _solutionSystem.SplitSolution(drain.Owner, drainSolution, (drain.UnitsDestroyedPerSecond * drain.DrainFrequency)); - /// This will ensure that UnitsPerSecond is per second... + // This will ensure that UnitsPerSecond is per second... var amount = drain.UnitsPerSecond * drain.DrainFrequency; - var xform = Transform(drain.Owner); - List puddles = new(); + + if (!xformQuery.TryGetComponent(drain.Owner, out var xform)) + continue; + + puddles.Clear(); foreach (var entity in _lookup.GetEntitiesInRange(xform.MapPosition, drain.Range)) { - /// No InRangeUnobstructed because there's no collision group that fits right now - /// and these are placed by mappers and not buildable/movable so shouldnt really be a problem... - if (TryComp(entity, out var puddleComp)) + // No InRangeUnobstructed because there's no collision group that fits right now + // and these are placed by mappers and not buildable/movable so shouldnt really be a problem... + if (puddleQuery.TryGetComponent(entity, out var puddle)) { - puddles.Add(puddleComp); + puddles.Add((entity, puddle.SolutionName)); } } @@ -58,28 +70,28 @@ namespace Content.Server.Fluids.EntitySystems amount /= puddles.Count; - foreach (var puddle in puddles) + foreach (var (puddle, solution) in puddles) { - /// Queue the solution deletion if it's empty. EvaporationSystem might also do this - /// but queuedelete should be pretty safe. - if (!_solutionSystem.TryGetSolution(puddle.Owner, puddle.SolutionName, out var puddleSolution)) + // Queue the solution deletion if it's empty. EvaporationSystem might also do this + // but queuedelete should be pretty safe. + if (!_solutionSystem.TryGetSolution(puddle, solution, out var puddleSolution)) { - EntityManager.QueueDeleteEntity(puddle.Owner); + EntityManager.QueueDeleteEntity(puddle); continue; } - /// Removes the lowest of: - /// the drain component's units per second adjusted for # of puddles - /// the puddle's remaining volume (making it cleanly zero) - /// the drain's remaining volume in its buffer. - var transferSolution = _solutionSystem.SplitSolution(puddle.Owner, puddleSolution, + // Removes the lowest of: + // the drain component's units per second adjusted for # of puddles + // the puddle's remaining volume (making it cleanly zero) + // the drain's remaining volume in its buffer. + var transferSolution = _solutionSystem.SplitSolution(puddle, puddleSolution, FixedPoint2.Min(FixedPoint2.New(amount), puddleSolution.CurrentVolume, drainSolution.AvailableVolume)); _solutionSystem.TryAddSolution(drain.Owner, drainSolution, transferSolution); if (puddleSolution.CurrentVolume <= 0) { - EntityManager.QueueDeleteEntity(puddle.Owner); + QueueDel(puddle); } } }