using cfg.LegionBattleCfg;
using Cysharp.Threading.Tasks;
using Framework;
using Gameplay.LegionBattle.Unit;
using Gameplay.Net;
using Google.Protobuf.Collections;
using NLDPB;
using PhxhSDK;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Gameplay.LegionBattle
{
public sealed partial class LegionBattle : IUpdatable, ILoadable
{
///
/// 军团信息字典,key:军团阵营,value:军团数据
///
private Dictionary dicLegionData;
///
/// 玩家棋子字典,key:玩家id,value:玩家单位
///
private Dictionary dicActorUnit;
///
/// 建筑数据字典,key:建筑所在格子索引,value:建筑数据
///
private Dictionary dicBuildingData;
///
/// 安全区索引
///
private HashSet setSafeZoneIndex;
#region 属性
///
/// 所有建筑数据
///
public IEnumerable BuildingDatas
{
get
{
foreach (LegionLevelData.Building building in LevelData.Buildings)
{
if (dicBuildingData.TryGetValue(building.position, out LegionBuildingData buildingData))
yield return buildingData;
}
}
}
///
/// 所有玩家数据
///
public IEnumerable ActorDatas
{
get
{
foreach (LegionBattleActorUnit unit in dicActorUnit.Values)
{
yield return unit.Data;
}
}
}
///
/// 军团战关卡数据
///
public LegionLevelData LevelData { get; private set; }
///
/// 军团战地图配置数据
///
public DataLegionBattleMap MapCfg { get; private set; }
///
/// 战场结束时间
///
public DateTime EndTime { get; private set; }
///
/// 玩家自己的阵营
///
public BattlefieldActorCamp MyCamp { get; private set; } = BattlefieldActorCamp.BacNone;
///
/// 建筑数量
///
public int BuildingCount { get { return LevelData.Buildings.Count; } }
#endregion
///
/// 更新所有单位
///
public void UpdateUnit(float dt)
{
foreach (LegionBattleActorUnit unit in dicActorUnit.Values)
{
unit.LogicUpdate(dt);
}
}
///
/// 清除数据
///
public void ClearInfo()
{
if (null != dicLegionData)
{
dicLegionData.Clear();
dicLegionData = null;
}
if (null != dicActorUnit)
{
foreach (var i in dicActorUnit.Values)
{
i.Dispose();
}
dicActorUnit.Clear();
dicActorUnit = null;
}
if (null != dicBuildingData)
{
dicBuildingData.Clear();
dicBuildingData = null;
}
if (null != setSafeZoneIndex)
{
setSafeZoneIndex.Clear();
setSafeZoneIndex = null;
}
}
#region 更新数据
///
/// 初始化军团数据
///
public void InitLegionData(int mapId, uint startTime, int timeLength, MSG_LB_Legion legionA, MSG_LB_Legion legionB)
{
foreach (DataLegionBattleMap dataLegionBattleMap in TableManager.Instance.Tables.LegionBattleMap.DataList)
{
if (dataLegionBattleMap.ID == mapId)
{
MapCfg = dataLegionBattleMap;
break;
}
}
EndTime = CommonUtils.GetTimeByTimestamp(startTime).AddSeconds(timeLength);
if (null == dicLegionData)
dicLegionData = new Dictionary();
LegionData legionAInfo = new(BattlefieldActorCamp.CampA);
legionAInfo.InitData(legionA);
dicLegionData.Add(BattlefieldActorCamp.CampA, legionAInfo);
LegionData legionBInfo = new(BattlefieldActorCamp.CampB);
legionBInfo.InitData(legionB);
dicLegionData.Add(BattlefieldActorCamp.CampB, legionBInfo);
}
///
/// 初始化军团战玩家数据
///
public void InitActorUnit(MSG_LB_Actor data)
{
foreach (var kv in dicLegionData)
{
if (kv.Value.DicMember.TryGetValue(data.Id, out LegionActorData memberData))
{
memberData.CopyData(data);
break;
}
}
#region 记录玩家自己属于哪个阵营
if (Actor.Instance.Base.GetProp(ActorProp.ActorId) == data.Id)
{
foreach (var kv in dicLegionData)
{
if (kv.Value.DicMember.TryGetValue(data.Id, out _))
{
MyCamp = kv.Key;
LegionBattleManager.Debug($"玩家属于{MyCamp}阵营");
break;
}
}
}
#endregion
}
///
/// 初始化军团战建筑信息
///
public void InitBuildingInfo(MSG_LB_Building data)
{
if (!dicBuildingData.TryGetValue((int)data.Index, out LegionBuildingData buildingData))
return;
buildingData.CopyData(data);
UpdateBuildingCell(buildingData.Index);
EventManager.Instance.Send(EventManager.EventName.UpdateLegionBattleBuilding, buildingData.Index);
}
///
/// 更新军团战玩家数据
///
///
///
public void UpdateActorData(MSG_LB_ActorUpdate info)
{
if (!dicActorUnit.TryGetValue(info.Id, out LegionBattleActorUnit actorUnit))
return;
actorUnit.AsynData(info);
EventManager.Instance.Send(EventManager.EventName.UpdateLegionBattleActor, info.Id);
}
///
/// 通过id更新军团战玩家数据
///
///
///
///
///
///
///
public void UpdateActorInfoById(uint id, BattlefieldActorCommand command, int x, int z, RepeatedField pathX, RepeatedField pathZ)
{
if (!dicActorUnit.TryGetValue(id, out LegionBattleActorUnit actorUnit))
return;
actorUnit.AsynData(command, x, z, pathX, pathZ);
EventManager.Instance.Send(EventManager.EventName.UpdateLegionBattleActor, id);
}
///
/// 通过索引更新军团战建筑信息
///
public void UpdateBuildingInfoByIndex(int index, BattlefieldActorCamp camp, int defCount, int total, RepeatedField actorIds)
{
LegionBuildingData buildingData = dicBuildingData[index];
BattlefieldActorCamp oldCamp = buildingData.CurCamp;
buildingData.CopyData(camp, defCount, total, actorIds);
if (oldCamp != buildingData.CurCamp) // 阵营变化时刷新格子颜色
{
UpdateBuildingCell(buildingData.Index);
if (BattlefieldActorCamp.BacNone == oldCamp)
{
if(1 == buildingData.AttackedTotal)
UI_LegionBattleNoticeController.Open(E_LegionBattleNotice.BaseChange, index).Forget();
}
else if (BattlefieldActorCamp.BacNone != buildingData.CurCamp)
UI_LegionBattleNoticeController.Open(E_LegionBattleNotice.BaseChange, index).Forget();
}
if (0 != buildingData.DefenceCount && 0 == buildingData.DefenceCount % 3)
UI_LegionBattleNoticeController.Open(E_LegionBattleNotice.ContinuousDef, index).Forget();
EventManager.Instance.Send(EventManager.EventName.UpdateLegionBattleBuilding, index);
}
///
/// 设置军团战分数
///
///
///
public void SetScore(int aScore, int bScore)
{
dicLegionData[BattlefieldActorCamp.CampA].SetScore(aScore);
dicLegionData[BattlefieldActorCamp.CampB].SetScore(bScore);
EventManager.Instance.Send(EventManager.EventName.UpdateLegionBattleScore);
}
///
/// 攻击玩家
///
public void AttackActor(Vector2Int attackPos, uint attackActorId, uint targetActorId)
{
if (dicActorUnit.TryGetValue(attackActorId, out LegionBattleActorUnit actorUnit))
actorUnit.PlayAttackAnim();
if (dicActorUnit.TryGetValue(targetActorId, out LegionBattleActorUnit targetUnit))
targetUnit.PlayAttackAnim();
}
///
/// 攻击建筑
///
///
///
///
public void AttackBuilding(int index, uint actorId, RepeatedField targets)
{
LegionBattleManager.Debug($"{actorId}攻击建筑{index}");
}
#endregion
#region 获取数据
///
/// 尝试获取军团数据
///
public bool TryGetLegionData(BattlefieldActorCamp camp, out LegionData legionData)
{
if (!dicLegionData.TryGetValue(camp, out legionData))
return false;
if (null == legionData)
return false;
return true;
}
///
/// 尝试获取玩家数据
///
///
///
///
public bool TryGetActorData(uint actorId, out LegionActorData actorData)
{
if (!dicActorUnit.TryGetValue(actorId, out LegionBattleActorUnit actorUnit))
{
actorData = null;
return false;
}
if (null == actorUnit)
{
actorData = null;
return false;
}
actorData = actorUnit.Data;
return true;
}
///
/// 通过阵营获取玩家数据列表
///
public void GetActorDataListByCamp(BattlefieldActorCamp camp,ref List listActorData)
{
if (null == listActorData)
listActorData = new List();
else
listActorData.Clear();
if (!dicLegionData.TryGetValue(camp, out LegionData legionData)) // 通过阵营获取军团数据
return;
foreach (uint actorId in legionData.DicMember.Keys)
{
if(dicActorUnit.TryGetValue(actorId, out LegionBattleActorUnit actorUnit))
listActorData.Add(actorUnit.Data);
}
}
///
/// 通过索引尝试获取建筑数据
///
///
///
///
public bool TryGetBuildingDataByIndex(int index, out LegionBuildingData buildingData)
{
return dicBuildingData.TryGetValue(index, out buildingData);
}
///
/// 是否安全区
///
///
///
public bool IsSafeZone(int index)
{
return setSafeZoneIndex.Contains(index);
}
#endregion
///
/// 加载关卡数据
///
///
private async UniTask LoadLevelData()
{
string levelDataPath = CommonUtils.GetLegionBattleLevelData(MapCfg.LevelData);
TextAsset textAsset = await AssetManager.Instance.LoadAssetAsync(levelDataPath);
if (null == textAsset)
{
DebugUtil.LogError($"(军团战)关卡数据路径有误: {levelDataPath}");
return;
}
LevelData = JsonUtility.FromJson(textAsset.text);
#region 记录安全区
setSafeZoneIndex = new();
foreach (int index in LevelData.BornPosA)
{
setSafeZoneIndex.Add(index);
}
foreach (int index in LevelData.BornPosB)
{
setSafeZoneIndex.Add(index);
}
#endregion
if (null == dicBuildingData)
dicBuildingData = new Dictionary();
#region 所有地格记录是否有建筑
foreach (LegionLevelData.Building building in LevelData.Buildings)
{
if (!dicBuildingData.TryGetValue(building.position, out LegionBuildingData buildingData))
buildingData = new LegionBuildingData(building, LevelData.Width, LevelData.Height, Map);
foreach (int index in buildingData.SetAllIndex)
{
dicBuildingData[index] = buildingData;
}
}
#endregion
}
///
/// 加载玩家
///
///
private async UniTask LoadActor()
{
if (null == dicActorUnit)
dicActorUnit = new Dictionary();
foreach (var legionKV in dicLegionData)
{
foreach (var actorKV in legionKV.Value.DicMember)
{
if (!actorKV.Value.IsBattleActor) // 排除不能进入军团战的玩家
continue;
LegionBattleActorUnit legionBattleUnit = new(actorKV.Key, actorKV.Value);
dicActorUnit.Add(actorKV.Key, legionBattleUnit);
await legionBattleUnit.CreateAsync();
}
}
}
}
}