using cfg.AreaCfg; using Framework; using Gameplay.Level; using System; using System.Collections.Generic; using Gameplay.Area.AttackArea; using Gameplay.Area.Ready; using Gameplay.Common; using Gameplay.Skill; using Gameplay.Unit; using Gameplay.Unit.Data; using UnityEngine; namespace Gameplay.Area { using Skill; public class AreaManager { public static bool ENABLE_LOG = false; private static AreaManager _instance; public static AreaManager instance { get { return _instance; } } public static void CreateInstance() { if (_instance != null) { DebugUtil.LogError("请勿重复创建AreaManager"); return; } _instance = new AreaManager(); } private readonly Dictionary> _areaDict; // public readonly SkillAreaSelector skillAreaSelector; public readonly SkillAreaSelector2 skillAreaSelector2; private readonly Dictionary> _cellIndex2Units; private Map _map; private readonly AttackAreaView _attackArea; public readonly ReadyAreaManager readyAreaManager; public readonly AttackAreaManager attackAreaManager; public readonly MoveAreaView moveAreaView; // public SkillAreaSelecter skillAreaSelecter => _skillAreaSelecter; private Dictionary _aroundCellDatas = new Dictionary(); public bool isInSkillPreview { get { return skillAreaSelector2.skillHandle != null; } } private AreaManager() { _areaDict = new Dictionary>(); // skillAreaSelector = new SkillAreaSelector(); skillAreaSelector2 = new SkillAreaSelector2(); _cellIndex2Units = new Dictionary>(); _attackArea = new AttackAreaView(); _map = LevelManager.Instance.CurrentLevel.Map; readyAreaManager = new ReadyAreaManager(_map); attackAreaManager = new AttackAreaManager(); moveAreaView = new MoveAreaView(); } public void Init() { moveAreaView.Init(); // skillAreaSelector.Init(); _attackArea.Init(); readyAreaManager.Init(); attackAreaManager.Init(); _RegistEvents(); } public void Dispose() { // skillAreaSelector.Dispose(); readyAreaManager.Dispose(); attackAreaManager.Dispose(); moveAreaView.Dispose(); _aroundCellDatas.Clear(); _UnRegistEvents(); _instance = null; } private void _RegistEvents() { // EventManager.Instance.Register(EventManager.EventName.UI_START_USE_SKILL, (Action)_OnPreUseSkill); // EventManager.Instance.Register(EventManager.EventName.UI_END_USE_SKILL, (Action)_OnEndUseSkill); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_READY, (Action)_OnUnitReady); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_REMOVE, (Action)_OnUnitRemove); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, (Action)_OnUnitCellChange); EventManager.Instance.Register(EventManager.EventName.LevelUnitSelect, (Action)_OnSelectCharacter); EventManager.Instance.Register(EventManager.EventName.LevelUnitUnSelect, (Action)_OnUnSelectCharacter); EventManager.Instance.Register(EventManager.EventName.INFIGHT_UP_VEHICLE, (Action)_OnUpVehicle); EventManager.Instance.Register(EventManager.EventName.INFIGHT_DOWN_VEHICLE, (Action)_OnDownVehicle); EventManager.Instance.Register(EventManager.EventName.INFIGHT_SKILL_END_PAUSE, _OnSkillPauseEnd); } private void _UnRegistEvents() { // EventManager.Instance.Unregister(EventManager.EventName.UI_START_USE_SKILL, (Action)_OnPreUseSkill); // EventManager.Instance.Unregister(EventManager.EventName.UI_END_USE_SKILL, (Action)_OnEndUseSkill); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_READY, (Action)_OnUnitReady); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_REMOVE, (Action)_OnUnitRemove); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, (Action)_OnUnitCellChange); EventManager.Instance.Unregister(EventManager.EventName.LevelUnitSelect, (Action)_OnSelectCharacter); EventManager.Instance.Unregister(EventManager.EventName.LevelUnitUnSelect, (Action)_OnUnSelectCharacter); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UP_VEHICLE, (Action)_OnUpVehicle); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_DOWN_VEHICLE, (Action)_OnDownVehicle); EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_SKILL_END_PAUSE, _OnSkillPauseEnd); } private void _OnUpVehicle(GameUnit unit) { var cellIndex = unit.transData.cellIndex; // 设置地图通行状态 // _map.GetRuntimeBlockProperty(cellIndex, out var oldData); // var blockData = _map.GetBlockData(cellIndex); // oldData.crossLevel = blockData.GetTerrainTypeProperty().crossLevel; // _map.SetRuntimeBlockProperty(cellIndex, oldData); // 移除角色 var unitList = _cellIndex2Units[cellIndex]; unitList.Remove(unit); _Log($"Unit: {unit.GetID()} Up Vehicle at:{cellIndex}"); } private void _OnDownVehicle(EDDownVehicle ed) { var unit = ed.unit; var bornCellIndex = unit.transData.cellIndex; _Log($"Unit: {unit.GetID()} Down Vehicle at:{bornCellIndex}"); var getUnits = GetUnitsByCellIndex(bornCellIndex); if (getUnits.Contains(unit)) { // 重复添加 return; } _AddUnitToCellIndex(bornCellIndex, unit); } private void _OnSelectCharacter(GameUnit c) { _attackArea.SetOwner(c); moveAreaView.Show(c); } private void _OnUnSelectCharacter(GameUnit c) { _attackArea.HideArea(); moveAreaView.Hide(); } private void _OnUnitReady(GameUnit unit) { var bornCellIndex = unit.transData.cellIndex; _Log($"Unit: {unit.GetID()} Ready at: {bornCellIndex}"); var getUnits = GetUnitsByCellIndex(bornCellIndex); if (getUnits.Contains(unit)) { // 重复添加 return; } _AddUnitToCellIndex(bornCellIndex, unit); } private void _AddUnitToCellIndex(int cellIndex, GameUnit unit) { // 设置地图通行状态 // >0 才进行设置 // if (unit.commonData.standLevel > 0) // { // _map.GetRuntimeBlockProperty(cellIndex, out var setData); // setData.crossLevel = unit.commonData.standLevel; // _map.SetRuntimeBlockProperty(cellIndex, setData); // } if (_cellIndex2Units.TryGetValue(cellIndex, out var unitList)) { unitList.Add(unit); } else { unitList = new List(); unitList.Add(unit); _cellIndex2Units.Add(cellIndex, unitList); } _Log($"add unit:{unit.GetID()} to cellIndex:{cellIndex}"); } private void _OnUnitRemove(GameUnit unit) { var cellIndex = unit.transData.cellIndex; if (DebugUtil.LogEnable) _Log($"Unit: {unit.GetID()} Remove at: {cellIndex}"); // 这里必须能去到,所以不用tryget, 如果报错 需要排查上游 // if (unit.commonData.standLevel > 0) // { // // 设置地图通行状态 // _map.GetRuntimeBlockProperty(cellIndex, out var oldData); // var blockData = _map.GetBlockData(cellIndex); // oldData.crossLevel = blockData.GetTerrainTypeProperty().crossLevel; // _map.SetRuntimeBlockProperty(cellIndex, oldData); // } var unitList = _cellIndex2Units[cellIndex]; unitList.Remove(unit); } private void _OnUnitCellChange(GameUnit unit) { var lastCellIndex = unit.transData.lastCellIndex; var newCellIndex = unit.transData.cellIndex; if (lastCellIndex != -1) { // 移除旧的 var unitList = _cellIndex2Units[lastCellIndex]; unitList.Remove(unit); } // 添加新的 _AddUnitToCellIndex(newCellIndex, unit); if (DebugUtil.LogEnable) _Log($"Unit CellIndexChange:{unit.GetID()} from:{lastCellIndex} to {newCellIndex}"); } private static void _Log(string str) { if (!ENABLE_LOG) return; DebugUtil.Log("[AreaManager] {0}", str); } public DataArea GetConfigById(int areaId) { return TableManager.Instance.Tables.AreaConfig.Get(areaId); } private List _emptyList = new List(); public List GetCellIndexsAround(int centerCellIndex, int distance, bool containsCenter = true) { var key = AroundCellData.GetKey(centerCellIndex, distance, containsCenter); if (_aroundCellDatas.TryGetValue(key, out var data)) { return data.aroundCellIndexs; } var list = _GetCellIndexsAround(centerCellIndex, distance, containsCenter); var aroundData = new AroundCellData(centerCellIndex, distance, containsCenter); aroundData.aroundCellIndexs = list; _aroundCellDatas.Add(key, aroundData); return list; } private List _GetCellIndexsAround(int centerCellIndex, int distance, bool containsCenter = true) { if (distance <= 0) { if (containsCenter) { return new List() { centerCellIndex }; } else { return _emptyList; } } var list = _map.TerrainGridSystem.CellGetNeighboursWithinRange(centerCellIndex, 0, distance, canCrossCheckType: TGS.CanCrossCheckType.IgnoreCanCrossCheckOnAllCells); if (containsCenter) { list.Insert(0, centerCellIndex); } return list; } public bool IsCellEmpty(int cellIndex) { var unitList = GetUnitsByCellIndex(cellIndex); return unitList.Count == 0; } public int GetDistance(int cellIndex1, int cellIndex2) { return _map.TerrainGridSystem.CellGetHexagonDistance(cellIndex1, cellIndex2); } public Vector3 GetWorldPosByIndex(int cellIndex) { var getPos = _map.TerrainGridSystem.CellGetPosition(cellIndex); return getPos; } public int GetCellIndexByPos(Vector3 pos) { if (_map.WorldPosition2TGSCellIndex(pos, out var result)) { return result; } DebugUtil.LogError("无法获取到CellIndex:" + pos); return -1; } public bool CheckIsNeighbour(int fromIndex, int checkIndex) { var aroundList = _map.TerrainGridSystem.CellGetNeighbours(fromIndex); for (var i = 0; i < aroundList.Count; i++) { var around = aroundList[i]; if (around.index == checkIndex) { return true; } } return false; } public List GetCellIndexs(int centerCellIndex, int areaId) { var list = new List(); GetCellIndexs(centerCellIndex, areaId, list); return list; } public void GetCellIndexs(int centerCellIndex, int areaId, List list) { var map = LevelManager.Instance.CurrentLevel.Map; var posVec = map.TGSCellIndex2BlockPosition(centerCellIndex); var offsetList = _GetOffsetList(areaId); for (var i = 0; i < offsetList.Count; ++i) { var offset = offsetList[i]; var calcPos = posVec + offset; if (posVec.x % 2 == 1 && calcPos.x % 2 == 0) { calcPos.y += 1; } var cellIndex = map.BlockPosition2TGSCellIndex(calcPos); if (cellIndex == -1) { continue; } var getSuccess = map.GetRuntimeBlockProperty(cellIndex, out var blockData); if (!getSuccess) { continue; } if (blockData.selectable == false) { continue; } list.Add(cellIndex); } } private List _GetOffsetList(int areaId) { if (_areaDict.TryGetValue(areaId, out var offsetList)) { return offsetList; } else { // 不存在,现场进行加载 var areaData = GetConfigById(areaId); if (areaData == null) { DebugUtil.LogError("AreaId:{0}不存在", areaId); return null; } offsetList = new List(); var intList = areaData.Points; for (int i = 0; i < intList.Count; i += 2) { offsetList.Add(new Vector2Int(intList[i], intList[i + 1])); } _areaDict.Add(areaId, offsetList); return offsetList; } } // private void _OnPreUseSkill(GameUnit unit) // { // var skillUnit = SkillManager.instance.GetUnitSkillManager(unit); // if (skillUnit == null) // { // DebugUtil.LogError("Unit:{0} 未挂载UnitSkillManager", unit.GetID()); // return; // } // if (skillUnit.positiveSkill == null) // { // DebugUtil.LogError("Unit:{0} 未挂载PositiveSkill", unit.GetID()); // return; // } // // _attackArea.ForceHide(); // skillAreaSelector.ShowArea(skillUnit.positiveSkill); // } // private void _OnEndUseSkill(bool isCancel) // { // if (DebugUtil.LogEnable) // DebugUtil.Log("UI事件: 结束技能预选: 是否cancel:{0}", isCancel); // var isUse = skillAreaSelector.EndShow(!isCancel); // // if (isUse) // { // // 使用技能的话 要等技能结束才显示攻击范围 // } // else // { // _attackArea.CancelForce(); // } // } private void _OnSkillPauseEnd() { if (_attackArea == null) { DebugUtil.LogError("AttackArea为空"); return; } _attackArea.CancelForce(); } public void LogicUpdate(float dt) { // skillAreaSelector.LogicUpdate(dt); _attackArea.LogicUpdate(dt); readyAreaManager.LogicUpdate(dt); attackAreaManager.LogicUpdate(dt); moveAreaView.LogicUpdate(); } public bool CheckContainsMoveUnit(int cellIndex) { var units = GetUnitsByCellIndex(cellIndex); for (int i = 0; i < units.Count; i++) { var unit = units[i]; if (unit.gameunitType == EGameUnitType.Character || unit.gameunitType == EGameUnitType.Vehicle) { return true; } } return false; } public List GetUnitsByCellIndex(int cellIndex) { if (_cellIndex2Units.TryGetValue(cellIndex, out var result)) { return result; } else { var newList = new List(); _cellIndex2Units.Add(cellIndex, newList); return newList; } } public bool CheckCellCanCross(int targetCellIndex, int crossLevel) { _map.GetRuntimeBlockProperty(targetCellIndex, out var blockData); return blockData.crossLevel >= crossLevel; } } }