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