From 89e853d8e253e4dc801c751f17ea0fddcc07c11d Mon Sep 17 00:00:00 2001 From: DrSmugleaf Date: Tue, 8 Dec 2020 12:54:34 +0100 Subject: [PATCH] Make disposal units also flush air (#2686) * Make disposal units also flush air * Make disposals use tile.AssumeAir instead of tile.Air.Merge Co-authored-by: Vera Aguilera Puerto <6766154+Zumorica@users.noreply.github.com> --- .../Disposal/DisposalEntryComponent.cs | 13 ++--- .../Disposal/DisposalHolderComponent.cs | 48 +++++++++++++------ .../Disposal/DisposalUnitComponent.cs | 30 +++++++++--- 3 files changed, 65 insertions(+), 26 deletions(-) diff --git a/Content.Server/GameObjects/Components/Disposal/DisposalEntryComponent.cs b/Content.Server/GameObjects/Components/Disposal/DisposalEntryComponent.cs index 4128234253..b8fe213197 100644 --- a/Content.Server/GameObjects/Components/Disposal/DisposalEntryComponent.cs +++ b/Content.Server/GameObjects/Components/Disposal/DisposalEntryComponent.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; using System.Linq; using Robust.Shared.GameObjects; -using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Random; using Robust.Shared.IoC; using Robust.Shared.Maths; @@ -20,16 +18,19 @@ namespace Content.Server.GameObjects.Components.Disposal public override string Name => "DisposalEntry"; - public bool TryInsert(IReadOnlyCollection entities) + public bool TryInsert(DisposalUnitComponent from) { var holder = Owner.EntityManager.SpawnEntity(HolderPrototypeId, Owner.Transform.MapPosition); var holderComponent = holder.GetComponent(); - foreach (var entity in entities) + foreach (var entity in from.ContainedEntities) { holderComponent.TryInsert(entity); } + holderComponent.Air.Merge(from.Air); + from.Air.Clear(); + return TryInsert(holderComponent); } @@ -57,10 +58,10 @@ namespace Content.Server.GameObjects.Components.Disposal { if (holder.PreviousTube != null && DirectionTo(holder.PreviousTube) == ConnectableDirections()[0]) { - var invalidDirections = new Direction[] { ConnectableDirections()[0], Direction.Invalid }; + var invalidDirections = new[] { ConnectableDirections()[0], Direction.Invalid }; var directions = Enum.GetValues(typeof(Direction)) .Cast().Except(invalidDirections).ToList(); - return _random.Pick(directions); + return _random.Pick(directions); } return ConnectableDirections()[0]; diff --git a/Content.Server/GameObjects/Components/Disposal/DisposalHolderComponent.cs b/Content.Server/GameObjects/Components/Disposal/DisposalHolderComponent.cs index 18525da18b..4adfffbfcc 100644 --- a/Content.Server/GameObjects/Components/Disposal/DisposalHolderComponent.cs +++ b/Content.Server/GameObjects/Components/Disposal/DisposalHolderComponent.cs @@ -1,7 +1,10 @@ #nullable enable using System.Collections.Generic; using System.Linq; +using Content.Server.Atmos; using Content.Server.GameObjects.Components.Items.Storage; +using Content.Server.Interfaces; +using Content.Shared.Atmos; using Content.Shared.GameObjects.Components.Body; using Robust.Server.GameObjects.Components.Container; using Robust.Shared.Containers; @@ -9,13 +12,14 @@ using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Maths; +using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; namespace Content.Server.GameObjects.Components.Disposal { // TODO: Add gas [RegisterComponent] - public class DisposalHolderComponent : Component + public class DisposalHolderComponent : Component, IGasMixtureHolder { public override string Name => "DisposalHolder"; @@ -49,6 +53,28 @@ namespace Content.Server.GameObjects.Components.Disposal [ViewVariables] public HashSet Tags { get; set; } = new(); + [ViewVariables] public GasMixture Air { get; set; } = default!; + + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + + serializer.DataField(this, x => x.Air, "air", new GasMixture(Atmospherics.CellVolume)); + } + + public override void Initialize() + { + base.Initialize(); + + _contents = ContainerManagerComponent.Ensure(nameof(DisposalHolderComponent), Owner); + } + + public override void OnRemove() + { + base.OnRemove(); + ExitDisposals(); + } + private bool CanInsert(IEntity entity) { if (!_contents.CanInsert(entity)) @@ -118,6 +144,13 @@ namespace Content.Server.GameObjects.Components.Disposal } } + if (Owner.Transform.Coordinates.TryGetTileAtmosphere(out var tileAtmos) && + tileAtmos.Air != null) + { + tileAtmos.AssumeAir(Air); + Air.Clear(); + } + Owner.Delete(); } @@ -159,18 +192,5 @@ namespace Content.Server.GameObjects.Components.Disposal } } } - - public override void OnRemove() - { - base.OnRemove(); - ExitDisposals(); - } - - public override void Initialize() - { - base.Initialize(); - - _contents = ContainerManagerComponent.Ensure(nameof(DisposalHolderComponent), Owner); - } } } diff --git a/Content.Server/GameObjects/Components/Disposal/DisposalUnitComponent.cs b/Content.Server/GameObjects/Components/Disposal/DisposalUnitComponent.cs index f22e01e374..a77aae196f 100644 --- a/Content.Server/GameObjects/Components/Disposal/DisposalUnitComponent.cs +++ b/Content.Server/GameObjects/Components/Disposal/DisposalUnitComponent.cs @@ -4,14 +4,16 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using Content.Server.Atmos; using Content.Server.GameObjects.Components.GUI; using Content.Server.GameObjects.Components.Items.Storage; -using Content.Server.GameObjects.Components.Mobs.State; using Content.Server.GameObjects.Components.Power.ApcNetComponents; -using Content.Server.GameObjects.Components.Projectiles; +using Content.Server.GameObjects.EntitySystems; using Content.Server.GameObjects.EntitySystems.DoAfter; +using Content.Server.Interfaces; using Content.Server.Interfaces.GameObjects.Components.Items; using Content.Server.Utility; +using Content.Shared.Atmos; using Content.Shared.GameObjects.Components.Body; using Content.Shared.GameObjects.Components.Damage; using Content.Shared.GameObjects.Components.Disposal; @@ -41,7 +43,6 @@ using Robust.Shared.Localization; using Robust.Shared.Log; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; -using Timer = Robust.Shared.Timers.Timer; namespace Content.Server.GameObjects.Components.Disposal { @@ -49,7 +50,7 @@ namespace Content.Server.GameObjects.Components.Disposal [ComponentReference(typeof(SharedDisposalUnitComponent))] [ComponentReference(typeof(IActivate))] [ComponentReference(typeof(IInteractUsing))] - public class DisposalUnitComponent : SharedDisposalUnitComponent, IInteractHand, IActivate, IInteractUsing, IDragDropOn, IThrowCollide + public class DisposalUnitComponent : SharedDisposalUnitComponent, IInteractHand, IActivate, IInteractUsing, IDragDropOn, IThrowCollide, IGasMixtureHolder { [Dependency] private readonly IGameTiming _gameTiming = default!; @@ -133,6 +134,8 @@ namespace Content.Server.GameObjects.Components.Disposal /// private (PressureState State, string Localized) _locState; + public GasMixture Air { get; set; } = default!; + public bool CanInsert(IEntity entity) { if (!Anchored) @@ -283,13 +286,27 @@ namespace Content.Server.GameObjects.Components.Disposal } var entryComponent = entry.GetComponent(); - var entities = _container.ContainedEntities.ToList(); foreach (var entity in _container.ContainedEntities.ToList()) { _container.Remove(entity); } - entryComponent.TryInsert(entities); + if (Owner.Transform.Coordinates.TryGetTileAtmosphere(out var tileAtmos) && + tileAtmos.Air != null && + tileAtmos.Air.Temperature > 0) + { + var tileAir = tileAtmos.Air; + var transferMoles = 0.1f * (0.05f * Atmospherics.OneAtmosphere * 1.01f - Air.Pressure) * Air.Volume / (tileAir.Temperature * Atmospherics.R); + + Air = tileAir.Remove(transferMoles); + + var atmosSystem = EntitySystem.Get(); + atmosSystem + .GetGridAtmosphere(Owner.Transform.GridID)? + .Invalidate(tileAtmos.GridIndices); + } + + entryComponent.TryInsert(this); _automaticEngageToken?.Cancel(); _automaticEngageToken = null; @@ -525,6 +542,7 @@ namespace Content.Server.GameObjects.Components.Disposal seconds => _flushDelay = TimeSpan.FromSeconds(seconds), () => (int) _flushDelay.TotalSeconds); + serializer.DataField(this, x => x.Air, "air", new GasMixture(Atmospherics.CellVolume)); serializer.DataField(ref _entryDelay, "entryDelay", 0.5f); }