Fix sinks and toilets not draining (#33691)

* Fix AutoDrain

Per the system comments, AutoDrain is designed to automatically move
puddles into the drain (like a floor drain). Drains without AutoDrain
are still supposed to gradually empty the buffer, but not remove puddles
(like sinks and toilets).

However, a logic error in the original implementation causes drains with
AutoDrain set to false to simply not work. Hence sinks never emptied.

* Update documentation
This commit is contained in:
Partmedia
2024-12-03 18:42:16 -08:00
committed by GitHub
parent 87182635b6
commit cf202e805d
2 changed files with 31 additions and 35 deletions

View File

@@ -134,13 +134,6 @@ public sealed class DrainSystem : SharedDrainSystem
} }
drain.Accumulator -= drain.DrainFrequency; drain.Accumulator -= drain.DrainFrequency;
// Disable ambient sound from emptying manually
if (!drain.AutoDrain)
{
_ambientSoundSystem.SetAmbience(uid, false);
continue;
}
if (!managerQuery.TryGetComponent(uid, out var manager)) if (!managerQuery.TryGetComponent(uid, out var manager))
continue; continue;
@@ -160,41 +153,44 @@ public sealed class DrainSystem : SharedDrainSystem
// This will ensure that UnitsPerSecond is per second... // This will ensure that UnitsPerSecond is per second...
var amount = drain.UnitsPerSecond * drain.DrainFrequency; var amount = drain.UnitsPerSecond * drain.DrainFrequency;
_puddles.Clear(); if (drain.AutoDrain)
_lookup.GetEntitiesInRange(Transform(uid).Coordinates, drain.Range, _puddles);
if (_puddles.Count == 0)
{ {
_ambientSoundSystem.SetAmbience(uid, false); _puddles.Clear();
continue; _lookup.GetEntitiesInRange(Transform(uid).Coordinates, drain.Range, _puddles);
}
_ambientSoundSystem.SetAmbience(uid, true); if (_puddles.Count == 0)
amount /= _puddles.Count;
foreach (var puddle in _puddles)
{
// Queue the solution deletion if it's empty. EvaporationSystem might also do this
// but queuedelete should be pretty safe.
if (!_solutionContainerSystem.ResolveSolution(puddle.Owner, puddle.Comp.SolutionName, ref puddle.Comp.Solution, out var puddleSolution))
{ {
EntityManager.QueueDeleteEntity(puddle); _ambientSoundSystem.SetAmbience(uid, false);
continue; continue;
} }
// Removes the lowest of: _ambientSoundSystem.SetAmbience(uid, true);
// 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 = _solutionContainerSystem.SplitSolution(puddle.Comp.Solution.Value,
FixedPoint2.Min(FixedPoint2.New(amount), puddleSolution.Volume, drainSolution.AvailableVolume));
drainSolution.AddSolution(transferSolution, _prototypeManager); amount /= _puddles.Count;
if (puddleSolution.Volume <= 0) foreach (var puddle in _puddles)
{ {
QueueDel(puddle); // Queue the solution deletion if it's empty. EvaporationSystem might also do this
// but queuedelete should be pretty safe.
if (!_solutionContainerSystem.ResolveSolution(puddle.Owner, puddle.Comp.SolutionName, ref puddle.Comp.Solution, out var puddleSolution))
{
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 = _solutionContainerSystem.SplitSolution(puddle.Comp.Solution.Value,
FixedPoint2.Min(FixedPoint2.New(amount), puddleSolution.Volume, drainSolution.AvailableVolume));
drainSolution.AddSolution(transferSolution, _prototypeManager);
if (puddleSolution.Volume <= 0)
{
QueueDel(puddle);
}
} }
} }

View File

@@ -27,8 +27,8 @@ public sealed partial class DrainComponent : Component
public float Accumulator = 0f; public float Accumulator = 0f;
/// <summary> /// <summary>
/// Does this drain automatically absorb surrouding puddles? Or is it a drain designed to empty /// If true, automatically transfers solutions from nearby puddles and drains them. True for floor drains;
/// solutions in it manually? /// false for things like toilets and sinks.
/// </summary> /// </summary>
[DataField] [DataField]
public bool AutoDrain = true; public bool AutoDrain = true;