339 lines
9.6 KiB
C#
339 lines
9.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using AOT.PostProcess.BlackArea;
|
|
using Framework;
|
|
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<int> _mapSavedReadyCellIndexs;
|
|
public List<int> mapSavedReadyCellIndexs => _mapSavedReadyCellIndexs;
|
|
|
|
public bool isShow { get; private set; }
|
|
|
|
public NormalVehicle followVehicle { get; set; }
|
|
|
|
public bool isVehicleBuffActive
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
private List<int> _finalReadyCellIndexs;
|
|
|
|
private Dictionary<int, ReadyAreaPoint> _readyAreaDict;
|
|
private Stack<ReadyAreaPoint> _pointsStack;
|
|
public GameObject rootObj;
|
|
|
|
private bool _needUpdate;
|
|
|
|
public ReadyAreaManager(Map map)
|
|
{
|
|
rootObj = new GameObject("[ReadyArea]");
|
|
_map = map;
|
|
isShow = false;
|
|
_readyAreaDict = new Dictionary<int, ReadyAreaPoint>();
|
|
_pointsStack = new Stack<ReadyAreaPoint>();
|
|
_finalReadyCellIndexs = new List<int>();
|
|
_InitReadyAreaFromLevel();
|
|
}
|
|
|
|
public void Init()
|
|
{
|
|
EventManager.Instance.Register<CaptureInst>(EventManager.EventName.INFIGHT_CAPTURE_FINSIHED, _OnCaptureArea);
|
|
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, _OnCellIndexChanged);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
EventManager.Instance.Unregister<CaptureInst>(EventManager.EventName.INFIGHT_CAPTURE_FINSIHED, _OnCaptureArea);
|
|
EventManager.Instance.Unregister<GameUnit>(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<int>();
|
|
var levelData = LevelManager.Instance.CurrentLevel.GetLevelData();
|
|
var areaId = levelData.preparingRegionId;
|
|
var area = _map.MapData.GetRegion(areaId);
|
|
if (area == null)
|
|
{
|
|
DebugUtil.LogError("读取准备区域失败");
|
|
return;
|
|
}
|
|
var cellIndexs = area.positions;
|
|
foreach (var cellIndex in cellIndexs)
|
|
{
|
|
if (_mapSavedReadyCellIndexs.Contains(cellIndex))
|
|
{
|
|
continue;
|
|
}
|
|
_mapSavedReadyCellIndexs.Add(cellIndex);
|
|
}
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
private void _SetPointsShow(List<int> cellIndexs)
|
|
{
|
|
for (int i = 0; i < cellIndexs.Count; i++)
|
|
{
|
|
var cellIndex = cellIndexs[i];
|
|
_SetPointShow(cellIndex);
|
|
}
|
|
}
|
|
|
|
private void _SetPointsHide(List<int> 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.isEmptyBlock)
|
|
{
|
|
return false;
|
|
}
|
|
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<int> cellList)
|
|
{
|
|
for (int i = 0; i < cellList.Count; i++)
|
|
{
|
|
var cellIndex = cellList[i];
|
|
BlackAreaManager.instance.LightUpCell(cellIndex, 0.1f);
|
|
}
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
}
|
|
}
|