413 lines
9.3 KiB
C#
413 lines
9.3 KiB
C#
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;
|
||
|
||
/// <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>
|
||
/// 章节索引
|
||
/// </summary>
|
||
private int chapterIndex = -1;
|
||
/// <summary>
|
||
/// 关卡索引
|
||
/// </summary>
|
||
private int levelIndex = -1;
|
||
/// <summary>
|
||
/// 解锁条件id
|
||
/// </summary>
|
||
private int unLockConditionId;
|
||
#endregion
|
||
|
||
#region config
|
||
/// <summary>
|
||
/// 配置数据
|
||
/// </summary>
|
||
public DataLevel Cfg { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 关卡名
|
||
/// </summary>
|
||
public string Name
|
||
{
|
||
get { return StringManager.Instance.GetLocalizeTextByKey(Cfg.Name); }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关卡描述
|
||
/// </summary>
|
||
public string Desc
|
||
{
|
||
get { return StringManager.Instance.GetLocalizeTextByKey(Cfg.Desc); }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 章节序号
|
||
/// </summary>
|
||
public int ChapterIndex
|
||
{
|
||
get
|
||
{
|
||
if (-1 == chapterIndex)
|
||
{
|
||
if (Cfg.Id < 100000)
|
||
{
|
||
DebugUtil.LogError("关卡id为{0}的关卡id没到6位", Cfg.Id);
|
||
return 0;
|
||
}
|
||
|
||
string resultStr = Cfg.Id.ToString().Substring(1, 2);
|
||
chapterIndex = int.Parse(resultStr);
|
||
}
|
||
|
||
return chapterIndex;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关卡序号
|
||
/// </summary>
|
||
public int LevelIndex
|
||
{
|
||
get
|
||
{
|
||
if (-1 == levelIndex)
|
||
{
|
||
if (Cfg.Id < 100000)
|
||
{
|
||
DebugUtil.LogError("关卡id为{0}的关卡id没到6位", Cfg.Id);
|
||
return 0;
|
||
}
|
||
|
||
string resultStr = Cfg.Id.ToString().Substring(3, 3);
|
||
levelIndex = int.Parse(resultStr);
|
||
}
|
||
|
||
return levelIndex;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 索引名
|
||
/// </summary>
|
||
public string IndexName
|
||
{
|
||
get { return $"{ChapterIndex}-{LevelIndex}"; }
|
||
}
|
||
#endregion
|
||
|
||
#region Data
|
||
/// <summary>
|
||
/// 所属关卡组信息
|
||
/// </summary>
|
||
public LevelGroupInfo GroupInfo
|
||
{
|
||
get
|
||
{
|
||
if (LevelManager.Instance.TryGetLevelGroupInfoByID(Cfg.LevelGroupID, out LevelGroupInfo levelGroupInfo))
|
||
return levelGroupInfo;
|
||
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 所属章节信息
|
||
/// </summary>
|
||
public ChapterInfo ChapterInfo
|
||
{
|
||
get { return GroupInfo?.ChapterInfo; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 环境类型
|
||
/// </summary>
|
||
public EnvironmentType Environment
|
||
{
|
||
get
|
||
{
|
||
if (null == MapData)
|
||
return EnvironmentType.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 ??= MapUtils.LoadMapData(Cfg.MapData); }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关卡数据
|
||
/// </summary>
|
||
public LevelData LevelData
|
||
{
|
||
get { return levelData ??= LevelUtils.LoadLevelData(Cfg.Id); }
|
||
}
|
||
|
||
/// <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)Environment).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;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <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();
|
||
}
|
||
}
|
||
|
||
/// <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;
|
||
IsLock = true;
|
||
RefreshServerData(true);
|
||
}
|
||
|
||
#region API
|
||
/// <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;
|
||
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)
|
||
{
|
||
Debug.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, Cfg.Id);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加注册解锁条件
|
||
/// </summary>
|
||
private void AddLockConditionReaction()
|
||
{
|
||
ConditionReactor.Instance.RemoveReaction(unLockConditionId);
|
||
unLockConditionId = ConditionReactor.Instance.AddReaction(Cfg.Unlock, 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
|
||
} |