using System.Collections.Generic; using System.Linq; using asap.core; using Capsule.Reward; using cfg; using GameCore; using Newtonsoft.Json; using UnityEngine; namespace Capsule.Pack.Manager { public static class CapsulePackDataEx { // 根据权重随机获取奖励 public static ICapsuleReward GetRandomRewardIndex(this CapsulePackData data) { var reward =data.GetRemainRewards(); var totalWeight=data.CalculateWeights(reward, out var weightRanges,out var canObtainRewards); if (totalWeight <= 0) { Debug.LogError("总权重为0"); return reward.FirstOrDefault(); } var randomValue = Random.Range(0, totalWeight); for (var i = 0; i < weightRanges.Count; i++) if (randomValue < weightRanges[i]) return canObtainRewards.ElementAt(i); return canObtainRewards.LastOrDefault(); } public static List GetRemainRewards(this CapsulePackData data) { return data?.GetAllRewards().Where(r => !(data.CurrentProgress?.Contains(r.Index) ?? false)) .Select(r => (ICapsuleReward)new EventToyMachineRewardAdapter(r, data.InflationRate)).ToList(); } private static int CalculateWeights(this CapsulePackData data,List remainRewards, out List weightRanges,out IEnumerable canObtainRewards) { canObtainRewards =data.GetCanObtainRewards(remainRewards).ToList(); var totalWeight = canObtainRewards.Sum(r => r.Weight); weightRanges= BuildWeightRanges(canObtainRewards); return totalWeight; } private static IEnumerable GetCanObtainRewards(this CapsulePackData data,List remainRewards) { return remainRewards.Where(r=> data.CurrentProgressCount + 1 >= r.RoundLimit); } private static List GetAllRewards(this CapsulePackData data) { var roundConfig = data.GetRoundConfig(); if (roundConfig == null) return null; List rewards = new(); foreach (var id in roundConfig.RewardList) { var rewardConfig = data.Tables.TbEventToyMachineReward.Get(id); if (rewardConfig == null || rewards.Find(x => x.Index == rewardConfig.Index) != null) continue; rewards.Add(rewardConfig); } return rewards; } private static List BuildWeightRanges(IEnumerable canObtainRewards) { var weightRanges=new List(); var currentWeight = 0; foreach (var reward in canObtainRewards) { currentWeight += reward.Weight; weightRanges.Add(currentWeight); } return weightRanges; } private static EventToyMachineRound GetRoundConfig(this CapsulePackData data) { var packConfig = data.GetPackConfig(); var roundConfig = data.Tables.TbEventToyMachineRound.GetOrDefault(packConfig.DropID); if (roundConfig == null) Debug.LogError($"配置错误 约定 dropId配置 roundID packConfig.ID {packConfig.ID}"); return roundConfig; } public static cfg.Pack GetPackConfig(this CapsulePackData data) { var packManager = data.Tables?.TbEventPackManager.GetOrDefault(data.MainConfig.PackManagerID[data.CurrentRoundCount]); if (packManager == null) { Debug.LogError( $"CapsulePackManager GetPackConfig packManager is null EventPackManagerID {JsonConvert.SerializeObject(data.MainConfig.PackManagerID)} {data.CurrentRoundCount}"); return null; } var vipLevel = GContext.container.Resolve().PriceLv; if(vipLevel>=packManager.VIPPackList.Count) vipLevel=packManager.VIPPackList.Count-1; var packList = packManager.VIPPackList[vipLevel]; var maxCount = data.CurrentProgressCount < packList.Count ? data.CurrentProgressCount : packList.Count - 1; var packConfigID = packManager.VIPPackList[vipLevel][maxCount]; return data.Tables?.TbPack.GetOrDefault(packConfigID); } #region probility public static GeneralProbabilityData[] GetProbabilityData(this CapsulePackData data) { var rewardConfigs =data.GetAllRewards(); var res = new GeneralProbabilityData[rewardConfigs.Count]; var tbRewards = rewardConfigs; var totalWeight = tbRewards.Where(r => !data.IsClaimed(r.Index)).Sum(r => r.Weight); for (int i = 0; i < rewardConfigs.Count; i++) { res[i] = new GeneralProbabilityData { Item = GetItemFromIndex(rewardConfigs[i],data.InflationRate), Probability = tbRewards[i].Weight / (float)totalWeight, IsClaimed =data.IsClaimed(rewardConfigs[i].Index) }; } return res; } private static ItemData GetItemFromIndex(EventToyMachineReward config,float? inflate) { var rewardItemData = GContext.container.Resolve() .GetItemDataByDropIdAndTypeLureInflation(inflate, config.DropID); return rewardItemData.FirstOrDefault(); } private static bool IsClaimed(this CapsulePackData data,int idx) { var remainConfigs = data.GetRemainRewards(); var remainIndexes = new HashSet(remainConfigs.Select(r => r.Index)); return !remainIndexes.Contains(idx); } #endregion } }