NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Level/AutoDeployment/AutoDeploymentManager.cs

260 lines
9.9 KiB
C#
Raw Normal View History

2025-03-27 15:01:26 +08:00
using System.Collections.Generic;
using Gameplay;
using Gameplay.Character;
using Gameplay.Level;
using Gameplay.Unit;
using PhxhSDK;
public class AutoDeploymentManager : Singlenton<AutoDeploymentManager>
{
2025-04-01 12:13:38 +08:00
public bool IsAutoDeployEnabled { get; private set; } = true;
2025-03-27 15:01:26 +08:00
// 存储每个格子的前出等级
private Dictionary<int, float> _cellForwardScores = new Dictionary<int, float>();
// 敌人分组信息
private List<EnemyGroup> _enemyGroups = new List<EnemyGroup>();
// 记录已分配的格子
private HashSet<int> _occupiedCells = new HashSet<int>();
private class EnemyGroup
{
public int centerCellIndex; // 改用cellIndex替代世界坐标
public int count;
}
private const int GROUP_DISTANCE_THRESHOLD = 3; // 六边形格子距离阈值
private void GroupEnemies(List<GameUnit> 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;
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[GroupEnemies] 敌人(格子={enemyCellIndex})加入组(中心={oldCenterCell}->新中心={newCenterCell}, 数量={group.count})");
2025-03-27 15:01:26 +08:00
break;
}
}
// 如果没有合适的分组,创建新分组
if (!added)
{
_enemyGroups.Add(new EnemyGroup
{
centerCellIndex = enemyCellIndex,
count = 1
});
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[GroupEnemies] 创建新敌人组: 中心格子 = {enemyCellIndex}, 数量 = 1");
2025-03-27 15:01:26 +08:00
}
}
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[GroupEnemies] 敌人分组完成,共 {_enemyGroups.Count} 个组");
2025-03-27 15:01:26 +08:00
}
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<GameUnit>();
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);
}
}
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[AutoDeploy] 找到可用己方单位: {availableUnits.Count}个");
2025-03-27 15:01:26 +08:00
// 2. 获取敌方单位
var enemies = new List<GameUnit>();
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);
}
}
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[AutoDeploy] 找到敌方单位: {enemies.Count}个");
2025-03-27 15:01:26 +08:00
// 3. 对敌人进行分组
GroupEnemies(enemies, level.Map);
// 4. 计算每个格子的前出等级
CalculateCellForwardScores(level.Map.MapData, level.GetLevelData().preparingRegionId);
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[AutoDeploy] 格子前出等级计算完成,共 {_cellForwardScores.Count} 个格子");
2025-03-27 15:01:26 +08:00
// 5. 对可用单位按前出程度排序
var sortedUnits = new List<GameUnit>(availableUnits);
UnitDeploymentSorter.SortUnitsForDeployment(sortedUnits);
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError("[AutoDeploy] 单位按前出程度排序完成");
2025-03-27 15:01:26 +08:00
// 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++;
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[AutoDeploy] 部署单位: ID = {unit.GetID()}, 职业 = {unit.commonData.eJob}, 格子 = {bestCell}");
2025-03-27 15:01:26 +08:00
}
else
{
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[AutoDeploy] 未找到合适格子部署单位: ID = {unit.GetID()}, 职业 = {unit.commonData.eJob}");
2025-03-27 15:01:26 +08:00
}
}
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[AutoDeploy] 自动部署完成,成功部署 {deployedCount}/{sortedUnits.Count} 个单位");
2025-03-27 15:01:26 +08:00
}
private int FindBestCellForUnit(GameUnit unit)
{
var unitForwardLevel = UnitForwardLevelHelper.GetUnitForwardLevel(unit);
var bestScore = float.MinValue;
var bestCell = -1;
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[FindBestCellForUnit] 为单位寻找最佳格子: ID = {unit.GetID()}, 职业 = {unit.commonData.eJob}, 前出等级 = {unitForwardLevel}");
2025-03-27 15:01:26 +08:00
// 遍历所有计算过前出等级的格子
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;
}
}
2025-04-01 12:13:38 +08:00
/*if (bestCell >= 0)
2025-03-27 15:01:26 +08:00
{
DebugUtil.LogError($"[FindBestCellForUnit] 找到最佳格子: {bestCell}, 调整后评分 = {bestScore}");
}
else
{
DebugUtil.LogError($"[FindBestCellForUnit] 未找到合适格子");
2025-04-01 12:13:38 +08:00
}*/
2025-03-27 15:01:26 +08:00
return bestCell;
}
private void CalculateCellForwardScores(MapData mapData, int preparingRegionId)
{
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError("[CalculateCellForwardScores] 开始计算格子前出等级");
2025-03-27 15:01:26 +08:00
_cellForwardScores.Clear();
var preparingRegion = mapData.GetRegion(preparingRegionId);
if (preparingRegion == null)
{
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[CalculateCellForwardScores] 错误:找不到准备区域(ID={preparingRegionId})");
2025-03-27 15:01:26 +08:00
return;
}
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[CalculateCellForwardScores] 准备区域格子数: {preparingRegion.positions.Count}");
2025-03-27 15:01:26 +08:00
// 对准备区域的每个格子计算分数
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;
}
2025-04-01 12:13:38 +08:00
/*// 记录最高分和最低分
2025-03-27 15:01:26 +08:00
if (_cellForwardScores.Count > 0)
{
var maxScore = _cellForwardScores.Max(p => p.Value);
var minScore = _cellForwardScores.Min(p => p.Value);
DebugUtil.LogError($"[CalculateCellForwardScores] 格子评分范围: 最低 = {minScore}, 最高 = {maxScore}");
}
2025-04-01 12:13:38 +08:00
DebugUtil.LogError($"[CalculateCellForwardScores] 计算完成,共 {_cellForwardScores.Count} 个格子");*/
2025-03-27 15:01:26 +08:00
}
public void SetAutoDeployEnabled(bool enabled)
{
IsAutoDeployEnabled = enabled;
2025-04-01 12:13:38 +08:00
// DebugUtil.LogError($"[SetAutoDeployEnabled] 自动部署功能已{(enabled ? "启用" : "禁用")}");
2025-03-27 15:01:26 +08:00
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] 自动部署功能未启用,跳过自动部署");
}
}
}