AI/ActionSystem/Actions/LeaveParkAction.cs
namespace HC3;

public sealed class LeaveParkAction : AgentAction
{
	private ParkEntrance _entrance;
	private Vector3 _target;

	private Guest Guest => Agent as Guest;

	bool IsInsidePark => BuildingZone.Instance.IsOwned( Agent.WorldPosition );

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

		if ( Guest.IsArrested )
			return 1010f;

		if ( !IsInsidePark && Guest.Money < ParkManager.Instance.AdmissionFee )
			return 1010f;

		if ( !(ParkManager.Instance?.IsOpen() ?? false) )
			return 1010f;

		if ( Guest.Needs.Happiness < 0.05f )
			return 1010f;

		return 0f;
	}

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

		_entrance = Scene.GetAll<ParkEntrance>().FirstOrDefault();
		_target = Scene.GetComponentInChildren<SpawnPoint>()?.GameObject.WorldPosition
			   ?? _entrance?.WorldPosition
			   ?? Agent.WorldPosition;

		var flags = NavFlags.Default.WithFlag( NavFlags.Owned, false );
		Controller.Navigate( _target, flags );
	}

	bool wasInsidePark;

	public override Status TickAction()
	{
		if ( !IsInsidePark && wasInsidePark )
		{
			GuestManager.Instance.UnregisterGuest( Guest );
		}
		wasInsidePark = IsInsidePark;

		if ( WorldPosition.Distance( _target ) < 10f )
		{
			IParkEvents.PostToGameObject( Agent.GameObject.Root, x => x.OnAgentExit( Agent ) );
			return Status.Success;
		}

		// Re-navigate if path was lost (e.g. after save load)
		if ( !Controller.IsNavigating )
		{
			var flags = NavFlags.Default.WithFlag( NavFlags.Owned, false );
			Controller.Navigate( _target, flags );
		}

		return Status.Running;
	}

	public override ActionDisplayInfo? GetDisplay()
	{
		return new ActionDisplayInfo(
			"exit_to_app",
			Guest.IsArrested ? "Being arrested" : "Leaving the park",
			Controller.GetPathProgress()
		);
	}
}