Skip to content

Commit

Permalink
Fix sinks and toilets not draining (space-wizards#33691)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Partmedia authored Dec 4, 2024
1 parent 8718263 commit cf202e8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 35 deletions.
62 changes: 29 additions & 33 deletions Content.Server/Fluids/EntitySystems/DrainSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,6 @@ public override void Update(float frameTime)
}
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))
continue;

Expand All @@ -160,41 +153,44 @@ public override void Update(float frameTime)
// This will ensure that UnitsPerSecond is per second...
var amount = drain.UnitsPerSecond * drain.DrainFrequency;

_puddles.Clear();
_lookup.GetEntitiesInRange(Transform(uid).Coordinates, drain.Range, _puddles);

if (_puddles.Count == 0)
if (drain.AutoDrain)
{
_ambientSoundSystem.SetAmbience(uid, false);
continue;
}
_puddles.Clear();
_lookup.GetEntitiesInRange(Transform(uid).Coordinates, drain.Range, _puddles);

_ambientSoundSystem.SetAmbience(uid, true);

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))
if (_puddles.Count == 0)
{
EntityManager.QueueDeleteEntity(puddle);
_ambientSoundSystem.SetAmbience(uid, false);
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));
_ambientSoundSystem.SetAmbience(uid, true);

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);
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions Content.Shared/Fluids/Components/DrainComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public sealed partial class DrainComponent : Component
public float Accumulator = 0f;

/// <summary>
/// Does this drain automatically absorb surrouding puddles? Or is it a drain designed to empty
/// solutions in it manually?
/// If true, automatically transfers solutions from nearby puddles and drains them. True for floor drains;
/// false for things like toilets and sinks.
/// </summary>
[DataField]
public bool AutoDrain = true;
Expand Down

0 comments on commit cf202e8

Please sign in to comment.