NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Area/Ready/ReadyAreaManager.cs

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();
}
}
}