Move board spawning out of DoorSystem (#11772)
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using Content.Server.Construction.Components;
|
using Content.Server.Construction.Components;
|
||||||
|
using Content.Server.Containers;
|
||||||
using Content.Shared.Construction;
|
using Content.Shared.Construction;
|
||||||
using Content.Shared.Construction.Prototypes;
|
using Content.Shared.Construction.Prototypes;
|
||||||
using Content.Shared.Construction.Steps;
|
using Content.Shared.Construction.Steps;
|
||||||
@@ -281,20 +282,33 @@ namespace Content.Server.Construction
|
|||||||
Resolve(uid, ref containerManager, false);
|
Resolve(uid, ref containerManager, false);
|
||||||
|
|
||||||
// We create the new entity.
|
// We create the new entity.
|
||||||
var newUid = EntityManager.SpawnEntity(newEntity, transform.Coordinates);
|
var newUid = EntityManager.CreateEntityUninitialized(newEntity, transform.Coordinates);
|
||||||
|
|
||||||
// Construction transferring.
|
// Construction transferring.
|
||||||
var newConstruction = EntityManager.EnsureComponent<ConstructionComponent>(newUid);
|
var newConstruction = EntityManager.EnsureComponent<ConstructionComponent>(newUid);
|
||||||
|
|
||||||
// We set the graph and node accordingly... Then we append our containers to theirs.
|
// Transfer all construction-owned containers.
|
||||||
|
newConstruction.Containers.UnionWith(construction.Containers);
|
||||||
|
|
||||||
|
// Prevent MapInitEvent spawned entities from spawning into the containers.
|
||||||
|
// Containers created by ChangeNode() actions do not exist until after this function is complete,
|
||||||
|
// but this should be fine, as long as the target entity properly declared its managed containers.
|
||||||
|
if (TryComp(newUid, out ContainerFillComponent? containerFill) && containerFill.IgnoreConstructionSpawn)
|
||||||
|
{
|
||||||
|
foreach (var id in newConstruction.Containers)
|
||||||
|
{
|
||||||
|
containerFill.Containers.Remove(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityManager.InitializeAndStartEntity(newUid);
|
||||||
|
|
||||||
|
// We set the graph and node accordingly.
|
||||||
ChangeGraph(newUid, userUid, construction.Graph, construction.Node, false, newConstruction);
|
ChangeGraph(newUid, userUid, construction.Graph, construction.Node, false, newConstruction);
|
||||||
|
|
||||||
if (construction.TargetNode is {} targetNode)
|
if (construction.TargetNode is {} targetNode)
|
||||||
SetPathfindingTarget(newUid, targetNode, newConstruction);
|
SetPathfindingTarget(newUid, targetNode, newConstruction);
|
||||||
|
|
||||||
// Transfer all construction-owned containers.
|
|
||||||
newConstruction.Containers.UnionWith(construction.Containers);
|
|
||||||
|
|
||||||
// Transfer all pending interaction events too.
|
// Transfer all pending interaction events too.
|
||||||
while (construction.InteractionQueue.TryDequeue(out var ev))
|
while (construction.InteractionQueue.TryDequeue(out var ev))
|
||||||
{
|
{
|
||||||
|
|||||||
95
Content.Server/Containers/ContainerFillComponent.cs
Normal file
95
Content.Server/Containers/ContainerFillComponent.cs
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
using Content.Server.Storage.Components;
|
||||||
|
using Content.Shared.Storage;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Serialization.Manager;
|
||||||
|
using Robust.Shared.Serialization.Markdown;
|
||||||
|
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||||
|
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||||
|
using Robust.Shared.Serialization.Markdown.Validation;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||||
|
|
||||||
|
namespace Content.Server.Containers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Component for spawning entity prototypes into containers on map init.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Unlike <see cref="StorageFillComponent"/> this is deterministic and supports arbitrary containers. While this
|
||||||
|
/// could maybe be merged with that component, it would require significant changes to <see
|
||||||
|
/// cref="EntitySpawnCollection.GetSpawns"/>, which is also used by several other systems.
|
||||||
|
/// </remarks>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class ContainerFillComponent : Component
|
||||||
|
{
|
||||||
|
[DataField("containers", customTypeSerializer:typeof(ContainerFillSerializer))]
|
||||||
|
public readonly Dictionary<string, List<string>> Containers = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, entities spawned via the construction system will not have entities spawned into containers managed
|
||||||
|
/// by the construction system.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("ignoreConstructionSpawn")]
|
||||||
|
public bool IgnoreConstructionSpawn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all of this exists just to validate prototype ids.
|
||||||
|
// it would be nice if you could specify only a type validator and not have to re-implement everything else.
|
||||||
|
// or a dictionary serializer that accepts a custom type serializer for the dictionary values
|
||||||
|
public sealed class ContainerFillSerializer : ITypeSerializer<Dictionary<string, List<string>>, MappingDataNode>
|
||||||
|
{
|
||||||
|
private static PrototypeIdListSerializer<EntityPrototype> ListSerializer => new();
|
||||||
|
|
||||||
|
public ValidationNode Validate(
|
||||||
|
ISerializationManager serializationManager,
|
||||||
|
MappingDataNode node,
|
||||||
|
IDependencyCollection dependencies,
|
||||||
|
ISerializationContext? context = null)
|
||||||
|
{
|
||||||
|
var mapping = new Dictionary<ValidationNode, ValidationNode>();
|
||||||
|
|
||||||
|
foreach (var (key, val) in node.Children)
|
||||||
|
{
|
||||||
|
var keyVal = serializationManager.ValidateNode<string>(key, context);
|
||||||
|
|
||||||
|
var listVal = (val is SequenceDataNode seq)
|
||||||
|
? ListSerializer.Validate(serializationManager, seq, dependencies, context)
|
||||||
|
: new ErrorNode(val, "ContainerFillComponent prototypes must be a sequence/list");
|
||||||
|
|
||||||
|
mapping.Add(keyVal, listVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ValidatedMappingNode(mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, List<string>> Copy(
|
||||||
|
ISerializationManager serializationManager,
|
||||||
|
Dictionary<string, List<string>> source,
|
||||||
|
Dictionary<string, List<string>> target,
|
||||||
|
bool skipHook,
|
||||||
|
ISerializationContext? context = null)
|
||||||
|
{
|
||||||
|
serializationManager.Copy(source, ref target, context, skipHook);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, List<string>> Read(
|
||||||
|
ISerializationManager serializationManager,
|
||||||
|
MappingDataNode node,
|
||||||
|
IDependencyCollection dependencies,
|
||||||
|
bool skipHook,
|
||||||
|
ISerializationContext? context = null,
|
||||||
|
Dictionary<string, List<string>>? value = null)
|
||||||
|
{
|
||||||
|
return serializationManager.Read(node, context, skipHook, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataNode Write(ISerializationManager serializationManager,
|
||||||
|
Dictionary<string, List<string>> value,
|
||||||
|
IDependencyCollection dependencies,
|
||||||
|
bool alwaysWrite = false,
|
||||||
|
ISerializationContext? context = null)
|
||||||
|
{
|
||||||
|
return serializationManager.WriteValue(value, alwaysWrite, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
47
Content.Server/Containers/ContainerFillSystem.cs
Normal file
47
Content.Server/Containers/ContainerFillSystem.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using Robust.Shared.Containers;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
|
||||||
|
namespace Content.Server.Containers;
|
||||||
|
|
||||||
|
public sealed class ContainerFillSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<ContainerFillComponent, MapInitEvent>(OnMapInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMapInit(EntityUid uid, ContainerFillComponent component, MapInitEvent args)
|
||||||
|
{
|
||||||
|
if (!TryComp(uid, out ContainerManagerComponent? containerComp))
|
||||||
|
{
|
||||||
|
Logger.Error($"Entity {ToPrettyString(uid)} with a {nameof(ContainerFillComponent)} has no {nameof(ContainerManagerComponent)}.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var xform = Transform(uid);
|
||||||
|
var coords = new EntityCoordinates(uid, Vector2.Zero);
|
||||||
|
|
||||||
|
foreach (var (contaienrId, prototypes) in component.Containers)
|
||||||
|
{
|
||||||
|
if (!_containerSystem.TryGetContainer(uid, contaienrId, out var container, containerComp))
|
||||||
|
{
|
||||||
|
Logger.Error($"Entity {ToPrettyString(uid)} with a {nameof(ContainerFillComponent)} is missing a container ({contaienrId}).");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var proto in prototypes)
|
||||||
|
{
|
||||||
|
var ent = Spawn(proto, coords);
|
||||||
|
if (!container.Insert(ent, EntityManager, null, xform))
|
||||||
|
{
|
||||||
|
Logger.Error($"Entity {ToPrettyString(uid)} with a {nameof(ContainerFillComponent)} failed to insert an entity: {ToPrettyString(ent)}.");
|
||||||
|
Transform(ent).AttachToGridOrMap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,6 @@ using Content.Shared.Tools.Components;
|
|||||||
using Content.Shared.Verbs;
|
using Content.Shared.Verbs;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Physics.Dynamics;
|
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Robust.Shared.Physics.Components;
|
using Robust.Shared.Physics.Components;
|
||||||
@@ -38,7 +37,6 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<DoorComponent, MapInitEvent>(OnMapInit);
|
|
||||||
SubscribeLocalEvent<DoorComponent, InteractUsingEvent>(OnInteractUsing, after: new[] { typeof(ConstructionSystem) });
|
SubscribeLocalEvent<DoorComponent, InteractUsingEvent>(OnInteractUsing, after: new[] { typeof(ConstructionSystem) });
|
||||||
|
|
||||||
// Mob prying doors
|
// Mob prying doors
|
||||||
@@ -274,30 +272,6 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||||||
TryOpen(uid, door, otherUid);
|
TryOpen(uid, door, otherUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMapInit(EntityUid uid, DoorComponent door, MapInitEvent args)
|
|
||||||
{
|
|
||||||
// Ensure that the construction component is aware of the board container.
|
|
||||||
if (TryComp(uid, out ConstructionComponent? construction))
|
|
||||||
_constructionSystem.AddContainer(uid, "board", construction);
|
|
||||||
|
|
||||||
// We don't do anything if this is null or empty.
|
|
||||||
if (string.IsNullOrEmpty(door.BoardPrototype))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var container = _containerSystem.EnsureContainer<Container>(uid, "board", out var existed);
|
|
||||||
|
|
||||||
if (existed && container.ContainedEntities.Count != 0)
|
|
||||||
{
|
|
||||||
// We already contain a board. Note: We don't check if it's the right one!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var board = EntityManager.SpawnEntity(door.BoardPrototype, Transform(uid).Coordinates);
|
|
||||||
|
|
||||||
if(!container.Insert(board))
|
|
||||||
Logger.Warning($"Couldn't insert board {ToPrettyString(board)} into door {ToPrettyString(uid)}!");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnEmagged(EntityUid uid, DoorComponent door, GotEmaggedEvent args)
|
private void OnEmagged(EntityUid uid, DoorComponent door, GotEmaggedEvent args)
|
||||||
{
|
{
|
||||||
if(TryComp<AirlockComponent>(uid, out var airlockComponent))
|
if(TryComp<AirlockComponent>(uid, out var airlockComponent))
|
||||||
|
|||||||
@@ -169,9 +169,6 @@ public sealed class DoorComponent : Component, ISerializationHooks
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
[DataField("board", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
|
||||||
public string? BoardPrototype;
|
|
||||||
|
|
||||||
[DataField("pryingQuality", customTypeSerializer: typeof(PrototypeIdSerializer<ToolQualityPrototype>))]
|
[DataField("pryingQuality", customTypeSerializer: typeof(PrototypeIdSerializer<ToolQualityPrototype>))]
|
||||||
public string PryingQuality = "Prying";
|
public string PryingQuality = "Prying";
|
||||||
|
|
||||||
|
|||||||
@@ -41,8 +41,10 @@
|
|||||||
- FullTileMask
|
- FullTileMask
|
||||||
layer:
|
layer:
|
||||||
- AirlockLayer
|
- AirlockLayer
|
||||||
|
- type: ContainerFill
|
||||||
|
containers:
|
||||||
|
board: [ DoorElectronics ]
|
||||||
- type: Door
|
- type: Door
|
||||||
board: DoorElectronics
|
|
||||||
crushDamage:
|
crushDamage:
|
||||||
types:
|
types:
|
||||||
Blunt: 15
|
Blunt: 15
|
||||||
@@ -96,6 +98,8 @@
|
|||||||
- type: Construction
|
- type: Construction
|
||||||
graph: Airlock
|
graph: Airlock
|
||||||
node: airlock
|
node: airlock
|
||||||
|
containers:
|
||||||
|
- board
|
||||||
- type: IconSmooth
|
- type: IconSmooth
|
||||||
key: walls
|
key: walls
|
||||||
mode: NoSprite
|
mode: NoSprite
|
||||||
|
|||||||
@@ -35,8 +35,13 @@
|
|||||||
- FullTileMask
|
- FullTileMask
|
||||||
layer:
|
layer:
|
||||||
- WallLayer
|
- WallLayer
|
||||||
|
- type: ContainerFill
|
||||||
|
containers:
|
||||||
|
board: [ DoorElectronics ]
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
board: !type:Container
|
||||||
- type: Door
|
- type: Door
|
||||||
board: DoorElectronics
|
|
||||||
crushDamage:
|
crushDamage:
|
||||||
types:
|
types:
|
||||||
Blunt: 50
|
Blunt: 50
|
||||||
|
|||||||
@@ -32,7 +32,6 @@
|
|||||||
bumpOpen: false
|
bumpOpen: false
|
||||||
closeTimeTwo: 0.4
|
closeTimeTwo: 0.4
|
||||||
openTimeTwo: 0.4
|
openTimeTwo: 0.4
|
||||||
board: DoorElectronics
|
|
||||||
crushDamage:
|
crushDamage:
|
||||||
types:
|
types:
|
||||||
Blunt: 15
|
Blunt: 15
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
id: Firelock
|
id: BaseFirelock
|
||||||
|
abstract: true
|
||||||
parent: BaseStructure
|
parent: BaseStructure
|
||||||
name: firelock
|
name: firelock
|
||||||
description: Apply crowbar.
|
description: Apply crowbar.
|
||||||
@@ -97,14 +98,27 @@
|
|||||||
enabled: false
|
enabled: false
|
||||||
- type: Occluder
|
- type: Occluder
|
||||||
enabled: false
|
enabled: false
|
||||||
- type: Construction
|
|
||||||
graph: Firelock
|
|
||||||
node: Firelock
|
|
||||||
- type: WallMount
|
- type: WallMount
|
||||||
arc: 360
|
arc: 360
|
||||||
- type: StaticPrice
|
- type: StaticPrice
|
||||||
price: 150
|
price: 150
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: Firelock
|
||||||
|
parent: BaseFirelock
|
||||||
|
components:
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
board: !type:Container
|
||||||
|
- type: Construction
|
||||||
|
graph: Firelock
|
||||||
|
node: Firelock
|
||||||
|
containers:
|
||||||
|
- board
|
||||||
|
- type: ContainerFill
|
||||||
|
containers:
|
||||||
|
board: [ FirelockElectronics ]
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: FirelockGlass
|
id: FirelockGlass
|
||||||
parent: Firelock
|
parent: Firelock
|
||||||
@@ -126,10 +140,12 @@
|
|||||||
- GlassAirlockLayer
|
- GlassAirlockLayer
|
||||||
- type: Door
|
- type: Door
|
||||||
occludes: false
|
occludes: false
|
||||||
|
- type: Construction
|
||||||
|
node: FirelockGlass
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: FirelockEdge
|
id: FirelockEdge
|
||||||
parent: Firelock
|
parent: BaseFirelock
|
||||||
name: firelock
|
name: firelock
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
name: shutter
|
name: shutter
|
||||||
abstract: true
|
abstract: true
|
||||||
description: One shudders to think about what might be behind this shutter.
|
description: One shudders to think about what might be behind this shutter.
|
||||||
|
placement:
|
||||||
|
mode: SnapgridCenter
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
netsync: false
|
netsync: false
|
||||||
@@ -22,8 +24,13 @@
|
|||||||
- FullTileMask
|
- FullTileMask
|
||||||
layer:
|
layer:
|
||||||
- AirlockLayer
|
- AirlockLayer
|
||||||
|
- type: ContainerFill
|
||||||
|
containers:
|
||||||
|
board: [ DoorElectronics ]
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
board: !type:Container
|
||||||
- type: Door
|
- type: Door
|
||||||
board: DoorElectronics
|
|
||||||
bumpOpen: false
|
bumpOpen: false
|
||||||
clickOpen: false
|
clickOpen: false
|
||||||
closeTimeOne: 0.2
|
closeTimeOne: 0.2
|
||||||
@@ -78,8 +85,6 @@
|
|||||||
messagePerceivedByOthers: comp-window-knock
|
messagePerceivedByOthers: comp-window-knock
|
||||||
interactSuccessSound:
|
interactSuccessSound:
|
||||||
path: /Audio/Effects/glass_knock.ogg
|
path: /Audio/Effects/glass_knock.ogg
|
||||||
placement:
|
|
||||||
mode: SnapgridCenter
|
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: ShuttersNormal
|
id: ShuttersNormal
|
||||||
@@ -89,6 +94,8 @@
|
|||||||
- type: Construction
|
- type: Construction
|
||||||
graph: Shutters
|
graph: Shutters
|
||||||
node: Shutters
|
node: Shutters
|
||||||
|
containers:
|
||||||
|
- board
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: ShuttersNormalOpen
|
id: ShuttersNormalOpen
|
||||||
@@ -105,9 +112,6 @@
|
|||||||
airBlocked: false
|
airBlocked: false
|
||||||
- type: RadiationBlocker
|
- type: RadiationBlocker
|
||||||
enabled: false
|
enabled: false
|
||||||
- type: Construction
|
|
||||||
graph: Shutters
|
|
||||||
node: Shutters
|
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: ShuttersRadiation
|
id: ShuttersRadiation
|
||||||
@@ -125,6 +129,8 @@
|
|||||||
- type: Construction
|
- type: Construction
|
||||||
graph: Shutters
|
graph: Shutters
|
||||||
node: ShuttersRadiation
|
node: ShuttersRadiation
|
||||||
|
containers:
|
||||||
|
- board
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: ShuttersRadiationOpen
|
id: ShuttersRadiationOpen
|
||||||
@@ -133,9 +139,6 @@
|
|||||||
components:
|
components:
|
||||||
- type: Door
|
- type: Door
|
||||||
state: Open
|
state: Open
|
||||||
- type: Construction
|
|
||||||
graph: Shutters
|
|
||||||
node: ShuttersRadiation
|
|
||||||
- type: Occluder
|
- type: Occluder
|
||||||
enabled: false
|
enabled: false
|
||||||
- type: Physics
|
- type: Physics
|
||||||
@@ -160,6 +163,8 @@
|
|||||||
- type: Construction
|
- type: Construction
|
||||||
graph: Shutters
|
graph: Shutters
|
||||||
node: ShuttersWindow
|
node: ShuttersWindow
|
||||||
|
containers:
|
||||||
|
- board
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: ShuttersWindowOpen
|
id: ShuttersWindowOpen
|
||||||
@@ -168,9 +173,6 @@
|
|||||||
components:
|
components:
|
||||||
- type: Door
|
- type: Door
|
||||||
state: Open
|
state: Open
|
||||||
- type: Construction
|
|
||||||
graph: Shutters
|
|
||||||
node: ShuttersWindow
|
|
||||||
- type: Physics
|
- type: Physics
|
||||||
canCollide: false
|
canCollide: false
|
||||||
- type: Airtight
|
- type: Airtight
|
||||||
@@ -192,6 +194,8 @@
|
|||||||
- type: Construction
|
- type: Construction
|
||||||
graph: Shutters
|
graph: Shutters
|
||||||
node: frame1
|
node: frame1
|
||||||
|
containers:
|
||||||
|
- board
|
||||||
- type: InteractionOutline
|
- type: InteractionOutline
|
||||||
- type: Damageable
|
- type: Damageable
|
||||||
damageContainer: Inorganic
|
damageContainer: Inorganic
|
||||||
|
|||||||
@@ -76,9 +76,14 @@
|
|||||||
openPanelVisible: true
|
openPanelVisible: true
|
||||||
# needed so that windoors will close regardless of whether there are people in it; it doesn't crush after all
|
# needed so that windoors will close regardless of whether there are people in it; it doesn't crush after all
|
||||||
safety: false
|
safety: false
|
||||||
|
- type: ContainerFill
|
||||||
|
containers:
|
||||||
|
board: [ DoorElectronics ]
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
board: !type:Container
|
||||||
- type: Door
|
- type: Door
|
||||||
canCrush: false
|
canCrush: false
|
||||||
board: DoorElectronics
|
|
||||||
openSound:
|
openSound:
|
||||||
path: /Audio/Machines/windoor_open.ogg
|
path: /Audio/Machines/windoor_open.ogg
|
||||||
closeSound:
|
closeSound:
|
||||||
@@ -111,6 +116,8 @@
|
|||||||
- type: Construction
|
- type: Construction
|
||||||
graph: Windoor
|
graph: Windoor
|
||||||
node: windoor
|
node: windoor
|
||||||
|
containers:
|
||||||
|
- board
|
||||||
- type: StaticPrice
|
- type: StaticPrice
|
||||||
price: 100
|
price: 100
|
||||||
|
|
||||||
|
|||||||
@@ -148,7 +148,7 @@
|
|||||||
prototype: SheetGlass1
|
prototype: SheetGlass1
|
||||||
amount: 2
|
amount: 2
|
||||||
steps:
|
steps:
|
||||||
- tool: Screwing
|
- tool: Prying
|
||||||
doAfter: 1
|
doAfter: 1
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -379,6 +379,23 @@
|
|||||||
conditions:
|
conditions:
|
||||||
- !type:TileNotBlocked
|
- !type:TileNotBlocked
|
||||||
|
|
||||||
|
- type: construction
|
||||||
|
name: glass firelock
|
||||||
|
id: FirelockGlass
|
||||||
|
graph: Firelock
|
||||||
|
startNode: start
|
||||||
|
targetNode: FirelockGlass
|
||||||
|
category: construction-category-structures
|
||||||
|
description: This is a firelock - it locks an area when a fire alarm in the area is triggered. Don't get squished!
|
||||||
|
icon:
|
||||||
|
sprite: Structures/Doors/Airlocks/Glass/firelock.rsi
|
||||||
|
state: closed
|
||||||
|
objectType: Structure
|
||||||
|
placementMode: SnapgridCenter
|
||||||
|
canBuildInImpassable: false
|
||||||
|
conditions:
|
||||||
|
- !type:TileNotBlocked
|
||||||
|
|
||||||
- type: construction
|
- type: construction
|
||||||
name: shutter
|
name: shutter
|
||||||
id: Shutters
|
id: Shutters
|
||||||
|
|||||||
Reference in New Issue
Block a user