using System; using Grid; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Serialization; namespace Actions { public class UnitActionSystem : MonoBehaviour { [FormerlySerializedAs("UnitsLayerMask")] [SerializeField] private LayerMask unitsLayerMask; [SerializeField] private Unit selectedUnit; private bool isBusy; private BaseAction selectedAction; public static UnitActionSystem Instance { get; private set; } private bool IsBusy { get => isBusy; set { isBusy = value; OnBusyChanged?.Invoke(this, IsBusy); } } public BaseAction SelectedAction { get => selectedAction; private set { selectedAction = value; OnSelectedActionChanged?.Invoke(this, EventArgs.Empty); } } public Unit SelectedUnit { get => selectedUnit; private set { selectedUnit = value; OnSelectedUnitChanged?.Invoke(this, EventArgs.Empty); } } private void Awake() { if (Instance is not null) { Debug.LogError($"There is more than one UnitActionSystem! {transform} - {Instance}"); Destroy(gameObject); return; } Instance = this; } private void Start() => SetSelectedUnit(SelectedUnit); private void Update() { Debug.Log(LevelGrid.Instance.GetGridPosition(MouseWorld.GetPosition())); if (IsBusy) return; if (!TurnSystem.Instance.IsPlayerTurn) return; if (EventSystem.current.IsPointerOverGameObject()) return; if (TryHandleUnitSelection()) return; if (SelectedUnit is not null) HandleSelectedAction(); } private void HandleSelectedAction() { if (!InputManager.Instance.IsMouseButtonDownThisFrame()) return; GridPosition mouseGridPosition = LevelGrid.Instance.GetGridPosition(MouseWorld.GetPosition()); if (!SelectedAction.IsValidActionGridPosition(mouseGridPosition)) return; if (!selectedUnit.TrySpendActionPointsToTakeAction(SelectedAction)) return; SetBusy(); SelectedAction.TakeAction(mouseGridPosition, ClearBusy); OnActionStarted?.Invoke(this, EventArgs.Empty); } private void SetBusy() => IsBusy = true; private void ClearBusy() => IsBusy = false; public event EventHandler OnSelectedUnitChanged; public event EventHandler OnSelectedActionChanged; public event EventHandler OnBusyChanged; public event EventHandler OnActionStarted; private bool TryHandleUnitSelection() { if (!InputManager.Instance.IsMouseButtonDownThisFrame()) return false; if (!Physics.Raycast(Camera.main.ScreenPointToRay(InputManager.Instance.GetMouseScreenPosition()), out RaycastHit raycastHit, float.MaxValue, unitsLayerMask)) return false; if (!raycastHit.transform.TryGetComponent(out Unit unit) || unit is null) return false; if (unit == selectedUnit) return false; if (unit.IsEnemy) return false; SetSelectedUnit(unit); return true; } private void SetSelectedUnit(Unit unit) { SelectedUnit = unit; SelectedAction = unit.GetAction(); } public void SetSelectedAction(BaseAction baseAction) => SelectedAction = baseAction; } }