using System; using System.Collections.Generic; using Grid; using UnityEngine; namespace Actions { public class SwordAction : BaseAction { private State state; private float stateTimer; public int MaxSwordDistance { get; private set; } private Unit TargetUnit { get; set; } protected override void Awake() { base.Awake(); ActionPointsCost = 1; MaxSwordDistance = 1; ActionName = "Sword"; } private void Update() { if (!IsActive) return; stateTimer -= Time.deltaTime; switch (state) { case State.SwingingSwordBeforeHit: Vector3 aimDirection = (TargetUnit.GetWorldPosition() - Unit.GetWorldPosition()).normalized; const float rotationSpeed = 10f; transform.forward = Vector3.Lerp(transform.forward, aimDirection, rotationSpeed * Time.deltaTime); break; case State.SwingingSwordAfterHit: break; } if (stateTimer <= 0f) NextState(); } public static event EventHandler OnAnySwordHit; public event EventHandler OnSwordActionStarted; public event EventHandler OnSwordActionCompleted; public override void TakeAction(GridPosition gridPosition, Action onActionComplete) { TargetUnit = LevelGrid.Instance.GetUnitAtGridPosition(gridPosition); state = State.SwingingSwordBeforeHit; const float beforeHitStateTime = 0.7f; stateTimer = beforeHitStateTime; OnSwordActionStarted?.Invoke(this, EventArgs.Empty); ActionStart(onActionComplete); } public override List GetValidActionGridPositionList() { List validGridPositionList = new(); GridPosition unitGridPosition = Unit.GridPosition; for (int x = -MaxSwordDistance; x <= MaxSwordDistance; x++) { for (int z = -MaxSwordDistance; z <= MaxSwordDistance; z++) { GridPosition offsetGridPosition = new(x, z, 0); GridPosition testGridPosition = unitGridPosition + offsetGridPosition; if (!LevelGrid.Instance.IsValidGridPosition(testGridPosition)) continue; //Only return valid grid positions if (!LevelGrid.Instance.HasAnyUnitOnGridPosition(testGridPosition)) continue; //Grid position is empty, no unit Unit unitAtGridPosition = LevelGrid.Instance.GetUnitAtGridPosition(testGridPosition); if (unitAtGridPosition.IsEnemy == Unit.IsEnemy) continue; //Both units are on the same 'team' // TargetUnit = unitAtGridPosition; validGridPositionList.Add(testGridPosition); } } return validGridPositionList; } protected override EnemyAIAction GetEnemyAIAction(GridPosition gridPosition) => new(gridPosition, 200); private void NextState() { switch (state) { case State.SwingingSwordBeforeHit: state = State.SwingingSwordAfterHit; const float afterHitStateTime = 0.5f; stateTimer = afterHitStateTime; TargetUnit.Damage(100); OnAnySwordHit?.Invoke(this, EventArgs.Empty); break; case State.SwingingSwordAfterHit: OnSwordActionCompleted?.Invoke(this, EventArgs.Empty); ActionComplete(); break; } } private enum State { SwingingSwordBeforeHit, SwingingSwordAfterHit, } } }