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

649 lines
22 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
{
/// <summary>
/// 军团信息字典,key:军团阵营,value:军团数据
/// </summary>
private Dictionary<BattlefieldActorCamp, LegionData> dicLegionData;
/// <summary>
/// 玩家棋子字典,key:玩家id,value:玩家单位
/// </summary>
private Dictionary<uint, LegionBattleActorUnit> dicActorUnit;
/// <summary>
/// 建筑数据字典,key:建筑所在格子索引,value:建筑数据
/// </summary>
private Dictionary<int, LegionBuildingData> dicBuildingData;
/// <summary>
/// 军团战战斗数据池
/// </summary>
private Queue<LegionBattleFightData> queueFightDataPool;
/// <summary>
/// 军团战战斗数据
/// </summary>
private Dictionary<uint, LegionBattleFightData> dicFightingData;
/// <summary>
/// 安全区索引
/// </summary>
private HashSet<int> setSafeZoneIndex;
#region 属性
/// <summary>
/// 所有建筑数据
/// </summary>
public IEnumerable<LegionBuildingData> BuildingDatas
{
get
{
foreach (LegionLevelData.Building building in LevelData.Buildings)
{
if (dicBuildingData.TryGetValue(building.position, out LegionBuildingData buildingData))
yield return buildingData;
}
}
}
/// <summary>
/// 所有玩家数据
/// </summary>
public IEnumerable<LegionActorData> ActorDatas
{
get
{
foreach (LegionBattleActorUnit unit in dicActorUnit.Values)
{
yield return unit.Data;
}
}
}
/// <summary>
/// 军团战关卡数据
/// </summary>
public LegionLevelData LevelData { get; private set; }
/// <summary>
/// 军团战地图配置数据
/// </summary>
public DataLegionBattleMap MapCfg { get; private set; }
/// <summary>
/// 战报数据列表
/// </summary>
public List<LegionBattleReportData> ListReportData { get; private set; }
/// <summary>
/// 战场结束时间
/// </summary>
public DateTime EndTime { get; private set; }
/// <summary>
/// 玩家自己的阵营
/// </summary>
public BattlefieldActorCamp MyCamp { get; private set; } = BattlefieldActorCamp.BacNone;
/// <summary>
/// 建筑数量
/// </summary>
public int BuildingCount { get { return LevelData.Buildings.Count; } }
#endregion
/// <summary>
/// 更新所有单位
/// </summary>
public void UpdateUnit(float dt)
{
foreach (LegionBattleActorUnit unit in dicActorUnit.Values)
{
unit.LogicUpdate(dt);
}
}
/// <summary>
/// 清除数据
/// </summary>
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 != dicFightingData)
{
dicFightingData.Clear();
dicFightingData = null;
}
if (null != queueFightDataPool)
{
queueFightDataPool.Clear();
queueFightDataPool = null;
}
if (null != dicHexesData)
{
dicHexesData.Clear();
dicHexesData = null;
}
if (null != ListReportData)
{
ListReportData.Clear();
ListReportData = null;
}
if (null != setSafeZoneIndex)
{
setSafeZoneIndex.Clear();
setSafeZoneIndex = null;
}
}
#region 更新数据
/// <summary>
/// 初始化军团数据
/// </summary>
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 == ListReportData)
ListReportData = new List<LegionBattleReportData>();
if (null == dicLegionData)
dicLegionData = new Dictionary<BattlefieldActorCamp, LegionData>();
if (null == dicFightingData)
dicFightingData = new Dictionary<uint, LegionBattleFightData>();
if (null == queueFightDataPool)
queueFightDataPool = new Queue<LegionBattleFightData>();
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);
}
/// <summary>
/// 初始化军团战玩家数据
/// </summary>
public void InitActorUnit(MSG_LB_Actor data)
{
if (null == dicActorUnit)
dicActorUnit = new Dictionary<uint, LegionBattleActorUnit>();
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
}
/// <summary>
/// 初始化军团战建筑信息
/// </summary>
public void InitBuildingData(MSG_LB_Building data)
{
if (!dicBuildingData.TryGetValue((int)data.Index, out LegionBuildingData buildingData))
return;
buildingData.CopyData(data);
EventManager.Instance.Send(EventManager.EventName.UpdateLegionBattleBuilding, buildingData.Index);
}
/// <summary>
/// 初始化战报数据
/// </summary>
public void InitReportData(RepeatedField<MSG_CombatRecord> listReportData)
{
foreach (MSG_CombatRecord reportData in listReportData)
{
ListReportData.Add(new LegionBattleReportData(reportData));
}
}
/// <summary>
/// 更新军团战玩家数据
/// </summary>
/// <param name="index"></param>
/// <param name="info"></param>
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);
}
/// <summary>
/// 通过id更新军团战玩家数据
/// </summary>
/// <param name="id"></param>
/// <param name="command"></param>
/// <param name="x"></param>
/// <param name="z"></param>
/// <param name="pathX"></param>
/// <param name="pathZ"></param>
public void UpdateActorInfoById(uint id, BattlefieldActorCommand command, int x, int z, RepeatedField<uint> pathX, RepeatedField<uint> pathZ)
{
if (!dicActorUnit.TryGetValue(id, out LegionBattleActorUnit actorUnit))
return;
actorUnit.AsynData(command, x, z, pathX, pathZ);
EventManager.Instance.Send(EventManager.EventName.UpdateLegionBattleActor, id);
}
/// <summary>
/// 通过索引更新军团战建筑信息
/// </summary>
public void UpdateBuildingInfoByIndex(int index, BattlefieldActorCamp camp, int defCount, int total, RepeatedField<uint> actorIds)
{
LegionBuildingData buildingData = dicBuildingData[index];
BattlefieldActorCamp oldCamp = buildingData.CurCamp;
buildingData.CopyData(camp, defCount, total, actorIds);
if (oldCamp != buildingData.CurCamp) // 阵营变化时刷新格子颜色
{
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);
}
/// <summary>
/// 更新格子信息
/// </summary>
/// <param name="pos"></param>
/// <param name="camp"></param>
public void UpdateHexes(RepeatedField<int> listX, RepeatedField<int> listY, RepeatedField<int> listCamp)
{
for (int i = 0; i < listX.Count; ++i)
{
if (!dicHexesData.TryGetValue(new Vector2Int(listX[i], listY[i]), out LegionBattleHexesData hexesData))
return;
hexesData.SetCamp((BattlefieldActorCamp)listCamp[i]);
UpdateCellColorByIndex(hexesData);
}
UpdateCellLine();
}
/// <summary>
/// 设置军团战分数
/// </summary>
/// <param name="aScore"></param>
/// <param name="bScore"></param>
public void SetScore(int aScore, int bScore)
{
dicLegionData[BattlefieldActorCamp.CampA].SetScore(aScore);
dicLegionData[BattlefieldActorCamp.CampB].SetScore(bScore);
EventManager.Instance.Send(EventManager.EventName.UpdateLegionBattleScore);
}
/// <summary>
/// 更新建筑分数
/// </summary>
/// <param name="camp"></param>
/// <param name="pos"></param>
/// <param name="score"></param>
public void UpdateBuildingScore(BattlefieldActorCamp camp, Vector2Int pos, int score)
{
if (null == Map)
return;
if (BattlefieldActorCamp.BacNone == camp)
return;
int index = Map.BlockPosition2TGSCellIndex(pos);
LegionBattleBuildingScoreData buildingScoreData = new(camp, index, score);
LegionBattleManager.Debug($"更新军团战建筑得分数据,阵营:{camp},建筑索引:{index},得分:{score}");
EventManager.Instance.Send(EventManager.EventName.UpdateLegionBattleBuildingScore, buildingScoreData);
}
/// <summary>
/// 开始战斗(进入集结状态)
/// </summary>
public async void FightStart(uint id, uint passTime, RepeatedField<uint> attacks, RepeatedField<uint> defences, uint buildingX, uint buildingY)
{
if (dicFightingData.TryGetValue(id, out LegionBattleFightData fightData))
fightData.UpdateData(attacks, defences);
else
{
if (queueFightDataPool.Count > 0)
fightData = queueFightDataPool.Dequeue();
else
fightData = new LegionBattleFightData();
fightData.InitData(passTime * 0.001f, attacks, defences, new Vector2Int((int)buildingX, (int)buildingY));
dicFightingData.Add(id, fightData);
}
#region 进入集结
foreach (uint actorId in fightData.ListAttackId)
{
if (!TryGetActorData(actorId, out LegionActorData actorData))
continue;
actorData.IsAssemble = true;
actorData.IsAttack = true;
actorData.FightId = id;
}
foreach (uint actorId in fightData.ListDefenceId)
{
if (!TryGetActorData(actorId, out LegionActorData actorData))
continue;
actorData.IsAssemble = true;
actorData.IsAttack = false;
actorData.FightId = id;
if (actorId == Actor.Instance.Base.GetProp(ActorProp.ActorId))
await UI_LegionBattleBreatheController.Open(true);
}
if (!fightData.IsAttackActor)
{
fightData.BuildingData.IsAssemble = true;
fightData.BuildingData.FightId = id;
}
#endregion
LegionBattleManager.Debug($"战斗id为{id}的集结开始, {attacks}集结攻击");
}
/// <summary>
/// 战斗结束
/// </summary>
/// <param name="index"></param>
/// <param name="actorId"></param>
/// <param name="targets"></param>
public void FightOver(uint id, int attack, int def, float result, DateTime time,
BattlefieldActorCamp attackCamp, BattlefieldActorCamp defCamp, Vector2Int buildingPos,
bool isAttackLiving, bool isDefenceLiving, bool isAttackEscape, bool isDefenceEscape)
{
if (!dicFightingData.TryGetValue(id, out LegionBattleFightData fightData))
{
DebugUtil.LogError($"军团战战斗id:{id}不存在");
return;
}
#region 退出集结
foreach (uint actorId in fightData.ListAttackId)
{
if (!TryGetActorData(actorId, out LegionActorData actorData))
continue;
actorData.IsAssemble = false;
}
foreach (uint actorId in fightData.ListDefenceId)
{
if (!TryGetActorData(actorId, out LegionActorData actorData))
continue;
actorData.IsAssemble = false;
}
if (!fightData.IsAttackActor)
fightData.BuildingData.IsAssemble = false;
#endregion
LegionBattleReportData reportData = new(attack, def, result, fightData, time, attackCamp, defCamp,
isAttackLiving, isDefenceLiving, isAttackEscape, isDefenceEscape);
ListReportData.Add(reportData);
dicFightingData.Remove(id);
fightData.Clear();
queueFightDataPool.Enqueue(fightData);
EventManager.Instance.Send(EventManager.EventName.UpdateLegionBattleReport, reportData); // 更新军团战战报
}
#endregion
#region 获取数据
/// <summary>
/// 尝试获取军团数据
/// </summary>
public bool TryGetLegionData(BattlefieldActorCamp camp, out LegionData legionData)
{
if (!dicLegionData.TryGetValue(camp, out legionData))
return false;
if (null == legionData)
return false;
return true;
}
/// <summary>
/// 尝试获取玩家数据
/// </summary>
/// <param name="actorId"></param>
/// <param name="actorData"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 通过阵营获取玩家数据列表
/// </summary>
public void GetActorDataListByCamp(BattlefieldActorCamp camp,ref List<LegionActorData> listActorData)
{
if (null == listActorData)
listActorData = new List<LegionActorData>();
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);
}
}
/// <summary>
/// 通过索引尝试获取建筑数据
/// </summary>
/// <param name="index"></param>
/// <param name="buildingData"></param>
/// <returns></returns>
public bool TryGetBuildingDataByIndex(int index, out LegionBuildingData buildingData)
{
return dicBuildingData.TryGetValue(index, out buildingData);
}
/// <summary>
/// 是否安全区
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public bool IsSafeZone(int index)
{
return setSafeZoneIndex.Contains(index);
}
/// <summary>
/// 获取集结倒计时
/// </summary>
/// <param name="fightId"></param>
/// <returns></returns>
public float GetFightCDByID(uint fightId)
{
if (!dicFightingData.TryGetValue(fightId, out LegionBattleFightData fightData))
return 0f;
float fightTime = 0f;
foreach (DataLegionBattleCombatParam param in TableManager.Instance.Tables.LegionBattleCombatParam.DataList)
{
if (CombatParam.BattleTiming != param.ID)
continue;
fightTime = param.ParamInt1;
break;
}
TimeSpan timeSpan = fightData.StartFightTime.AddMilliseconds(fightTime) - CommonUtils.GetCurTime(CommonUtils.E_TimeType.Server);
return timeSpan.Seconds + 1;
}
#endregion
/// <summary>
/// 加载关卡数据
/// </summary>
/// <returns></returns>
private async UniTask LoadLevelData()
{
string levelDataPath = CommonUtils.GetLegionBattleLevelData(MapCfg.LevelData);
TextAsset textAsset = await AssetManager.Instance.LoadAssetAsync<TextAsset>(levelDataPath);
if (null == textAsset)
{
DebugUtil.LogError($"(军团战)关卡数据路径有误: {levelDataPath}");
return;
}
LevelData = JsonUtility.FromJson<LegionLevelData>(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<int, LegionBuildingData>();
#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
}
/// <summary>
/// 加载玩家
/// </summary>
/// <returns></returns>
private async UniTask LoadActor()
{
await UniTask.WaitUntil(() => { return null != dicActorUnit; });
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();
}
}
}
}
}