NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/LegionBattle/LegionBattle.Map.cs

217 lines
7.8 KiB
C#

using Cysharp.Threading.Tasks;
using Gameplay.Area;
using Gameplay.Area.Around;
using Gameplay.Area.BoardView;
using Gameplay.Common;
using Gameplay.Level;
using Gameplay.Story.Cmp.Anim;
using Gameplay.SubSystems;
using NLDPB;
using PhxhSDK;
using PhxhSDK.Res;
using System.Collections.Generic;
using UnityEngine;
namespace Gameplay.LegionBattle
{
public sealed partial class LegionBattle : IUpdatable, ILoadable
{
/// <summary>
/// 最大边数
/// </summary>
public const int MAX_SIDE = 6;
private Transform tsSideRoot;
/// <summary>
/// 边界线Prefab数组
/// </summary>
private GameObject[] goSides = new GameObject[MAX_SIDE];
/// <summary>
/// 格子数据
/// </summary>
private Dictionary<Vector2Int, LegionBattleHexesData> dicHexesData;
/// <summary>
/// 边界数据
/// </summary>
private Dictionary<int, LegionBattleSideData> dicSideData;
/// <summary>
/// 要更新的格子
/// </summary>
private HashSet<Vector2Int> setUpdateHexes;
/// <summary>
/// 要更新边的格子
/// </summary>
private HashSet<Vector2Int> setUpdateHexesSide;
/// <summary>
/// 军团战地图
/// </summary>
public Map Map { get; private set; }
/// <summary>
/// 两格之间的距离
/// </summary>
public float Distance { get; private set; }
public async UniTask LoadMap()
{
SceneHandle sceneHandle = await GameSceneManager.Instance.LoadSceneAsync(MapCfg.Path);
MapData mapData = await MapUtils.LoadMapData(MapCfg.MapData); // 加载地图数据
Map = await MapUtils.LoadMap(mapData); // 加载地图
AroundHelper.Init(Map);
Camera camera = sceneHandle.Camera;
CameraManager.Instance.SwitchMainCamera(camera);
MapUtils.BindCameraController(camera, Map);
Map.TerrainGridSystem.showCells = true;
Map.TerrainGridSystem.cellBorderThickness = 0.04f;
Vector3 start = Map.TGSCellIndex2WorldPosition(0);
Vector3 end = Map.TGSCellIndex2WorldPosition(1);
Distance = (end - start).magnitude;
if (null == setUpdateHexes)
setUpdateHexes = new HashSet<Vector2Int>();
if(null == setUpdateHexesSide)
setUpdateHexesSide = new HashSet<Vector2Int>();
if (null == dicHexesData)
dicHexesData = new Dictionary<Vector2Int, LegionBattleHexesData>();
if (null == dicSideData)
dicSideData = new Dictionary<int, LegionBattleSideData>();
#region 资源加载
for (int i = 0; i < MAX_SIDE; i++)
{
goSides[i] = await AssetManager.Instance.LoadAssetAsync<GameObject>(PathDefine.BoardSide.LEGION_BATTLE_SIDE_PATHS[i]);
}
AssetManager.Instance.PostPreload(PathDefine.MoveArea.LEGIONBATTLE_A_AREA_PATH); // 蓝色方地格
AssetManager.Instance.PostPreload(PathDefine.MoveArea.LEGIONBATTLE_B_AREA_PATH); // 红色方地格
#endregion
await AssetManager.Instance.WaitAllPreloads();
GameObject goSideRoot = new("[Side]");
tsSideRoot = goSideRoot.transform;
GameObject goCellRoot = new("[MoveArea]");
Transform tsCellRoot = goCellRoot.transform;
GameObject goACell = AssetManager.Instance.GetPreLoadResult<GameObject>(PathDefine.MoveArea.LEGIONBATTLE_A_AREA_PATH);
GameObject goBCell = AssetManager.Instance.GetPreLoadResult<GameObject>(PathDefine.MoveArea.LEGIONBATTLE_B_AREA_PATH);
foreach (TGS.Cell cell in Map.TerrainGridSystem.cells)
{
Vector3 pos = Map.TGSCellIndex2WorldPosition(cell.index);
Vector2Int coordinate = Map.TGSCellIndex2BlockPosition(cell.index);
GameObject goNewACell = Object.Instantiate(goACell, tsCellRoot); // 实例化地板
goNewACell.transform.position = pos;
goNewACell.SetActive(false);
GameObject goNewBCell = Object.Instantiate(goBCell, tsCellRoot); // 实例化地板
goNewBCell.transform.position = pos;
goNewBCell.SetActive(false);
LegionBattleHexesData hexesData = new(cell, coordinate, goNewACell, goNewBCell);
dicHexesData.Add(coordinate, hexesData);
foreach (int i in hexesData.ListAroundSideIndex)
{
CreateSideByIndex(i);
}
}
}
/// <summary>
/// 获取地板阵营根据索引
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public BattlefieldActorCamp GetCellCampByIndex(int index)
{
Vector2Int pos = Map.TGSCellIndex2BlockPosition(index);
if (!dicHexesData.TryGetValue(pos, out LegionBattleHexesData hexesData))
return BattlefieldActorCamp.BacNone;
return hexesData.Camp;
}
/// <summary>
/// 更新变化的格子边线
/// </summary>
private void UpdateAllSide()
{
foreach (Vector2Int pos in setUpdateHexes)
{
if (!dicHexesData.TryGetValue(pos, out LegionBattleHexesData hexesData))
continue;
setUpdateHexesSide.Add(pos);
foreach (Vector2Int aroundPos in hexesData.ListAroundCell)
{
setUpdateHexesSide.Add(aroundPos);
}
}
foreach (Vector2Int pos in setUpdateHexesSide)
{
if (!dicHexesData.TryGetValue(pos, out LegionBattleHexesData hexesData))
continue;
hexesData.UpdateSide();
}
setUpdateHexes.Clear();
setUpdateHexesSide.Clear();
}
/// <summary>
/// 设置格子边线是否显示
/// </summary>
/// <param name="camp">当前格子阵营</param>
/// <param name="aroundCell">周围格子</param>
/// <param name="sideIndex">边线索引</param>
public void UpdateSideShow(BattlefieldActorCamp camp, Vector2Int aroundCell, int sideIndex)
{
if (!dicSideData.TryGetValue(sideIndex, out LegionBattleSideData sideData))
return;
if (!dicHexesData.TryGetValue(aroundCell, out LegionBattleHexesData hexesData))
{
sideData.IsActive = true;
return;
}
sideData.IsActive = camp != hexesData.Camp;
}
/// <summary>
/// 创建边界线
/// </summary>
/// <param name="boardIndex"></param>
private void CreateSideByIndex(int boardIndex)
{
if (dicSideData.ContainsKey(boardIndex))
return;
int centerCellIndex = boardIndex / 10;
Vector3 centerPos = Map.TGSCellIndex2WorldPosition(centerCellIndex);
int side = boardIndex % 10;
dicSideData.Add(boardIndex, new LegionBattleSideData(centerPos, CreateBoardSideObj(side, centerPos, boardIndex.ToString())));
}
/// <summary>
/// 创建边的实例
/// </summary>
/// <param name="side"></param>
/// <param name="centerPos"></param>
/// <returns></returns>
private GameObject CreateBoardSideObj(int side, Vector3 centerPos, string name)
{
GameObject goSide = Object.Instantiate(goSides[side - 1], tsSideRoot);
goSide.transform.position = centerPos;
goSide.name = name;
return goSide;
}
}
}