AI/ActionSystem/Actions/Guest/DisposeTrashAction.cs
using HC3.Inventory;

namespace HC3;

public sealed class DisposeTrashAction : AgentAction
{
	[Sync( SyncFlags.FromHost )]
	private Bin Bin { get; set; }

	private Guest Guest => Agent as Guest;

	public override float Score()
	{
		if ( !Guest.IsValid() ) return 0f;
		if ( Bin.IsValid() ) return 300f;

		bool hasTrash = false;
		var items = Guest.Inventory.Items;
		for ( int i = 0; i < items.Count; i++ )
		{
			if ( items[i].GetComponent<Trash>().IsValid() )
			{
				hasTrash = true;
				break;
			}
		}
		if ( !hasTrash ) return 0f;

		// Find nearest walkable bin without LINQ allocation
		Bin nearest = null;
		float nearestDist = float.MaxValue;
		foreach ( var b in Scene.GetAll<Bin>() )
		{
			float dist = b.WorldPosition.DistanceSquared( Agent.WorldPosition );
			if ( dist < nearestDist && GridManager.IsWalkable( Agent.WorldPosition, b.WorldPosition ) )
			{
				nearestDist = dist;
				nearest = b;
			}
		}
		Bin = nearest;

		return Bin.IsValid() ? 300f : 0f;
	}

	public override void StartAction()
	{
		Controller.ClearNavigation();
	}

	public override Status TickAction()
	{
		if ( !Bin.IsValid() )
			return Status.Failure;

		var targetPos = Bin.WorldPosition;

		if ( !GridManager.IsWalkable( Agent.WorldPosition, targetPos ) )
		{
			Bin = null;
			return Status.Failure;
		}

		var flags = NavFlags.Default.WithFlag( NavFlags.Owned, false );

		if ( targetPos.Distance( Agent.WorldPosition ) > 64f && !Controller.Navigate( targetPos, flags ) )
			return Status.Running;

		Guest.Inventory.RemoveAll<Trash>();

		var building = Bin.GetComponentInChildren<Building>();

		if ( building.IsValid() )
		{
			building.Uses++;
		}

		Bin = null;

		return Status.Success;
	}

	public override void StopAction()
	{
		Bin = null;
	}

	public override ActionDisplayInfo? GetDisplay()
	{
		if ( !Bin.IsValid() ) return null;

		var dist = Agent.WorldPosition.Distance( Bin.WorldPosition );
		var progress = 1f - (dist / 1500f).Clamp( 0f, 1f );

		return new ActionDisplayInfo(
			"delete",
			$"Disposing of Trash",
			progress
		);
	}
}