using Gameplay; using Gameplay.Level; using Gameplay.Net; using System.Collections.Generic; using System.Linq; using cfg.RedPoint; using Cysharp.Threading.Tasks; using Framework; using Framework.Condition; using Debug = DebugUtil; using System; using cfg.LevelCfg; using static MapData; /// /// 关卡信息 /// public class LevelInfo : IRedPointTreeNode { #region 私有字段 /// /// 关卡数据 /// private LevelData levelData; /// /// 地图数据 /// private MapData mapData; /// /// 服务器关卡数据 /// private Gameplay.Net.LevelInfo serverData; /// /// 解锁条件id /// private int unLockConditionId; #endregion #region config /// /// 配置数据 /// public DataLevel Cfg { get; private set; } /// /// 关卡名 /// public string Name { get { return CommonUtils.GetLocalizeText(E_LocalizePrefix.LevelName, Cfg.Id); } } /// /// 关卡描述 /// public string Desc { get { return CommonUtils.GetLocalizeText(E_LocalizePrefix.LevelDesc, Cfg.Id); } } /// /// 关卡序号 /// public string Number { get { return CommonUtils.GetLocalizeText(E_LocalizePrefix.LevelNumber, Cfg.Id); } } /// /// 章节序号 /// public string ChapterNumber { get { if (null == ChapterInfo) return string.Empty; return ChapterInfo.Number; } } /// /// 完整序号 /// public string FullNumebr { get { string chapterNumber = ChapterNumber; string levelNumber = Number; if (string.Empty == chapterNumber) { if (string.Empty == levelNumber) return string.Empty; return $"0-{levelNumber}"; } if (string.Empty == levelNumber) return $"{chapterNumber}-0"; return $"{chapterNumber}-{levelNumber}"; } } #endregion #region Data /// /// 所属关卡组信息 /// public LevelGroupInfo GroupInfo { get { if (0 == Cfg.LevelGroupID) return null; LevelManager.Instance.TryGetLevelGroupInfoByID(Cfg.LevelGroupID, out LevelGroupInfo levelGroupInfo); return levelGroupInfo; } } /// /// 所属章节信息 /// public ChapterInfo ChapterInfo { get { return GroupInfo?.ChapterInfo; } } /// /// 环境类型 /// public EnvironmentType Environment { get { if (null == MapData) return EnvironmentType.Desert; return MapData.environmentType; } } /// /// 是否锁住 /// public bool IsLock { get; private set; } = true; /// /// 能否进入 /// public bool CanEnter { get { return !IsLock && IsConstEnough(); } } /// /// 地图数据 /// public MapData MapData { get { return mapData ??= MapUtils.LoadMapData(Cfg.MapData); } } /// /// 关卡数据 /// public LevelData LevelData { get { return levelData ??= LevelUtils.LoadLevelData(Cfg.Id); } } /// /// 是否剧情 /// public bool IsStory { get { return !string.IsNullOrWhiteSpace(Cfg.StoryID); } } /// /// 环境buff描述 /// public string EnvironmentBuffString { get { return CommonUtils.GetLocalizeText(TableManager.Instance.Tables.EnviormentConfig.Get((int)Environment).DescLocal); } } #endregion #region 服务器数据 /// /// 完成的星级或分数 /// public int Score { get { if (null == serverData) return 0; return ChapterInfo.Cfg.Type switch { E_ChapterType.War => serverData.Score, _ => serverData.StarCount, }; } } /// /// 最大星级或者分数 /// public int ScoreMax { get { switch (ChapterInfo.Cfg.Type) { case E_ChapterType.War: { int total = 0; if (null == LevelData) return total; foreach (ConditionModifier conditionModifier in LevelData.scoreTarget) { total += conditionModifier.score; } return total; } default: return (int)NLDPB.GlobalDefine.MaxLevelStar; } } } public int GetScoreTarget(int index) { if (index >= LevelData.scoreTarget.Count) { DebugUtil.LogError($"获取战役评价索引超出限制,index:{index}"); return 0; } var condition = LevelData.scoreTarget[index]; return condition.score; } /// /// 关卡评级 /// public E_WarRating WarRating { get { return LevelUtils.GetWarLevelRatingByLevelInfo(this); } } /// /// 星级达成结果 /// public bool[] StarResult { get { if (null == serverData) return new bool[(int)NLDPB.GlobalDefine.MaxLevelStar]; return serverData.star.Select(s => s > 0).ToArray(); } } public bool[] ScoreResult { get { bool[] results = new bool[15]; if (null == serverData) return results; uint value = serverData.star[1]; for (int i = 0; i < results.Length; ++i) { results[i] = ((value >> i) & 1u) == 1u; } return results; } } /// /// 是否通关 /// public bool IsPass { get { if (null == serverData) return false; return serverData.isPassed; } } /// /// 红点 /// public RedPointNode RedPoint { get; private set; } #endregion public LevelInfo(DataLevel config) { Cfg = config; IsLock = true; RefreshServerData(true); } #region API /// /// 获取解锁条件文本 /// /// public string GetUnlockLocalizationText() { if (Cfg.Unlock.Length > 0) return ConditionManager.Instance.GetConditionLocalization(Cfg.Unlock[0]); else return null; } /// /// 获得星级目标的文本 /// /// /// public string GetStarTargetLocalizationText(int targetIndex) { List starTarget = LevelData.starTarget; if (targetIndex < 0 || targetIndex >= starTarget.Count) return null; return starTarget[targetIndex].GetConditionLocalization(); } /// /// 刷新服务器数据 /// /// public void RefreshServerData(bool isReset) { serverData = Actor.Instance.Level.GetLevelInfo((uint)Cfg.Id); if (isReset) { IsLock = true; AddLockConditionReaction(); } } #endregion #region 私有方法 /// /// 体力是否足够 /// /// private bool IsConstEnough() { if (null == Cfg.CostItems || Cfg.CostItems.Count <= 0) return true; bool result = true; foreach (cfg.item.ItemCounts costItem in Cfg.CostItems) { int currCount = (int)Actor.Instance.Item.GetItemCount(costItem.Id); result &= currCount >= costItem.Count; if (!result) { Debug.LogError($"关卡消耗品不足,level id:{Cfg.Id}"); break; } } return result; } /// /// 构造红点树 /// /// public void ConstructRedPointTree(RedPointNode parent) { RedPoint = RedPointManager.Instance.AddDynamicNode(NodeType.Level, parent, Cfg.Id); } /// /// 添加注册解锁条件 /// private void AddLockConditionReaction() { ConditionReactor.Instance.RemoveReaction(unLockConditionId); unLockConditionId = ConditionReactor.Instance.AddReaction(Cfg.Unlock, OnUnlockConditionChanged); } /// /// 解锁回调 /// /// /// /// private void OnUnlockConditionChanged(bool result, object callBackParam, int reactionID) { if (result) { IsLock = false; DebugUtil.Log($"关卡未解锁,id:{Cfg.Id}"); EventManager.Instance.Send(EventManager.EventName.LevelUnlock, Cfg.Id); ConditionReactor.Instance.RemoveReaction(reactionID); } } public void ConstructRedPointTree(int parentID) { throw new NotImplementedException(); } #endregion } /// /// 战役评级 /// public enum E_WarRating { C = 0, B = 1, A = 2, S = 3 } public static class WarRating { public static Dictionary WarRatingPath = new Dictionary() { [E_WarRating.C] = "Assets/Art/UI/Texture/LevelSelectNew/War/UI_C.png", [E_WarRating.B] = "Assets/Art/UI/Texture/LevelSelectNew/War/UI_B.png", [E_WarRating.A] = "Assets/Art/UI/Texture/LevelSelectNew/War/UI_A.png", [E_WarRating.S] = "Assets/Art/UI/Texture/LevelSelectNew/War/UI_S.png", }; }