using System; using System.Collections.Generic; using AOT.PostProcess.BlackArea; using Framework; using Gameplay.Common; using Gameplay.Fight.Capture; using Gameplay.Level; using Gameplay.Unit; using Gameplay.Unit.Data; using Gameplay.Vehicle.Impl; using UnityEngine; using Object = UnityEngine.Object; namespace Gameplay.Area.Ready { public class ReadyAreaManager { public Map _map; private EReadyAreaStatus _areaStatus; private List _mapSavedReadyCellIndexs; public List mapSavedReadyCellIndexs => _mapSavedReadyCellIndexs; public bool isShow { get; private set; } public NormalVehicle followVehicle { get; set; } public bool isVehicleBuffActive { get; set; } private List _finalReadyCellIndexs; private Dictionary _readyAreaDict; private Stack _pointsStack; public GameObject rootObj; private bool _needUpdate; public ReadyAreaManager(Map map) { rootObj = new GameObject("[ReadyArea]"); _map = map; isShow = false; _readyAreaDict = new Dictionary(); _pointsStack = new Stack(); _finalReadyCellIndexs = new List(); } public void Init() { _InitReadyAreaFromLevel(); EventManager.Instance.Register(EventManager.EventName.INFIGHT_CAPTURE_FINSIHED, _OnCaptureArea); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, _OnCellIndexChanged); } public void Dispose() { EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_CAPTURE_FINSIHED, _OnCaptureArea); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, _OnCellIndexChanged); _HideAll(); _pointsStack.Clear(); if (rootObj != null) { Object.Destroy(rootObj); rootObj = null; } } private void _OnCellIndexChanged(GameUnit unit) { _needUpdate = true; } private void _InitReadyAreaFromLevel() { _mapSavedReadyCellIndexs = new List(); var levelData = LevelManager.Instance.CurrentLevel.GetLevelData(); var areaId = levelData.preparingRegionId; var area = _map.MapData.GetRegion(areaId); if (area == null) { DebugUtil.LogError("读取准备区域失败"); return; } var allPoints = area.positions; foreach (var cellIndex in allPoints) { if (_mapSavedReadyCellIndexs.Contains(cellIndex)) { continue; } _mapSavedReadyCellIndexs.Add(cellIndex); } } public void ClipMoveUnits() { var allUnitsCellIndex = new List(); var allUnits = GameUnitManager.instance.totalUnits.unitList; for (int i = 0; i < allUnits.Count; i++) { var unit = allUnits[i]; if (unit.gameunitType == EGameUnitType.Character || unit.gameunitType == EGameUnitType.Vehicle || unit.gameunitType == EGameUnitType.Building) { allUnitsCellIndex.Add(unit.transData.cellIndex); } } for (int i = 0; i < _mapSavedReadyCellIndexs.Count; i++) { var cellIndex = _mapSavedReadyCellIndexs[i]; var hasMoveUnit = allUnitsCellIndex.Contains(cellIndex); if (hasMoveUnit) { _mapSavedReadyCellIndexs.RemoveAt(i--); } } } private void _OnCaptureArea(CaptureInst inst) { if (_mapSavedReadyCellIndexs.Contains(inst.cellIndex)) { return; } _mapSavedReadyCellIndexs.Add(inst.cellIndex); _needUpdate = true; } private ReadyAreaPoint _GetOrCreate() { if (_pointsStack.Count > 0) { return _pointsStack.Pop(); } return new ReadyAreaPoint(PathDefine.ReadyArea.READY_AREA_POINT); } private void _SetPointsShow(List cellIndexs) { for (int i = 0; i < cellIndexs.Count; i++) { var cellIndex = cellIndexs[i]; _SetPointShow(cellIndex); } } private void _SetPointsHide(List cellIndexs) { for (int i = 0; i < cellIndexs.Count; i++) { var cellIndex = cellIndexs[i]; _SetPointHide(cellIndex); } } private void _HideAll() { foreach (var kv in _readyAreaDict) { var point = kv.Value; point.Hide(); _pointsStack.Push(point); } _readyAreaDict.Clear(); } private void _SetPointShow(int cellIndex) { if (_readyAreaDict.ContainsKey(cellIndex)) { // 已经在显示了 return; } var newPoint = _GetOrCreate(); newPoint.SetIndex(cellIndex); _readyAreaDict.Add(cellIndex, newPoint); } private void _SetPointHide(int cellIndex) { if (_readyAreaDict.TryGetValue(cellIndex, out var point)) { point.Hide(); _readyAreaDict.Remove(cellIndex); _pointsStack.Push(point); } } private void _GetPosFromVehicle() { var vehicleCellIndex = followVehicle.transData.cellIndex; var totalAround = AreaManager.instance.GetCellIndexsAround(vehicleCellIndex, followVehicle.aroundReadyRange, false); _finalReadyCellIndexs.AddRange(totalAround); } private void _GetPosFromMapSavedReady() { _finalReadyCellIndexs.AddRange(_mapSavedReadyCellIndexs); } private bool _CheckCanUp(int cellIndex) { if (cellIndex == -1) return false; if (_map.GetRuntimeBlockProperty(cellIndex, out var runtimeBlockProperty)) { if (!runtimeBlockProperty.selectable) { return false; } if (runtimeBlockProperty.banAttack) { return false; } var hasMoveUnit = AreaManager.instance.CheckContainsMoveUnit(cellIndex); if (hasMoveUnit) { return false; } return true; } return false; } private void _RemoveNotMatch() { for (int i = 0; i < _finalReadyCellIndexs.Count; i++) { var newIndex = _finalReadyCellIndexs[i]; if (!_CheckCanUp(newIndex)) { _finalReadyCellIndexs.RemoveAt(i--); } } } public void LogicUpdate(float dt) { if (!isShow) return; if (_needUpdate) { _UpdateArea(); _needUpdate = false; } _AutoLightUpReadyArea(); } private void _LightUpList(List cellList) { for (int i = 0; i < cellList.Count; i++) { var cellIndex = cellList[i]; BlackAreaManager.instance.LightUpCell(cellIndex, CodeDefine.Fight.LIGHT_UP_TIME); } } private void _AutoLightUpReadyArea() { _LightUpList(_finalReadyCellIndexs); } public bool CheckIsInReadyArea(int cellIndex) { return _finalReadyCellIndexs.Contains(cellIndex); } public void ShowReadyArea(EReadyAreaStatus showStatus = EReadyAreaStatus.FromMap, GameUnit unit = null) { if (isShow) { if (_areaStatus == showStatus) { // 重复的调用 _needUpdate = true; } else { // 需要切换显示状态 HideReadyArea(); } } isShow = true; _areaStatus = showStatus; _SetCurrentVehicle(unit); _UpdateArea(); _SetPointsShow(_finalReadyCellIndexs); } private void _UpdateArea() { _finalReadyCellIndexs.Clear(); if (!LevelManager.Instance.CurrentLevel.isInBattle) { // 不在战斗中,直接显示地图上的准备区域 _GetPosFromMapSavedReady(); return; } switch (_areaStatus) { case EReadyAreaStatus.Both: _GetPosFromVehicle(); _GetPosFromMapSavedReady(); break; case EReadyAreaStatus.AroundVehicle: _GetPosFromVehicle(); break; case EReadyAreaStatus.FromMap: _GetPosFromMapSavedReady(); if (isVehicleBuffActive) { _GetPosFromVehicle(); } break; } _RemoveNotMatch(); } private void _SetCurrentVehicle(GameUnit downUnit) { if (downUnit == null) return; if (downUnit.gameunitType != EGameUnitType.Character) { throw new Exception("不是角色1"); } var character = downUnit as Character.Character; if (character == null) { throw new Exception("不是角色2"); } followVehicle = character.runtimeData.belongVehicle; } public void HideReadyArea() { if (!isShow) { return; } isShow = false; _HideAll(); } } }