2023-04-07 11:21:12 -07:00
using Content.Shared.Hands.EntitySystems ;
2021-06-21 02:21:20 -07:00
using Robust.Shared.Containers ;
2021-07-12 01:32:10 -07:00
using Robust.Shared.GameStates ;
2019-11-13 17:37:46 -05:00
using Robust.Shared.Serialization ;
2017-09-26 21:27:48 +02:00
2022-03-17 20:13:31 +13:00
namespace Content.Shared.Hands.Components ;
2021-06-21 02:21:20 -07:00
2023-04-07 11:21:12 -07:00
[RegisterComponent, NetworkedComponent]
[Access(typeof(SharedHandsSystem))]
2023-08-22 18:14:33 -07:00
public sealed partial class HandsComponent : Component
2022-03-17 20:13:31 +13:00
{
/// <summary>
/// The currently active hand.
/// </summary>
[ViewVariables]
public Hand ? ActiveHand ;
2021-07-31 03:14:00 +02:00
2022-03-17 20:13:31 +13:00
/// <summary>
/// The item currently held in the active hand.
/// </summary>
[ViewVariables]
public EntityUid ? ActiveHandEntity = > ActiveHand ? . HeldEntity ;
2020-07-25 15:11:16 +02:00
2022-03-17 20:13:31 +13:00
[ViewVariables]
public Dictionary < string , Hand > Hands = new ( ) ;
2017-09-26 21:27:48 +02:00
2022-03-17 20:13:31 +13:00
public int Count = > Hands . Count ;
2018-04-22 06:11:38 -05:00
/// <summary>
2022-03-17 20:13:31 +13:00
/// List of hand-names. These are keys for <see cref="Hands"/>. The order of this list determines the order in which hands are iterated over.
2018-04-22 06:11:38 -05:00
/// </summary>
2022-03-17 20:13:31 +13:00
public List < string > SortedHands = new ( ) ;
2018-11-21 20:58:11 +01:00
2020-01-17 18:41:47 -08:00
/// <summary>
2022-03-17 20:13:31 +13:00
/// The amount of throw impulse per distance the player is from the throw target.
2020-01-17 18:41:47 -08:00
/// </summary>
2022-03-17 20:13:31 +13:00
[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
2020-01-17 18:41:47 -08:00
2021-06-21 02:21:20 -07:00
/// <summary>
2022-03-17 20:13:31 +13:00
/// Distance after which longer throw targets stop increasing throw impulse.
2021-06-21 02:21:20 -07:00
/// </summary>
2022-03-17 20:13:31 +13:00
[DataField("throwRange")]
[ViewVariables(VVAccess.ReadWrite)]
public float ThrowRange { get ; set ; } = 8f ;
2023-04-07 11:21:12 -07:00
/// <summary>
/// Whether or not to add in-hand sprites for held items. Some entities (e.g., drones) don't want these.
/// Used by the client.
/// </summary>
[DataField("showInHands")]
public bool ShowInHands = true ;
/// <summary>
/// Data about the current sprite layers that the hand is contributing to the owner entity. Used for sprite in-hands.
/// Used by the client.
/// </summary>
public readonly Dictionary < HandLocation , HashSet < string > > RevealedLayers = new ( ) ;
2022-03-17 20:13:31 +13:00
}
2018-11-21 20:58:11 +01:00
2022-03-17 20:13:31 +13:00
[Serializable, NetSerializable]
2022-09-11 21:30:11 -07:00
public sealed class Hand //TODO: This should definitely be a struct - Jezi
2022-03-17 20:13:31 +13:00
{
[ViewVariables]
public string Name { get ; }
[ViewVariables]
public HandLocation Location { get ; }
2019-08-31 17:49:18 -07:00
2021-06-21 02:21:20 -07:00
/// <summary>
2022-03-17 20:13:31 +13:00
/// The container used to hold the contents of this hand. Nullable because the client must get the containers via <see cref="ContainerManagerComponent"/>,
/// which may not be synced with the server when the client hands are created.
2021-06-21 02:21:20 -07:00
/// </summary>
2022-03-17 20:13:31 +13:00
[ViewVariables, NonSerialized]
public ContainerSlot ? Container ;
2019-08-31 17:49:18 -07:00
2022-03-17 20:13:31 +13:00
[ViewVariables]
public EntityUid ? HeldEntity = > Container ? . ContainedEntity ;
2020-10-28 10:16:40 +01:00
2022-03-17 20:13:31 +13:00
public bool IsEmpty = > HeldEntity = = null ;
public Hand ( string name , HandLocation location , ContainerSlot ? container = null )
2020-07-25 15:11:16 +02:00
{
2022-03-17 20:13:31 +13:00
Name = name ;
Location = location ;
Container = container ;
2020-07-25 15:11:16 +02:00
}
2022-03-17 20:13:31 +13:00
}
2021-02-03 22:07:13 +00:00
2022-03-17 20:13:31 +13:00
[Serializable, NetSerializable]
public sealed class HandsComponentState : ComponentState
{
public readonly List < Hand > Hands ;
public readonly List < string > HandNames ;
public readonly string? ActiveHand ;
2021-06-21 02:21:20 -07:00
2023-04-07 11:21:12 -07:00
public HandsComponentState ( HandsComponent handComp )
2022-03-17 20:13:31 +13:00
{
2023-10-22 16:55:10 +11:00
// cloning lists because of test networking.
2022-03-17 20:13:31 +13:00
Hands = new ( handComp . Hands . Values ) ;
2023-10-22 16:55:10 +11:00
HandNames = new ( handComp . SortedHands ) ;
2022-03-17 20:13:31 +13:00
ActiveHand = handComp . ActiveHand ? . Name ;
2021-06-21 02:21:20 -07:00
}
2017-09-26 21:27:48 +02:00
}
2022-03-17 20:13:31 +13:00
/// <summary>
/// What side of the body this hand is on.
/// </summary>
public enum HandLocation : byte
{
Left ,
Middle ,
Right
}