using Content.Shared.DoAfter; using Content.Shared.Containers.ItemSlots; using Content.Shared.Verbs; using Robust.Shared.Audio.Systems; using Content.Shared.Examine; namespace Content.Shared.Paper; public sealed class EnvelopeSystem : EntitySystem { [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; [Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnInsertAttempt); SubscribeLocalEvent(OnEjectAttempt); SubscribeLocalEvent>(OnGetAltVerbs); SubscribeLocalEvent(OnDoAfter); SubscribeLocalEvent(OnExamine); } private void OnExamine(Entity ent, ref ExaminedEvent args) { if (ent.Comp.State == EnvelopeComponent.EnvelopeState.Sealed) { args.PushMarkup(Loc.GetString("envelope-sealed-examine", ("envelope", ent.Owner))); } else if (ent.Comp.State == EnvelopeComponent.EnvelopeState.Torn) { args.PushMarkup(Loc.GetString("envelope-torn-examine", ("envelope", ent.Owner))); } } private void OnGetAltVerbs(Entity ent, ref GetVerbsEvent args) { if (!args.CanAccess || !args.CanInteract || args.Hands == null) return; if (ent.Comp.State == EnvelopeComponent.EnvelopeState.Torn) return; var user = args.User; args.Verbs.Add(new AlternativeVerb() { Text = Loc.GetString(ent.Comp.State == EnvelopeComponent.EnvelopeState.Open ? "envelope-verb-seal" : "envelope-verb-tear"), IconEntity = GetNetEntity(ent.Owner), Act = () => { TryStartDoAfter(ent, user, ent.Comp.State == EnvelopeComponent.EnvelopeState.Open ? ent.Comp.SealDelay : ent.Comp.TearDelay); }, }); } private void OnInsertAttempt(Entity ent, ref ItemSlotInsertAttemptEvent args) { args.Cancelled |= ent.Comp.State != EnvelopeComponent.EnvelopeState.Open; } private void OnEjectAttempt(Entity ent, ref ItemSlotEjectAttemptEvent args) { args.Cancelled |= ent.Comp.State == EnvelopeComponent.EnvelopeState.Sealed; } private void TryStartDoAfter(Entity ent, EntityUid user, TimeSpan delay) { if (ent.Comp.EnvelopeDoAfter.HasValue) return; var doAfterEventArgs = new DoAfterArgs(EntityManager, user, delay, new EnvelopeDoAfterEvent(), ent.Owner, ent.Owner) { BreakOnDamage = true, NeedHand = true, BreakOnHandChange = true, MovementThreshold = 0.01f, DistanceThreshold = 1.0f, }; if (_doAfterSystem.TryStartDoAfter(doAfterEventArgs, out var doAfterId)) ent.Comp.EnvelopeDoAfter = doAfterId; } private void OnDoAfter(Entity ent, ref EnvelopeDoAfterEvent args) { ent.Comp.EnvelopeDoAfter = null; if (args.Cancelled) return; if (ent.Comp.State == EnvelopeComponent.EnvelopeState.Open) { _audioSystem.PlayPredicted(ent.Comp.SealSound, ent.Owner, args.User); ent.Comp.State = EnvelopeComponent.EnvelopeState.Sealed; Dirty(ent.Owner, ent.Comp); } else if (ent.Comp.State == EnvelopeComponent.EnvelopeState.Sealed) { _audioSystem.PlayPredicted(ent.Comp.TearSound, ent.Owner, args.User); ent.Comp.State = EnvelopeComponent.EnvelopeState.Torn; Dirty(ent.Owner, ent.Comp); if (_itemSlotsSystem.TryGetSlot(ent.Owner, ent.Comp.SlotId, out var slotComp)) _itemSlotsSystem.TryEjectToHands(ent.Owner, slotComp, args.User); } } }