using System; using System.Collections.Generic; using Content.Shared.ActionBlocker; using Content.Shared.Hands.Components; using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; using Content.Shared.Interaction; namespace Content.Shared.Verbs { [Serializable, NetSerializable] public class RequestServerVerbsEvent : EntityEventArgs { public readonly EntityUid EntityUid; public readonly VerbType Type; /// /// 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 EntityUid? SlotOwner; public readonly bool AdminRequest; public RequestServerVerbsEvent(EntityUid entityUid, VerbType type, EntityUid? slotOwner = null, bool adminRequest = false) { EntityUid = entityUid; Type = type; SlotOwner = slotOwner; AdminRequest = adminRequest; } } [Serializable, NetSerializable] public class VerbsResponseEvent : EntityEventArgs { public readonly Dictionary>? Verbs; public readonly EntityUid Entity; public VerbsResponseEvent(EntityUid entity, Dictionary>? verbs) { Entity = entity; if (verbs == null) return; // Apparently SortedSet is not serlializable. Cast to List. Verbs = new(); foreach (var entry in verbs) { Verbs.Add(entry.Key, new List(entry.Value)); } } } [Serializable, NetSerializable] public class ExecuteVerbEvent : EntityEventArgs { public readonly EntityUid Target; public readonly Verb RequestedVerb; /// /// The type of verb to try execute. Avoids having to get a list of all verbs on the receiving end. /// public readonly VerbType Type; public ExecuteVerbEvent(EntityUid target, Verb requestedVerb, VerbType type) { Target = target; RequestedVerb = requestedVerb; Type = type; } } /// /// Request primary interaction verbs. This includes both use-in-hand and interacting with external entities. /// /// /// These verbs those that involve using the hands or the currently held item on some entity. These verbs usually /// correspond to interactions that can be triggered by left-clicking or using 'Z', and often depend on the /// currently held item. These verbs are collectively shown first in the context menu. /// public class GetInteractionVerbsEvent : GetVerbsEvent { public GetInteractionVerbsEvent(EntityUid user, EntityUid target, EntityUid? @using, SharedHandsComponent? hands, bool canInteract, bool canAccess) : base(user, target, @using, hands, canInteract, canAccess) { } } /// /// Request activation verbs. /// /// /// These are verbs that activate an item in the world but are independent of the currently held items. For /// example, opening a door or a GUI. These verbs should correspond to interactions that can be triggered by /// using 'E', though many of those can also be triggered by left-mouse or 'Z' if there is no other interaction. /// These verbs are collectively shown second in the context menu. /// public class GetActivationVerbsEvent : GetVerbsEvent { public GetActivationVerbsEvent(EntityUid user, EntityUid target, EntityUid? @using, SharedHandsComponent? hands, bool canInteract, bool canAccess) : base(user, target, @using, hands, canInteract, canAccess) { } } /// /// Request alternative-interaction verbs. /// /// /// When interacting with an entity via alt + left-click/E/Z the highest priority alt-interact verb is executed. /// These verbs are collectively shown second-to-last in the context menu. /// public class GetAlternativeVerbsEvent : GetVerbsEvent { public GetAlternativeVerbsEvent(EntityUid user, EntityUid target, EntityUid? @using, SharedHandsComponent? hands, bool canInteract, bool canAccess) : base(user, target, @using, hands, canInteract, canAccess) { } } /// /// Request Miscellaneous verbs. /// /// /// Includes (nearly) global interactions like "examine", "pull", or "debug". These verbs are collectively shown /// last in the context menu. /// public class GetOtherVerbsEvent : GetVerbsEvent { public GetOtherVerbsEvent(EntityUid user, EntityUid target, EntityUid? @using, SharedHandsComponent? hands, bool canInteract, bool canAccess) : base(user, target, @using, hands, canInteract, canAccess) { } } /// /// Directed event that requests verbs from any systems/components on a target entity. /// public class GetVerbsEvent : EntityEventArgs { /// /// Event output. Set of verbs that can be executed. /// public readonly SortedSet Verbs = new(); /// /// 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; /// /// The User's hand component. /// /// /// This may be null if the user has no hands. /// public readonly SharedHandsComponent? 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, SharedHandsComponent? hands, bool canInteract, bool canAccess) { User = user; Target = target; Using = @using; Hands = hands; CanAccess = canAccess; CanInteract = canInteract; } } }