using System.Collections.Generic; using System; using UnityEngine; /** * endless_port 无尽模式关卡配置表数据处理类 * @Author: chenxin * @Date: 2020-10-10 17:11:23 */ namespace KTGMGemClient { public class EndlessPortConfig { /// /// 配置表数据 /// public endless_port Config; /// /// 预先随机好的敌人数据,spawnAgent时直接取这个数据,不再动态随机, /// id > 0:获取指定id的小怪, /// id = -1:从类型为1(小怪)随机, /// id = -2:从类型为2(精英怪)随机 /// id = -3:从所有小怪中随机 /// 当前 id = -1, id = -2, id = -3时,EnemyDataList列表的数量就是敌人数量, id > 0 时因为是指定id所以敌人是重复的,EnemyDataList长度为1 /// public List EnemyDataList; /// /// 掉落概率总权重,即:表中掉落概率那一项全部加起来 /// public float DropTotalWeight; /// /// 关卡等级 /// public int PortLevel; } public class EndlessPortData { /// /// 无尽模式关卡配置表 /// private static List endlessPortList; private static List portConfigList; /// /// 关卡配置字典 /// private static Dictionary> portDic; /// /// 关卡每波次敌人总血量字典 /// private static Dictionary> portEnemiesTotalHPDic; private static System.Random random; /// /// 最大关卡 /// /// private static int maxLevel { get; set; } /// /// 新手总关卡数 /// /// public static int NewbieTotalLevel { get; private set; } public static int MaxLevel { get { return maxLevel; } } /// /// 数据初始化 /// public static void Init() { random = new System.Random(); endlessPortList = JsonDataCenter.GetList(); portConfigList = new List(); portDic = new Dictionary>(); InitPortList(); InitPortEnemiesTotalHP(); } /// /// 初始化关卡数据 /// public static void InitPortList() { maxLevel = 0; int? preLevel = null; portConfigList.Clear(); portDic.Clear(); foreach (endless_port data in endlessPortList) { if (!GameConfig.IsNewbie && data.level < 0) continue; if (preLevel == null || preLevel != data.level) { preLevel = data.level; ++maxLevel; if (data.level < 0) ++NewbieTotalLevel; } EndlessPortConfig param = new EndlessPortConfig(); param.Config = data; param.EnemyDataList = new List(); if (param.Config.id > 0) param.EnemyDataList.Add(EndlessEnemyData.GetDataById(data.enemy_id)); else { for (int i = 0; i < data.amount; ++i) { param.EnemyDataList.Add(EndlessEnemyData.GetDataById(data.enemy_id)); } } param.PortLevel = maxLevel; int totalWeight = 0; for (int i = 0; i < data.drop_rate.Count; ++i) { totalWeight += data.drop_rate[i]; } param.DropTotalWeight = (float)data.drop_rate[0] / (float)totalWeight; portConfigList.Add(param); if (!portDic.ContainsKey(param.PortLevel)) portDic.Add(param.PortLevel, new List()); portDic[param.PortLevel].Add(param); } } /// /// 初始化关卡每波次敌人总血量 /// private static void InitPortEnemiesTotalHP() { portEnemiesTotalHPDic = new Dictionary>(); for (int i = 1; i <= MaxLevel; ++i) { List> levelData = GetLevelWaveData(i); if (levelData.Count == 0) continue; portEnemiesTotalHPDic.Add(i, new List()); // levelData.Count 就是 i关卡的总波次数 for (int j = 0; j < levelData.Count; ++j) { float total = 0; // levelData[j].Count 是这一波的所有可出怪的赛道数量 for (int k = 0; k < levelData[j].Count; ++k) { // > 0,生成的敌人是重复的,直接 × 数量就行 if (levelData[j][k].Config.enemy_id > 0) { float add = levelData[j][k].Config.amount * levelData[j][k].Config.b_hp * levelData[j][k].EnemyDataList[0].hp_rate; // 木属性小怪一次性生成两个 if (levelData[j][k].EnemyDataList[0].resource == 103) total += 2 * add; else total += add; } else { for (int n = 0; n < levelData[j][k].EnemyDataList.Count; ++n) { float add = levelData[j][k].Config.b_hp * levelData[j][k].EnemyDataList[n].hp_rate; if (levelData[j][k].EnemyDataList[n].resource == 103) total += 2 * add; else total += add; } } } portEnemiesTotalHPDic[i].Add(total); } } } /// /// 根据关卡,波次获得该波次敌人总血量 /// /// /// public static float GetWaveEnemiesTotalHP(int level, int wave) { return portEnemiesTotalHPDic[level][wave]; } /// /// 根据关卡等级获取关卡的所有波数据,如果本波次敌人数量为0,直接忽略掉 /// /// 关卡等级 /// public static List> GetLevelWaveData(int level) { List> ret = new List>(); List allLevelData = portDic[level]; int wave = 0; foreach (EndlessPortConfig data in allLevelData) { if (data.Config.amount == 0) continue; if (data.Config.wave != wave) { ret.Add(new List()); wave = data.Config.wave; } ret[data.Config.wave - 1].Add(data); } for (int i = 0; i < ret.Count; ++i) { if (ret[i].Count == 0) { ret.Remove(ret[i]); --i; } } return ret; } /// /// 根据关卡等级和波次获得该波次的掉落概率 /// /// /// /// public static float GetDropRate(int level, int wave) { List> list = GetLevelWaveData(level); if (list.Count == 0) return 0; Debug.Log($"level:{level} wave:{wave}"); List waveData = list[wave]; EndlessPortConfig tmpConfig = waveData[0]; if (tmpConfig != null) { return tmpConfig.DropTotalWeight; } return 0; } /// /// 根据关卡等级和波次获得该波次的掉落BOX /// /// /// /// public static reward GetDropReward(int level, int wave) { List> list = GetLevelWaveData(level); if (list.Count == 0) return null; List waveData = list[wave]; EndlessPortConfig tmpConfig = waveData[0]; if (tmpConfig != null) { return tmpConfig.Config.drop; } return null; } /// /// 根据关卡等级和波次获得该波次的所有敌人数量 /// /// /// /// public static int GetWaveEnemiesCount(int level, int wave) { List> list = GetLevelWaveData(level); if (list.Count == 0) return 0; List waveData = list[wave]; int ret = 0; for (int i = 0; i < waveData.Count; ++i) { int count = waveData[i].Config.amount; endless_enemy enemyData = EndlessEnemyData.GetDataById(waveData[i].Config.enemy_id); // WTF... if (enemyData.resource == 103) count *= 2; ret += count; } return ret; } /// /// 根据关卡等级和波次获得该波次敌人的血量 /// /// /// /// 赛道 public static float GetWaveEnemiesHP(int level, int wave, int tunel) { List> list = GetLevelWaveData(level); List waveData = list[wave]; float hp = 0; for (int i = 0; i < waveData.Count; ++i) { if (waveData[i].Config.tunel == tunel) { hp = waveData[i].Config.b_hp; break; } } return hp; } /// /// 根据关卡等级、波次、赛道获得击杀敌人掉落的奖励列表 /// /// 关卡等级 /// 波次 /// 第几条赛道 /// public static List GetDropRewardList(int level, int wave, int tunel) { List ret = new List(); List> levelData = GetLevelWaveData(level); if (levelData.Count == 0) throw new Exception($"当前关卡:{level}, 没有关卡数据"); List waveData = levelData[wave - 1]; if (waveData.Count == 0) throw new Exception($"当前关卡:{level},当前波次:{wave},没有波次数据"); for (int i = 0; i < waveData.Count; ++i) { if (waveData[i].Config.tunel != tunel) continue; // for (int j = 0; j < waveData[i].Config.drop.Count; ++j) // { // // 概率为0 // if (waveData[i].Config.drop_rate[j] == 0) continue; // float val = UnityEngine.Random.Range(0, waveData[i].DropTotalWeight); // if (val <= waveData[i].Config.drop_rate[j]) // // 命中 // ret.Add(waveData[i].Config.drop[j]); // } } return ret; } /// /// 根据关卡获得关卡奖励分数 /// /// public static int GetLevelScore(int level) { List> list = GetLevelWaveData(level); if (list.Count == 0) return 0; return list[0][0].Config.bonus; } } }