Files
ft/Client/Assets/Scripts/Capsule/Pack/Manager/CapsulePackDataEx.cs
2026-06-29 21:18:33 +08:00

137 lines
5.9 KiB
C#

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<ICapsuleReward> 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<ICapsuleReward> remainRewards, out List<int> weightRanges,out IEnumerable<ICapsuleReward> canObtainRewards)
{
canObtainRewards =data.GetCanObtainRewards(remainRewards).ToList();
var totalWeight = canObtainRewards.Sum(r => r.Weight);
weightRanges= BuildWeightRanges(canObtainRewards);
return totalWeight;
}
private static IEnumerable<ICapsuleReward> GetCanObtainRewards(this CapsulePackData data,List<ICapsuleReward> remainRewards)
{
return remainRewards.Where(r=> data.CurrentProgressCount + 1 >= r.RoundLimit);
}
private static List<EventToyMachineReward> GetAllRewards(this CapsulePackData data)
{
var roundConfig = data.GetRoundConfig();
if (roundConfig == null) return null;
List<EventToyMachineReward> 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<int> BuildWeightRanges(IEnumerable<ICapsuleReward> canObtainRewards)
{
var weightRanges=new List<int>();
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<PlayerData>().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<PlayerItemData>()
.GetItemDataByDropIdAndTypeLureInflation(inflate, config.DropID);
return rewardItemData.FirstOrDefault();
}
private static bool IsClaimed(this CapsulePackData data,int idx)
{
var remainConfigs = data.GetRemainRewards();
var remainIndexes = new HashSet<int>(remainConfigs.Select(r => r.Index));
return !remainIndexes.Contains(idx);
}
#endregion
}
}