using System.Collections.Generic; using AOT.PostProcess.BlackArea; using Framework; using Gameplay.Level; using Gameplay.Unit; using Gameplay.Unit.Data; using Gameplay.Vehicle.Impl; using PhxhSDK; using UnityEngine; using Constants = Framework.Constants; namespace Gameplay.Area { public class MoveAreaView { public GameUnit owner; public List moveCellList = new List(); public GameObject rootObj; private bool _needRefresh; private List _teamUnits = new List(); private List _buffCellNotices = new List(); private GameObject _buffNoticeObj; public void Init() { rootObj = new GameObject("[MoveArea]"); _buffNoticeObj = new GameObject("[BuffNotice]"); _InitBuffCellNotices(_buffNoticeObj.transform); } private void _InitBuffCellNotices(Transform parent) { var map = LevelManager.Instance.CurrentLevel.Map; 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 _OnCellIndexChange(GameUnit unit) { if (unit == owner) return; _needRefresh = true; } private void _RegisterEvent() { EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, _OnCellIndexChange); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UP_VEHICLE, _OnUpVehicle); EventManager.Instance.Register(EventManager.EventName.INFIGHT_DOWN_VEHICLE, _OnDownVehicle); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_REMOVE, _OnUnitRemove); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_READY, _OnUnitReady); EventManager.Instance.Register(EventManager.EventName.INFIGHT_VEHICLE_DESTROY, _OnVehicleDestroy); } private void _UnRegisterEvent() { EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, _OnCellIndexChange); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UP_VEHICLE, _OnUpVehicle); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_DOWN_VEHICLE, _OnDownVehicle); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_REMOVE, _OnUnitRemove); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_READY, _OnUnitReady); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_VEHICLE_DESTROY, _OnVehicleDestroy); } private void _OnVehicleDestroy(GameUnit unit) { _needRefresh = true; } private void _OnUnitReady(GameUnit unit) { _needRefresh = true; } private void _OnUnitRemove(GameUnit unit) { _needRefresh = true; } private void _OnUpVehicle(GameUnit unit) { _needRefresh = true; } private void _OnDownVehicle(GameUnit unit) { _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); } } 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.isOnVehicle) { 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 void _RefreshMoveArea() { moveCellList.Clear(); var centerIndex = owner.transData.cellIndex; var workList = new List(); var blockedSet = new HashSet(); var map = LevelManager.Instance.CurrentLevel.Map; workList.Add(centerIndex); while (workList.Count > 0) { var lastValue = workList[^1]; workList.RemoveAt(workList.Count - 1); // 判断当前格子是否可通行 if (!_CheckCanPass(lastValue)) { blockedSet.Add(lastValue); // DebugUtil.LogError("blockedSet.Add:" + lastValue); continue; } // 把自己加入到移动列表 moveCellList.Add(lastValue); // 把周围的格子加入到工作列表 var aroundList = AreaManager.instance.GetCellIndexsAround(lastValue, 1, false); for (int i = 0; i < aroundList.Count; i++) { var cellIndex = aroundList[i]; if (moveCellList.Contains(cellIndex)) { continue; } if (blockedSet.Contains(cellIndex)) { continue; } if (workList.Contains(cellIndex)) { continue; } workList.Add(cellIndex); } } // 将队友相关的格子移除 for (int i = 0; i < moveCellList.Count; i++) { var cellIndex = moveCellList[i]; if (!_CheckSelfUnits(cellIndex)) { moveCellList.RemoveAt(i); i--; } } // 将敌人所在格子加入 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); } } } // 刷新显示 if (moveCellList.Count != rootObj.transform.childCount) { // 需要匹配个数 if (moveCellList.Count < rootObj.transform.childCount) { // 多了, 需要删除 var needRemoveCount = rootObj.transform.childCount - moveCellList.Count; for (int i = 0; i < needRemoveCount; i++) { var child = rootObj.transform.GetChild(moveCellList.Count + i); Object.Destroy(child.gameObject); } } else { // 少了, 需要添加 var needAddCount = moveCellList.Count - rootObj.transform.childCount; for (int i = 0; i < needAddCount; i++) { var sampleObj = AssetManager.Instance.GetPreLoadResult(Constants.MOVE_AREA_POINT_PATH); var instanceObj = Object.Instantiate(sampleObj, rootObj.transform); } } } // 刷新位置 for (int i = 0; i < moveCellList.Count; i++) { var cellIndex = moveCellList[i]; var worldPos = AreaManager.instance.GetCellPosByIndex(cellIndex); var child = rootObj.transform.GetChild(i); child.position = worldPos; } } public void Dispose() { Hide(); owner = null; moveCellList.Clear(); for (int i = 0; i < _buffCellNotices.Count; i++) { var notice = _buffCellNotices[i]; notice.Dispose(); } _buffCellNotices.Clear(); if (rootObj != null) { Object.Destroy(rootObj); rootObj = null; } if (_buffNoticeObj != null) { Object.Destroy(_buffNoticeObj); _buffNoticeObj = null; } } } }