Add verbs to Open/Close Openable containers, and add optional seals (#24780)
* Implement closing; add open/close verbs * Add breakable seals * Allow custom verb names; make condiment bottles closeable * Remove pointless VV annotations and false defaults * Split Sealable off into a new component * Should have a Closed event too * Oh hey, there are icons I could use * Ternary operator * Add support for seal visualizers * Moved Sealable to Shared, added networking * Replaced bottle_close1.ogg
This commit is contained in:
32
Content.Shared/Nutrition/Components/SealableComponent.cs
Normal file
32
Content.Shared/Nutrition/Components/SealableComponent.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Content.Shared.Nutrition.EntitySystems;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Nutrition.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a tamper-evident seal on an Openable.
|
||||
/// Only affects the Examine text.
|
||||
/// Once the seal has been broken, it cannot be resealed.
|
||||
/// </summary>
|
||||
[NetworkedComponent, AutoGenerateComponentState]
|
||||
[RegisterComponent, Access(typeof(SealableSystem))]
|
||||
public sealed partial class SealableComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether the item's seal is intact (i.e. it has never been opened)
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool Sealed = true;
|
||||
|
||||
/// <summary>
|
||||
/// Text shown when examining and the item's seal has not been broken.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public LocId ExamineTextSealed = "drink-component-on-examine-is-sealed";
|
||||
|
||||
/// <summary>
|
||||
/// Text shown when examining and the item's seal has been broken.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public LocId ExamineTextUnsealed = "drink-component-on-examine-is-unsealed";
|
||||
}
|
||||
@@ -16,4 +16,11 @@ namespace Content.Shared.Nutrition.Components
|
||||
Opened,
|
||||
Layer
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum SealableVisuals : byte
|
||||
{
|
||||
Sealed,
|
||||
Layer,
|
||||
}
|
||||
}
|
||||
|
||||
59
Content.Shared/Nutrition/EntitySystems/SealableSystem.cs
Normal file
59
Content.Shared/Nutrition/EntitySystems/SealableSystem.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Nutrition.EntitySystems;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
|
||||
namespace Content.Shared.Nutrition.EntitySystems;
|
||||
|
||||
public sealed partial class SealableSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SealableComponent, ExaminedEvent>(OnExamined, after: new[] { typeof(SharedOpenableSystem) });
|
||||
SubscribeLocalEvent<SealableComponent, OpenableOpenedEvent>(OnOpened);
|
||||
}
|
||||
|
||||
private void OnExamined(EntityUid uid, SealableComponent comp, ExaminedEvent args)
|
||||
{
|
||||
if (!args.IsInDetailsRange)
|
||||
return;
|
||||
|
||||
var sealedText = comp.Sealed ? Loc.GetString(comp.ExamineTextSealed) : Loc.GetString(comp.ExamineTextUnsealed);
|
||||
|
||||
args.PushMarkup(sealedText);
|
||||
}
|
||||
|
||||
private void OnOpened(EntityUid uid, SealableComponent comp, OpenableOpenedEvent args)
|
||||
{
|
||||
comp.Sealed = false;
|
||||
|
||||
Dirty(uid, comp);
|
||||
|
||||
UpdateAppearance(uid, comp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update seal visuals to the current value.
|
||||
/// </summary>
|
||||
public void UpdateAppearance(EntityUid uid, SealableComponent? comp = null, AppearanceComponent? appearance = null)
|
||||
{
|
||||
if (!Resolve(uid, ref comp))
|
||||
return;
|
||||
|
||||
_appearance.SetData(uid, SealableVisuals.Sealed, comp.Sealed, appearance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the entity's seal is intact.
|
||||
/// Items without SealableComponent are considered unsealed.
|
||||
/// </summary>
|
||||
public bool IsSealed(EntityUid uid, SealableComponent? comp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref comp, false))
|
||||
return false;
|
||||
|
||||
return comp.Sealed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Content.Shared.Nutrition.EntitySystems;
|
||||
|
||||
public abstract partial class SharedOpenableSystem : EntitySystem
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised after an Openable is opened.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct OpenableOpenedEvent;
|
||||
|
||||
/// <summary>
|
||||
/// Raised after an Openable is closed.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct OpenableClosedEvent;
|
||||
Reference in New Issue
Block a user