NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Area/MoveArea/MoveAreaView.cs

414 lines
13 KiB
C#

using System.Collections.Generic;
using AOT.PostProcess.BlackArea;
using Framework;
using Gameplay.Common;
using Gameplay.Level;
using Gameplay.Unit;
using Gameplay.Unit.Data;
using Gameplay.Vehicle.Impl;
using PhxhSDK;
using UnityEngine;
using Constants = Framework.Constants;
namespace Gameplay.Area
{
public class MoveAreaView
{
public GameUnit owner;
public List<int> moveCellList = new List<int>();
public GameObject rootObj;
private bool _needRefresh;
private List<GameUnit> _teamUnits = new List<GameUnit>();
private List<BuffCellNotice> _buffCellNotices = new List<BuffCellNotice>();
private GameObject _buffNoticeObj;
public void Init()
{
rootObj = new GameObject("[MoveArea]");
_buffNoticeObj = new GameObject("[BuffNotice]");
_InitBuffCellNotices(_buffNoticeObj.transform);
}
private void _InitBuffCellNotices(Transform parent)
{
var map = LevelManager.Instance.CurrentLevel.Map;
var mapData = map.MapData;
for (int i = 0; i < mapData.showBuffPoints.Count; i++)
{
var buffPoint = mapData.showBuffPoints[i];
if (string.IsNullOrEmpty(buffPoint.path))
{
continue;
}
var cellIndex = buffPoint.cellIndex;
var notice = new BuffCellNotice()
{
cellIndex = cellIndex,
loadPath = buffPoint.path,
};
DebugUtil.LogG("BuffCellNotice:" + cellIndex + " " + buffPoint.path);
notice.CreateView(parent);
_buffCellNotices.Add(notice);
}
}
public void Show(GameUnit setOwner)
{
owner = setOwner;
_UpdateTeamUnits();
_RefreshMoveArea();
_needRefresh = false;
_ShowBuffNotices();
rootObj.SetActive(true);
_buffNoticeObj.SetActive(true);
_RegisterEvent();
}
private void _ShowBuffNotices()
{
for (int i = 0; i < _buffCellNotices.Count; i++)
{
var notice = _buffCellNotices[i];
if (moveCellList.Contains(notice.cellIndex))
{
notice.SetActive(true);
}
else
{
notice.SetActive(false);
}
}
}
private void _OnCellIndexChange(GameUnit unit)
{
if (unit == owner) return;
_needRefresh = true;
}
private void _RegisterEvent()
{
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, _OnCellIndexChange);
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_UP_VEHICLE, _OnUpVehicle);
EventManager.Instance.Register<EDDownVehicle>(EventManager.EventName.INFIGHT_DOWN_VEHICLE, _OnDownVehicle);
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_UNIT_REMOVE, _OnUnitRemove);
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_UNIT_READY, _OnUnitReady);
EventManager.Instance.Register<GameUnit>(EventManager.EventName.INFIGHT_VEHICLE_DESTROY, _OnVehicleDestroy);
}
private void _UnRegisterEvent()
{
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_UNIT_CELLINDEX_CHANGE, _OnCellIndexChange);
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_UP_VEHICLE, _OnUpVehicle);
EventManager.Instance.Unregister<EDDownVehicle>(EventManager.EventName.INFIGHT_DOWN_VEHICLE, _OnDownVehicle);
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_UNIT_REMOVE, _OnUnitRemove);
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_UNIT_READY, _OnUnitReady);
EventManager.Instance.Unregister<GameUnit>(EventManager.EventName.INFIGHT_VEHICLE_DESTROY, _OnVehicleDestroy);
}
private void _OnVehicleDestroy(GameUnit unit)
{
_needRefresh = true;
}
private void _OnUnitReady(GameUnit unit)
{
_needRefresh = true;
}
private void _OnUnitRemove(GameUnit unit)
{
_needRefresh = true;
}
private void _OnUpVehicle(GameUnit unit)
{
_needRefresh = true;
}
private void _OnDownVehicle(EDDownVehicle ed)
{
_needRefresh = true;
}
private void _UpdateTeamUnits()
{
_teamUnits.Clear();
var allUnits = GameUnitManager.instance.infightUnits.unitList;
for (int i = 0; i < allUnits.Count; i++)
{
var unit = allUnits[i];
if (unit == owner)
{
continue;
}
if (unit.commonData.troopId != owner.commonData.troopId)
{
continue;
}
// 只要角色和载具
if (unit.gameunitType != EGameUnitType.Character
&& unit.gameunitType != EGameUnitType.Vehicle)
{
continue;
}
_teamUnits.Add(unit);
}
}
public void Hide()
{
_UnRegisterEvent();
owner = null;
if (rootObj != null)
{
rootObj.SetActive(false);
}
if (_buffNoticeObj != null)
{
_buffNoticeObj.SetActive(false);
}
}
public void LogicUpdate()
{
if (owner == null) return;
if (_needRefresh)
{
_needRefresh = false;
_RefreshMoveArea();
}
}
public bool CheckIsInArea(int cellIndex)
{
return moveCellList.Contains(cellIndex);
}
private bool _CheckCanPass(int cellIndex)
{
if (cellIndex < 0)
{
return false;
}
if (cellIndex == owner.transData.cellIndex)
{
return true;
}
if (!PathFinder.CanPass(cellIndex, owner))
{
return false;
}
if (!BlackAreaManager.instance.CheckIsInLightArea(cellIndex))
{
return false;
}
return true;
}
private bool _CheckSelfUnits(int cellIndex)
{
// 判断所有队友在不在这个格子上
// 判断所有队友的targetcell在不在这个格子上
for (int i = 0; i < _teamUnits.Count; i++)
{
var unit = _teamUnits[i];
if (unit.statusData.isOnVehicle)
{
continue;
}
if (unit.statusData.isDead)
{
if (unit.transData.cellIndex == cellIndex)
{
return false;
}
continue;
}
if (unit.gameunitType == EGameUnitType.Vehicle)
{
// 载具需要额外判断是否已死亡和是否已满载
var vehicle = unit as NormalVehicle;
if (vehicle == null)
{
continue;
}
if (vehicle.CheckCanUp(owner))
{
continue;
}
}
if (unit.transData.cellIndex == cellIndex)
{
return false;
}
if (unit.controlData.targetCellIndex == cellIndex)
{
return false;
}
}
return true;
}
private void _RefreshMoveArea()
{
moveCellList.Clear();
var centerIndex = owner.transData.cellIndex;
var workList = new List<int>();
var checkedSet = new HashSet<int>();
workList.Add(centerIndex);
checkedSet.Add(centerIndex);
while (workList.Count > 0)
{
var lastValue = workList[^1];
workList.RemoveAt(workList.Count - 1);
// 添加到检查过列表中
// 判断当前格子是否可通行
if (!_CheckCanPass(lastValue))
{
// DebugUtil.LogError("blockedSet.Add:" + lastValue);
continue;
}
// 把自己加入到移动列表
moveCellList.Add(lastValue);
// 把周围的格子加入到工作列表
var aroundList = AreaManager.instance.GetCellIndexsAround(lastValue, 1, false);
for (int i = 0; i < aroundList.Count; i++)
{
var cellIndex = aroundList[i];
if (checkedSet.Contains(cellIndex))
{
continue;
}
workList.Add(cellIndex);
checkedSet.Add(cellIndex);
}
}
// 将队友相关的格子移除
for (int i = 0; i < moveCellList.Count; i++)
{
var cellIndex = moveCellList[i];
if (!_CheckSelfUnits(cellIndex))
{
moveCellList.RemoveAt(i);
i--;
}
}
// 将敌人所在格子加入
var units = GameUnitManager.instance.infightUnits.unitList;
for (int i = 0; i < units.Count; i++)
{
var unit = units[i];
if (unit == owner)
{
continue;
}
if (unit.commonData.troopId == owner.commonData.troopId)
{
continue;
}
var cellIndex = unit.transData.cellIndex;
if (!BlackAreaManager.instance.CheckIsInLightArea(cellIndex))
{
continue;
}
if (unit.statusData.canBeAttack)
{
if (!moveCellList.Contains(cellIndex))
{
moveCellList.Add(cellIndex);
}
}
}
// 刷新显示
if (moveCellList.Count != rootObj.transform.childCount)
{
// 需要匹配个数
if (moveCellList.Count < rootObj.transform.childCount)
{
// 多了, 需要删除
var needRemoveCount = rootObj.transform.childCount - moveCellList.Count;
for (int i = 0; i < needRemoveCount; i++)
{
var child = rootObj.transform.GetChild(moveCellList.Count + i);
Object.Destroy(child.gameObject);
}
}
else
{
// 少了, 需要添加
var needAddCount = moveCellList.Count - rootObj.transform.childCount;
for (int i = 0; i < needAddCount; i++)
{
var sampleObj = AssetManager.Instance.GetPreLoadResult<GameObject>(Constants.MOVE_AREA_POINT_PATH);
var instanceObj = Object.Instantiate(sampleObj, rootObj.transform);
}
}
}
// 刷新位置
for (int i = 0; i < moveCellList.Count; i++)
{
var cellIndex = moveCellList[i];
var worldPos = AreaManager.instance.GetCellPosByIndex(cellIndex);
var child = rootObj.transform.GetChild(i);
child.position = worldPos;
}
}
public void Dispose()
{
Hide();
owner = null;
moveCellList.Clear();
for (int i = 0; i < _buffCellNotices.Count; i++)
{
var notice = _buffCellNotices[i];
notice.Dispose();
}
_buffCellNotices.Clear();
if (rootObj != null)
{
Object.Destroy(rootObj);
rootObj = null;
}
if (_buffNoticeObj != null)
{
Object.Destroy(_buffNoticeObj);
_buffNoticeObj = null;
}
}
}
}