NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/LegionBattle/View/FightLineMap2.cs

396 lines
14 KiB
C#

using System.Collections.Generic;
using TGS;
using UnityEngine;
namespace Gameplay.LegionBattle.View
{
public class FightLineMap2
{
private Dictionary<int, FightLineCell2> _mapCellDict;
private List<FightLineCell2> _mapCellList;
private TerrainGridSystem _tgs;
public FightLineMap2(TerrainGridSystem tgs)
{
_tgs = tgs;
_mapCellDict = new Dictionary<int, FightLineCell2>();
_mapCellList = new List<FightLineCell2>();
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<FightLineStandUnit2> 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<FightLineStandUnit2> _teamLeftStandUnits = new List<FightLineStandUnit2>();
private List<FightLineStandUnit2> _teamRightStandUnits = new List<FightLineStandUnit2>();
private List<FightLineStandUnit2> _teamLeftBuildingUnits = new List<FightLineStandUnit2>();
private List<FightLineStandUnit2> _teamRightBuildingUnits = new List<FightLineStandUnit2>();
private List<FightLineCell2> _teamLeftCellList = new List<FightLineCell2>();
private List<FightLineCell2> _teamRightCellList = new List<FightLineCell2>();
private List<FightLineCell2> _teamLeftCellList2 = new List<FightLineCell2>();
private List<FightLineCell2> _teamRightCellList2 = new List<FightLineCell2>();
public void UpdateStandMap(IList<FightLineStandUnit2> 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<FightLineStandUnit2> 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<FightLineArea2> _areas = new List<FightLineArea2>();
private Queue<FightLineCell2> _workQuen = new Queue<FightLineCell2>();
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();
}
}
}
}
}