public static Dictionary <short, MoveNode> GetReachableZone(FightGame fight, Map map, short currentCellId) { Dictionary <short, MoveNode> zone = new Dictionary <short, MoveNode>(); if (fight.PlayedFighter.MovementPoints <= 0) { return(zone); } var maxDistance = fight.PlayedFighter.MovementPoints; List <PathNode> opened = new List <PathNode>(); Dictionary <short, PathNode> closed = new Dictionary <short, PathNode>(); var node = new PathNode(currentCellId, fight.PlayedFighter.MovementPoints, fight.PlayedFighter.ActionPoints, 0, 0, 1); opened.Add(node); closed[currentCellId] = node; while (opened.Count > 0) { var current = opened.Last(); opened.Remove(current); var cellId = current.CellId; var neighbours = MapPoint.GetNeighbourCells(cellId, false); var tacklers = new List <FighterEntry>(); int i = 0; while (i < neighbours.Count) { var tackler = fight.Fighters.FirstOrDefault(f => f.CellId == neighbours[i]?.CellId); if (neighbours[i] != null && tackler == null) { i++; continue; } neighbours.RemoveAt(i); if (tackler != null) { tacklers.Add(tackler); } } GetTackleCost(fight, tacklers, current.AvailableMp, current.AvailableAp, out int mpCost, out int apCost); var availableMp = current.AvailableMp - mpCost - 1; var availableAp = current.AvailableAp - apCost; var tackleMp = current.TackleMp + mpCost; var tackleAp = current.TackleAp + apCost; var distance = current.Distance + 1; var reachable = availableMp >= 0; // TODO: Handle marked cells for (i = 0; i < neighbours.Count; i++) { if (closed.ContainsKey(neighbours[i].CellId)) { var previous = closed[neighbours[i].CellId]; if (previous.AvailableMp > availableMp) { continue; } if (previous.AvailableMp == availableMp && previous.AvailableAp >= availableAp) { continue; } } if (!map.Cells[neighbours[i].CellId].IsWalkable(true)) { continue; } zone[neighbours[i].CellId] = new MoveNode(apCost, mpCost, cellId, reachable); node = new PathNode(neighbours[i].CellId, availableMp, availableAp, tackleMp, tackleAp, distance); closed[neighbours[i].CellId] = node; if (current.Distance < maxDistance) { opened.Add(node); } } } foreach (short cellKey in zone.Keys) { zone[cellKey].Path = GetPath(currentCellId, cellKey, zone); } return(zone); }