using System.Collections.Generic; using Gameplay; using Gameplay.Character; using Gameplay.Level; using Gameplay.Unit; using PhxhSDK; public class AutoDeploymentManager : Singlenton { public bool IsAutoDeployEnabled { get; private set; } = true; // 存储每个格子的前出等级 private Dictionary _cellForwardScores = new Dictionary(); // 敌人分组信息 private List _enemyGroups = new List(); // 记录已分配的格子 private HashSet _occupiedCells = new HashSet(); private class EnemyGroup { public int centerCellIndex; // 改用cellIndex替代世界坐标 public int count; } private const int GROUP_DISTANCE_THRESHOLD = 3; // 六边形格子距离阈值 private void GroupEnemies(List enemies, Map map) { _enemyGroups.Clear(); foreach (var enemy in enemies) { var enemyCellIndex = enemy.transData.cellIndex; var added = false; // 尝试加入现有分组 foreach (var group in _enemyGroups) { // 使用 MapUtils.Distance 计算格子距离 int distance = MapUtils.Distance(map, enemyCellIndex, group.centerCellIndex); if (distance <= GROUP_DISTANCE_THRESHOLD) { // 更新组中心格子 var oldCenterCell = group.centerCellIndex; var newCenterCell = CalculateGroupCenterCell(group.centerCellIndex, enemyCellIndex, group.count, map); group.centerCellIndex = newCenterCell; group.count++; added = true; // DebugUtil.LogError($"[GroupEnemies] 敌人(格子={enemyCellIndex})加入组(中心={oldCenterCell}->新中心={newCenterCell}, 数量={group.count})"); break; } } // 如果没有合适的分组,创建新分组 if (!added) { _enemyGroups.Add(new EnemyGroup { centerCellIndex = enemyCellIndex, count = 1 }); // DebugUtil.LogError($"[GroupEnemies] 创建新敌人组: 中心格子 = {enemyCellIndex}, 数量 = 1"); } } // DebugUtil.LogError($"[GroupEnemies] 敌人分组完成,共 {_enemyGroups.Count} 个组"); } private int CalculateGroupCenterCell(int currentCenterCell, int newCellIndex, int currentCount, Map map) { // 获取当前中心和新格子的世界坐标 var currentCenterPos = map.TGSCellIndex2WorldPosition(currentCenterCell); var newCellPos = map.TGSCellIndex2WorldPosition(newCellIndex); // 计算新的中心点位置 var newCenterPos = (currentCenterPos * currentCount + newCellPos) / (currentCount + 1); // 找到最接近这个世界坐标的格子 map.WorldPosition2TGSCellIndex(newCenterPos, out int nearestCellIndex); return nearestCellIndex; } public void AutoDeploy(Level level) { // 清空已分配格子记录 _occupiedCells.Clear(); // 1. 获取可用的己方单位 var availableUnits = new List(); for (var i = 0; i < GameUnitManager.instance.totalUnits.count; i++) { var unit = GameUnitManager.instance.totalUnits.GetByIndex(i); if (unit.commonData.troopId == ETroopsId.Self && !GameUnitManager.instance.infightUnits.Contains(unit.GetID())) { availableUnits.Add(unit); } } // DebugUtil.LogError($"[AutoDeploy] 找到可用己方单位: {availableUnits.Count}个"); // 2. 获取敌方单位 var enemies = new List(); for (var i = 0; i < GameUnitManager.instance.infightUnits.count; i++) { var unit = GameUnitManager.instance.infightUnits.GetByIndex(i); if (unit.commonData.troopId != ETroopsId.Self) { enemies.Add(unit); } } // DebugUtil.LogError($"[AutoDeploy] 找到敌方单位: {enemies.Count}个"); // 3. 对敌人进行分组 GroupEnemies(enemies, level.Map); // 4. 计算每个格子的前出等级 CalculateCellForwardScores(level.Map.MapData, level.GetLevelData().preparingRegionId); // DebugUtil.LogError($"[AutoDeploy] 格子前出等级计算完成,共 {_cellForwardScores.Count} 个格子"); // 5. 对可用单位按前出程度排序 var sortedUnits = new List(availableUnits); UnitDeploymentSorter.SortUnitsForDeployment(sortedUnits); // DebugUtil.LogError("[AutoDeploy] 单位按前出程度排序完成"); // 6. 为每个单位分配位置 int deployedCount = 0; foreach(var unit in sortedUnits) { var bestCell = FindBestCellForUnit(unit); if (bestCell >= 0) { var yaw = LevelUtils.SetCharaterToward(level.GetLevelData().preparingRegionToward); // 部署单位 GameUnitManager.instance.MoveUnitToFight(unit.GetID(), bestCell, yaw); // 标记格子为已占用 _occupiedCells.Add(bestCell); deployedCount++; // DebugUtil.LogError($"[AutoDeploy] 部署单位: ID = {unit.GetID()}, 职业 = {unit.commonData.eJob}, 格子 = {bestCell}"); } else { // DebugUtil.LogError($"[AutoDeploy] 未找到合适格子部署单位: ID = {unit.GetID()}, 职业 = {unit.commonData.eJob}"); } } // DebugUtil.LogError($"[AutoDeploy] 自动部署完成,成功部署 {deployedCount}/{sortedUnits.Count} 个单位"); } private int FindBestCellForUnit(GameUnit unit) { var unitForwardLevel = UnitForwardLevelHelper.GetUnitForwardLevel(unit); var bestScore = float.MinValue; var bestCell = -1; // DebugUtil.LogError($"[FindBestCellForUnit] 为单位寻找最佳格子: ID = {unit.GetID()}, 职业 = {unit.commonData.eJob}, 前出等级 = {unitForwardLevel}"); // 遍历所有计算过前出等级的格子 foreach (var kvp in _cellForwardScores) { var cellIndex = kvp.Key; var score = kvp.Value; // 检查格子是否已被占用(使用 HashSet 直接检查) if (_occupiedCells.Contains(cellIndex)) continue; // 根据单位的前出程度调整分数 var adjustedScore = score * unitForwardLevel; if (adjustedScore > bestScore) { bestScore = adjustedScore; bestCell = cellIndex; } } /*if (bestCell >= 0) { DebugUtil.LogError($"[FindBestCellForUnit] 找到最佳格子: {bestCell}, 调整后评分 = {bestScore}"); } else { DebugUtil.LogError($"[FindBestCellForUnit] 未找到合适格子"); }*/ return bestCell; } private void CalculateCellForwardScores(MapData mapData, int preparingRegionId) { // DebugUtil.LogError("[CalculateCellForwardScores] 开始计算格子前出等级"); _cellForwardScores.Clear(); var preparingRegion = mapData.GetRegion(preparingRegionId); if (preparingRegion == null) { // DebugUtil.LogError($"[CalculateCellForwardScores] 错误:找不到准备区域(ID={preparingRegionId})"); return; } // DebugUtil.LogError($"[CalculateCellForwardScores] 准备区域格子数: {preparingRegion.positions.Count}"); // 对准备区域的每个格子计算分数 foreach (var cellIndex in preparingRegion.positions) { float score = 0; // 计算与所有敌人组的距离评分 foreach (var group in _enemyGroups) { // 使用 MapUtils.Distance 计算格子距离 int distance = MapUtils.Distance( LevelManager.Instance.CurrentLevel.Map, cellIndex, group.centerCellIndex); // 距离越近分数越高,同时考虑敌人组的数量权重 // 使用 1.0f / (distance + 1) 确保不会除以0,并且距离越近分数越高 var groupScore = (1.0f / (distance + 1)) * group.count; score += groupScore; } _cellForwardScores[cellIndex] = score; } /*// 记录最高分和最低分 if (_cellForwardScores.Count > 0) { var maxScore = _cellForwardScores.Max(p => p.Value); var minScore = _cellForwardScores.Min(p => p.Value); DebugUtil.LogError($"[CalculateCellForwardScores] 格子评分范围: 最低 = {minScore}, 最高 = {maxScore}"); } DebugUtil.LogError($"[CalculateCellForwardScores] 计算完成,共 {_cellForwardScores.Count} 个格子");*/ } public void SetAutoDeployEnabled(bool enabled) { IsAutoDeployEnabled = enabled; // DebugUtil.LogError($"[SetAutoDeployEnabled] 自动部署功能已{(enabled ? "启用" : "禁用")}"); if (enabled && LevelManager.Instance.CurrentLevel != null) { AutoDeploy(LevelManager.Instance.CurrentLevel); } } public void OnLevelPreparationStart() { if (IsAutoDeployEnabled) { DebugUtil.Log("[OnLevelPreparationStart] 自动部署功能已启用,开始执行自动部署"); AutoDeploy(LevelManager.Instance.CurrentLevel); } else { DebugUtil.Log("[OnLevelPreparationStart] 自动部署功能未启用,跳过自动部署"); } } }