using System.Linq; using Content.Server.Buckle.Components; using Content.Server.Storage.Components; using Content.Shared.Foldable; using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; namespace Content.Server.Foldable { [UsedImplicitly] public sealed class FoldableSystem : SharedFoldableSystem { [Dependency] private SharedContainerSystem _container = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnFoldableOpenAttempt); SubscribeLocalEvent(AddFoldVerb); } private void OnFoldableOpenAttempt(EntityUid uid, FoldableComponent component, StorageOpenAttemptEvent args) { if (component.IsFolded) args.Cancel(); } public bool TryToggleFold(FoldableComponent comp) { return TrySetFolded(comp, !comp.IsFolded); } public bool CanToggleFold(EntityUid uid, FoldableComponent? fold = null) { if (!Resolve(uid, ref fold)) return false; // Can't un-fold in hands / inventory if (_container.IsEntityInContainer(uid)) return false; // If an entity is buckled to the object we can't pick it up or fold it if (TryComp(uid, out StrapComponent? strap) && strap.BuckledEntities.Any()) return false; // Also check if this entity is "open" (e.g., body bags) return !TryComp(uid, out EntityStorageComponent? storage) || !storage.Open; } /// /// Try to fold/unfold /// /// /// Folded state we want /// True if successful public bool TrySetFolded(FoldableComponent comp, bool state) { if (state == comp.IsFolded) return false; if (!CanToggleFold(comp.Owner, comp)) return false; SetFolded(comp, state); return true; } /// /// Set the folded state of the given /// /// /// If true, the component will become folded, else unfolded public override void SetFolded(FoldableComponent component, bool folded) { base.SetFolded(component, folded); // You can't buckle an entity to a folded object if (TryComp(component.Owner, out StrapComponent? strap)) strap.Enabled = !component.IsFolded; } #region Verb private void AddFoldVerb(EntityUid uid, FoldableComponent component, GetAlternativeVerbsEvent args) { if (!args.CanAccess || !args.CanInteract || !CanToggleFold(uid, component)) return; Verb verb = new() { Act = () => TryToggleFold(component), Text = component.IsFolded ? Loc.GetString("unfold-verb") : Loc.GetString("fold-verb"), IconTexture = "/Textures/Interface/VerbIcons/fold.svg.192dpi.png", // If the object is unfolded and they click it, they want to fold it, if it's folded, they want to pick it up Priority = component.IsFolded ? 0 : 2, }; args.Verbs.Add(verb); } #endregion } }