MovementValidator.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. using UnityEngine;
  2. namespace MazeGen
  3. {
  4. /// <summary>
  5. /// Handles all validation logic for movement and attack ranges in combat.
  6. /// Centralizes rules for what's allowed vs. what's not.
  7. /// </summary>
  8. public static class MovementValidator
  9. {
  10. /// <summary>
  11. /// Determine the effective attack range for a weapon.
  12. /// Melee weapons have range 1 (adjacent), ranged/magic respect their Range attribute.
  13. /// </summary>
  14. public static int GetAttackRange(Weapon weapon)
  15. {
  16. if (weapon == null) return 1;
  17. return weapon.Range;
  18. }
  19. /// <summary>
  20. /// Check if an actor can attack a target with their equipped weapon.
  21. /// Melee: must be adjacent (1 square away)
  22. /// Ranged/Magic: must be within weapon range
  23. /// </summary>
  24. public static bool CanAttack(Combatant actor, Combatant target, Weapon weapon)
  25. {
  26. if (actor == null || target == null || weapon == null)
  27. return false;
  28. if (actor == target)
  29. return false; // Can't attack self
  30. if (!actor.IsAlive || !target.IsAlive)
  31. return false; // Only alive combatants can attack
  32. if (actor.Team == target.Team)
  33. return false; // Can't attack teammates
  34. return actor.CanReachTarget(target, weapon);
  35. }
  36. /// <summary>
  37. /// Check if an actor can move to a destination on the grid.
  38. /// Basic validation: not already there, not moving more than movement range,
  39. /// destination must be valid per the grid.
  40. /// </summary>
  41. public static bool CanMoveTo(Combatant actor, Vector2Int destination, CombatGrid grid)
  42. {
  43. if (actor == null || grid == null)
  44. return false;
  45. // Already at destination
  46. if (actor.GridPosition == destination)
  47. return false;
  48. // Calculate movement distance
  49. int movementDistance = actor.GridPosition.x != destination.x ?
  50. Mathf.Abs(actor.GridPosition.x - destination.x) :
  51. Mathf.Abs(actor.GridPosition.y - destination.y);
  52. // Check if within movement budget
  53. int maxMovement = actor.Sheet.Stats.GetMovementRange();
  54. if (movementDistance > maxMovement)
  55. return false;
  56. // Check if destination is valid on grid
  57. return grid.IsPositionValid(destination, actor);
  58. }
  59. /// <summary>
  60. /// Check if two positions are adjacent (1 square apart, horizontally or vertically).
  61. /// Used for melee range validation.
  62. /// </summary>
  63. public static bool IsAdjacentTo(Vector2Int pos1, Vector2Int pos2)
  64. {
  65. int distX = Mathf.Abs(pos1.x - pos2.x);
  66. int distY = Mathf.Abs(pos1.y - pos2.y);
  67. // Adjacent means 1 square away (Manhattan distance = 1)
  68. return (distX == 1 && distY == 0) || (distX == 0 && distY == 1);
  69. }
  70. /// <summary>
  71. /// Calculate Manhattan distance between two grid positions.
  72. /// Used for range calculations and pathfinding.
  73. /// </summary>
  74. public static int ManhattanDistance(Vector2Int pos1, Vector2Int pos2)
  75. {
  76. return Mathf.Abs(pos1.x - pos2.x) + Mathf.Abs(pos1.y - pos2.y);
  77. }
  78. /// <summary>
  79. /// Get the direction from one position to another (returns normalized direction vector).
  80. /// Used for pathfinding towards targets.
  81. /// </summary>
  82. public static Vector2Int GetDirectionTowards(Vector2Int from, Vector2Int to)
  83. {
  84. Vector2Int direction = Vector2Int.zero;
  85. if (from.x < to.x) direction.x = 1;
  86. else if (from.x > to.x) direction.x = -1;
  87. if (from.y < to.y) direction.y = 1;
  88. else if (from.y > to.y) direction.y = -1;
  89. return direction;
  90. }
  91. /// <summary>
  92. /// Get a position one step closer to the target using Manhattan distance pathfinding.
  93. /// Used to move towards enemies during combat.
  94. /// </summary>
  95. public static Vector2Int GetNextPositionTowards(Vector2Int from, Vector2Int to)
  96. {
  97. if (from == to) return from;
  98. Vector2Int direction = GetDirectionTowards(from, to);
  99. // Prefer moving horizontally/vertically to get closer
  100. if (direction.x != 0)
  101. return from + new Vector2Int(direction.x, 0);
  102. else if (direction.y != 0)
  103. return from + new Vector2Int(0, direction.y);
  104. return from;
  105. }
  106. }
  107. }