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;
}
}
}