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

public class DropOnUse : Component, IItemEvents
{
	/// <summary>
	/// The prefab to drop when an item has been used.
	/// </summary>
	[Property] public GameObject PrefabToDrop { get; set; }

	/// <summary>
	/// How much to vary the X and Y position when dropping.
	/// </summary>
	[Property] public RangedFloat PositionVariation { get; set; } = new( -2f, 2f );

	/// <summary>
	/// How much to vary yaw rotation when dropping.
	/// </summary>
	[Property] public RangedFloat YawVariation { get; set; } = new( 0f, 360f );

	/// <summary>
	/// How likely are we to drop this?
	/// </summary>
	[Property, Range( 0f, 1f )] public float DropChance { get; set; } = 0.6f;

	void IItemEvents.OnUsed( Item item )
	{
		if ( !Networking.IsHost )
			return;

		if ( Game.Random.Float() > DropChance )
			return;

		var startPosition = item.WorldPosition + Vector3.Up * 16f;
		startPosition.x += PositionVariation.GetValue();
		startPosition.y += PositionVariation.GetValue();

		var trace = Scene.Trace
			.WithTag( "path" )
			.Ray( startPosition, startPosition + Vector3.Down * 64f )
			.Run();

		if ( !trace.Hit )
			return;

		var go = PrefabToDrop?.Clone( trace.HitPosition );
		var randomYaw = Rotation.FromAxis( trace.Normal, YawVariation.GetValue() );
		go.WorldRotation = Rotation.LookAt( randomYaw.Forward, trace.Normal );
		go.NetworkSpawn();
	}
}