using Framework; using Gameplay.Net; using System; using System.Collections.Generic; using Code.Scripts.Gameplay.Game; using Cysharp.Threading.Tasks; using Gameplay.Guide; using NLDPB; using UnityEngine; using Debug = DebugUtil; using cfg.LevelCfg; using Gameplay.Effect; namespace Gameplay.Level { public partial class LevelManager { //todo 修改服务器回消息底层逻辑后处理进入关卡失败的逻辑 const int NO_LEVEL_FLAG = -1; private int _levelIDTryToEnter = NO_LEVEL_FLAG; /// /// 剧情加载完成后是否立即播放 /// private bool isPlay; private object _levelParam; private Action _enterLevelFinishCallBack; private Action _exitLevelFinishCallBack; /// /// 退出关卡是否切换主场景回调 /// public Func ExitLevelChangeMainFunc; private int _bgmID; private List _resultTmp = null; public bool IsInLevel { get; private set; } public bool IsSuccess { get; private set; } public LevelInfo CurrLevel { get; set; } public bool IsSweep { get; set; } private UIPosterAndSkillInfoController _skillWindow; private void InitAction() { IsInLevel = false; CurrLevel = null; RegisterEventAction(); } private void ReleaseAction() { UnregisterEventAction(); _enterLevelFinishCallBack = null; _exitLevelFinishCallBack = null; _levelParam = null; } private void RegisterEventAction() { EventManager.Instance.Register(EventManager.EventName.ServerResponseEnterLevel, OnServerResponseEnterLevel); EventManager.Instance.Register(EventManager.EventName.ServerResponseExitLevel, OnServerResponseExitLevel); EventManager.Instance.Register(EventManager.EventName.Relogin_BackToGame, ResendMessage); } private void UnregisterEventAction() { EventManager.Instance.Unregister(EventManager.EventName.ServerResponseEnterLevel, OnServerResponseEnterLevel); EventManager.Instance.Unregister(EventManager.EventName.ServerResponseExitLevel, OnServerResponseExitLevel); EventManager.Instance.Unregister(EventManager.EventName.Relogin_BackToGame, ResendMessage); } //服务器回消息,进入关卡 private void OnServerResponseEnterLevel() { WaitingForServer.Instance.EventDone(WaitingForServer.EventName.FightEnter); if (_levelIDTryToEnter != NO_LEVEL_FLAG) { _EnterLevelDirectly(_levelIDTryToEnter); } else Debug.LogError($"levelID 不合法,无法进入关卡,levelID:{_levelIDTryToEnter}"); _levelIDTryToEnter = NO_LEVEL_FLAG; } private async void OnServerResponseExitLevel(ItemList itemList) { if (!IsInLevel) { Debug.LogError("当前未处于关卡中"); return; } if (CurrLevel.IsStory) { var filterItemList = CommonUtils.GetLevelRewardFilterItemList(itemList); var listItem = new ListItem(filterItemList); CommonUtils.FilterListItem(listItem); if (listItem.Length > 0) { _EnterStorySettle(listItem); } else { ExitLevelDirectly(_exitLevelFinishCallBack); _exitLevelFinishCallBack = null; } } else { StopBGM(); //TeamManager.IsHideAllUI = true; TeamManager.Instance.TeamUIClose(); if (IsSuccess) { // CommonUtils.CaptureScreenshot(); // UIManager.Instance.OpenWindow(UINameConst.UIMissionWin, itemList).Forget(); await ShowTransitionMgr.Instance.ShowLevelTransition(UI_LevelTransitionController.OpenType.Success); await SettleSceneProcess(itemList, false); } else { await ShowTransitionMgr.Instance.ShowLevelTransition(UI_LevelTransitionController.OpenType.Fail); if (!UIManager.Instance.IsWindowOpening(UINameConst.UIDefeatGame)) { UIDefeatGameController.Open().Forget(); } } } _resultTmp = null; SaveFightLevel(CurrLevel); } void ResendMessage() { //重连之后如果发现发送消息缓存没有被清空,说明没有收到消息的回复,需要重新发送 if (_resultTmp != null) { NetHelper.ExitLevel(IsSuccess, _resultTmp); DebugUtil.Log("Level ResendMessage"); } } private void _EnterLevelDirectly(int levelID) { if (!Instance.TryGetLevelInfoByID(levelID, out LevelInfo levelInfo)) { Debug.LogError($"关卡不存在,id:{levelID}"); return; } if (levelInfo.IsStory) GameStateManager.Instance.ChangeState(new GameStateStory(levelInfo.Cfg.StoryID.ToString(), isPlay)); else GameStateManager.Instance.ChangeState(new GameStateLevel(levelID)); CurrLevel = levelInfo; IsInLevel = true; _enterLevelFinishCallBack?.Invoke(); _enterLevelFinishCallBack = null; // if (!levelInfo.IsStory) // PlayBGM(); } public void _ExitLevelDirectly() { if (!CurrLevel.IsStory) TeamManager.Instance.Release(); var levelID = CurrLevel.Cfg.Id; var isPVP = false; if (CurrentLevel != null) { isPVP = CurrentLevel.IsPvPLevel; } if (null != ExitLevelChangeMainFunc && !ExitLevelChangeMainFunc.Invoke()) { CurrLevel = null; IsInLevel = false; EventManager.Instance.Send(EventManager.EventName.GuideExitLevel); } else { if (isPVP) { SignUpManager.Instance.DoNotShowDailyAccumulate = true; GameStateManager.Instance.ChangeState(new GameStateMainScene(false, false, async () => { CurrLevel = null; IsInLevel = false; await JumpToManager.JumpFuncAsync(cfg.JumpFuncType.PVP_Main); })); } else { SignUpManager.Instance.DoNotShowDailyAccumulate = true; GameStateManager.Instance.ChangeState(new GameStateMainScene(false, false, async () => { CurrLevel = null; IsInLevel = false; await JumpToManager.JumpFuncAsync(cfg.JumpFuncType.Level_Select, levelID); })); } } ExitLevelChangeMainFunc = null; _exitLevelFinishCallBack?.Invoke(); _exitLevelFinishCallBack = null; _cacheSettleData = null; } public void ExitLevelOnLogout() { if (!IsInLevel) { return; } if (!CurrLevel.IsStory) TeamManager.Instance.Release(); var levelID = CurrLevel.Cfg.Id; var isPVP = false; if (CurrentLevel != null) { isPVP = CurrentLevel.IsPvPLevel; } if (null != ExitLevelChangeMainFunc && !ExitLevelChangeMainFunc.Invoke()) { CurrLevel = null; IsInLevel = false; EventManager.Instance.Send(EventManager.EventName.GuideExitLevel); } else { CurrLevel = null; IsInLevel = false; } ExitLevelChangeMainFunc = null; _exitLevelFinishCallBack?.Invoke(); _exitLevelFinishCallBack = null; _cacheSettleData = null; } private async void _EnterStorySettle(ListItem listItem) { CommonUtils.CaptureScreenshot(); await ShowTransitionMgr.Instance.EnterBlackTransition(true); await ShowTransitionMgr.Instance.EnterBlack(); await UniTask.Delay(150); await UI_GetItemWindowController.Open(listItem, UI_GetItemWindowController.EShowType.StorySettle, cb: () => { ExitFromLevel();//自己传入关闭奖励领取界面的后续操作 }); await UniTask.Delay(250); await ShowTransitionMgr.Instance.ExitBlack(); ShowTransitionMgr.Instance.ExitTransition(); } async void ExitFromLevel() { LevelManager.Instance.ExitLevelDirectly(); await GameSceneHelper.Instance.UnLoadSceneForRt(); AudioManager.Instance.StopAll(); EffectManager.instance.rootObj.SetActive(true); UIManager.Instance.CloseWindow(UINameConst.UIMissionWin); } #region API /// /// 向服务器发送消息准备进入关卡 /// /// /// /// /// 剧情加载完成后是否立即播放 public void TryEnterLevel(int id, Action finishCallback = null, object param = null, bool isPlay = true) { WaitingForServer.Instance.EventWaiting(WaitingForServer.EventName.FightEnter, false); IsSweep = false; if (IsInLevel) { Debug.LogError($"进入关卡失败!当前正处于关卡中!当前关卡ID:{CurrLevel.Cfg.Id}"); return; } if(!TryGetLevelInfoByID(id, out LevelInfo levelInfo)) { Debug.LogError($"关卡不存在,id:{id}"); return; } if (!levelInfo.CanEnter) { Debug.LogError($"关卡无法进入,id:{id}"); return; } //清掉上次的奖励 Actor.Instance.RewardItems.Clear(); var team = TeamEditManager.Instance.GetSelectTeam(); _cacheSettleData = new LevelSettleData(id, team); var temIdx = TeamEditManager.Instance.SelectTeamIdx; NetHelper.EnterLevel((uint)id, (uint)temIdx); if (LevelManager.Instance.TryGetLevelInfoByID(id,out LevelInfo curLevelInfo)) { BIManager.Instance.TrackEvent("level_event", new Dictionary//关卡事件开始 { {"level_id", curLevelInfo.Cfg.Id}, {"level_type" ,(int)curLevelInfo.ChapterInfo.Cfg.Type}, {"difficulty", (int)curLevelInfo.GroupInfo.Cfg.LevelDifficulty}, {"event", 0}, {"auto", 0} }); } _enterLevelFinishCallBack = finishCallback; _levelParam = param; _levelIDTryToEnter = id; this.isPlay = isPlay; } //向服务器发送消息退出关卡 public void TryExitLevel(bool isSuccess, Action finishCallback = null, bool isGiveup = false) { if (!IsInLevel) { Debug.LogError("当前未处于关卡中"); return; } List starResult = new() { 0, 0, 0 }; if (E_ChapterType.War == CurrLevel.ChapterInfo.Cfg.Type) { if (CurrentLevel != null && CurrentLevel.StarResult != null) { starResult[0] = (uint)CurrentLevel.Score; // 第一位记录分数 for (int i = 0; i < CurrentLevel.StarResult.Count; ++i) { uint result = CurrentLevel.StarResult[i]; if (result > 0) starResult[1] += 1u << i; // 按位存是否完成目标 } } } else { if (CurrentLevel != null && CurrentLevel.StarResult != null) { for (int i = 0; i < CurrentLevel.StarResult.Count; ++i) { uint result = CurrentLevel.StarResult[i]; if (result > 0 && result <= starResult.Count) { starResult[(int)result - 1] = 1; } } } } IsSuccess = isSuccess; //由于pvp关卡结算不走这边流程所以这里不需要判断 if (CurrLevel != null) { var curLevelInfo = CurrLevel; BIManager.Instance.TrackEvent("level_event", new Dictionary//关卡通关成功打点 { {"level_id", curLevelInfo.Cfg.Id}, {"level_type" ,(int)curLevelInfo.ChapterInfo.Cfg.Type}, {"difficulty", (int)curLevelInfo.GroupInfo.Cfg.LevelDifficulty}, {"event", isSuccess? 1 : isGiveup ? 3 : 2 },//0:开始/1: 成功 / 2 :失败 / 3: 中途退出 {"auto", 0} }); } _resultTmp = starResult; NetHelper.ExitLevel(isSuccess, starResult); _exitLevelFinishCallBack = finishCallback; } //直接进入关卡,不通过服务器 public void EnterLevelDirectly(int levelID, Action enterLevelFinishCallBack = null, object param = null) { _enterLevelFinishCallBack = enterLevelFinishCallBack; _levelParam = param; _EnterLevelDirectly(levelID); if (!TryGetLevelInfoByID(levelID, out LevelInfo levelInfo)) return; if (!levelInfo.IsStory && GuideManager.Instance.IsGuiding) PlayBGM(); } //直接退出关卡,不走服务器 public void ExitLevelDirectly(Action exitLevelFinishCallBack = null) { if (IsSweep) return; _exitLevelFinishCallBack = exitLevelFinishCallBack; _ExitLevelDirectly(); } public void PlayBGM() { //_bgmID = await AudioManager.Instance.PlayAudio("NLD_BGM_01"); AudioManager.Instance.StopAll(); _bgmID = AudioManager.Instance.PlayAudio("bgm_1", AudioCriManager.EPlayType.Music, null, true); } public void StopBGM() { AudioManager.Instance.AudioMgrObj.StopMusicById(_bgmID); } public async UniTask OnPVPSettle() { if (CurrentLevel.IsPvPLevel) { // ShowTransitionMgr.Instance.ExitTransition(); // await ShowTransitionMgr.Instance.EnterBlack(); // await UniTask.Delay(250); // await UI_PVPSettlementController.Open(PVPManager.Instance.IsWin); // await ShowTransitionMgr.Instance.ExitBlack(); // ShowTransitionMgr.Instance.ExitTruansition(); // if (PVPManager.Instance.RewardItemList == null || PVPManager.Instance.RewardItemList.Lists.Length <= 0) // { // PVPManager.Instance.RewardItemList = Actor.Instance.RewardItems; // } TeamManager.Instance.TeamUIClose(); await SettlePvPSceneProcess(PVPManager.Instance.RewardItemList, PVPManager.Instance.IsWin); } } public async void SkillInfoOpen(uint selectID, UIPosterAndSkillInfoController.OpenType type = UIPosterAndSkillInfoController.OpenType.Normal) { if (_skillWindow == null) { if (type == UIPosterAndSkillInfoController.OpenType.Normal) { if (selectID > 0) { _skillWindow = await UIPosterAndSkillInfoController.Open(selectID) as UIPosterAndSkillInfoController; } else { _skillWindow = await UIPosterAndSkillInfoController.Open() as UIPosterAndSkillInfoController; } } else { _skillWindow = await UIPosterAndSkillInfoController.Open(selectID, type) as UIPosterAndSkillInfoController; } return; } if (type == UIPosterAndSkillInfoController.OpenType.Normal) { if (selectID > 0) { _skillWindow.ShowWindow(new UIPosterAndSkillInfoController.OpenData() { OpenType = type, Uid = selectID }); } else { _skillWindow.ShowWindow(); } } else { _skillWindow.ShowWindow(new UIPosterAndSkillInfoController.OpenData() { OpenType = type, Uid = selectID }); } } public void SkillInfoClose(bool isRelease = false) { if(isRelease) { if (_skillWindow != null) { _skillWindow.CloseWindow(); } _skillWindow = null; return; } if (_skillWindow != null) { _skillWindow.HideWindow(); } } #endregion API } }