TurnBasedStrategyCourse/Assets/Scripts/Actions/UnitActionSystem.cs

100 lines
3.6 KiB
C#

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.GetPositionOnlyHitVisible());
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<bool> 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<MoveAction>();
}
public void SetSelectedAction(BaseAction baseAction) => SelectedAction = baseAction;
}
}