482 lines
16 KiB
C#
482 lines
16 KiB
C#
using Cysharp.Threading.Tasks;
|
|
using Framework;
|
|
using Gameplay.Net;
|
|
using Google.Protobuf.Collections;
|
|
using NLDPB;
|
|
using PhxhSDK;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Gameplay.LegionBattle
|
|
{
|
|
public sealed partial class LegionBattleManager : Singlenton<LegionBattleManager>, IUpdatable
|
|
{
|
|
/// <summary>
|
|
/// 是否军团战中
|
|
/// </summary>
|
|
public bool IsLegionBattle { get; private set; }
|
|
|
|
/// <summary>
|
|
/// 是否进入军团战完成
|
|
/// </summary>
|
|
public bool IsLegionBattleOK { get; private set; }
|
|
|
|
/// <summary>
|
|
/// 初始化同步完成军团数据
|
|
/// </summary>
|
|
private bool isInitAsynLegionData;
|
|
/// <summary>
|
|
/// 初始化同步完成玩家数据
|
|
/// </summary>
|
|
private bool isInitAsynActorData;
|
|
/// <summary>
|
|
/// 初始化同步完成建筑数据
|
|
/// </summary>
|
|
private bool isInitAsynBuildingData;
|
|
|
|
private void InitAction()
|
|
{
|
|
IsLegionBattle = false;
|
|
IsLegionBattleOK = false;
|
|
|
|
EventManager.Instance.Register(EventManager.EventName.EnterLegionBattle, OnServerEnterLegionBattle);
|
|
EventManager.Instance.Register(EventManager.EventName.EnterLegionBattleSuccess, OnServerEnterLegionBattleOK);
|
|
EventManager.Instance.Register(EventManager.EventName.ExitLegionBattle, OnServerExitLegionBattle);
|
|
}
|
|
|
|
private void ReleaseAction()
|
|
{
|
|
EventManager.Instance.Unregister(EventManager.EventName.ExitLegionBattle, OnServerExitLegionBattle);
|
|
EventManager.Instance.Unregister(EventManager.EventName.EnterLegionBattleSuccess, OnServerEnterLegionBattleOK);
|
|
EventManager.Instance.Unregister(EventManager.EventName.EnterLegionBattle, OnServerEnterLegionBattle);
|
|
}
|
|
|
|
#region 进入军团战
|
|
/// <summary>
|
|
/// 进入军团战观察地图
|
|
/// </summary>
|
|
public void EnterLegionBattleAndInspect()
|
|
{
|
|
GameStateManager.Instance.ChangeState(new GameStateLegionBattleInspect());
|
|
}
|
|
|
|
/// <summary>
|
|
/// 向服务器发送消息进入军团战
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="finishCallback"></param>
|
|
/// <param name="param"></param>
|
|
/// <param name="isPlay">剧情加载完成后是否立即播放</param>
|
|
public async void TryEnterLegionBattleByServer()
|
|
{
|
|
WaitingForServer.Instance.EventWaiting(WaitingForServer.EventName.FightEnter, false);
|
|
|
|
if (IsLegionBattle)
|
|
{
|
|
DebugUtil.LogError($"进入军团战失败!当前正处于军团战中!");
|
|
WaitingForServer.Instance.EventDone(WaitingForServer.EventName.FightEnter);
|
|
return;
|
|
}
|
|
|
|
CurBattle = new();
|
|
isInitAsynLegionData = false;
|
|
isInitAsynActorData = false;
|
|
isInitAsynBuildingData = false;
|
|
|
|
NetHelper.EnterLegionBattle(); // 进入军团战消息
|
|
|
|
await UniTask.WaitForSeconds(10f); // 10秒没有进入军团战停止转圈
|
|
if(!IsLegionBattle)
|
|
WaitingForServer.Instance.EventDone(WaitingForServer.EventName.FightEnter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 向服务器发送消息退出军团战
|
|
/// </summary>
|
|
public void TryExitLegionBattleByServer()
|
|
{
|
|
WaitingForServer.Instance.EventWaiting(WaitingForServer.EventName.FightEnter, false);
|
|
|
|
if (!IsLegionBattleOK)
|
|
{
|
|
DebugUtil.LogError($"退出军团战失败!当前不处于军团战中!");
|
|
WaitingForServer.Instance.EventDone(WaitingForServer.EventName.FightEnter);
|
|
return;
|
|
}
|
|
|
|
NetHelper.ExitLegionBattle(); // 退出军团战消息
|
|
}
|
|
|
|
/// <summary>
|
|
/// 进入军团战(不经过服务器)
|
|
/// </summary>
|
|
public void EnterLegionBattle()
|
|
{
|
|
IsLegionBattle = true;
|
|
|
|
GameStateManager.Instance.ChangeState(new GameStateLegionBattle());
|
|
}
|
|
|
|
/// <summary>
|
|
/// 退出军团战(经过服务器)
|
|
/// </summary>
|
|
public void ExitLegionBattle()
|
|
{
|
|
IsLegionBattleOK = false;
|
|
IsLegionBattle = false;
|
|
|
|
GameStateManager.Instance.ChangeState(new GameStateMainScene());
|
|
}
|
|
|
|
/// <summary>
|
|
/// 退出军团战观察地图
|
|
/// </summary>
|
|
public void ExitLegionBattleInspect()
|
|
{
|
|
GameStateManager.Instance.ChangeState(new GameStateMainScene());
|
|
}
|
|
#endregion
|
|
|
|
#region 同步数据
|
|
/// <summary>
|
|
/// 同步初始化军团战军团数据
|
|
/// </summary>
|
|
public void InitLegionData(int mapId, uint startTime, int timeLength, MSG_LB_Legion legionAData, MSG_LB_Legion legionBData)
|
|
{
|
|
CurBattle.InitLegionData(mapId, startTime, timeLength, legionAData, legionBData);
|
|
|
|
Debug("军团战初始数据同步完成");
|
|
isInitAsynLegionData = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步初始化军团战玩家数据
|
|
/// </summary>
|
|
public async void InitActorData(RepeatedField<MSG_LB_Actor> actorDatas)
|
|
{
|
|
await UniTask.WaitUntil(() => { return isInitAsynLegionData; });
|
|
|
|
foreach (MSG_LB_Actor actorData in actorDatas)
|
|
{
|
|
CurBattle.InitActorUnit(actorData);
|
|
//View.AddActor(actorData.Id, actorData.MoveTime);
|
|
}
|
|
|
|
Debug("军团战初始玩家数据同步完成");
|
|
isInitAsynActorData = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步初始化军团战建筑数据
|
|
/// </summary>
|
|
public async void InitBuildingData(RepeatedField<MSG_LB_Building> buildingDatas)
|
|
{
|
|
await UniTask.WaitUntil(() => { return isInitAsynActorData && CurBattle.IsLoadComplete; });
|
|
|
|
foreach (MSG_LB_Building buildingData in buildingDatas)
|
|
{
|
|
CurBattle.InitBuildingData(buildingData);
|
|
}
|
|
|
|
Debug("军团战初始建筑数据同步完成");
|
|
isInitAsynBuildingData = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新军团战玩家数据
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <param name="actorData"></param>
|
|
public async void UpdateActorData(MSG_LB_ActorUpdate actorData)
|
|
{
|
|
await UniTask.WaitUntil(() => { return isInitAsynActorData; });
|
|
|
|
CurBattle.UpdateActorData(actorData);
|
|
}
|
|
|
|
/// <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 UpdateActorDataById(uint id, BattlefieldActorCommand command, int x, int z, RepeatedField<uint> pathX, RepeatedField<uint> pathZ)
|
|
{
|
|
CurBattle.UpdateActorInfoById(id, command, x, z, pathX, pathZ);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 通过索引更新军团战建筑数据
|
|
/// </summary>
|
|
public void UpdateBuildingDataByIndex(int index, BattlefieldActorCamp camp, int defCount, int total, RepeatedField<uint> actorIds)
|
|
{
|
|
CurBattle.UpdateBuildingInfoByIndex(index, camp, defCount, total, actorIds);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置军团战分数
|
|
/// </summary>
|
|
/// <param name="aScore"></param>
|
|
/// <param name="bScore"></param>
|
|
public void UpdateScore(int aScore, int bScore)
|
|
{
|
|
CurBattle.SetScore(aScore, bScore);
|
|
|
|
if (IsLegionBattle)
|
|
EventManager.Instance.Send(EventManager.EventName.UpdateLegionBattleScore);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新建筑分数
|
|
/// </summary>
|
|
/// <param name="x"></param>
|
|
/// <param name="z"></param>
|
|
/// <param name="score"></param>
|
|
public void UpdateBuildingScore(uint camp, uint x, uint z, uint score)
|
|
{
|
|
CurBattle.UpdateBuildingScore((BattlefieldActorCamp)camp, new Vector2Int((int)x, (int)z), (int)score);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新格子
|
|
/// </summary>
|
|
/// <param name="listX"></param>
|
|
/// <param name="listY"></param>
|
|
/// <param name="listCamp"></param>
|
|
public async void UpdateHexes(RepeatedField<int> listX, RepeatedField<int> listY, RepeatedField<int> listCamp)
|
|
{
|
|
await UniTask.WaitUntil(() => { return isInitAsynBuildingData; });
|
|
|
|
if (listX.Count != listY.Count || listX.Count != listCamp.Count)
|
|
{
|
|
DebugUtil.LogError($"(军团战),同步的格子数据数量不一致错误");
|
|
return;
|
|
}
|
|
|
|
CurBattle.UpdateHexes(listX, listY, listCamp);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新通知
|
|
/// </summary>
|
|
public async void UpdateNotice(BattlefieldActorCamp camp, int x, int y, E_LegionBattleNotice notice)
|
|
{
|
|
if (camp == CurBattle.MyCamp || camp == BattlefieldActorCamp.BacNone) // 友方阵营或者无阵营
|
|
{
|
|
Vector2Int pos = new(x, y);
|
|
|
|
await UI_LegionBattleNoticeController.Open(notice, CurBattle.Map.BlockPosition2TGSCellIndex(pos));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始化战报数据
|
|
/// </summary>
|
|
public async void InitReportData(RepeatedField<MSG_CombatRecord> listReportData)
|
|
{
|
|
await UniTask.WaitUntil(() => { return isInitAsynBuildingData; });
|
|
|
|
CurBattle.InitReportData(listReportData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 开始战斗(进入集结状态)
|
|
/// </summary>
|
|
/// <param name="attackPos"></param>
|
|
/// <param name="attackActorId"></param>
|
|
/// <param name="targetActorId"></param>
|
|
public void FightStart(uint id, uint passTime, RepeatedField<uint> attacks, RepeatedField<uint> defences, uint buildingX, uint buildingY)
|
|
{
|
|
CurBattle.FightStart(id, passTime, attacks, defences, buildingX, buildingY);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 战斗结束
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
public void FightOver(B_Clt_LegionBattlefieldCombatEnd data)
|
|
{
|
|
CurBattle.FightOver(data.Id,
|
|
(int)data.Attack,
|
|
(int)data.Defence,
|
|
data.Result,
|
|
CommonUtils.GetTimeByTimestamp(data.Time),
|
|
(BattlefieldActorCamp)data.AttackCamp,
|
|
(BattlefieldActorCamp)data.DefenceCamp,
|
|
new Vector2Int((int)data.Z, (int)data.X),
|
|
data.IsAttackLiving,
|
|
data.IsDefenceLiving,
|
|
data.IsAttackEscape,
|
|
data.IsDefenceEscape);
|
|
|
|
Debug($"id为{data.Id}战斗结束");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 军团战结算
|
|
/// </summary>
|
|
public async void LegionBattleOver(BattlefieldActorCamp winCamp, RepeatedField<LegionBattleEndActor> a, RepeatedField<LegionBattleEndActor> b,uint prizeType)
|
|
{
|
|
if (!IsLegionBattle)
|
|
return;
|
|
|
|
await UniTask.WaitUntil(() => { return IsLegionBattleOK; }); // 等待军团战加载完成,防止正好有人在加载阶段
|
|
CurBattle.EndLegionBattle(new LegionSettleData(winCamp, a, b, prizeType));
|
|
}
|
|
#endregion
|
|
|
|
#region 获取数据
|
|
/// <summary>
|
|
/// 尝试获取友方军团数据
|
|
/// </summary>
|
|
/// <param name="legionData"></param>
|
|
/// <returns></returns>
|
|
public bool TryGetMyLegionData(out LegionData legionData)
|
|
{
|
|
return CurBattle.TryGetLegionData(CurBattle.MyCamp, out legionData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 尝试获取敌方军团数据
|
|
/// </summary>
|
|
/// <param name="legionData"></param>
|
|
/// <returns></returns>
|
|
public bool TryGetEnemyLegionData(out LegionData legionData)
|
|
{
|
|
if (BattlefieldActorCamp.CampA == CurBattle.MyCamp)
|
|
return CurBattle.TryGetLegionData(BattlefieldActorCamp.CampB, out legionData);
|
|
else
|
|
return CurBattle.TryGetLegionData(BattlefieldActorCamp.CampA, out legionData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 尝试获取军团数据
|
|
/// </summary>
|
|
public bool TryGetLegionData(BattlefieldActorCamp camp, out LegionData legionData)
|
|
{
|
|
return CurBattle.TryGetLegionData(camp, out legionData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 尝试获取玩家数据
|
|
/// </summary>
|
|
/// <param name="actorId"></param>
|
|
/// <param name="actorData"></param>
|
|
/// <returns></returns>
|
|
public bool TryGetActorData(uint actorId, out LegionActorData actorData)
|
|
{
|
|
return CurBattle.TryGetActorData(actorId, out actorData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 尝试获取玩家自己的数据
|
|
/// </summary>
|
|
/// <param name="actorData"></param>
|
|
/// <returns></returns>
|
|
public bool TryGetMyActorData(out LegionActorData actorData)
|
|
{
|
|
return CurBattle.TryGetActorData(Actor.Instance.Base.GetProp(ActorProp.ActorId), out actorData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取友方军团玩家列表
|
|
/// </summary>
|
|
public void GetMyLegionActorList(ref List<LegionActorData> listActorData)
|
|
{
|
|
CurBattle.GetActorDataListByCamp(CurBattle.MyCamp, ref listActorData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 尝试通过索引获取建筑数据
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <param name="buildingData"></param>
|
|
/// <returns></returns>
|
|
public bool TryGetBuildingDataByIndex(int index, out LegionBuildingData buildingData)
|
|
{
|
|
return CurBattle.TryGetBuildingDataByIndex(index, out buildingData);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取地块阵营根据地块索引
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public BattlefieldActorCamp GetCellCampByIndex(int index)
|
|
{
|
|
return CurBattle.GetCellCampByIndex(index);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 判断位置是否安全区
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool IsSafeZone(int index)
|
|
{
|
|
return CurBattle.IsSafeZone(index);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取集结倒计时
|
|
/// </summary>
|
|
/// <param name="fightId"></param>
|
|
/// <returns></returns>
|
|
public float GetFightCDByID(uint fightId)
|
|
{
|
|
return CurBattle.GetFightCDByID(fightId);
|
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 获取阵营通过玩家id
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public BattlefieldActorCamp GetCampByActorId(uint actorId)
|
|
{
|
|
if (!TryGetActorData(actorId, out LegionActorData actorData))
|
|
return BattlefieldActorCamp.BacNone;
|
|
|
|
return actorData.Camp;
|
|
}
|
|
|
|
#region 回调
|
|
/// <summary>
|
|
/// 服务器回调进入军团战
|
|
/// </summary>
|
|
private void OnServerEnterLegionBattle()
|
|
{
|
|
WaitingForServer.Instance.EventDone(WaitingForServer.EventName.FightEnter);
|
|
|
|
EnterLegionBattle();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 服务器回调进入军团战完成
|
|
/// </summary>
|
|
private void OnServerEnterLegionBattleOK()
|
|
{
|
|
IsLegionBattleOK = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 服务器退出军团战
|
|
/// </summary>
|
|
private void OnServerExitLegionBattle()
|
|
{
|
|
WaitingForServer.Instance.EventDone(WaitingForServer.EventName.FightEnter);
|
|
|
|
ExitLegionBattle();
|
|
}
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 军团战测试Log
|
|
/// </summary>
|
|
public static void Debug(string content)
|
|
{
|
|
DebugUtil.Log($"(军团战)<color=#00FFFF>{content}</color>");
|
|
}
|
|
}
|
|
} |