private Affix GetRandomAffixFromPool(AffixPool pool, double targetWeight, HashSet <string> existingGroups, double prefixSkipAmount, double suffixSkipAmount) { Affix affix = null; bool skipPrefixes = Math.Abs(prefixSkipAmount - pool.PrefixWeight) < .001; bool skipSuffixes = Math.Abs(suffixSkipAmount - pool.SuffixWeight) < .001; if (skipPrefixes && skipSuffixes) { return(null); } if (targetWeight <= pool.PrefixWeight && !skipPrefixes) { affix = RandomAffixFromPool(targetWeight, existingGroups, pool.PrefixGroupWeights, 0, pool.PrefixGroupToAffixWeights); } if (affix != null) { return(affix); } if (!skipSuffixes) { affix = RandomAffixFromPool(targetWeight, existingGroups, pool.SuffixGroupWeights, pool.PrefixWeight - prefixSkipAmount, pool.SuffixGroupToAffixWeights); } return(affix); }
private AffixPool GenerateAffixPool(List <string> addedTags, List <Fossil> fossils, List <string> masterMods) { var tags = new HashSet <string>(_baseTags.Union(addedTags)); var masterModSet = new HashSet <string>(masterMods); var fossilAffixes = fossils .SelectMany(x => x.AddedAffixes) .Distinct() .Where(x => x.RequiredLevel <= _baseLevel) .ToList(); var affixesToEvaluate = _itemAffixes.Union(fossilAffixes).ToList(); var fossilWeightModifiers = fossils .SelectMany(x => x.ModWeightModifiers) .GroupBy(x => x.Key) .ToDictionary(x => x.Key, x => x.Aggregate(1d, (y, z) => y * z.Value / 100d)); AffixPool pool = new AffixPool(); pool.PrefixGroupToAffixWeights = GroupToAffixWeights(affixesToEvaluate.Where(x => x.GenerationType == "prefix").ToList(), tags, fossilWeightModifiers, masterModSet); pool.SuffixGroupToAffixWeights = GroupToAffixWeights(affixesToEvaluate.Where(x => x.GenerationType == "suffix").ToList(), tags, fossilWeightModifiers, masterModSet); pool.PrefixGroupWeights = pool.PrefixGroupToAffixWeights.ToDictionary(x => x.Key, x => x.Value.Sum(y => y.Weight)); pool.SuffixGroupWeights = pool.SuffixGroupToAffixWeights.ToDictionary(x => x.Key, x => x.Value.Sum(y => y.Weight)); pool.PrefixWeight = pool.PrefixGroupWeights.Sum(x => x.Value); pool.SuffixWeight = pool.SuffixGroupWeights.Sum(x => x.Value); pool.TotalWeight = pool.PrefixWeight + pool.SuffixWeight; pool.AffixCount = pool.PrefixGroupToAffixWeights.Sum(x => x.Value.Count) + pool.SuffixGroupToAffixWeights.Sum(x => x.Value.Count); return(pool); }
public Affix GetAffix(List <Affix> affixes, EquipmentRarity rarity, IRandom random, List <Fossil> fossils = null) { if (fossils == null) { fossils = new List <Fossil>(); } var addedTags = affixes.SelectMany(x => x.AddsTags).Distinct().ToList(); var fossilNames = fossils.Select(x => x.FullName).Distinct().ToList(); var masterMods = affixes.Where(x => x.Group.Contains(NoAttackMods) || x.Group.Contains(NoCasterMods)).Select(x => x.Group).ToList(); PoolKey key = new PoolKey(addedTags, fossilNames, masterMods); if (!_poolDic.ContainsKey(key)) { _poolDic.Add(key, GenerateAffixPool(addedTags, fossils, masterMods)); } AffixPool pool = _poolDic[key]; var existingGroups = new HashSet <string>(affixes.Select(x => x.Group)); int affixesCount = rarity == EquipmentRarity.Normal ? 0 : rarity == EquipmentRarity.Magic ? 1 : rarity == EquipmentRarity.Rare ? 3 : 0; double prefixSkipAmount = 0; double suffixSkipAmount = 0; if (affixes.Count(x => x.GenerationType == "prefix") >= affixesCount) { prefixSkipAmount = pool.PrefixWeight; } else { prefixSkipAmount = affixes .Select(x => x.Group) .Where(x => pool.PrefixGroupWeights.ContainsKey(x)) .Sum(x => pool.PrefixGroupWeights[x]); } if (affixes.Count(x => x.GenerationType == "suffix") >= affixesCount) { suffixSkipAmount = pool.SuffixWeight; } else { suffixSkipAmount = affixes .Select(x => x.Group) .Where(x => pool.SuffixGroupWeights.ContainsKey(x)) .Sum(x => pool.SuffixGroupWeights[x]); } var totalWeight = pool.TotalWeight; totalWeight -= prefixSkipAmount; totalWeight -= suffixSkipAmount; var targetWeight = random.NextDouble() * totalWeight; return(GetRandomAffixFromPool(pool, targetWeight, existingGroups, prefixSkipAmount, suffixSkipAmount)); }