456 lines
16 KiB
C#
456 lines
16 KiB
C#
using cfg.AreaCfg;
|
|
using Framework;
|
|
using Gameplay.Level;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Gameplay.Area.Ready;
|
|
using Gameplay.Fight.Protect;
|
|
using Gameplay.Unit;
|
|
using Gameplay.Unit.Data;
|
|
using UnityEngine;
|
|
|
|
namespace Gameplay.Area
|
|
{
|
|
using Common;
|
|
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<int, List<Vector2Int>> _areaDict;
|
|
private readonly SkillAreaSelecter _skillAreaSelecter;
|
|
|
|
private readonly Dictionary<int, List<GameUnit>> _cellIndex2Units;
|
|
|
|
private Map _map;
|
|
|
|
private readonly RoadLineView _roadLine;
|
|
private readonly List<RoadLineView> _beProtectUnitLines;
|
|
|
|
private readonly AttackAreaView _attackArea;
|
|
|
|
public readonly ReadyAreaManager readyAreaManager;
|
|
|
|
public bool isInSelecting
|
|
{
|
|
get
|
|
{
|
|
return _skillAreaSelecter.isOnSelecting;
|
|
}
|
|
}
|
|
|
|
private AreaManager()
|
|
{
|
|
_areaDict = new Dictionary<int, List<Vector2Int>>();
|
|
_skillAreaSelecter = new SkillAreaSelecter();
|
|
_cellIndex2Units = new Dictionary<int, List<GameUnit>>();
|
|
_roadLine = new RoadLineView();
|
|
_attackArea = new AttackAreaView();
|
|
_beProtectUnitLines = new List<RoadLineView>();
|
|
|
|
_map = LevelManager.Instance.CurrentLevel.Map;
|
|
|
|
readyAreaManager = new ReadyAreaManager(_map);
|
|
}
|
|
|
|
public void Init()
|
|
{
|
|
// 这里要不要做预加载
|
|
_roadLine.Init();
|
|
_skillAreaSelecter.Init();
|
|
_attackArea.Init();
|
|
readyAreaManager.Init();
|
|
_RegistEvents();
|
|
}
|
|
|
|
public void RegistBeProtectUnit(BeProtectUnit unit)
|
|
{
|
|
var line = new RoadLineView();
|
|
line.owner = unit;
|
|
line.Init();
|
|
_beProtectUnitLines.Add(line);
|
|
}
|
|
|
|
private void _RegistEvents()
|
|
{
|
|
EventManager.Instance.Register(EventManager.EventName.UI_START_USE_SKILL, (Action<GameUnit>)_OnPreUseSkill);
|
|
EventManager.Instance.Register(EventManager.EventName.UI_END_USE_SKILL, (Action<bool>)_OnEndUseSkill);
|
|
|
|
EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_READY, (Action<GameUnit>)_OnUnitReady);
|
|
EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_REMOVE, (Action<GameUnit>)_OnUnitRemove);
|
|
EventManager.Instance.Register(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, (Action<GameUnit>)_OnUnitCellChange);
|
|
|
|
EventManager.Instance.Register(EventManager.EventName.LevelUnitSelect, (Action<GameUnit>)_OnSelectCharacter);
|
|
EventManager.Instance.Register(EventManager.EventName.LevelUnitUnSelect, (Action<GameUnit>)_OnUnSelectCharacter);
|
|
|
|
EventManager.Instance.Register(EventManager.EventName.INFIGHT_UP_VEHICLE, (Action<GameUnit>)_OnUpVehicle);
|
|
EventManager.Instance.Register(EventManager.EventName.INFIGHT_DOWN_VEHICLE, (Action<GameUnit>)_OnDownVehicle);
|
|
|
|
EventManager.Instance.Register(EventManager.EventName.INFIGHT_SKILL_END_PAUSE, _OnSkillPauseEnd);
|
|
}
|
|
|
|
private void _UnRegistEvents()
|
|
{
|
|
EventManager.Instance.Unregister(EventManager.EventName.UI_START_USE_SKILL, (Action<GameUnit>)_OnPreUseSkill);
|
|
EventManager.Instance.Unregister(EventManager.EventName.UI_END_USE_SKILL, (Action<bool>)_OnEndUseSkill);
|
|
|
|
EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_READY, (Action<GameUnit>)_OnUnitReady);
|
|
EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_REMOVE, (Action<GameUnit>)_OnUnitRemove);
|
|
EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, (Action<GameUnit>)_OnUnitCellChange);
|
|
|
|
EventManager.Instance.Unregister(EventManager.EventName.LevelUnitSelect, (Action<GameUnit>)_OnSelectCharacter);
|
|
EventManager.Instance.Unregister(EventManager.EventName.LevelUnitUnSelect, (Action<GameUnit>)_OnUnSelectCharacter);
|
|
|
|
EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_UP_VEHICLE, (Action<GameUnit>)_OnUpVehicle);
|
|
EventManager.Instance.Unregister(EventManager.EventName.INFIGHT_DOWN_VEHICLE, (Action<GameUnit>)_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);
|
|
if (DebugUtil.LogEnable)
|
|
_Log($"Unit: {unit.GetID()} Up Vehicle at:{cellIndex}");
|
|
}
|
|
|
|
private void _OnDownVehicle(GameUnit unit)
|
|
{
|
|
var bornCellIndex = unit.transData.cellIndex;
|
|
if (DebugUtil.LogEnable)
|
|
_Log($"Unit: {unit.GetID()} Down Vehicle at:{bornCellIndex}");
|
|
_AddUnitToCellIndex(bornCellIndex, unit);
|
|
}
|
|
|
|
private void _OnSelectCharacter(GameUnit c)
|
|
{
|
|
_roadLine.UpdateLine(c);
|
|
_attackArea.SetOwner(c);
|
|
}
|
|
|
|
private void _OnUnSelectCharacter(GameUnit c)
|
|
{
|
|
_roadLine.HideLine();
|
|
_attackArea.HideArea();
|
|
}
|
|
|
|
private void _OnUnitReady(GameUnit unit)
|
|
{
|
|
var bornCellIndex = unit.transData.cellIndex;
|
|
if (DebugUtil.LogEnable)
|
|
_Log($"Unit: {unit.GetID()} Ready at: {bornCellIndex}");
|
|
_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<GameUnit>();
|
|
unitList.Add(unit);
|
|
_cellIndex2Units.Add(cellIndex, unitList);
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
// 设置地图通行状态
|
|
if (unit.commonData.standLevel > 0)
|
|
{
|
|
_map.GetRuntimeBlockProperty(lastCellIndex, out var oldData);
|
|
var blockData = _map.GetBlockData(lastCellIndex);
|
|
oldData.crossLevel = blockData.GetTerrainTypeProperty().crossLevel;
|
|
_map.SetRuntimeBlockProperty(lastCellIndex, oldData);
|
|
}
|
|
|
|
// 移除旧的
|
|
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 void Dispose()
|
|
{
|
|
_skillAreaSelecter.Dispose();
|
|
_roadLine.Dispose();
|
|
for (int i = 0; i < _beProtectUnitLines.Count; i++)
|
|
{
|
|
var line = _beProtectUnitLines[i];
|
|
line.Dispose();
|
|
}
|
|
_beProtectUnitLines.Clear();
|
|
readyAreaManager.Dispose();
|
|
_UnRegistEvents();
|
|
_instance = null;
|
|
}
|
|
|
|
public DataArea GetConfigById(int areaId)
|
|
{
|
|
return TableManager.Instance.Tables.AreaConfig.Get(areaId);
|
|
}
|
|
|
|
public List<int> GetCellIndexsAround(int centerCellIndex,
|
|
int distance)
|
|
{
|
|
var list = _map.TerrainGridSystem.CellGetNeighboursWithinRange(centerCellIndex, 0, distance, canCrossCheckType: TGS.CanCrossCheckType.IgnoreCanCrossCheckOnAllCells);
|
|
list.Add(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 GetCellPosByIndex(int cellIndex)
|
|
{
|
|
var getPos = _map.TerrainGridSystem.CellGetPosition(cellIndex);
|
|
return getPos;
|
|
}
|
|
|
|
public int GetCellIndexByPos(Vector3 pos)
|
|
{
|
|
if (_map.WorldPosition2TGSCellIndex(pos, out var result))
|
|
{
|
|
return result;
|
|
}
|
|
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<int> GetCellIndexs(int centerCellIndex,
|
|
int areaId)
|
|
{
|
|
var list = new List<int>();
|
|
GetCellIndexs(centerCellIndex, areaId, list);
|
|
return list;
|
|
}
|
|
|
|
public void GetCellIndexs(int centerCellIndex,
|
|
int areaId,
|
|
List<int> 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);
|
|
list.Add(cellIndex);
|
|
}
|
|
}
|
|
|
|
private List<Vector2Int> _GetOffsetList(int areaId)
|
|
{
|
|
if (_areaDict.TryGetValue(areaId, out var offsetList))
|
|
{
|
|
return offsetList;
|
|
}
|
|
else
|
|
{
|
|
// 不存在,现场进行加载
|
|
var DataAreaConfig = GetConfigById(areaId);
|
|
if (DataAreaConfig == null)
|
|
{
|
|
DebugUtil.LogError("AreaId:{0}不存在", areaId);
|
|
return null;
|
|
}
|
|
offsetList = new List<Vector2Int>();
|
|
var intList = DataAreaConfig.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();
|
|
_skillAreaSelecter.ShowArea(skillUnit.positiveSkill);
|
|
}
|
|
|
|
private void _OnEndUseSkill(bool isCancel)
|
|
{
|
|
if (DebugUtil.LogEnable)
|
|
DebugUtil.Log("UI事件: 结束技能预选: 是否cancel:{0}", isCancel);
|
|
var isUse = _skillAreaSelecter.EndShow(!isCancel);
|
|
|
|
if (isUse)
|
|
{
|
|
// 使用技能的话 要等技能结束才显示攻击范围
|
|
}
|
|
else
|
|
{
|
|
_attackArea.CancelForce();
|
|
}
|
|
}
|
|
|
|
private void _OnSkillPauseEnd()
|
|
{
|
|
if (_attackArea == null)
|
|
{
|
|
DebugUtil.LogError("AttackArea为空");
|
|
return;
|
|
}
|
|
_attackArea.CancelForce();
|
|
}
|
|
|
|
public void LogicUpdate(float dt)
|
|
{
|
|
_skillAreaSelecter.LogicUpdate(dt);
|
|
_roadLine.LogicUpdate(dt);
|
|
for (int i = 0; i < _beProtectUnitLines.Count; i++)
|
|
{
|
|
var line = _beProtectUnitLines[i];
|
|
line.LogicUpdate(dt);
|
|
}
|
|
_attackArea.LogicUpdate(dt);
|
|
readyAreaManager.LogicUpdate(dt);
|
|
}
|
|
|
|
public List<GameUnit> GetUnitsByCellIndex(int cellIndex)
|
|
{
|
|
if (_cellIndex2Units.TryGetValue(cellIndex, out var result))
|
|
{
|
|
return result;
|
|
}
|
|
else
|
|
{
|
|
var newList = new List<GameUnit>();
|
|
_cellIndex2Units.Add(cellIndex, newList);
|
|
return newList;
|
|
}
|
|
}
|
|
|
|
public bool CheckCellCanCross(int targetCellIndex, int crossLevel)
|
|
{
|
|
_map.GetRuntimeBlockProperty(targetCellIndex, out var blockData);
|
|
return blockData.crossLevel >= crossLevel;
|
|
}
|
|
|
|
}
|
|
}
|