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);
}
}
}