Entity storage now holds air (#11355)

This commit is contained in:
Kara
2022-09-16 11:46:09 -07:00
committed by GitHub
parent edd41c04e0
commit 4e5def0d03
3 changed files with 112 additions and 7 deletions

View File

@@ -1,3 +1,4 @@
using Content.Server.Atmos;
using Content.Shared.Physics; using Content.Shared.Physics;
using Content.Shared.Whitelist; using Content.Shared.Whitelist;
using Robust.Shared.Audio; using Robust.Shared.Audio;
@@ -6,9 +7,10 @@ using Robust.Shared.Containers;
namespace Content.Server.Storage.Components; namespace Content.Server.Storage.Components;
[RegisterComponent] [RegisterComponent]
public sealed class EntityStorageComponent : Component public sealed class EntityStorageComponent : Component, IGasMixtureHolder
{ {
public readonly float MaxSize = 1.0f; // maximum width or height of an entity allowed inside the storage. public readonly float MaxSize = 1.0f; // maximum width or height of an entity allowed inside the storage.
public const float GasMixVolume = 70f;
public static readonly TimeSpan InternalOpenAttemptDelay = TimeSpan.FromSeconds(0.5); public static readonly TimeSpan InternalOpenAttemptDelay = TimeSpan.FromSeconds(0.5);
public TimeSpan LastInternalOpenAttempt; public TimeSpan LastInternalOpenAttempt;
@@ -77,6 +79,13 @@ public sealed class EntityStorageComponent : Component
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public bool IsWeldedShut; public bool IsWeldedShut;
/// <summary>
/// Gas currently contained in this entity storage.
/// None while open. Grabs gas from the atmosphere when closed, and exposes any entities inside to it.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public GasMixture Air { get; set; } = new (GasMixVolume);
} }
public sealed class InsertIntoEntityStorageAttemptEvent : CancellableEntityEventArgs { } public sealed class InsertIntoEntityStorageAttemptEvent : CancellableEntityEventArgs { }

View File

@@ -0,0 +1,10 @@
namespace Content.Server.Storage.Components;
/// <summary>
/// Added to entities contained within entity storage, for directed event purposes.
/// </summary>
[RegisterComponent]
public sealed class InsideEntityStorageComponent : Component
{
public EntityUid Storage;
}

View File

@@ -1,4 +1,5 @@
using System.Linq; using System.Linq;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Construction; using Content.Server.Construction;
using Content.Server.Construction.Components; using Content.Server.Construction.Components;
using Content.Server.Popups; using Content.Server.Popups;
@@ -29,6 +30,8 @@ public sealed class EntityStorageSystem : EntitySystem
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
[Dependency] private readonly PlaceableSurfaceSystem _placeableSurface = default!; [Dependency] private readonly PlaceableSurfaceSystem _placeableSurface = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly AtmosphereSystem _atmos = default!;
[Dependency] private readonly IMapManager _map = default!;
public const string ContainerName = "entity_storage"; public const string ContainerName = "entity_storage";
@@ -41,6 +44,10 @@ public sealed class EntityStorageSystem : EntitySystem
SubscribeLocalEvent<EntityStorageComponent, WeldableAttemptEvent>(OnWeldableAttempt); SubscribeLocalEvent<EntityStorageComponent, WeldableAttemptEvent>(OnWeldableAttempt);
SubscribeLocalEvent<EntityStorageComponent, WeldableChangedEvent>(OnWelded); SubscribeLocalEvent<EntityStorageComponent, WeldableChangedEvent>(OnWelded);
SubscribeLocalEvent<EntityStorageComponent, DestructionEventArgs>(OnDestroy); SubscribeLocalEvent<EntityStorageComponent, DestructionEventArgs>(OnDestroy);
SubscribeLocalEvent<InsideEntityStorageComponent, InhaleLocationEvent>(OnInsideInhale);
SubscribeLocalEvent<InsideEntityStorageComponent, ExhaleLocationEvent>(OnInsideExhale);
SubscribeLocalEvent<InsideEntityStorageComponent, AtmosExposedGetAirEvent>(OnInsideExposed);
} }
private void OnInit(EntityUid uid, EntityStorageComponent component, ComponentInit args) private void OnInit(EntityUid uid, EntityStorageComponent component, ComponentInit args)
@@ -54,6 +61,13 @@ public sealed class EntityStorageSystem : EntitySystem
if (TryComp<PlaceableSurfaceComponent>(uid, out var placeable)) if (TryComp<PlaceableSurfaceComponent>(uid, out var placeable))
_placeableSurface.SetPlaceable(uid, component.Open, placeable); _placeableSurface.SetPlaceable(uid, component.Open, placeable);
if (!component.Open)
{
// If we're closed on spawn, we need to pull some air into our environment from where we spawned,
// so that we have -something-. For example, if you bought an animal crate or something.
TakeGas(uid, component);
}
} }
private void OnInteract(EntityUid uid, EntityStorageComponent component, ActivateInWorldEvent args) private void OnInteract(EntityUid uid, EntityStorageComponent component, ActivateInWorldEvent args)
@@ -117,13 +131,14 @@ public sealed class EntityStorageSystem : EntitySystem
var containedArr = component.Contents.ContainedEntities.ToArray(); var containedArr = component.Contents.ContainedEntities.ToArray();
foreach (var contained in containedArr) foreach (var contained in containedArr)
{ {
if (component.Contents.Remove(contained)) if (!component.Contents.Remove(contained))
{ continue;
RemComp<InsideEntityStorageComponent>(contained);
Transform(contained).WorldPosition = Transform(contained).WorldPosition =
uidXform.WorldPosition + uidXform.WorldRotation.RotateVec(component.EnteringOffset); uidXform.WorldPosition + uidXform.WorldRotation.RotateVec(component.EnteringOffset);
} }
} }
}
public void OpenStorage(EntityUid uid, EntityStorageComponent? component = null) public void OpenStorage(EntityUid uid, EntityStorageComponent? component = null)
{ {
@@ -134,6 +149,7 @@ public sealed class EntityStorageSystem : EntitySystem
EmptyContents(uid, component); EmptyContents(uid, component);
ModifyComponents(uid, component); ModifyComponents(uid, component);
SoundSystem.Play(component.OpenSound.GetSound(), Filter.Pvs(component.Owner), component.Owner); SoundSystem.Play(component.OpenSound.GetSound(), Filter.Pvs(component.Owner), component.Owner);
ReleaseGas(uid, component);
RaiseLocalEvent(uid, new StorageAfterOpenEvent()); RaiseLocalEvent(uid, new StorageAfterOpenEvent());
} }
@@ -161,11 +177,15 @@ public sealed class EntityStorageSystem : EntitySystem
if (!AddToContents(entity, uid, component)) if (!AddToContents(entity, uid, component))
continue; continue;
var inside = EnsureComp<InsideEntityStorageComponent>(entity);
inside.Storage = uid;
count++; count++;
if (count >= component.Capacity) if (count >= component.Capacity)
break; break;
} }
TakeGas(uid, component);
ModifyComponents(uid, component); ModifyComponents(uid, component);
SoundSystem.Play(component.CloseSound.GetSound(), Filter.Pvs(uid), uid); SoundSystem.Play(component.CloseSound.GetSound(), Filter.Pvs(uid), uid);
component.LastInternalOpenAttempt = default; component.LastInternalOpenAttempt = default;
@@ -365,4 +385,70 @@ public sealed class EntityStorageSystem : EntitySystem
appearance.SetData(StorageVisuals.HasContents, component.Contents.ContainedEntities.Any()); appearance.SetData(StorageVisuals.HasContents, component.Contents.ContainedEntities.Any());
} }
} }
private void TakeGas(EntityUid uid, EntityStorageComponent component)
{
var tile = GetOffsetTileRef(uid, component);
if (tile != null && _atmos.GetTileMixture(tile.Value.GridUid, null, tile.Value.GridIndices, true) is {} environment)
{
_atmos.Merge(component.Air, environment.RemoveVolume(EntityStorageComponent.GasMixVolume));
}
}
private void ReleaseGas(EntityUid uid, EntityStorageComponent component)
{
var tile = GetOffsetTileRef(uid, component);
if (tile != null && _atmos.GetTileMixture(tile.Value.GridUid, null, tile.Value.GridIndices, true) is {} environment)
{
_atmos.Merge(environment, component.Air);
component.Air.Clear();
}
}
private TileRef? GetOffsetTileRef(EntityUid uid, EntityStorageComponent component)
{
var targetCoordinates = new EntityCoordinates(uid, component.EnteringOffset).ToMap(EntityManager);
if (_map.TryFindGridAt(targetCoordinates, out var grid))
{
return grid.GetTileRef(targetCoordinates);
}
return null;
}
#region Gas mix event handlers
private void OnInsideInhale(EntityUid uid, InsideEntityStorageComponent component, InhaleLocationEvent args)
{
if (TryComp<EntityStorageComponent>(component.Storage, out var storage))
{
args.Gas = storage.Air;
}
}
private void OnInsideExhale(EntityUid uid, InsideEntityStorageComponent component, ExhaleLocationEvent args)
{
if (TryComp<EntityStorageComponent>(component.Storage, out var storage))
{
args.Gas = storage.Air;
}
}
private void OnInsideExposed(EntityUid uid, InsideEntityStorageComponent component, ref AtmosExposedGetAirEvent args)
{
if (args.Handled)
return;
if (TryComp<EntityStorageComponent>(component.Storage, out var storage))
{
args.Gas = storage.Air;
}
args.Handled = true;
}
#endregion
} }