using UnityEngine; namespace MazeGen { /// /// Handles all validation logic for movement and attack ranges in combat. /// Centralizes rules for what's allowed vs. what's not. /// public static class MovementValidator { /// /// Determine the effective attack range for a weapon. /// Melee weapons have range 1 (adjacent), ranged/magic respect their Range attribute. /// public static int GetAttackRange(Weapon weapon) { if (weapon == null) return 1; return weapon.Range; } /// /// Check if an actor can attack a target with their equipped weapon. /// Melee: must be adjacent (1 square away) /// Ranged/Magic: must be within weapon range /// public static bool CanAttack(Combatant actor, Combatant target, Weapon weapon) { if (actor == null || target == null || weapon == null) return false; if (actor == target) return false; // Can't attack self if (!actor.IsAlive || !target.IsAlive) return false; // Only alive combatants can attack if (actor.Team == target.Team) return false; // Can't attack teammates return actor.CanReachTarget(target, weapon); } /// /// Check if an actor can move to a destination on the grid. /// Basic validation: not already there, not moving more than movement range, /// destination must be valid per the grid. /// public static bool CanMoveTo(Combatant actor, Vector2Int destination, CombatGrid grid) { if (actor == null || grid == null) return false; // Already at destination if (actor.GridPosition == destination) return false; // Calculate movement distance int movementDistance = actor.GridPosition.x != destination.x ? Mathf.Abs(actor.GridPosition.x - destination.x) : Mathf.Abs(actor.GridPosition.y - destination.y); // Check if within movement budget int maxMovement = actor.Sheet.Stats.GetMovementRange(); if (movementDistance > maxMovement) return false; // Check if destination is valid on grid return grid.IsPositionValid(destination, actor); } /// /// Check if two positions are adjacent (1 square apart, horizontally or vertically). /// Used for melee range validation. /// public static bool IsAdjacentTo(Vector2Int pos1, Vector2Int pos2) { int distX = Mathf.Abs(pos1.x - pos2.x); int distY = Mathf.Abs(pos1.y - pos2.y); // Adjacent means 1 square away (Manhattan distance = 1) return (distX == 1 && distY == 0) || (distX == 0 && distY == 1); } /// /// Calculate Manhattan distance between two grid positions. /// Used for range calculations and pathfinding. /// public static int ManhattanDistance(Vector2Int pos1, Vector2Int pos2) { return Mathf.Abs(pos1.x - pos2.x) + Mathf.Abs(pos1.y - pos2.y); } /// /// Get the direction from one position to another (returns normalized direction vector). /// Used for pathfinding towards targets. /// public static Vector2Int GetDirectionTowards(Vector2Int from, Vector2Int to) { Vector2Int direction = Vector2Int.zero; if (from.x < to.x) direction.x = 1; else if (from.x > to.x) direction.x = -1; if (from.y < to.y) direction.y = 1; else if (from.y > to.y) direction.y = -1; return direction; } /// /// Get a position one step closer to the target using Manhattan distance pathfinding. /// Used to move towards enemies during combat. /// public static Vector2Int GetNextPositionTowards(Vector2Int from, Vector2Int to) { if (from == to) return from; Vector2Int direction = GetDirectionTowards(from, to); // Prefer moving horizontally/vertically to get closer if (direction.x != 0) return from + new Vector2Int(direction.x, 0); else if (direction.y != 0) return from + new Vector2Int(0, direction.y); return from; } } }