Universal weldable component (#7955)

* Weldable component for door

* Content update

* Examine message

* Universal visualizer

* Small fix

* Entity storage

* Content

* Fixed test

* Update Content.Shared/Storage/SharedStorageComponent.cs

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* Fixed loc string

* Add public API to change welding time

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
Alex Evgrashin
2022-05-09 08:51:52 +03:00
committed by GitHub
parent 02de328d9c
commit df49c2fd57
29 changed files with 367 additions and 215 deletions

View File

@@ -160,7 +160,6 @@ namespace Content.Client.Doors
var door = _entMan.GetComponent<DoorComponent>(component.Owner); var door = _entMan.GetComponent<DoorComponent>(component.Owner);
var unlitVisible = true; var unlitVisible = true;
var boltedVisible = false; var boltedVisible = false;
var weldedVisible = false;
var emergencyLightsVisible = false; var emergencyLightsVisible = false;
if (component.TryGetData(DoorVisuals.BaseRSI, out string baseRsi)) if (component.TryGetData(DoorVisuals.BaseRSI, out string baseRsi))
@@ -210,7 +209,6 @@ namespace Content.Client.Doors
animPlayer.Play(DenyAnimation, AnimationKey); animPlayer.Play(DenyAnimation, AnimationKey);
break; break;
case DoorState.Welded: case DoorState.Welded:
weldedVisible = true;
break; break;
case DoorState.Emagging: case DoorState.Emagging:
animPlayer.Play(EmaggingAnimation, AnimationKey); animPlayer.Play(EmaggingAnimation, AnimationKey);
@@ -236,7 +234,6 @@ namespace Content.Client.Doors
if (!_simpleVisuals) if (!_simpleVisuals)
{ {
sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, unlitVisible && state != DoorState.Closed && state != DoorState.Welded); sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, unlitVisible && state != DoorState.Closed && state != DoorState.Welded);
sprite.LayerSetVisible(DoorVisualLayers.BaseWelded, weldedVisible);
sprite.LayerSetVisible(DoorVisualLayers.BaseBolted, unlitVisible && boltedVisible); sprite.LayerSetVisible(DoorVisualLayers.BaseBolted, unlitVisible && boltedVisible);
if (_emergencyAccessLayer) if (_emergencyAccessLayer)
{ {
@@ -255,7 +252,6 @@ namespace Content.Client.Doors
{ {
Base, Base,
BaseUnlit, BaseUnlit,
BaseWelded,
BaseBolted, BaseBolted,
BaseEmergencyAccess, BaseEmergencyAccess,
} }

View File

@@ -76,21 +76,12 @@ namespace Content.Client.Storage.Visualizers
sprite.LayerSetState(StorageVisualLayers.Lock, locked ? "locked" : "unlocked"); sprite.LayerSetState(StorageVisualLayers.Lock, locked ? "locked" : "unlocked");
} }
} }
if (component.TryGetData(StorageVisuals.CanWeld, out bool canWeld) && canWeld)
{
if (component.TryGetData(StorageVisuals.Welded, out bool weldedVal))
{
sprite.LayerSetVisible(StorageVisualLayers.Welded, weldedVal);
}
}
} }
} }
public enum StorageVisualLayers : byte public enum StorageVisualLayers : byte
{ {
Door, Door,
Welded,
Lock Lock
} }
} }

View File

@@ -0,0 +1,9 @@
using Content.Shared.Tools.Components;
namespace Content.Client.Tools.Components;
[RegisterComponent]
public sealed class WeldableComponent : SharedWeldableComponent
{
}

View File

@@ -0,0 +1,22 @@
using Content.Client.Tools.Components;
using Content.Shared.Tools.Components;
using Robust.Client.GameObjects;
namespace Content.Client.Tools.Visualizers;
public sealed class WeldableVisualizerSystem : VisualizerSystem<WeldableComponent>
{
protected override void OnAppearanceChange(EntityUid uid, WeldableComponent component, ref AppearanceChangeEvent args)
{
base.OnAppearanceChange(uid, component, ref args);
if (!TryComp(uid, out SpriteComponent? sprite))
return;
args.Component.TryGetData(WeldableVisuals.IsWelded, out bool isWelded);
if (sprite.LayerMapTryGet(WeldableLayers.BaseWelded, out var layer))
{
sprite.LayerSetVisible(layer, isWelded);
}
}
}

View File

