NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Area/MoveArea/MoveAreaView.cs

577 lines
18 KiB
C#

using System.Collections.Generic;
using AOT.PostProcess.BlackArea;
using Framework;
using Gameplay.Area.BoardView;
using Gameplay.Common;
using Gameplay.Level;
using Gameplay.Unit;
using Gameplay.Unit.Data;
using Gameplay.Vehicle.Impl;
using PhxhSDK;
using UnityEngine;
namespace Gameplay.Area
{
public class MoveAreaView
{
public GameUnit owner;
public List<int> moveCellList = new List<int>();
public GameObject rootObj;
private bool _needRefresh;
private Map _map;
private List<GameUnit> _teamUnits = new List<GameUnit>();
private List<BuffCellNotice> _buffCellNotices = new List<BuffCellNotice>();
private GameObject _buffNoticeObj;
private List<BoardViewData> _boardViewDataList = new List<BoardViewData>();
public BoardLineObjPool boardLineObjPool = new BoardLineObjPool();
// 存储所有格子对象的数组
private GameObject[] _cellObjects;
// 标记是否已初始化格子对象
private bool _isInitialized = false;
public void Init(Map map)
{
rootObj = new GameObject("[MoveArea]");
_buffNoticeObj = new GameObject("[BuffNotice]");
_map = map;
_InitBuffCellNotices(_buffNoticeObj.transform);
boardLineObjPool.Init();
// 提前初始化所有格子对象,避免首次刷新时卡顿
_InitializeCellObjects();
}
private void _InitBuffCellNotices(Transform parent)
{
var mapData = _map.MapData;
for (int i = 0; i < mapData.showBuffPoints.Count; i++)
{
var buffPoint = mapData.showBuffPoints[i];
if (string.IsNullOrEmpty(buffPoint.path))
{
continue;
}
var cellIndex = buffPoint.cellIndex;
var notice = new BuffCellNotice()
{
cellIndex = cellIndex,
loadPath = buffPoint.path,
};
DebugUtil.LogG("BuffCellNotice:" + cellIndex + " " + buffPoint.path);
notice.CreateView(parent);
_buffCellNotices.Add(notice);
}
}
public void Show(GameUnit setOwner)
{
owner = setOwner;
_UpdateTeamUnits();
_RefreshMoveArea();
_needRefresh = false;
_ShowBuffNotices();
rootObj.SetActive(true);
_buffNoticeObj.SetActive(true);
_RegisterEvent();
}
private void _ShowBuffNotices()
{
for (int i = 0; i < _buffCellNotices.Count; i++)
{
var notice = _buffCellNotices[i];
if (moveCellList.Contains(notice.cellIndex))
{
notice.SetActive(true);
}
else
{
notice.SetActive(false);
}
}
}
private void _RegisterEvent()
{
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, _OnCellIndexChange);
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_ENTER_UNITCONTAINER, _OnEnterUnitContainer);
EventManager.Instance.Register<EDExitUnitContainer>(EventManager.EventName.INFIGHT_EXIT_UNITCONTAINER, _OnExitUnitContainer);
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_UNIT_REMOVE, _OnUnitRemove);
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_UNIT_READY, _OnUnitReady);
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_VEHICLE_DESTROY, _OnVehicleDestroy);
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_STATE_ENTER_RETREAT, _OnRetreatStateChange);
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_STATE_EXIT_RETREAT, _OnRetreatStateChange);
}
private void _UnRegisterEvent()
{
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, _OnCellIndexChange);
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_ENTER_UNITCONTAINER, _OnEnterUnitContainer);
EventManager.Instance.Unregister<EDExitUnitContainer>(EventManager.EventName.INFIGHT_EXIT_UNITCONTAINER, _OnExitUnitContainer);
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_UNIT_REMOVE, _OnUnitRemove);
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_UNIT_READY, _OnUnitReady);
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_VEHICLE_DESTROY, _OnVehicleDestroy);
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_STATE_ENTER_RETREAT, _OnRetreatStateChange);
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_STATE_EXIT_RETREAT, _OnRetreatStateChange);
}
private void _OnCellIndexChange(GameUnit unit)
{
if (unit == owner) return;
_needRefresh = true;
}
private void _OnRetreatStateChange(GameUnit unit)
{
if (unit == owner)
{
_needRefresh = true;
}
}
private void _OnVehicleDestroy(GameUnit unit)
{
_needRefresh = true;
}
private void _OnUnitReady(GameUnit unit)
{
_needRefresh = true;
}
private void _OnUnitRemove(GameUnit unit)
{
_needRefresh = true;
}
private void _OnEnterUnitContainer(GameUnit unit)
{
_needRefresh = true;
}
private void _OnExitUnitContainer(EDExitUnitContainer ed)
{
_needRefresh = true;
}
private void _UpdateTeamUnits()
{
_teamUnits.Clear();
var allUnits = GameUnitManager.instance.infightUnits.unitList;
for (int i = 0; i < allUnits.Count; i++)
{
var unit = allUnits[i];
if (unit == owner)
{
continue;
}
if (unit.commonData.troopId != owner.commonData.troopId)
{
continue;
}
// 只要角色和载具
if (unit.gameunitType != EGameUnitType.Character
&& unit.gameunitType != EGameUnitType.Vehicle)
{
continue;
}
_teamUnits.Add(unit);
}
}
public void Hide()
{
_UnRegisterEvent();
owner = null;
if (rootObj != null)
{
rootObj.SetActive(false);
}
if (_buffNoticeObj != null)
{
_buffNoticeObj.SetActive(false);
}
if (_boardViewDataList != null)
{
for (int i = 0; i < _boardViewDataList.Count; i++)
{
var boardViewData = _boardViewDataList[i];
boardViewData.Destroy(LevelManager.Instance.CurrentLevel.Map.TerrainGridSystem);
}
_boardViewDataList.Clear();
}
boardLineObjPool.ReturnAll();
}
public void LogicUpdate()
{
if (owner == null) return;
if (_needRefresh)
{
_needRefresh = false;
_RefreshMoveArea();
}
}
public bool CheckIsInArea(int cellIndex)
{
return moveCellList.Contains(cellIndex);
}
private bool _CheckCanPass(int cellIndex)
{
if (cellIndex < 0)
{
return false;
}
if (cellIndex == owner.transData.cellIndex)
{
return true;
}
if (!PathFinder.CanPass(cellIndex, owner))
{
return false;
}
if (!BlackAreaManager.instance.CheckIsInLightArea(cellIndex))
{
return false;
}
return true;
}
private bool _CheckSelfUnits(int cellIndex)
{
// 判断所有队友在不在这个格子上
// 判断所有队友的targetcell在不在这个格子上
for (int i = 0; i < _teamUnits.Count; i++)
{
var unit = _teamUnits[i];
if (!unit.statusData.isOnFloor)
{
continue;
}
if (unit.statusData.isDead)
{
if (unit.transData.cellIndex == cellIndex)
{
return false;
}
continue;
}
if (unit.gameunitType == EGameUnitType.Vehicle)
{
// 载具需要额外判断是否已死亡和是否已满载
var vehicle = unit as NormalVehicle;
if (vehicle == null)
{
continue;
}
if (vehicle.CheckCanUp(owner))
{
continue;
}
}
if (unit.transData.cellIndex == cellIndex)
{
return false;
}
if (unit.controlData.targetCellIndex == cellIndex)
{
return false;
}
}
return true;
}
private Queue<TGS.Cell> _workList = new Queue<TGS.Cell>(100);
private void _UpdateMoveCellList()
{
var centerIndex = owner.transData.cellIndex;
var workList = _workList;
workList.Clear();
var mapTgs = LevelManager.Instance.CurrentLevel.Map.TerrainGridSystem;
var allCellS = mapTgs.cells;
for (int i = 0; i < allCellS.Count; i++)
{
var iCell = allCellS[i];
iCell.isVisited = false;
}
var centerCell = mapTgs.cells[centerIndex];
workList.Enqueue(centerCell);
centerCell.isVisited = true;
while (workList.Count > 0)
{
var workCell = workList.Dequeue();
// 判断当前格子是否可通行
if (!_CheckCanPass(workCell.index))
{
// DebugUtil.LogError("blockedSet.Add:" + lastValue);
continue;
}
// 把自己加入到移动列表
moveCellList.Add(workCell.index);
// 把周围的格子加入到工作列表
var neighbors = workCell.neighbours;
for (int i = 0; i < neighbors.Count; i++)
{
var iCell = neighbors[i];
if (iCell.isVisited)
{
continue;
}
// 添加到检查过列表中
workList.Enqueue(iCell);
iCell.isVisited = true;
}
}
}
private void _AutoRemoveSelfUnits()
{
for (int i = 0; i < _teamUnits.Count; i++)
{
var unit = _teamUnits[i];
if (!unit.statusData.isOnFloor)
{
continue;
}
if (unit.statusData.isDead)
{
continue;
}
if (unit.gameunitType == EGameUnitType.Vehicle)
{
// 载具需要额外判断是否已死亡和是否已满载
var vehicle = unit as NormalVehicle;
if (vehicle == null)
{
continue;
}
if (vehicle.CheckCanUp(owner))
{
continue;
}
}
{
var searchIndex = moveCellList.IndexOf(unit.transData.cellIndex);
if (searchIndex >= 0)
{
// fast remove
moveCellList[searchIndex] = moveCellList[^1];
moveCellList.RemoveAt(moveCellList.Count - 1);
}
}
{
var searchIndex = moveCellList.IndexOf(unit.controlData.targetCellIndex);
if (searchIndex >= 0)
{
// fast remove
moveCellList[searchIndex] = moveCellList[^1];
moveCellList.RemoveAt(moveCellList.Count - 1);
}
}
}
}
private void _AutoAddEnemiesCellIndex()
{
var units = GameUnitManager.instance.infightUnits.unitList;
for (int i = 0; i < units.Count; i++)
{
var unit = units[i];
if (unit == owner)
{
continue;
}
if (unit.commonData.troopId == owner.commonData.troopId)
{
continue;
}
var cellIndex = unit.transData.cellIndex;
if (!BlackAreaManager.instance.CheckIsInLightArea(cellIndex))
{
continue;
}
if (unit.statusData.canBeAttack)
{
if (!moveCellList.Contains(cellIndex))
{
moveCellList.Add(cellIndex);
}
}
}
}
private void _RefreshBoardView()
{
for (int i = 0; i < _boardViewDataList.Count; i++)
{
var boardViewData = _boardViewDataList[i];
boardViewData.Destroy(LevelManager.Instance.CurrentLevel.Map.TerrainGridSystem);
}
_boardViewDataList.Clear();
boardLineObjPool.ReturnAll();
BoardViewHelper.GenerateBoard(moveCellList, _boardViewDataList, LevelManager.Instance.CurrentLevel.Map.TerrainGridSystem);
for (int i = 0; i < _boardViewDataList.Count; i++)
{
var boardViewData = _boardViewDataList[i];
boardViewData.CreateBoardSideView(LevelManager.Instance.CurrentLevel.Map.TerrainGridSystem);
}
}
private void _RefreshViewStatus()
{
var allCellList = LevelManager.Instance.CurrentLevel.Map.TerrainGridSystem.cells;
var cellCount = allCellList.Count;
// 先将所有单元格标记为未访问
for (int i = 0; i < cellCount; i++)
{
allCellList[i].isVisited = false;
}
// 标记可移动格子
for (int i = 0; i < moveCellList.Count; i++)
{
int cellIndex = moveCellList[i];
allCellList[cellIndex].isVisited = true;
}
// 更新所有格子的显示状态
for (int i = 0; i < cellCount; i++)
{
bool canNotMove = !allCellList[i].isVisited;
_cellObjects[i].SetActiveEx(canNotMove);
}
}
// 初始化所有格子对象的方法
private void _InitializeCellObjects()
{
if (_isInitialized) return;
var terrainGridSystem = LevelManager.Instance.CurrentLevel.Map.TerrainGridSystem;
var cellCount = terrainGridSystem.cells.Count;
// 创建对象数组
_cellObjects = new GameObject[cellCount];
// 预加载对象模板
var sampleObj = AssetManager.Instance.GetPreLoadResult<GameObject>(PathDefine.MoveArea.CANNOT_MOVE_AREA_POINT_PATH);
// 批量创建所有对象
for (int i = 0; i < cellCount; i++)
{
_cellObjects[i] = Object.Instantiate(sampleObj, rootObj.transform);
// 设置到对应格子的世界位置
_cellObjects[i].transform.position = AreaManager.instance.GetWorldPosByIndex(i);
// 初始时全部隐藏
_cellObjects[i].SetActive(false);
}
_isInitialized = true;
}
private void _RefreshMoveArea()
{
moveCellList.Clear();
if (owner.statusData.isRetreat)
{
// 逃跑状态
// do nothing
}
else
{
_UpdateMoveCellList();
}
// 刷新显示
// _RefreshBoardView();
// 将队友相关的格子移除
_AutoRemoveSelfUnits();
// 将敌人所在格子加入
_AutoAddEnemiesCellIndex();
_RefreshViewStatus();
}
public void Dispose()
{
Hide();
moveCellList.Clear();
for (int i = 0; i < _buffCellNotices.Count; i++)
{
var notice = _buffCellNotices[i];
notice.Dispose();
}
_buffCellNotices.Clear();
// 清理格子对象
_cellObjects = null;
_isInitialized = false;
if (rootObj != null)
{
Object.Destroy(rootObj);
rootObj = null;
}
if (_buffNoticeObj != null)
{
Object.Destroy(_buffNoticeObj);
_buffNoticeObj = null;
}
boardLineObjPool.Dispose();
boardLineObjPool = null;
}
}
}