using System.Collections.Generic; using System.Linq; // ============================================================ // 文件:BossConfig.cs // 职责:Boss 各种死亡爆奖配置(幸运轮盘/小丑扑克/幸运飞碟/破坏球/烈焰风暴/星际巡航/神龙转盘 等) // - 服务端下发配置,客户端解析后用 GetResponse() 取随机结果 // - 已将服务端依赖(GlobalRandom/RandomBossOption/BsonIgnoreExtraElements) // 替换为 Unity 客户端兼容实现 // ============================================================ namespace Assets.MyGame.Scripts.Net.APIResponses.GameConfig_SubClass { /// /// Boss设定配置信息 /// public class BossConfig { /// 幸运轮盘配置信息 public List LuckWheel { get; set; } = new List(); /// 小丑扑克 public LuckPokerConfig LuckPoker { get; set; } = new LuckPokerConfig(); /// 幸运飞碟 public List LuckFlyDisk { get; set; } = new List(); /// 全屏秒怪 public BaseBossConfig FullScreen { get; set; } = new BaseBossConfig(); /// 范围秒怪 public BaseBossConfig Range { get; set; } = new BaseBossConfig(); /// 弹药箱配置 public AmmunitionBoxConfig AmmunitionBox { get; set; } = new AmmunitionBoxConfig(); /// 星际巡航配置 public InterstellarCruiseConfig InterstellarCruise { get; set; } = new InterstellarCruiseConfig(); /// 烈焰风暴-死亡配置 public BossFlameStormConfig FlameStorm { get; set; } = new BossFlameStormConfig(); /// 破坏球-死亡配置 public BossBombConfig Bomb { get; set; } = new BossBombConfig(); /// 概率击杀 public List Probability { get; set; } = new List(); /// 神龙转盘 public List LuckDragon { get; set; } = new List(); /// /// 根据权重随机获取一个 Boss 选项 /// public static int GetBossProbabilityConfigResponse(List configParams) { if (configParams == null || configParams.Count == 0) return 0; int totalWeight = configParams.Sum(p => p.TriggerRate); if (totalWeight <= 0) return 0; int randomValue = GlobalRandom.Next(0, totalWeight); int currentWeightSum = 0; foreach (var param in configParams) { currentWeightSum += param.TriggerRate; if (randomValue < currentWeightSum) { return GlobalRandom.NextInclusive(param.Min, param.Max); } } return 0; } /// /// 根据权重随机获取一个死亡次数配置 /// public static CruiseConfigCount GetRandomCountConfigOption(List options) { if (options == null || !options.Any()) return null; long totalWeight = options.Sum(o => (long)o.TriggerRate); if (totalWeight <= 0) return null; long randomValue = GlobalRandom.NextInt64(0, totalWeight); long currentWeightSum = 0; foreach (var option in options) { currentWeightSum += option.TriggerRate; if (randomValue < currentWeightSum) { return option; } } return options.FirstOrDefault(o => o.TriggerRate > 0); } /// 死亡次数配置参数 public class CruiseConfigCount { /// 死亡次数 public int Count { get; set; } /// 触发权重 public int TriggerRate { get; set; } = 0; /// 击杀权重 public int KillRate { get; set; } = 0; } /// 神龙转盘 public class LuckDragonConfig : BaseBossConfig { /// 外圈配置 下一个配置为-1 public List OuterConfig { get; set; } = new List(); /// 中圈配置 下一个配置为-1 public List MiddleConfig { get; set; } = new List(); /// 内圈配置 下一个配置为-1 public List InnerConfig { get; set; } = new List(); /// 获取结果 public (List option, int beizhu) GetResponse() { int beishu = 1; var result = new List(); int outerResult = GetBossProbabilityConfigResponse(OuterConfig); result.Add(outerResult); if (outerResult == -1) { int middleResult = GetBossProbabilityConfigResponse(MiddleConfig); result.Add(middleResult); if (outerResult == -1) { int innerResult = GetBossProbabilityConfigResponse(InnerConfig); result.Add(innerResult); beishu = innerResult; } else { beishu = middleResult; } } else { beishu = outerResult; } UnityEngine.Debug.Log($"[BossConfig] LuckDragon.GetResponse 选项=[{string.Join(",", result)}] 倍数={beishu}"); return (result, beishu); } } /// 破坏球配置参数 public class BossBombConfig : BaseBossConfig { /// 死亡次数配置 public List CountConfig { get; set; } = new List(); /// 第一次死亡配置 public List OneDeathConfig { get; set; } = new List(); /// 第二次死亡配置 public List TwoDeathConfig { get; set; } = new List(); /// 获取破坏球配置响应信息 public (int beishu, int type) GetResponse(string fishId) { int beishu = 0; var countConfig = GetRandomCountConfigOption(CountConfig); if (countConfig == null) { UnityEngine.Debug.Log("[BossConfig] Bomb.GetResponse countConfig为null 返回 (1,1)"); return (1, 1); } if (countConfig.Count == 1) { beishu = GetBossProbabilityConfigResponse(OneDeathConfig); UnityEngine.Debug.Log($"[BossConfig] Bomb.GetResponse 死亡次数={countConfig.Count} 倍数={beishu} type=1 fishId={fishId}"); return (beishu, 1); } else { beishu = GetBossProbabilityConfigResponse(TwoDeathConfig); UnityEngine.Debug.Log($"[BossConfig] Bomb.GetResponse 死亡次数={countConfig.Count} 倍数={beishu} type=2 fishId={fishId}"); return (beishu, 2); } } } /// 烈焰风暴配置 public class BossFlameStormConfig : BaseBossConfig { /// 死亡次数配置 public List CountConfig { get; set; } = new List(); /// 第一次死亡配置 public List OneDeathConfig { get; set; } = new List(); /// 第二次死亡配置 public List TwoDeathConfig { get; set; } = new List(); /// 获取烈焰风暴配置响应信息 public (bool isKill, int beishu, string fishId) GetResponse(string fishId) { bool isKill = false; int beishu = 0; int count = 1; int sumcount = 1; if (!fishId.Contains("-")) // 首次击杀 { var countConfig = GetRandomCountConfigOption(CountConfig); if (countConfig == null) { UnityEngine.Debug.Log($"[BossConfig] FlameStorm.GetResponse 首击 countConfig为null 返回 (true,1,{fishId})"); return (true, 1, fishId); } count = countConfig.Count; beishu = GetBossProbabilityConfigResponse(OneDeathConfig); if (count == 1) { isKill = true; UnityEngine.Debug.Log($"[BossConfig] FlameStorm.GetResponse 首击一次死 isKill=true 倍数={beishu} fishId={fishId}-{count}-{sumcount}"); return (isKill, beishu, $"{fishId}-{count}-{sumcount}"); } else { sumcount = countConfig.Count; } } else { var parts = fishId.Split('-'); count = int.Parse(parts[1]); sumcount = int.Parse(parts[2]); } if (count == 1) { beishu = GetBossProbabilityConfigResponse(TwoDeathConfig); if (sumcount == 2 && count == 1) { UnityEngine.Debug.Log($"[BossConfig] FlameStorm.GetResponse 二击致死 isKill=true 倍数={beishu} fishId={fishId}-{count + 1}-{sumcount}"); return (true, beishu, $"{fishId}-{count + 1}-{sumcount}"); } else { UnityEngine.Debug.Log($"[BossConfig] FlameStorm.GetResponse 二击未死 isKill=false 倍数={beishu} fishId={fishId}-{count + 1}-{sumcount}"); return (false, beishu, $"{fishId}-{count + 1}-{sumcount}"); } } UnityEngine.Debug.Log($"[BossConfig] FlameStorm.GetResponse 三击致死 isKill=true 倍数={beishu} fishId={fishId}-{count + 1}-{sumcount}"); return (true, beishu, $"{fishId}-{count + 1}-{sumcount}"); } } /// 星际巡航配置 public class InterstellarCruiseConfig : BaseBossConfig { /// 死亡次数配置 public List CountConfig { get; set; } = new List(); /// 第一次死亡配置 public List OneDeathConfig { get; set; } = new List(); /// 第二次死亡配置 public List TwoDeathConfig { get; set; } = new List(); /// 第三次死亡配置 public List ThreeDeathConfig { get; set; } = new List(); /// 获取星际巡航配置响应信息 public (bool isKill, int beishu, string fishId) GetResponse(string fishId) { bool isKill = false; int beishu = 0; int count = 1; int sumcount = 1; if (!fishId.Contains("-")) // 首次击杀 { var countConfig = GetRandomCountConfigOption(CountConfig); if (countConfig == null) { UnityEngine.Debug.Log($"[BossConfig] Cruise.GetResponse 首击 countConfig为null 返回 (true,1,{fishId})"); return (true, 1, fishId); } count = countConfig.Count; beishu = GetBossProbabilityConfigResponse(OneDeathConfig); if (count == 1) { isKill = true; UnityEngine.Debug.Log($"[BossConfig] Cruise.GetResponse 首击一次死 isKill=true 倍数={beishu} fishId={fishId}-{count}-{sumcount}"); return (isKill, beishu, $"{fishId}-{count}-{sumcount}"); } else { sumcount = countConfig.Count; } } else { var parts = fishId.Split('-'); count = int.Parse(parts[1]); sumcount = int.Parse(parts[2]); } if (count == 1) { beishu = GetBossProbabilityConfigResponse(TwoDeathConfig); if (sumcount == 2 && count == 1) { UnityEngine.Debug.Log($"[BossConfig] Cruise.GetResponse 二击致死 isKill=true 倍数={beishu} fishId={fishId}-{count + 1}-{sumcount}"); return (true, beishu, $"{fishId}-{count + 1}-{sumcount}"); } else { UnityEngine.Debug.Log($"[BossConfig] Cruise.GetResponse 二击未死 isKill=false 倍数={beishu} fishId={fishId}-{count + 1}-{sumcount}"); return (false, beishu, $"{fishId}-{count + 1}-{sumcount}"); } } beishu = GetBossProbabilityConfigResponse(ThreeDeathConfig); UnityEngine.Debug.Log($"[BossConfig] Cruise.GetResponse 三击致死 isKill=true 倍数={beishu} fishId={fishId}-{count + 1}-{sumcount}"); return (true, beishu, $"{fishId}-{count + 1}-{sumcount}"); } } /// 概率击杀 public class BossProbabilityConfig : BaseBossConfig { public List configParams { get; set; } = new List(); public int GetResponse() { int beishu = GetBossProbabilityConfigResponse(configParams); UnityEngine.Debug.Log($"[BossConfig] Probability.GetResponse 倍数={beishu}"); return beishu; } } /// 弹药箱配置 public class AmmunitionBoxConfig : BaseBossConfig { /// 3个一样的 public List OptionList { get; set; } = new List(); /// 获取随机结果 public List GetResponse() { var opt = RandomBossOption.GetRandomBossOption(OptionList); if (opt == null) { UnityEngine.Debug.LogWarning("[BossConfig] AmmunitionBox.GetResponse 选中为null"); return null; } UnityEngine.Debug.Log($"[BossConfig] AmmunitionBox.GetResponse 选项Id={opt.OptionId} 倍数/分值={opt.Score}"); return new List() { opt }; } } /// 幸运飞碟配置信息 public class LuckFlyDiskConfig : BaseBossConfig { /// 内层配置选项列表 public List InnerOptionList { get; set; } = new List(); /// 外层配置选项列表 public List OuterOptionList { get; set; } = new List(); /// 获取随机结果 public List GetResponse() { List result = new List(); var opt = RandomBossOption.GetRandomBossOption(InnerOptionList); result.Add(opt); var opt1 = RandomBossOption.GetRandomBossOption(OuterOptionList); result.Add(opt1); UnityEngine.Debug.Log($"[BossConfig] FlyDisk.GetResponse 内层={(opt?.OptionId.ToString() ?? "null")} 外层={(opt1?.OptionId.ToString() ?? "null")}"); return result; } } /// 小丑扑克 public class LuckPokerConfig : BaseBossConfig { /// 配置选项列表 public List OptionList { get; set; } = new List(); /// 获取随机结果 public List GetResponse() { var opt = RandomBossOption.GetRandomBossOption(OptionList); if (opt == null) { UnityEngine.Debug.LogWarning("[BossConfig] Poker.GetResponse 选中为null"); return null; } UnityEngine.Debug.Log($"[BossConfig] Poker.GetResponse 选项Id={opt.OptionId} 倍数/分值={opt.Score}"); return new List() { opt }; } } /// 幸运轮盘配置信息 public class LuckWheelConfig : BaseBossConfig { /// 配置选项列表 public List OptionList { get; set; } = new List(); /// 配置项数量配置列表 public List CountList { get; set; } = new List(); /// 获取随机结果 public List GetResponse() { List count = new List(); List option = new List(); foreach (var item in CountList) { if (item.TriggerRate >= 100) { count.Add(item.OptionId); continue; } if (GlobalRandom.Next(100) < item.TriggerRate) { count.Add(item.OptionId); continue; } break; } foreach (var item in count) { var opt = RandomBossOption.GetRandomBossOption(OptionList); if (opt == null) continue; option.Add(opt); } UnityEngine.Debug.Log($"[BossConfig] Wheel.GetResponse 触发次数={count.Count} 选项Ids=[{string.Join(",", option.Select(o => o.OptionId))}]"); return option; } } /// Boss配置基类 public class BaseBossConfig { /// 鱼编号 public List FishNumber { get; set; } = new List(); } /// boss 概率配置参数 public class BossProbabilityConfigParam { public BossProbabilityConfigParam() { } public BossProbabilityConfigParam(int min, int max, int triggerRate) { Min = min; Max = max; TriggerRate = triggerRate; } /// 最小值 public int Min { get; set; } /// 最大值 public int Max { get; set; } /// 触发权重 public int TriggerRate { get; set; } = 0; } } /// Boss道具掉落配置项 public class BossDropItemConfig { /// 道具编号 public string PropNumber { get; set; } = string.Empty; /// 道具名称 public string PropName { get; set; } = string.Empty; /// 掉落数量 public int Count { get; set; } = 1; /// 掉落权重(概率 = Weight / 10000) public int Weight { get; set; } = 0; } /// Boss道具掉落配置 public class BossDropConfig { /// 不掉落权重(概率 = NoDropWeight / 总权重和) public int NoDropWeight { get; set; } = 5000; /// 掉落道具列表 public List DropItems { get; set; } = new List(); } /// 公共选项配置 public class BossOptionBaseParam { public BossOptionBaseParam() { } public BossOptionBaseParam(double optionId, int triggerRate, double score = 0) { OptionId = optionId; TriggerRate = triggerRate; Score = score; } /// 选项编号 public double OptionId { get; set; } /// 触发权重 public int TriggerRate { get; set; } = 0; /// 分值 public double Score { get; set; } = 0; } // ============================================================ // 服务端依赖的 Unity 客户端兼容实现 // ============================================================ /// /// 线程安全的随机数工具(替代服务端的 GlobalRandom)。 /// 全部走 UnityEngine.Random,保证客户端单线程主逻辑使用。 /// public static class GlobalRandom { /// [min, max) 的随机整数 public static int Next(int min, int max) { return UnityEngine.Random.Range(min, max); } /// [0, max) 的随机整数 public static int Next(int max) { return UnityEngine.Random.Range(0, max); } /// [min, max] 闭区间的随机整数(含两端) public static int NextInclusive(int min, int max) { // Range 的整数重载是 [min, max) 上界开,这里补 1 实现闭区间 if (min > max) return min; return UnityEngine.Random.Range(min, max + 1); } /// [min, max) 的随机 long public static long NextInt64(long min, long max) { if (min >= max) return min; // UnityEngine.Random 无 long 重载,用 double 映射 double t = UnityEngine.Random.value; return (long)(min + (max - min) * t); } } /// /// Boss 选项权重随机工具(替代服务端的 RandomBossOption)。 /// public static class RandomBossOption { /// /// 按权重随机选中一个 Boss 选项。 /// public static BossOptionBaseParam GetRandomBossOption(List options) { if (options == null || options.Count == 0) return null; long totalWeight = options.Sum(o => (long)o.TriggerRate); if (totalWeight <= 0) return null; long randomValue = GlobalRandom.NextInt64(0, totalWeight); long currentWeightSum = 0; foreach (var option in options) { currentWeightSum += option.TriggerRate; if (randomValue < currentWeightSum) { return option; } } return options.FirstOrDefault(o => o.TriggerRate > 0); } } }