AI/Guests/Inventory/Components/Wearable.cs
namespace HC3.Inventory;

public partial class Wearable : Component, IItemEvents
{
	[Property] public string Bone { get; set; }
	[Property] public string Attachment { get; set; }
	[Property] public bool UseRotation { get; set; } = true;
	[Property] public bool RandomColour { get; set; } = true;
	[Property] public ModelRenderer Renderer { get; set; }

	Item item;

	protected override void OnStart()
	{
		item = GetComponent<Item>();

		if ( Renderer.IsValid() && RandomColour )
		{
			Renderer.Tint = TycoonColor.RandomPalette();
		}

		AttachToBone();
	}

	private void AttachToBone()
	{
		if ( item?.Guest?.Body == null ) return;

		var body = item.Guest.Body;

		// Prefer attachment point if specified
		if ( !string.IsNullOrEmpty( Attachment ) && body.GetAttachment( Attachment ).HasValue )
		{
			var attach = body.GetAttachment( Attachment ).Value;

			// Parent to the bone that drives this attachment
			if ( !string.IsNullOrEmpty( Bone ) )
			{
				var boneGo = body.GetBoneObject( Bone );
				if ( boneGo != null )
				{
					GameObject.SetParent( boneGo, false );
					LocalPosition = boneGo.WorldTransform.PointToLocal( attach.Position );
					if ( UseRotation )
						LocalRotation = boneGo.WorldTransform.RotationToLocal( attach.Rotation );
					return;
				}
			}

			// No bone specified, just set world position
			GameObject.Flags |= GameObjectFlags.Absolute;
			WorldPosition = attach.Position;
			if ( UseRotation )
				WorldRotation = attach.Rotation;
			return;
		}

		// Parent directly to bone
		if ( !string.IsNullOrEmpty( Bone ) )
		{
			var boneGo = body.GetBoneObject( Bone );
			if ( boneGo != null )
			{
				GameObject.SetParent( boneGo, false );
				LocalPosition = Vector3.Zero;
				if ( UseRotation )
					LocalRotation = Rotation.Identity;
				return;
			}
		}
	}
}