@@ -18,6 +18,7 @@ using Robust.Shared.Containers;
using Robust.Shared.Physics.Dynamics; using Robust.Shared.Physics.Dynamics;
using Robust.Shared.Player; using Robust.Shared.Player;
using System.Linq; using System.Linq;
using Content.Server.Tools.Systems;
using Content.Shared.Tools.Components; using Content.Shared.Tools.Components;
namespace Content.Server.Doors.Systems; namespace Content.Server.Doors.Systems;
@@ -39,8 +40,8 @@ public sealed class DoorSystem : SharedDoorSystem
SubscribeLocalEvent<DoorComponent, PryFinishedEvent>(OnPryFinished); SubscribeLocalEvent<DoorComponent, PryFinishedEvent>(OnPryFinished);
SubscribeLocalEvent<DoorComponent, PryCancelledEvent>(OnPryCancelled); SubscribeLocalEvent<DoorComponent, PryCancelledEvent>(OnPryCancelled);
SubscribeLocalEvent<DoorComponent, WeldFinishedEvent>(OnWeldFinished); SubscribeLocalEvent<DoorComponent, WeldableAttemptEvent>(OnWeldAttempt);
SubscribeLocalEvent<DoorComponent, WeldCancelledEvent>(OnWeldCancelled); SubscribeLocalEvent<DoorComponent, WeldableChangedEvent>(OnWeldChanged);
SubscribeLocalEvent<DoorComponent, GotEmaggedEvent>(OnEmagged); SubscribeLocalEvent<DoorComponent, GotEmaggedEvent>(OnEmagged);
} }
@@ -129,32 +130,27 @@ public sealed class DoorSystem : SharedDoorSystem
args.Handled = TryPryDoor(uid, args.Used, args.User, door); args.Handled = TryPryDoor(uid, args.Used, args.User, door);
return; return;
} }
}
if (door.Weldable && tool.Qualities.Contains(door.WeldingQuality)) private void OnWeldAttempt(EntityUid uid, DoorComponent component, WeldableAttemptEvent args)
{
if (component.CurrentlyCrushing.Count > 0)
{ {
args.Handled = TryWeldDoor(uid, args.Used, args.User, door); args.Cancel();
return;
}
if (component.State != DoorState.Closed && component.State != DoorState.Welded)
{
args.Cancel();
} }
} }
/// <summary> private void OnWeldChanged(EntityUid uid, DoorComponent component, WeldableChangedEvent args)
/// Attempt to weld a door shut, or unweld it if it is already welded. This does not actually check if the user
/// is holding the correct tool.
/// </summary>
private bool TryWeldDoor(EntityUid target, EntityUid used, EntityUid user, DoorComponent door)
{ {
if (!door.Weldable || door.BeingWelded || door.CurrentlyCrushing.Count > 0) if (component.State == DoorState.Closed)
return false; SetState(uid, DoorState.Welded, component);
else if (component.State == DoorState.Welded)
// is the door in a weld-able state? SetState(uid, DoorState.Closed, component);
if (door.State != DoorState.Closed && door.State != DoorState.Welded)
return false;
// perform a do-after delay
door.BeingWelded = true;
_toolSystem.UseTool(used, user, target, 3f, 3f, door.WeldingQuality,
new WeldFinishedEvent(), new WeldCancelledEvent(), target);
return true; // we might not actually succeeded, but a do-after has started
} }
/// <summary> /// <summary>
@@ -182,24 +178,6 @@ public sealed class DoorSystem : SharedDoorSystem
return true; // we might not actually succeeded, but a do-after has started return true; // we might not actually succeeded, but a do-after has started
} }
private void OnWeldCancelled(EntityUid uid, DoorComponent door, WeldCancelledEvent args)
{
door.BeingWelded = false;
}
private void OnWeldFinished(EntityUid uid, DoorComponent door, WeldFinishedEvent args)
{
door.BeingWelded = false;
if (!door.Weldable)
return;
if (door.State == DoorState.Closed)
SetState(uid, DoorState.Welded, door);
else if (door.State == DoorState.Welded)
SetState(uid, DoorState.Closed, door);
}
private void OnPryCancelled(EntityUid uid, DoorComponent door, PryCancelledEvent args) private void OnPryCancelled(EntityUid uid, DoorComponent door, PryCancelledEvent args)
{ {
door.BeingPried = false; door.BeingPried = false;
@@ -324,5 +302,4 @@ public sealed class DoorSystem : SharedDoorSystem
public sealed class PryFinishedEvent : EntityEventArgs { } public sealed class PryFinishedEvent : EntityEventArgs { }
public sealed class PryCancelledEvent : EntityEventArgs { } public sealed class PryCancelledEvent : EntityEventArgs { }
public sealed class WeldFinishedEvent : EntityEventArgs { }
public sealed class WeldCancelledEvent : EntityEventArgs { }

View File

@@ -29,7 +29,7 @@ namespace Content.Server.Storage.Components
[Virtual] [Virtual]
[ComponentReference(typeof(IActivate))] [ComponentReference(typeof(IActivate))]
[ComponentReference(typeof(IStorageComponent))] [ComponentReference(typeof(IStorageComponent))]
public class EntityStorageComponent : Component, IActivate, IStorageComponent, IInteractUsing public class EntityStorageComponent : Component, IActivate, IStorageComponent
{ {
[Dependency] private readonly IEntityManager _entMan = default!; [Dependency] private readonly IEntityManager _entMan = default!;
@@ -72,15 +72,6 @@ namespace Content.Server.Storage.Components
[DataField("open")] [DataField("open")]
public bool Open; public bool Open;
[DataField("weldingQuality", customTypeSerializer:typeof(PrototypeIdSerializer<ToolQualityPrototype>))]
private string _weldingQuality = "Welding";
[DataField("CanWeldShut")]
private bool _canWeldShut = true;
[DataField("IsWeldedShut")]
private bool _isWeldedShut;
[DataField("closeSound")] [DataField("closeSound")]
private SoundSpecifier _closeSound = new SoundPathSpecifier("/Audio/Effects/closetclose.ogg"); private SoundSpecifier _closeSound = new SoundPathSpecifier("/Audio/Effects/closetclose.ogg");
@@ -116,32 +107,7 @@ namespace Content.Server.Storage.Components
} }
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public bool IsWeldedShut public bool IsWeldedShut;
{
get => _isWeldedShut;
set
{
if (_isWeldedShut == value) return;
_isWeldedShut = value;
UpdateAppearance();
}
}
private bool _beingWelded;
[ViewVariables(VVAccess.ReadWrite)]
public bool CanWeldShut
{
get => _canWeldShut;
set
{
if (_canWeldShut == value) return;
_canWeldShut = value;
UpdateAppearance();
}
}
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]
public float EnteringRange public float EnteringRange
@@ -165,8 +131,6 @@ namespace Content.Server.Storage.Components
{ {
EntitySystem.Get<PlaceableSurfaceSystem>().SetPlaceable(Owner, Open, surface); EntitySystem.Get<PlaceableSurfaceSystem>().SetPlaceable(Owner, Open, surface);
} }
UpdateAppearance();
} }
public virtual void Activate(ActivateEventArgs eventArgs) public virtual void Activate(ActivateEventArgs eventArgs)
@@ -296,15 +260,6 @@ namespace Content.Server.Storage.Components
SoundSystem.Play(Filter.Pvs(Owner), _openSound.GetSound(), Owner); SoundSystem.Play(Filter.Pvs(Owner), _openSound.GetSound(), Owner);
} }
private void UpdateAppearance()
{
if (_entMan.TryGetComponent(Owner, out AppearanceComponent? appearance))
{
appearance.SetData(StorageVisuals.CanWeld, _canWeldShut);
appearance.SetData(StorageVisuals.Welded, _isWeldedShut);
}
}
private void ModifyComponents() private void ModifyComponents()
{ {
if (!_isCollidableWhenOpen && _entMan.TryGetComponent<FixturesComponent?>(Owner, out var manager) if (!_isCollidableWhenOpen && _entMan.TryGetComponent<FixturesComponent?>(Owner, out var manager)
@@ -409,48 +364,6 @@ namespace Content.Server.Storage.Components
return Contents.CanInsert(entity); return Contents.CanInsert(entity);
} }
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
if (_beingWelded)
return false;
if (Open)
{
_beingWelded = false;
return false;
}
if (!CanWeldShut)
{
_beingWelded = false;
return false;
}
if (Contents.Contains(eventArgs.User))
{
_beingWelded = false;
Owner.PopupMessage(eventArgs.User, Loc.GetString("entity-storage-component-already-contains-user-message"));
return false;
}
if (_beingWelded)
return false;
_beingWelded = true;
var toolSystem = EntitySystem.Get<ToolSystem>();
if (!await toolSystem.UseTool(eventArgs.Using, eventArgs.User, Owner, 1f, 1f, _weldingQuality))
{
_beingWelded = false;
return false;
}
_beingWelded = false;
IsWeldedShut ^= true;
return true;
}
protected virtual IEnumerable<EntityUid> DetermineCollidingEntities() protected virtual IEnumerable<EntityUid> DetermineCollidingEntities()
{ {
var entityLookup = EntitySystem.Get<EntityLookupSystem>(); var entityLookup = EntitySystem.Get<EntityLookupSystem>();

View File

@@ -1,18 +1,47 @@
using System.Linq; using System.Linq;
using Content.Server.Popups;
using Content.Server.Storage.Components; using Content.Server.Storage.Components;
using Content.Server.Tools.Systems;
using Content.Shared.Destructible; using Content.Shared.Destructible;
using Content.Shared.Interaction;
using Robust.Shared.Physics; using Robust.Shared.Physics;
using Robust.Shared.Player;
namespace Content.Server.Storage.EntitySystems; namespace Content.Server.Storage.EntitySystems;
public sealed class EntityStorageSystem : EntitySystem public sealed class EntityStorageSystem : EntitySystem
{ {
[Dependency] private readonly PopupSystem _popupSystem = default!;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<EntityStorageComponent, WeldableAttemptEvent>(OnWeldableAttempt);
SubscribeLocalEvent<EntityStorageComponent, WeldableChangedEvent>(OnWelded);
SubscribeLocalEvent<EntityStorageComponent, DestructionEventArgs>(OnDestroy); SubscribeLocalEvent<EntityStorageComponent, DestructionEventArgs>(OnDestroy);
} }
private void OnWeldableAttempt(EntityUid uid, EntityStorageComponent component, WeldableAttemptEvent args)
{
if (component.Open)
{
args.Cancel();
return;
}
if (component.Contents.Contains(args.User))
{
var msg = Loc.GetString("entity-storage-component-already-contains-user-message");
_popupSystem.PopupEntity(msg, args.User, Filter.Entities(args.User));
args.Cancel();
}
}
private void OnWelded(EntityUid uid, EntityStorageComponent component, WeldableChangedEvent args)
{
component.IsWeldedShut = args.IsWelded;
}
private void OnDestroy(EntityUid uid, EntityStorageComponent component, DestructionEventArgs args) private void OnDestroy(EntityUid uid, EntityStorageComponent component, DestructionEventArgs args)
{ {
component.Open = true; component.Open = true;

View File

@@ -0,0 +1,61 @@
using Content.Server.Tools.Systems;
using Content.Shared.Tools;
using Content.Shared.Tools.Components;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Tools.Components;
/// <summary>
/// Allows users to weld/unweld doors, crates and lockers.
/// </summary>
[RegisterComponent]
[Friend(typeof(WeldableSystem))]
public sealed class WeldableComponent : SharedWeldableComponent
{
/// <summary>
/// Tool quality for welding.
/// </summary>
[DataField("weldingQuality", customTypeSerializer: typeof(PrototypeIdSerializer<ToolQualityPrototype>))]
[ViewVariables(VVAccess.ReadWrite)]
public string WeldingQuality = "Welding";
/// <summary>
/// Whether this entity can ever be welded shut.
/// </summary>
[DataField("weldable")]
[ViewVariables(VVAccess.ReadWrite)]
public bool Weldable = true;
/// <summary>
/// How much fuel does it take to weld/unweld entity.
/// </summary>
[DataField("fuel")]
[ViewVariables(VVAccess.ReadWrite)]
public float FuelConsumption = 1f;
/// <summary>
/// How much time does it take to weld/unweld entity.
/// </summary>
[DataField("time")]
[ViewVariables(VVAccess.ReadWrite)]
public TimeSpan WeldingTime = TimeSpan.FromSeconds(1f);
/// <summary>
/// Shown when welded entity is examined.
/// </summary>
[DataField("weldedExamineMessage")]
[ViewVariables(VVAccess.ReadWrite)]
public string? WeldedExamineMessage = "weldable-component-examine-is-welded";
/// <summary>
/// Whether something is currently using a welder on this so DoAfter isn't spammed.
/// </summary>
[ViewVariables(VVAccess.ReadOnly)]
public bool BeingWelded;
/// <summary>
/// Is this entity currently welded shut?
/// </summary>
[ViewVariables(VVAccess.ReadOnly)]
public bool IsWelded;
}

View File

@@ -0,0 +1,159 @@
using Content.Server.Tools.Components;
using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Tools.Components;
namespace Content.Server.Tools.Systems;
public sealed class WeldableSystem : EntitySystem
{
[Dependency] private readonly ToolSystem _toolSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<WeldableComponent, InteractUsingEvent>(OnInteractUsing);
SubscribeLocalEvent<WeldableComponent, WeldFinishedEvent>(OnWeldFinished);
SubscribeLocalEvent<WeldableComponent, WeldCancelledEvent>(OnWeldCanceled);
SubscribeLocalEvent<WeldableComponent, ExaminedEvent>(OnExamine);
}
private void OnExamine(EntityUid uid, WeldableComponent component, ExaminedEvent args)
{
if (component.IsWelded && component.WeldedExamineMessage != null)
args.PushText(Loc.GetString(component.WeldedExamineMessage));
}
private void OnInteractUsing(EntityUid uid, WeldableComponent component, InteractUsingEvent args)
{
if (args.Handled)
return;
args.Handled = TryWeld(uid, args.Used, args.User, component);
}
private bool CanWeld(EntityUid uid, EntityUid tool, EntityUid user, WeldableComponent? component = null)
{
if (!Resolve(uid, ref component))
return false;
// Basic checks
if (!component.Weldable || component.BeingWelded)
return false;
if (!_toolSystem.HasQuality(tool, component.WeldingQuality))
return false;
// Other component systems
var attempt = new WeldableAttemptEvent(user, tool);
RaiseLocalEvent(uid, attempt);
if (attempt.Cancelled)
return false;
return true;
}
private bool TryWeld(EntityUid uid, EntityUid tool, EntityUid user, WeldableComponent? component = null)
{
if (!Resolve(uid, ref component))
return false;
if (!CanWeld(uid, tool, user, component))
return false;
component.BeingWelded = true;
_toolSystem.UseTool(tool, user, uid, component.FuelConsumption,
component.WeldingTime.Seconds, component.WeldingQuality,
new WeldFinishedEvent(user, tool), new WeldCancelledEvent(), uid);
return true;
}
private void OnWeldFinished(EntityUid uid, WeldableComponent component, WeldFinishedEvent args)
{
component.BeingWelded = false;
// Check if target is still valid
if (!CanWeld(uid, args.Tool, args.User, component))
return;
component.IsWelded = !component.IsWelded;
RaiseLocalEvent(uid, new WeldableChangedEvent(component.IsWelded));
UpdateAppearance(uid, component);
}
private void OnWeldCanceled(EntityUid uid, WeldableComponent component, WeldCancelledEvent args)
{
component.BeingWelded = false;
}
private void UpdateAppearance(EntityUid uid, WeldableComponent? component = null)
{
if (!Resolve(uid, ref component))
return;
if (!TryComp(uid, out AppearanceComponent? appearance))
return;
appearance.SetData(WeldableVisuals.IsWelded, component.IsWelded);
}
public void SetWeldingTime(EntityUid uid, TimeSpan time, WeldableComponent? component = null)
{
if (!Resolve(uid, ref component))
return;
component.WeldingTime = time;
}
/// <summary>
/// Raised after welding do_after has finished. It doesn't guarantee success,
/// use <see cref="WeldableChangedEvent"/> to get updated status.
/// </summary>
private sealed class WeldFinishedEvent : EntityEventArgs
{
public readonly EntityUid User;
public readonly EntityUid Tool;
public WeldFinishedEvent(EntityUid user, EntityUid tool)
{
User = user;
Tool = tool;
}
}
/// <summary>
/// Raised when entity welding has failed.
/// </summary>
private sealed class WeldCancelledEvent : EntityEventArgs
{
}
}
/// <summary>
/// Checks that entity can be weld/unweld.
/// Raised twice: before do_after and after to check that entity still valid.
/// </summary>
public sealed class WeldableAttemptEvent : CancellableEntityEventArgs
{
public readonly EntityUid User;
public readonly EntityUid Tool;
public WeldableAttemptEvent(EntityUid user, EntityUid tool)
{
User = user;
Tool = tool;
}
}
/// <summary>
/// Raised when <see cref="WeldableComponent.IsWelded"/> has changed.
/// </summary>
public sealed class WeldableChangedEvent : EntityEventArgs
{
public readonly bool IsWelded;
public WeldableChangedEvent(bool isWelded)
{
IsWelded = isWelded;
}
}

View File

@@ -75,24 +75,6 @@ public sealed class DoorComponent : Component, ISerializationHooks
public bool Partial; public bool Partial;
#endregion #endregion
#region Welding
// TODO WELDING. Consider creating a WeldableComponent for use with doors, crates and lockers? Currently they all
// have their own welding logic.
[DataField("weldingQuality", customTypeSerializer: typeof(PrototypeIdSerializer<ToolQualityPrototype>))]
public string WeldingQuality = "Welding";
/// <summary>
/// Whether the door can ever be welded shut.
/// </summary>
[DataField("weldable")]
public bool Weldable = true;
/// <summary>
/// Whether something is currently using a welder on this so DoAfter isn't spammed.
/// </summary>
public bool BeingWelded;
#endregion
public bool BeingPried; public bool BeingPried;
#region Sounds #region Sounds

View File

@@ -47,7 +47,6 @@ public abstract class SharedDoorSystem : EntitySystem
SubscribeLocalEvent<DoorComponent, ComponentHandleState>(OnHandleState); SubscribeLocalEvent<DoorComponent, ComponentHandleState>(OnHandleState);
SubscribeLocalEvent<DoorComponent, ActivateInWorldEvent>(OnActivate); SubscribeLocalEvent<DoorComponent, ActivateInWorldEvent>(OnActivate);
SubscribeLocalEvent<DoorComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<DoorComponent, StartCollideEvent>(HandleCollide); SubscribeLocalEvent<DoorComponent, StartCollideEvent>(HandleCollide);
SubscribeLocalEvent<DoorComponent, PreventCollideEvent>(PreventCollision); SubscribeLocalEvent<DoorComponent, PreventCollideEvent>(PreventCollision);
@@ -173,12 +172,6 @@ public abstract class SharedDoorSystem : EntitySystem
args.Handled = true; args.Handled = true;
} }
private void OnExamine(EntityUid uid, DoorComponent door, ExaminedEvent args)
{
if (door.State == DoorState.Welded)
args.PushText(Loc.GetString("door-component-examine-is-welded"));
}
/// <summary> /// <summary>
/// Update the door state/visuals and play an access denied sound when a user without access interacts with the /// Update the door state/visuals and play an access denied sound when a user without access interacts with the
/// door. /// door.

View File

@@ -78,11 +78,9 @@ namespace Content.Shared.Storage
[NetSerializable] [NetSerializable]
[Serializable] [Serializable]
public enum StorageVisuals public enum StorageVisuals : byte
{ {
Open, Open,
CanWeld,
Welded,
CanLock, CanLock,
Locked Locked
} }

View File

@@ -0,0 +1,20 @@
using Robust.Shared.Serialization;
namespace Content.Shared.Tools.Components;
public abstract class SharedWeldableComponent : Component
{
}
[Serializable, NetSerializable]
public enum WeldableVisuals : byte
{
IsWelded
}
[Serializable, NetSerializable]
public enum WeldableLayers : byte
{
BaseWelded
}

View File

@@ -1 +0,0 @@
door-component-examine-is-welded = It has been welded shut.

View File

@@ -0,0 +1 @@
weldable-component-examine-is-welded = It has been welded shut.

View File

@@ -153,7 +153,6 @@
netsync: false netsync: false
- type: EntityStorage - type: EntityStorage
Capacity: 8 Capacity: 8
CanWeldShut: false
- type: PlaceableSurface - type: PlaceableSurface
placeCentered: true placeCentered: true
- type: Item - type: Item

View File

@@ -39,7 +39,6 @@
mask: mask:
- Impassable - Impassable
- type: BodyBagEntityStorage - type: BodyBagEntityStorage
CanWeldShut: false
Capacity: 1 Capacity: 1
IsCollidableWhenOpen: true IsCollidableWhenOpen: true
closeSound: closeSound:

View File

@@ -19,7 +19,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: locked - state: locked
map: ["enum.StorageVisualLayers.Lock"] map: ["enum.StorageVisualLayers.Lock"]
shader: unshaded shader: unshaded
@@ -42,7 +42,7 @@
state: artifact_container_icon state: artifact_container_icon
- type: ArtifactStorage - type: ArtifactStorage
Capacity: 1 Capacity: 1
CanWeldShut: true - type: Weldable
- type: SuppressArtifactContainer - type: SuppressArtifactContainer
- type: PlaceableSurface - type: PlaceableSurface
- type: Damageable - type: Damageable

View File

@@ -15,7 +15,7 @@
shader: unshaded shader: unshaded
map: ["enum.DoorVisualLayers.BaseUnlit"] map: ["enum.DoorVisualLayers.BaseUnlit"]
- state: welded - state: welded
map: ["enum.DoorVisualLayers.BaseWelded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: bolted_unlit - state: bolted_unlit
shader: unshaded shader: unshaded
map: ["enum.DoorVisualLayers.BaseBolted"] map: ["enum.DoorVisualLayers.BaseBolted"]
@@ -48,6 +48,9 @@
path: /Audio/Machines/airlock_close.ogg path: /Audio/Machines/airlock_close.ogg
denySound: denySound:
path: /Audio/Machines/airlock_deny.ogg path: /Audio/Machines/airlock_deny.ogg
- type: Weldable
fuel: 3
time: 3
- type: Airlock - type: Airlock
- type: Appearance - type: Appearance
visuals: visuals:

View File

@@ -16,7 +16,7 @@
shader: unshaded shader: unshaded
map: ["enum.DoorVisualLayers.BaseUnlit"] map: ["enum.DoorVisualLayers.BaseUnlit"]
- state: welded - state: welded
map: ["enum.DoorVisualLayers.BaseWelded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: bolted_unlit - state: bolted_unlit
shader: unshaded shader: unshaded
map: ["enum.DoorVisualLayers.BaseBolted"] map: ["enum.DoorVisualLayers.BaseBolted"]
@@ -71,7 +71,7 @@
shader: unshaded shader: unshaded
map: ["enum.DoorVisualLayers.BaseUnlit"] map: ["enum.DoorVisualLayers.BaseUnlit"]
- state: welded - state: welded
map: ["enum.DoorVisualLayers.BaseWelded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: bolted_unlit - state: bolted_unlit
shader: unshaded shader: unshaded
map: ["enum.DoorVisualLayers.BaseBolted"] map: ["enum.DoorVisualLayers.BaseBolted"]

View File

@@ -36,7 +36,7 @@
shader: unshaded shader: unshaded
map: ["enum.DoorVisualLayers.BaseUnlit"] map: ["enum.DoorVisualLayers.BaseUnlit"]
- state: welded - state: welded
map: ["enum.DoorVisualLayers.BaseWelded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: bolted_unlit - state: bolted_unlit
shader: unshaded shader: unshaded
map: ["enum.DoorVisualLayers.BaseBolted"] map: ["enum.DoorVisualLayers.BaseBolted"]
@@ -73,6 +73,9 @@
path: /Audio/Machines/airlock_close.ogg path: /Audio/Machines/airlock_close.ogg
denySound: denySound:
path: /Audio/Machines/airlock_deny.ogg path: /Audio/Machines/airlock_deny.ogg
- type: Weldable
fuel: 3
time: 3
- type: Firelock - type: Firelock
- type: Appearance - type: Appearance
visuals: visuals:

View File

@@ -30,7 +30,6 @@
- type: Door - type: Door
bumpOpen: false bumpOpen: false
clickOpen: true clickOpen: true
weldable: false
canCrush: false canCrush: false
closeTimeOne: 0.2 closeTimeOne: 0.2
closeTimeTwo: 0.6 closeTimeTwo: 0.6
@@ -89,7 +88,6 @@
- type: Door - type: Door
bumpOpen: false bumpOpen: false
clickOpen: true clickOpen: true
weldable: false
closeTimeOne: 0.2 closeTimeOne: 0.2
closeTimeTwo: 0.6 closeTimeTwo: 0.6
openTimeOne: 0.6 openTimeOne: 0.6

View File

@@ -41,6 +41,9 @@
path: /Audio/Machines/blastdoor.ogg path: /Audio/Machines/blastdoor.ogg
closeSound: closeSound:
path: /Audio/Machines/blastdoor.ogg path: /Audio/Machines/blastdoor.ogg
- type: Weldable
fuel: 3
time: 3
- type: Appearance - type: Appearance
visuals: visuals:
- type: AirlockVisualizer - type: AirlockVisualizer

View File

@@ -30,7 +30,7 @@
shader: unshaded shader: unshaded
map: ["enum.DoorVisualLayers.BaseUnlit"] map: ["enum.DoorVisualLayers.BaseUnlit"]
- state: welded - state: welded
map: ["enum.DoorVisualLayers.BaseWelded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: bolted_unlit - state: bolted_unlit
shader: unshaded shader: unshaded
map: ["enum.DoorVisualLayers.BaseBolted"] map: ["enum.DoorVisualLayers.BaseBolted"]
@@ -75,7 +75,6 @@
safety: false safety: false
- type: Door - type: Door
canCrush: false canCrush: false
weldable: false
board: DoorElectronics board: DoorElectronics
openSound: openSound:
path: /Audio/Machines/windoor_open.ogg path: /Audio/Machines/windoor_open.ogg
@@ -123,7 +122,7 @@
shader: unshaded shader: unshaded
map: [ "enum.DoorVisualLayers.BaseUnlit" ] map: [ "enum.DoorVisualLayers.BaseUnlit" ]
- state: welded - state: welded
map: [ "enum.DoorVisualLayers.BaseWelded" ] map: [ "enum.WeldableLayers.BaseWelded" ]
- state: bolted_unlit - state: bolted_unlit
shader: unshaded shader: unshaded
map: [ "enum.DoorVisualLayers.BaseBolted" ] map: [ "enum.DoorVisualLayers.BaseBolted" ]

View File

@@ -18,7 +18,7 @@
shader: unshaded shader: unshaded
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: Destructible - type: Destructible
thresholds: thresholds:
- trigger: - trigger:

View File

@@ -17,7 +17,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: MovedByPressure - type: MovedByPressure
- type: DamageOnHighSpeedImpact - type: DamageOnHighSpeedImpact
damage: damage:
@@ -41,6 +41,7 @@
- MobImpassable - MobImpassable
- SmallImpassable - SmallImpassable
- type: EntityStorage - type: EntityStorage
- type: Weldable
- type: PlaceableSurface - type: PlaceableSurface
placeCentered: true placeCentered: true
- type: Damageable - type: Damageable

View File

@@ -16,7 +16,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: InteractionOutline - type: InteractionOutline
- type: Physics - type: Physics
- type: Fixtures - type: Fixtures
@@ -34,7 +34,7 @@
- SmallImpassable - SmallImpassable
- type: EntityStorage - type: EntityStorage
Capacity: 500 Capacity: 500
CanWeldShut: true - type: Weldable
- type: PlaceableSurface - type: PlaceableSurface
- type: Damageable - type: Damageable
damageContainer: Inorganic damageContainer: Inorganic
@@ -79,7 +79,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: InteractionOutline - type: InteractionOutline
- type: Physics - type: Physics
- type: Fixtures - type: Fixtures
@@ -97,7 +97,7 @@
- SmallImpassable - SmallImpassable
- type: EntityStorage - type: EntityStorage
Capacity: 500 Capacity: 500
CanWeldShut: true - type: Weldable
- type: PlaceableSurface - type: PlaceableSurface
- type: Damageable - type: Damageable
damageContainer: Inorganic damageContainer: Inorganic

View File

@@ -11,7 +11,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: Icon - type: Icon
sprite: Structures/Storage/Crates/generic.rsi sprite: Structures/Storage/Crates/generic.rsi
state: crate_icon state: crate_icon
@@ -38,7 +38,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: Icon - type: Icon
sprite: Structures/Storage/Crates/plastic.rsi sprite: Structures/Storage/Crates/plastic.rsi
state: plasticcrate_icon state: plasticcrate_icon
@@ -64,7 +64,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: Icon - type: Icon
sprite: Structures/Storage/Crates/freezer.rsi sprite: Structures/Storage/Crates/freezer.rsi
state: freezer_icon state: freezer_icon
@@ -90,7 +90,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: Icon - type: Icon
sprite: Structures/Storage/Crates/hydro.rsi sprite: Structures/Storage/Crates/hydro.rsi
state: hydrocrate_icon state: hydrocrate_icon
@@ -116,7 +116,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: Icon - type: Icon
sprite: Structures/Storage/Crates/medical.rsi sprite: Structures/Storage/Crates/medical.rsi
state: medicalcrate_icon state: medicalcrate_icon
@@ -143,7 +143,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: Icon - type: Icon
sprite: Structures/Storage/Crates/radiation.rsi sprite: Structures/Storage/Crates/radiation.rsi
state: radiationcrate_icon state: radiationcrate_icon
@@ -169,7 +169,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: Icon - type: Icon
sprite: Structures/Storage/Crates/o2.rsi sprite: Structures/Storage/Crates/o2.rsi
state: o2crate_icon state: o2crate_icon
@@ -195,7 +195,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: Icon - type: Icon
sprite: Structures/Storage/Crates/electricalcrate.rsi sprite: Structures/Storage/Crates/electricalcrate.rsi
state: electricalcrate_icon state: electricalcrate_icon
@@ -221,7 +221,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: Icon - type: Icon
sprite: Structures/Storage/Crates/engicrate.rsi sprite: Structures/Storage/Crates/engicrate.rsi
state: engicrate_icon state: engicrate_icon
@@ -247,7 +247,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: Icon - type: Icon
sprite: Structures/Storage/Crates/scicrate.rsi sprite: Structures/Storage/Crates/scicrate.rsi
state: scicrate_icon state: scicrate_icon
@@ -273,7 +273,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- type: Icon - type: Icon
sprite: Structures/Storage/Crates/surgerycrate.rsi sprite: Structures/Storage/Crates/surgerycrate.rsi
state: surgerycrate_icon state: surgerycrate_icon
@@ -304,7 +304,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: locked - state: locked
map: ["enum.StorageVisualLayers.Lock"] map: ["enum.StorageVisualLayers.Lock"]
shader: unshaded shader: unshaded
@@ -333,7 +333,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: locked - state: locked
map: ["enum.StorageVisualLayers.Lock"] map: ["enum.StorageVisualLayers.Lock"]
shader: unshaded shader: unshaded
@@ -362,7 +362,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: locked - state: locked
map: ["enum.StorageVisualLayers.Lock"] map: ["enum.StorageVisualLayers.Lock"]
shader: unshaded shader: unshaded
@@ -390,7 +390,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: locked - state: locked
map: ["enum.StorageVisualLayers.Lock"] map: ["enum.StorageVisualLayers.Lock"]
shader: unshaded shader: unshaded
@@ -419,7 +419,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: locked - state: locked
map: ["enum.StorageVisualLayers.Lock"] map: ["enum.StorageVisualLayers.Lock"]
shader: unshaded shader: unshaded
@@ -448,7 +448,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: locked - state: locked
map: ["enum.StorageVisualLayers.Lock"] map: ["enum.StorageVisualLayers.Lock"]
shader: unshaded shader: unshaded
@@ -476,7 +476,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: locked - state: locked
map: ["enum.StorageVisualLayers.Lock"] map: ["enum.StorageVisualLayers.Lock"]
shader: unshaded shader: unshaded
@@ -505,7 +505,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: locked - state: locked
map: ["enum.StorageVisualLayers.Lock"] map: ["enum.StorageVisualLayers.Lock"]
shader: unshaded shader: unshaded
@@ -560,7 +560,7 @@
map: ["enum.StorageVisualLayers.Door"] map: ["enum.StorageVisualLayers.Door"]
- state: welded - state: welded
visible: false visible: false
map: ["enum.StorageVisualLayers.Welded"] map: ["enum.WeldableLayers.BaseWelded"]
- state: locked - state: locked
map: ["enum.StorageVisualLayers.Lock"] map: ["enum.StorageVisualLayers.Lock"]
shader: unshaded shader: unshaded
@@ -580,7 +580,6 @@
components: components:
- type: EntityStorage - type: EntityStorage
Capacity: 500 Capacity: 500
CanWeldShut: false
- type: Sprite - type: Sprite
sprite: Structures/Storage/Crates/livestock.rsi sprite: Structures/Storage/Crates/livestock.rsi
layers: layers:

View File

@@ -34,7 +34,6 @@
- VaultImpassable - VaultImpassable
- SmallImpassable - SmallImpassable
- type: MorgueEntityStorage - type: MorgueEntityStorage
CanWeldShut: false
IsCollidableWhenOpen: true IsCollidableWhenOpen: true
Capacity: 1 Capacity: 1
closeSound: closeSound:
@@ -116,7 +115,6 @@
- VaultImpassable - VaultImpassable
- SmallImpassable - SmallImpassable
- type: CrematoriumEntityStorage - type: CrematoriumEntityStorage
CanWeldShut: false
IsCollidableWhenOpen: true IsCollidableWhenOpen: true
Capacity: 1 Capacity: 1
closeSound: closeSound: