using System.Collections.Generic; using TGS; using UnityEngine; namespace Gameplay.LegionBattle.View { public class FightLineMap2 { private Dictionary _mapCellDict; private List _mapCellList; private TerrainGridSystem _tgs; public FightLineMap2(TerrainGridSystem tgs) { _tgs = tgs; _mapCellDict = new Dictionary(); _mapCellList = new List(); var allCellList = tgs.cells; for (int i = 0; i < allCellList.Count; i++) { var cell = allCellList[i]; var cellIndex = cell.index; var mapCell = new FightLineCell2(cellIndex); _mapCellDict.Add(cellIndex, mapCell); _mapCellList.Add(mapCell); } for (int i = 0; i < allCellList.Count; i++) { var cell = allCellList[i]; var cellIndex = cell.index; var mapCell = _mapCellDict[cellIndex]; var neighborCellList = cell.neighbours; for (int j = 0; j < neighborCellList.Count; j++) { var neighborCell = neighborCellList[j]; var neighborCellIndex = neighborCell.index; if (_mapCellDict.TryGetValue(neighborCellIndex, out var neighborMapCell)) { mapCell.neighCells.Add(neighborMapCell); } } } } public void CreateView(GameObject sampleObj) { for (int i = 0; i < _mapCellList.Count; i++) { var cell = _mapCellList[i]; var worldPos = _tgs.CellGetPosition(cell.cellIndex); cell.CreateView(sampleObj, worldPos); } } public void Init(IList allUnits) { _UpdateUnitsGroup(allUnits); _UpdateBuildings(true); } public void UpdateColor() { var cellCount = _mapCellList.Count; for (int i = 0; i < cellCount; i++) { _mapCellList[i].UpdateColor(); } } public void DestroyView() { var cellCount = _mapCellList.Count; for (int i = 0; i < cellCount; i++) { _mapCellList[i].DestroyView(); } } public FightLineCell2 GetCell(int cellIndex) { if (_mapCellDict.TryGetValue(cellIndex, out var cell)) { return cell; } return null; } private List _teamLeftStandUnits = new List(); private List _teamRightStandUnits = new List(); private List _teamLeftBuildingUnits = new List(); private List _teamRightBuildingUnits = new List(); private List _teamLeftCellList = new List(); private List _teamRightCellList = new List(); private List _teamLeftCellList2 = new List(); private List _teamRightCellList2 = new List(); public void UpdateStandMap(IList totalCells) { _UpdateUnitsGroup(totalCells); _UpdateBuildings(false); _UpdateMoveUnits(); } private void _UpdateMoveUnits() { for (int i = 0; i < _mapCellList.Count; i++) { var cell = _mapCellList[i]; cell.isVisited = false; cell.iteration = 0; } _teamLeftCellList.Clear(); _teamLeftCellList2.Clear(); _teamRightCellList.Clear(); _teamRightCellList2.Clear(); for (int i = 0; i < _teamLeftStandUnits.Count; i++) { var unit = _teamLeftStandUnits[i]; var cell = GetCell(unit.standCellIndex); if (cell == null) continue; if (cell.standValue != unit.side) { continue; } cell.iteration = unit.maxDistance; cell.isVisited = true; _teamLeftCellList.Add(cell); } for (int i = 0; i < _teamRightStandUnits.Count; i++) { var unit = _teamRightStandUnits[i]; var cell = GetCell(unit.standCellIndex); if (cell == null) continue; if (cell.standValue != unit.side) { continue; } cell.iteration = unit.maxDistance; cell.isVisited = true; _teamRightCellList.Add(cell); } // 向外扩张 while (_teamLeftCellList.Count > 0 || _teamRightCellList.Count > 0) { for (int i = 0; i < _teamLeftCellList.Count; i++) { var cell = _teamLeftCellList[i]; cell.standValue = -1; if (cell.iteration > 0) { var aroundCellList = cell.neighCells; for (int j = 0; j < aroundCellList.Count; j++) { var aroundCell = aroundCellList[j]; if (aroundCell.isVisited || aroundCell.claimUnit != null && aroundCell.claimUnit.side != -1) continue; aroundCell.iteration = Mathf.Max(cell.iteration - 1, aroundCell.iteration); aroundCell.isVisited = true; _teamLeftCellList2.Add(aroundCell); } } } _teamLeftCellList.Clear(); _teamLeftCellList.AddRange(_teamLeftCellList2); _teamLeftCellList2.Clear(); for (int i = 0; i < _teamRightCellList.Count; i++) { var cell = _teamRightCellList[i]; cell.standValue = 1; if (cell.iteration > 0) { var aroundCellList = cell.neighCells; for (int j = 0; j < aroundCellList.Count; j++) { var aroundCell = aroundCellList[j]; if (aroundCell.isVisited || aroundCell.claimUnit != null && aroundCell.claimUnit.side != 1) continue; aroundCell.isVisited = true; aroundCell.iteration = Mathf.Max(cell.iteration - 1, aroundCell.iteration); _teamRightCellList2.Add(aroundCell); } } } _teamRightCellList.Clear(); _teamRightCellList.AddRange(_teamRightCellList2); _teamRightCellList2.Clear(); } } private void _UpdateBuildings(bool isFillAll) { for (int i = 0; i < _mapCellList.Count; i++) { var cell = _mapCellList[i]; cell.isVisited = false; cell.iteration = 0; cell.claimUnit = null; } _teamLeftCellList.Clear(); _teamLeftCellList2.Clear(); _teamRightCellList.Clear(); _teamRightCellList2.Clear(); for (int i = 0; i < _teamLeftBuildingUnits.Count; i++) { var unit = _teamLeftBuildingUnits[i]; var cell = GetCell(unit.standCellIndex); if (cell == null) continue; cell.iteration = unit.maxDistance; cell.isVisited = true; cell.claimUnit = unit; _teamLeftCellList.Add(cell); } for (int i = 0; i < _teamRightBuildingUnits.Count; i++) { var unit = _teamRightBuildingUnits[i]; var cell = GetCell(unit.standCellIndex); if (cell == null) continue; cell.iteration = unit.maxDistance; cell.isVisited = true; cell.claimUnit = unit; _teamRightCellList.Add(cell); } // 向外扩张 while (_teamLeftCellList.Count > 0 || _teamRightCellList.Count > 0) { for (int i = 0; i < _teamLeftCellList.Count; i++) { var cell = _teamLeftCellList[i]; cell.standValue = -1; cell.claimUnit = _teamLeftBuildingUnits[0]; if (cell.iteration > 0 || isFillAll) { var aroundCellList = cell.neighCells; for (int j = 0; j < aroundCellList.Count; j++) { var aroundCell = aroundCellList[j]; if (aroundCell.isVisited) continue; aroundCell.iteration = Mathf.Max(cell.iteration - 1, aroundCell.iteration); aroundCell.isVisited = true; _teamLeftCellList2.Add(aroundCell); } } } _teamLeftCellList.Clear(); _teamLeftCellList.AddRange(_teamLeftCellList2); _teamLeftCellList2.Clear(); for (int i = 0; i < _teamRightCellList.Count; i++) { var cell = _teamRightCellList[i]; cell.standValue = 1; cell.claimUnit = _teamRightBuildingUnits[0]; if (cell.iteration > 0 || isFillAll) { var aroundCellList = cell.neighCells; for (int j = 0; j < aroundCellList.Count; j++) { var aroundCell = aroundCellList[j]; if (aroundCell.isVisited) continue; aroundCell.isVisited = true; aroundCell.iteration = Mathf.Max(cell.iteration - 1, aroundCell.iteration); _teamRightCellList2.Add(aroundCell); } } } _teamRightCellList.Clear(); _teamRightCellList.AddRange(_teamRightCellList2); _teamRightCellList2.Clear(); } } private void _UpdateUnitsGroup(IList allUnits) { _teamLeftStandUnits.Clear(); _teamRightStandUnits.Clear(); _teamLeftBuildingUnits.Clear(); _teamRightBuildingUnits.Clear(); for (int i = 0; i < allUnits.Count; i++) { var unit = allUnits[i]; var isLeft = unit.side < 0; if (unit.isBuild) { if (isLeft) { _teamLeftBuildingUnits.Add(unit); } else { _teamRightBuildingUnits.Add(unit); } } else { if (isLeft) { _teamLeftStandUnits.Add(unit); } else { _teamRightStandUnits.Add(unit); } } } } private FightLineCell2 _SearchNoFinishCell() { for (int i = 0; i < _mapCellList.Count; i++) { var cell = _mapCellList[i]; if (!cell.isVisited) { return cell; } } return null; } private List _areas = new List(); private Queue _workQuen = new Queue(); public void UpdateAreas() { _areas.Clear(); for (int i = 0; i < _mapCellList.Count; i++) { var cell = _mapCellList[i]; cell.isVisited = false; } var firstCell = _SearchNoFinishCell(); if (firstCell == null) return; firstCell.isVisited = true; _workQuen.Clear(); _workQuen.Enqueue(firstCell); var workArea = new FightLineArea2(); _areas.Add(workArea); while (_workQuen.Count > 0) { var cell = _workQuen.Dequeue(); workArea.AddCell(cell); var aroundCellList = cell.neighCells; for (var i = 0; i < aroundCellList.Count; ++i) { var aroundCell = aroundCellList[i]; if (aroundCell.isVisited) continue; if (aroundCell.standValue != cell.standValue) continue; _workQuen.Enqueue(aroundCell); aroundCell.isVisited = true; } if (_workQuen.Count == 0) { // 区域完结 var nextCell = _SearchNoFinishCell(); if (nextCell != null) { nextCell.isVisited = true; _workQuen.Enqueue(nextCell); workArea = new FightLineArea2(); _areas.Add(workArea); } } } } public void ReverseAloneArea() { for (int i = 0; i < _areas.Count; i++) { var area = _areas[i]; if (!area.hasClaimed) { area.ReverseCells(); } } } } }