NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Level/LevelInfo.cs

499 lines
12 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 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 System;
using cfg.FightCfg;
using cfg.LevelCfg;
using Gameplay.Fight.FightStory;
using Gameplay.Fight.FightStory.Data;
/// <summary>
/// 关卡信息
/// </summary>
public class LevelInfo : IRedPointTreeNode
{
#region 私有字段
/// <summary>
/// 关卡数据
/// </summary>
private LevelData levelData;
/// <summary>
/// 地图数据
/// </summary>
private MapData mapData;
/// <summary>
/// 服务器关卡数据
/// </summary>
private Gameplay.Net.LevelInfo serverData;
/// <summary>
/// 解锁条件id
/// </summary>
private int unLockConditionId;
#endregion
#region 公有字段
/// <summary>
/// 战斗内剧情数据,如果没有则为空
/// </summary>
public FightStoryData fightStoryData { get; private set; }
#endregion
#region config
/// <summary>
/// 配置数据
/// </summary>
public DataLevel Cfg { get; private set; }
/// <summary>
/// 关卡名
/// </summary>
public string Name
{
get { return CommonUtils.GetLocalizeText(E_LocalizePrefix.LevelName, Cfg.Id); }
}
/// <summary>
/// 关卡描述
/// </summary>
public string Desc
{
get { return CommonUtils.GetLocalizeText(E_LocalizePrefix.LevelDesc, Cfg.Id); }
}
/// <summary>
/// 关卡序号
/// </summary>
public string Number
{
get { return CommonUtils.GetLocalizeText(E_LocalizePrefix.LevelNumber, Cfg.Id); }
}
/// <summary>
/// 章节序号
/// </summary>
public string ChapterNumber
{
get
{
if (null == ChapterInfo)
return string.Empty;
return ChapterInfo.Number;
}
}
/// <summary>
/// 完整序号
/// </summary>
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
/// <summary>
/// 所属关卡组信息
/// </summary>
public LevelGroupInfo GroupInfo
{
get
{
if (0 == Cfg.LevelGroupID)
return null;
LevelManager.Instance.TryGetLevelGroupInfoByID(Cfg.LevelGroupID, out LevelGroupInfo levelGroupInfo);
return levelGroupInfo;
}
}
/// <summary>
/// 所属章节信息
/// </summary>
public ChapterInfo ChapterInfo
{
get { return GroupInfo?.ChapterInfo; }
}
/// <summary>
/// 环境类型
/// </summary>
public ELevelTerrainType eLevelTerrain
{
get
{
if (null == MapData)
return ELevelTerrainType.Desert;
return MapData.environmentType;
}
}
/// <summary>
/// 是否锁住
/// </summary>
public bool IsLock { get; private set; } = true;
/// <summary>
/// 能否进入
/// </summary>
public bool CanEnter
{
get { return !IsLock && IsConstEnough(); }
}
/// <summary>
/// 地图数据
/// </summary>
public MapData MapData
{
get { return mapData; }
}
/// <summary>
/// 关卡数据
/// </summary>
public LevelData LevelData
{
get { return levelData; }
}
/// <summary>
/// 是否剧情
/// </summary>
public bool IsStory
{
get { return !string.IsNullOrWhiteSpace(Cfg.StoryID); }
}
/// <summary>
/// 环境buff描述
/// </summary>
public string EnvironmentBuffString
{
get
{
return CommonUtils.GetLocalizeText(TableManager.Instance.Tables.EnviormentConfig.Get((int)eLevelTerrain).DescLocal);
}
}
#endregion
#region 服务器数据
/// <summary>
/// 完成的星级或分数
/// </summary>
public int Score
{
get
{
if (null == serverData)
return 0;
return ChapterInfo.Cfg.Type switch
{
E_ChapterType.War => serverData.Score,
_ => serverData.StarCount,
};
}
}
/// <summary>
/// 最大星级或者分数
/// </summary>
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;
}
/// <summary>
/// 关卡评级
/// </summary>
public E_WarRating WarRating
{
get { return LevelUtils.GetWarLevelRatingByLevelInfo(this); }
}
/// <summary>
/// 星级达成结果
/// </summary>
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;
}
}
/// <summary>
/// 获取服务器存储的战役分
/// </summary>
public uint WarScoreBySever
{
get
{
if (null == serverData)
return 0;
return serverData.star[1];
}
}
/// <summary>
/// 是否通关
/// </summary>
public bool IsPass
{
get
{
if (null == serverData)
return false;
return serverData.isPassed;
}
}
/// <summary>
/// 红点
/// </summary>
public RedPointNode RedPoint { get; private set; }
#endregion
public LevelInfo(DataLevel config)
{
Cfg = config;
RefreshServerData(true);
}
public async void Load()
{
if (E_LevelType.Storyline != Cfg.LevelType)
{
mapData = await MapUtils.LoadMapData(Cfg.MapData);
levelData = await LevelUtils.LoadLevelData(Cfg.Id);
if (null == mapData)
DebugUtil.LogError("Map data is null, level id = {0}", Cfg?.Id);
if (null == levelData)
DebugUtil.LogError("Level data is null, level id = {0}", Cfg?.Id);
}
fightStoryData = await FightStoryUtils.LoadFightStoryData(Cfg.FightStoryNameId);
}
#region API
/// <summary>
/// 获取解锁条件文本
/// </summary>
/// <returns></returns>
public string GetUnlockLocalizationText()
{
string res = string.Empty;
string[] unlocks = Cfg.Unlocks.Split('|');
foreach (string condition in unlocks)
{
if (null != res && string.Empty != res)
res += "";
res += ConditionManager.Instance.GetConditionLocalization(condition);
}
return res;
}
/// <summary>
/// 获得星级目标的文本
/// </summary>
/// <param name="targetIndex"></param>
/// <returns></returns>
public string GetStarTargetLocalizationText(int targetIndex)
{
List<ConditionModifier> starTarget = LevelData.starTarget;
if (targetIndex < 0 || targetIndex >= starTarget.Count)
return null;
return starTarget[targetIndex].GetConditionLocalization();
}
/// <summary>
/// 刷新服务器数据
/// </summary>
/// <param name="isReset"></param>
public void RefreshServerData(bool isReset)
{
serverData = Actor.Instance.Level.GetLevelInfo((uint)Cfg.Id);
if (isReset)
IsLock = true;
if (IsLock)
AddLockConditionReaction();
}
#endregion
#region 私有方法
/// <summary>
/// 体力是否足够
/// </summary>
/// <returns></returns>
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)
{
DebugUtil.LogError($"关卡消耗品不足level id:{Cfg.Id}");
break;
}
}
return result;
}
/// <summary>
/// 构造红点树
/// </summary>
/// <param name="parent"></param>
public void ConstructRedPointTree(RedPointNode parent)
{
RedPoint = RedPointManager.Instance.AddDynamicNode(NodeType.Level, parent,
new ValueTuple<E_LevelRedType, int>(E_LevelRedType.Level, Cfg.Id));
}
/// <summary>
/// 添加注册解锁条件
/// </summary>
private void AddLockConditionReaction()
{
ConditionReactor.Instance.RemoveReaction(unLockConditionId);
unLockConditionId = ConditionReactor.Instance.AddReaction(Cfg.Unlocks, OnUnlockConditionChanged);
}
/// <summary>
/// 解锁回调
/// </summary>
/// <param name="result"></param>
/// <param name="callBackParam"></param>
/// <param name="reactionID"></param>
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
}
/// <summary>
/// 战役评级
/// </summary>
public enum E_WarRating
{
C = 0,
B = 1,
A = 2,
S = 3
}
public static class WarRating
{
public static Dictionary<E_WarRating, string> WarRatingPath = new Dictionary<E_WarRating, string>()
{
[E_WarRating.C] = "Assets/Art_Out/UI/Texture/LevelSelectNew/War/UI_C.png",
[E_WarRating.B] = "Assets/Art_Out/UI/Texture/LevelSelectNew/War/UI_B.png",
[E_WarRating.A] = "Assets/Art_Out/UI/Texture/LevelSelectNew/War/UI_A.png",
[E_WarRating.S] = "Assets/Art_Out/UI/Texture/LevelSelectNew/War/UI_S.png",
};
}