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(EquipmentModifiers equipmentModifiers, CurrencyModifiers currencyModifiers) { var tags = new HashSet <string>(_baseTags.Union(equipmentModifiers.AddedTags)); var masterModSet = new HashSet <string>(equipmentModifiers.MasterMods); var addedAffixes = currencyModifiers.AddedExplicits .Union(equipmentModifiers.Influence.SelectMany(x => _influenceAffixes[x])) .Where(x => x.RequiredLevel <= equipmentModifiers.ItemLevel) .ToList(); var affixesToEvaluate = _itemAffixes.Union(addedAffixes).ToList(); if (currencyModifiers.ItemLevelRestriction != null && currencyModifiers.ItemLevelRestriction < equipmentModifiers.ItemLevel) { affixesToEvaluate = affixesToEvaluate .Where(x => x.RequiredLevel <= currencyModifiers.ItemLevelRestriction) .ToList(); } List <KeyValuePair <string, double> > qualityWeightModifiers = new List <KeyValuePair <string, double> >(); if (currencyModifiers.QualityAffectsExplicitOdds) { qualityWeightModifiers.Add(equipmentModifiers.QualityGenerationWeight); } var weightModifiers = equipmentModifiers.GenerationWeights .Union(currencyModifiers.ExplicitWeightModifiers) .Union(qualityWeightModifiers) .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, weightModifiers, masterModSet); pool.SuffixGroupToAffixWeights = GroupToAffixWeights(affixesToEvaluate.Where(x => x.GenerationType == "suffix").ToList(), tags, weightModifiers, 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(EquipmentModifiers equipmentModifiers, CurrencyModifiers currencyModifiers, List <Affix> affixes, EquipmentRarity rarity, IRandom random) { PoolKey key = new PoolKey(equipmentModifiers, currencyModifiers); if (!_poolDic.ContainsKey(key)) { _poolDic.Add(key, GenerateAffixPool(equipmentModifiers, currencyModifiers)); } 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 = CalculateSkipAmount("prefix", pool.PrefixWeight, pool.PrefixGroupWeights, affixes, affixesCount); double suffixSkipAmount = CalculateSkipAmount("suffix", pool.SuffixWeight, pool.SuffixGroupWeights, affixes, affixesCount); var targetWeight = random.NextDouble() * (pool.TotalWeight - prefixSkipAmount - suffixSkipAmount); return(GetRandomAffixFromPool(pool, targetWeight, existingGroups, prefixSkipAmount, suffixSkipAmount)); }