396 lines
14 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|