using Content.Shared.Hands.EntitySystems; using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Serialization; namespace Content.Shared.Hands.Components; [RegisterComponent, NetworkedComponent] [Access(typeof(SharedHandsSystem))] public sealed partial class HandsComponent : Component { /// /// The currently active hand. /// [ViewVariables] public Hand? ActiveHand; /// /// The item currently held in the active hand. /// [ViewVariables] public EntityUid? ActiveHandEntity => ActiveHand?.HeldEntity; [ViewVariables] public Dictionary Hands = new(); public int Count => Hands.Count; /// /// List of hand-names. These are keys for . The order of this list determines the order in which hands are iterated over. /// public List SortedHands = new(); /// /// The amount of throw impulse per distance the player is from the throw target. /// [DataField("throwForceMultiplier")] [ViewVariables(VVAccess.ReadWrite)] public float ThrowForceMultiplier { get; set; } = 10f; //should be tuned so that a thrown item lands about under the player's cursor /// /// Distance after which longer throw targets stop increasing throw impulse. /// [DataField("throwRange")] [ViewVariables(VVAccess.ReadWrite)] public float ThrowRange { get; set; } = 8f; /// /// Whether or not to add in-hand sprites for held items. Some entities (e.g., drones) don't want these. /// Used by the client. /// [DataField("showInHands")] public bool ShowInHands = true; /// /// Data about the current sprite layers that the hand is contributing to the owner entity. Used for sprite in-hands. /// Used by the client. /// public readonly Dictionary> RevealedLayers = new(); } [Serializable, NetSerializable] public sealed class Hand //TODO: This should definitely be a struct - Jezi { [ViewVariables] public string Name { get; } [ViewVariables] public HandLocation Location { get; } /// /// The container used to hold the contents of this hand. Nullable because the client must get the containers via , /// which may not be synced with the server when the client hands are created. /// [ViewVariables, NonSerialized] public ContainerSlot? Container; [ViewVariables] public EntityUid? HeldEntity => Container?.ContainedEntity; public bool IsEmpty => HeldEntity == null; public Hand(string name, HandLocation location, ContainerSlot? container = null) { Name = name; Location = location; Container = container; } } [Serializable, NetSerializable] public sealed class HandsComponentState : ComponentState { public readonly List Hands; public readonly List HandNames; public readonly string? ActiveHand; public HandsComponentState(HandsComponent handComp) { Hands = new(handComp.Hands.Values); HandNames = handComp.SortedHands; ActiveHand = handComp.ActiveHand?.Name; } } /// /// What side of the body this hand is on. /// public enum HandLocation : byte { Left, Middle, Right }