using Content.Shared.ActionBlocker; using Content.Shared.Hands.Components; using Content.Shared.Interaction; using Robust.Shared.Containers; using Robust.Shared.Serialization; using Robust.Shared.Utility; namespace Content.Shared.Verbs { [Serializable, NetSerializable] public sealed class RequestServerVerbsEvent : EntityEventArgs { public readonly NetEntity EntityUid; public readonly List VerbTypes = new(); /// /// If the target item is inside of some storage (e.g., backpack), this is the entity that owns that item /// slot. Needed for validating that the user can access the target item. /// public readonly NetEntity? SlotOwner; public readonly bool AdminRequest; public RequestServerVerbsEvent(NetEntity entityUid, IEnumerable verbTypes, NetEntity? slotOwner = null, bool adminRequest = false) { EntityUid = entityUid; SlotOwner = slotOwner; AdminRequest = adminRequest; foreach (var type in verbTypes) { DebugTools.Assert(typeof(Verb).IsAssignableFrom(type)); VerbTypes.Add(type.Name); } } } [Serializable, NetSerializable] public sealed class VerbsResponseEvent : EntityEventArgs { public readonly List? Verbs; public readonly NetEntity Entity; public VerbsResponseEvent(NetEntity entity, SortedSet? verbs) { Entity = entity; if (verbs == null) return; // Apparently SortedSet is not serializable, so we cast to List. Verbs = new(verbs); } } [Serializable, NetSerializable] public sealed class ExecuteVerbEvent : EntityEventArgs { public readonly NetEntity Target; public readonly Verb RequestedVerb; public ExecuteVerbEvent(NetEntity target, Verb requestedVerb) { Target = target; RequestedVerb = requestedVerb; } } /// /// Directed event that requests verbs from any systems/components on a target entity. /// public sealed class GetVerbsEvent : EntityEventArgs where TVerb : Verb { /// /// Event output. Set of verbs that can be executed. /// public readonly SortedSet Verbs = new(); /// /// Additional verb categories to show in the pop-up menu, even if there are no verbs currently associated /// with that category. This is mainly useful to prevent verb menu pop-in. E.g., admins will get admin/debug /// related verbs on entities, even though most of those verbs are all defined server-side. /// public readonly List ExtraCategories; /// /// Can the user physically access the target? /// /// /// This is a combination of and /// . /// public readonly bool CanAccess = false; /// /// The entity being targeted for the verb. /// public readonly EntityUid Target; /// /// The entity that will be "performing" the verb. /// public readonly EntityUid User; /// /// Can the user physically interact? /// /// /// This is a just a cached result. Given that many verbs need /// to check this, it prevents it from having to be repeatedly called by each individual system that might /// contribute a verb. /// public readonly bool CanInteract; /// /// Cached version of CanComplexInteract /// public readonly bool CanComplexInteract; /// /// The User's hand component. /// /// /// This may be null if the user has no hands. /// public readonly HandsComponent? Hands; /// /// The entity currently being held by the active hand. /// /// /// This is only ever not null when is true and the user /// has hands. /// public readonly EntityUid? Using; public GetVerbsEvent(EntityUid user, EntityUid target, EntityUid? @using, HandsComponent? hands, bool canInteract, bool canComplexInteract, bool canAccess, List extraCategories) { User = user; Target = target; Using = @using; Hands = hands; CanAccess = canAccess; CanComplexInteract = canComplexInteract; CanInteract = canInteract; ExtraCategories = extraCategories; } } }