AtmosDevices can optionally process in space. (#4405)
Refactors some misc atmos things, too.
This commit is contained in:
committed by
GitHub
parent
e42acf2401
commit
009087863f
@@ -47,7 +47,7 @@ namespace Content.Server.Atmos.Commands
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grid.HasComponent<IGridAtmosphereComponent>())
|
if (grid.HasComponent<IAtmosphereComponent>())
|
||||||
{
|
{
|
||||||
shell.WriteLine("Grid already has an atmosphere.");
|
shell.WriteLine("Grid already has an atmosphere.");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace Content.Server.Atmos.Commands
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grid.HasComponent<IGridAtmosphereComponent>())
|
if (grid.HasComponent<IAtmosphereComponent>())
|
||||||
{
|
{
|
||||||
shell.WriteLine("Grid already has an atmosphere.");
|
shell.WriteLine("Grid already has an atmosphere.");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ namespace Content.Server.Atmos.Components
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is our SSAir equivalent.
|
/// This is our SSAir equivalent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ComponentReference(typeof(IGridAtmosphereComponent))]
|
[ComponentReference(typeof(IAtmosphereComponent))]
|
||||||
[RegisterComponent, Serializable]
|
[RegisterComponent, Serializable]
|
||||||
public class GridAtmosphereComponent : Component, IGridAtmosphereComponent, ISerializationHooks
|
public class GridAtmosphereComponent : Component, IAtmosphereComponent, ISerializationHooks
|
||||||
{
|
{
|
||||||
public override string Name => "GridAtmosphere";
|
public override string Name => "GridAtmosphere";
|
||||||
public virtual bool Simulated => true;
|
public virtual bool Simulated => true;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Content.Server.Atmos.Components
|
namespace Content.Server.Atmos.Components
|
||||||
{
|
{
|
||||||
public interface IGridAtmosphereComponent : IComponent
|
public interface IAtmosphereComponent : IComponent
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this atmosphere is simulated or not.
|
/// Whether this atmosphere is simulated or not.
|
||||||
13
Content.Server/Atmos/Components/SpaceAtmosphereComponent.cs
Normal file
13
Content.Server/Atmos/Components/SpaceAtmosphereComponent.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Server.Atmos.Components
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
[ComponentReference(typeof(IAtmosphereComponent))]
|
||||||
|
public class SpaceAtmosphereComponent : Component, IAtmosphereComponent
|
||||||
|
{
|
||||||
|
public override string Name => "SpaceAtmosphere";
|
||||||
|
|
||||||
|
public bool Simulated => false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Content.Shared.Atmos;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
|
|
||||||
namespace Content.Server.Atmos.Components
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
[ComponentReference(typeof(IGridAtmosphereComponent))]
|
|
||||||
public class SpaceGridAtmosphereComponent : UnsimulatedGridAtmosphereComponent
|
|
||||||
{
|
|
||||||
public override string Name => "SpaceGridAtmosphere";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,10 +8,9 @@ using Robust.Shared.Maths;
|
|||||||
namespace Content.Server.Atmos.Components
|
namespace Content.Server.Atmos.Components
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[ComponentReference(typeof(IGridAtmosphereComponent))]
|
[ComponentReference(typeof(IAtmosphereComponent))]
|
||||||
[ComponentReference(typeof(GridAtmosphereComponent))]
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class UnsimulatedGridAtmosphereComponent : GridAtmosphereComponent, IGridAtmosphereComponent
|
public class UnsimulatedGridAtmosphereComponent : GridAtmosphereComponent
|
||||||
{
|
{
|
||||||
public override string Name => "UnsimulatedGridAtmosphere";
|
public override string Name => "UnsimulatedGridAtmosphere";
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,10 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
/// <returns>All tile mixtures in a grid.</returns>
|
/// <returns>All tile mixtures in a grid.</returns>
|
||||||
public IEnumerable<GasMixture> GetAllTileMixtures(GridId grid, bool invalidate = false)
|
public IEnumerable<GasMixture> GetAllTileMixtures(GridId grid, bool invalidate = false)
|
||||||
{
|
{
|
||||||
|
// Return an array with a single space gas mixture for invalid grids.
|
||||||
|
if (!grid.IsValid())
|
||||||
|
return new []{ GasMixture.SpaceGas };
|
||||||
|
|
||||||
if (!_mapManager.TryGetGrid(grid, out var mapGrid))
|
if (!_mapManager.TryGetGrid(grid, out var mapGrid))
|
||||||
return Enumerable.Empty<GasMixture>();
|
return Enumerable.Empty<GasMixture>();
|
||||||
|
|
||||||
@@ -678,6 +682,10 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
/// <returns>The tile mixture, or null</returns>
|
/// <returns>The tile mixture, or null</returns>
|
||||||
public GasMixture? GetTileMixture(GridId grid, Vector2i tile, bool invalidate = false)
|
public GasMixture? GetTileMixture(GridId grid, Vector2i tile, bool invalidate = false)
|
||||||
{
|
{
|
||||||
|
// Always return space gas mixtures for invalid grids (grid 0)
|
||||||
|
if (!grid.IsValid())
|
||||||
|
return GasMixture.SpaceGas;
|
||||||
|
|
||||||
if (!_mapManager.TryGetGrid(grid, out var mapGrid))
|
if (!_mapManager.TryGetGrid(grid, out var mapGrid))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -686,7 +694,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
return GetTileMixture(gridAtmosphere, tile, invalidate);
|
return GetTileMixture(gridAtmosphere, tile, invalidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ComponentManager.TryGetComponent(mapGrid.GridEntityId, out SpaceGridAtmosphereComponent? spaceAtmosphere))
|
if (ComponentManager.TryGetComponent(mapGrid.GridEntityId, out SpaceAtmosphereComponent? _))
|
||||||
{
|
{
|
||||||
// Always return a new space gas mixture in this case.
|
// Always return a new space gas mixture in this case.
|
||||||
return GasMixture.SpaceGas;
|
return GasMixture.SpaceGas;
|
||||||
@@ -967,6 +975,10 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
/// <returns>All adjacent tile gas mixtures to the tile in question</returns>
|
/// <returns>All adjacent tile gas mixtures to the tile in question</returns>
|
||||||
public IEnumerable<GasMixture> GetAdjacentTileMixtures(GridId grid, Vector2i tile, bool includeBlocked = false, bool invalidate = false)
|
public IEnumerable<GasMixture> GetAdjacentTileMixtures(GridId grid, Vector2i tile, bool includeBlocked = false, bool invalidate = false)
|
||||||
{
|
{
|
||||||
|
// For invalid grids, return an array with a single space gas mixture in it.
|
||||||
|
if (!grid.IsValid())
|
||||||
|
return new []{ GasMixture.SpaceGas };
|
||||||
|
|
||||||
if (!_mapManager.TryGetGrid(grid, out var mapGrid))
|
if (!_mapManager.TryGetGrid(grid, out var mapGrid))
|
||||||
return Enumerable.Empty<GasMixture>();
|
return Enumerable.Empty<GasMixture>();
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
|
||||||
|
private readonly AtmosDeviceUpdateEvent _updateEvent = new();
|
||||||
private readonly Stopwatch _simulationStopwatch = new();
|
private readonly Stopwatch _simulationStopwatch = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -204,11 +205,10 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
atmosphere.CurrentRunAtmosDevices = new Queue<AtmosDeviceComponent>(atmosphere.AtmosDevices);
|
atmosphere.CurrentRunAtmosDevices = new Queue<AtmosDeviceComponent>(atmosphere.AtmosDevices);
|
||||||
|
|
||||||
var time = _gameTiming.CurTime;
|
var time = _gameTiming.CurTime;
|
||||||
var updateEvent = new AtmosDeviceUpdateEvent();
|
|
||||||
var number = 0;
|
var number = 0;
|
||||||
while (atmosphere.CurrentRunAtmosDevices.TryDequeue(out var device))
|
while (atmosphere.CurrentRunAtmosDevices.TryDequeue(out var device))
|
||||||
{
|
{
|
||||||
EntityManager.EventBus.RaiseLocalEvent(device.Owner.Uid, updateEvent, false);
|
RaiseLocalEvent(device.Owner.Uid, _updateEvent, false);
|
||||||
device.LastProcess = time;
|
device.LastProcess = time;
|
||||||
|
|
||||||
if (number++ < LagCheckIterations) continue;
|
if (number++ < LagCheckIterations) continue;
|
||||||
@@ -241,7 +241,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
var atmosphere = _currentRunAtmosphere[_currentRunAtmosphereIndex];
|
var atmosphere = _currentRunAtmosphere[_currentRunAtmosphereIndex];
|
||||||
|
|
||||||
if (atmosphere.Paused || atmosphere.LifeStage >= ComponentLifeStage.Stopping)
|
if (atmosphere.Paused || !atmosphere.Simulated || atmosphere.LifeStage >= ComponentLifeStage.Stopping)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
atmosphere.Timer += frameTime;
|
atmosphere.Timer += frameTime;
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
// Map events.
|
// Map events.
|
||||||
_mapManager.MapCreated += OnMapCreated;
|
|
||||||
_mapManager.TileChanged += OnTileChanged;
|
_mapManager.TileChanged += OnTileChanged;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -39,7 +38,6 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
base.Shutdown();
|
base.Shutdown();
|
||||||
|
|
||||||
_mapManager.MapCreated -= OnMapCreated;
|
|
||||||
_mapManager.TileChanged -= OnTileChanged;
|
_mapManager.TileChanged -= OnTileChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,17 +55,6 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
InvalidateTile(eventArgs.NewTile.GridIndex, eventArgs.NewTile.GridIndices);
|
InvalidateTile(eventArgs.NewTile.GridIndex, eventArgs.NewTile.GridIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMapCreated(object? sender, MapEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.Map == MapId.Nullspace)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var map = _mapManager.GetMapEntity(e.Map);
|
|
||||||
|
|
||||||
if (!map.HasComponent<IGridAtmosphereComponent>())
|
|
||||||
map.AddComponent<SpaceGridAtmosphereComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
{
|
{
|
||||||
base.Update(frameTime);
|
base.Update(frameTime);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using Robust.Shared.ViewVariables;
|
|||||||
namespace Content.Server.Atmos.Piping.Components
|
namespace Content.Server.Atmos.Piping.Components
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds itself to a <see cref="IGridAtmosphereComponent"/> to be updated by.
|
/// Adds itself to a <see cref="IAtmosphereComponent"/> to be updated by.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class AtmosDeviceComponent : Component
|
public class AtmosDeviceComponent : Component
|
||||||
@@ -22,6 +22,19 @@ namespace Content.Server.Atmos.Piping.Components
|
|||||||
[DataField("requireAnchored")]
|
[DataField("requireAnchored")]
|
||||||
public bool RequireAnchored { get; private set; } = true;
|
public bool RequireAnchored { get; private set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this device will join an entity system to process when not in a grid.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
[DataField("joinSystem")]
|
||||||
|
public bool JoinSystem { get; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether we have joined an entity system to process.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public bool JoinedSystem { get; set; } = false;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public TimeSpan LastProcess { get; set; } = TimeSpan.Zero;
|
public TimeSpan LastProcess { get; set; } = TimeSpan.Zero;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Content.Server.Atmos.EntitySystems;
|
using Content.Server.Atmos.EntitySystems;
|
||||||
using Content.Server.Atmos.Piping.Components;
|
using Content.Server.Atmos.Piping.Components;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Physics;
|
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
namespace Content.Server.Atmos.Piping.EntitySystems
|
namespace Content.Server.Atmos.Piping.EntitySystems
|
||||||
@@ -12,9 +12,14 @@ namespace Content.Server.Atmos.Piping.EntitySystems
|
|||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public class AtmosDeviceSystem : EntitySystem
|
public class AtmosDeviceSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
||||||
|
|
||||||
|
private readonly AtmosDeviceUpdateEvent _updateEvent = new();
|
||||||
|
|
||||||
|
private float _timer = 0f;
|
||||||
|
private readonly HashSet<AtmosDeviceComponent> _joinedDevices = new();
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
@@ -33,11 +38,24 @@ namespace Content.Server.Atmos.Piping.EntitySystems
|
|||||||
public void JoinAtmosphere(AtmosDeviceComponent component)
|
public void JoinAtmosphere(AtmosDeviceComponent component)
|
||||||
{
|
{
|
||||||
if (!CanJoinAtmosphere(component))
|
if (!CanJoinAtmosphere(component))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// We try to add the device to a valid atmosphere.
|
// We try to add the device to a valid atmosphere, and if we can't, try to add it to the entity system.
|
||||||
if (!_atmosphereSystem.AddAtmosDevice(component))
|
if (!_atmosphereSystem.AddAtmosDevice(component))
|
||||||
|
{
|
||||||
|
if (component.JoinSystem)
|
||||||
|
{
|
||||||
|
_joinedDevices.Add(component);
|
||||||
|
component.JoinedSystem = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
component.LastProcess = _gameTiming.CurTime;
|
component.LastProcess = _gameTiming.CurTime;
|
||||||
|
|
||||||
@@ -46,8 +64,19 @@ namespace Content.Server.Atmos.Piping.EntitySystems
|
|||||||
|
|
||||||
public void LeaveAtmosphere(AtmosDeviceComponent component)
|
public void LeaveAtmosphere(AtmosDeviceComponent component)
|
||||||
{
|
{
|
||||||
if (!_atmosphereSystem.RemoveAtmosDevice(component))
|
// Try to remove the component from an atmosphere, and if not
|
||||||
|
if (component.JoinedGrid != null && !_atmosphereSystem.RemoveAtmosDevice(component))
|
||||||
|
{
|
||||||
|
// The grid might have been removed but not us... This usually shouldn't happen.
|
||||||
|
component.JoinedGrid = null;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.JoinedSystem)
|
||||||
|
{
|
||||||
|
_joinedDevices.Remove(component);
|
||||||
|
component.JoinedSystem = false;
|
||||||
|
}
|
||||||
|
|
||||||
component.LastProcess = TimeSpan.Zero;
|
component.LastProcess = TimeSpan.Zero;
|
||||||
RaiseLocalEvent(component.Owner.Uid, new AtmosDeviceDisabledEvent(), false);
|
RaiseLocalEvent(component.Owner.Uid, new AtmosDeviceDisabledEvent(), false);
|
||||||
@@ -85,5 +114,22 @@ namespace Content.Server.Atmos.Piping.EntitySystems
|
|||||||
{
|
{
|
||||||
RejoinAtmosphere(component);
|
RejoinAtmosphere(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
_timer += frameTime;
|
||||||
|
|
||||||
|
if (_timer < _atmosphereSystem.AtmosTime)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_timer -= _atmosphereSystem.AtmosTime;
|
||||||
|
|
||||||
|
var time = _gameTiming.CurTime;
|
||||||
|
foreach (var device in _joinedDevices)
|
||||||
|
{
|
||||||
|
RaiseLocalEvent(device.Owner.Uid, _updateEvent, false);
|
||||||
|
device.LastProcess = time;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
- type: entity
|
|
||||||
abstract: true
|
|
||||||
id: GasCanister
|
|
||||||
name: gas canister
|
|
||||||
description: A canister that can contain any type of gas. It can be attached to connector ports using a wrench.
|
|
||||||
parent: BaseStructureDynamic
|
|
||||||
components:
|
|
||||||
- type: InteractionOutline
|
|
||||||
- type: Sprite
|
|
||||||
netsync: false
|
|
||||||
sprite: Structures/Storage/canister.rsi
|
|
||||||
state: grey
|
|
||||||
- type: Appearance
|
|
||||||
visuals:
|
|
||||||
- type: GasPortableVisualizer
|
|
||||||
stateConnected: can-connector
|
|
||||||
- type: GasCanisterVisualizer
|
|
||||||
insertedTankState: can-open
|
|
||||||
pressureStates:
|
|
||||||
- can-o0
|
|
||||||
- can-o1
|
|
||||||
- can-o2
|
|
||||||
- can-o3
|
|
||||||
- type: UserInterface
|
|
||||||
interfaces:
|
|
||||||
- key: enum.GasCanisterUiKey.Key
|
|
||||||
type: GasCanisterBoundUserInterface
|
|
||||||
- type: Destructible
|
|
||||||
thresholds:
|
|
||||||
- trigger:
|
|
||||||
!type:DamageTrigger
|
|
||||||
damage: 300
|
|
||||||
behaviors:
|
|
||||||
- !type:PlaySoundBehavior
|
|
||||||
sound: /Audio/Effects/metalbreak.ogg
|
|
||||||
- !type:SpawnEntitiesBehavior
|
|
||||||
spawn:
|
|
||||||
GasCanisterBrokenBase:
|
|
||||||
min: 1
|
|
||||||
max: 1
|
|
||||||
- !type:DoActsBehavior
|
|
||||||
acts: [ "Destruction" ]
|
|
||||||
- type: Damageable
|
|
||||||
resistances: metallicResistances
|
|
||||||
- type: Physics
|
|
||||||
bodyType: Dynamic
|
|
||||||
fixtures:
|
|
||||||
- shape:
|
|
||||||
!type:PhysShapeAabb
|
|
||||||
bounds: "-0.25,-0.25,0.25,0.25"
|
|
||||||
mass: 25
|
|
||||||
mask:
|
|
||||||
- MobImpassable
|
|
||||||
layer:
|
|
||||||
- Opaque
|
|
||||||
- MobImpassable
|
|
||||||
- SmallImpassable
|
|
||||||
- VaultImpassable
|
|
||||||
- type: AtmosDevice
|
|
||||||
requireAnchored: false
|
|
||||||
- type: ContainerContainer
|
|
||||||
containers:
|
|
||||||
GasCanisterTankHolder: !type:ContainerSlot {}
|
|
||||||
- type: NodeContainer
|
|
||||||
nodes:
|
|
||||||
port:
|
|
||||||
!type:PortablePipeNode
|
|
||||||
nodeGroupID: Pipe
|
|
||||||
rotationsEnabled: false
|
|
||||||
volume: 1
|
|
||||||
- type: GasPortable
|
|
||||||
- type: GasCanister
|
|
||||||
@@ -1,3 +1,77 @@
|
|||||||
|
- type: entity
|
||||||
|
abstract: true
|
||||||
|
id: GasCanister
|
||||||
|
name: gas canister
|
||||||
|
description: A canister that can contain any type of gas. It can be attached to connector ports using a wrench.
|
||||||
|
parent: BaseStructureDynamic
|
||||||
|
components:
|
||||||
|
- type: InteractionOutline
|
||||||
|
- type: Sprite
|
||||||
|
netsync: false
|
||||||
|
sprite: Structures/Storage/canister.rsi
|
||||||
|
state: grey
|
||||||
|
- type: Appearance
|
||||||
|
visuals:
|
||||||
|
- type: GasPortableVisualizer
|
||||||
|
stateConnected: can-connector
|
||||||
|
- type: GasCanisterVisualizer
|
||||||
|
insertedTankState: can-open
|
||||||
|
pressureStates:
|
||||||
|
- can-o0
|
||||||
|
- can-o1
|
||||||
|
- can-o2
|
||||||
|
- can-o3
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
- key: enum.GasCanisterUiKey.Key
|
||||||
|
type: GasCanisterBoundUserInterface
|
||||||
|
- type: Destructible
|
||||||
|
thresholds:
|
||||||
|
- trigger:
|
||||||
|
!type:DamageTrigger
|
||||||
|
damage: 300
|
||||||
|
behaviors:
|
||||||
|
- !type:PlaySoundBehavior
|
||||||
|
sound: /Audio/Effects/metalbreak.ogg
|
||||||
|
- !type:SpawnEntitiesBehavior
|
||||||
|
spawn:
|
||||||
|
GasCanisterBrokenBase:
|
||||||
|
min: 1
|
||||||
|
max: 1
|
||||||
|
- !type:DoActsBehavior
|
||||||
|
acts: [ "Destruction" ]
|
||||||
|
- type: Damageable
|
||||||
|
resistances: metallicResistances
|
||||||
|
- type: Physics
|
||||||
|
bodyType: Dynamic
|
||||||
|
fixtures:
|
||||||
|
- shape:
|
||||||
|
!type:PhysShapeAabb
|
||||||
|
bounds: "-0.25,-0.25,0.25,0.25"
|
||||||
|
mass: 25
|
||||||
|
mask:
|
||||||
|
- MobImpassable
|
||||||
|
layer:
|
||||||
|
- Opaque
|
||||||
|
- MobImpassable
|
||||||
|
- SmallImpassable
|
||||||
|
- VaultImpassable
|
||||||
|
- type: AtmosDevice
|
||||||
|
requireAnchored: false
|
||||||
|
joinSystem: true
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
GasCanisterTankHolder: !type:ContainerSlot {}
|
||||||
|
- type: NodeContainer
|
||||||
|
nodes:
|
||||||
|
port:
|
||||||
|
!type:PortablePipeNode
|
||||||
|
nodeGroupID: Pipe
|
||||||
|
rotationsEnabled: false
|
||||||
|
volume: 1
|
||||||
|
- type: GasPortable
|
||||||
|
- type: GasCanister
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: GasCanister
|
parent: GasCanister
|
||||||
id: StorageCanister
|
id: StorageCanister
|
||||||
|
|||||||
Reference in New Issue
Block a user