Example #1
0
        public override string GetResultName(RecipeResult result)
        {
            if (result.MatchedItems.Any(i => i.ItemType == ItemType.Gear &&
                                        (i as Gear).Rarity == Rarity.Unique))
            {
                return("5 Orbs of Chance - Same base type with normal, magic, rare, and unique");
            }

            // All items have 20% quality and are either unidentified or normal rarity.
            if (result.MatchedItems.All(i => i.Quality == 20 &&
                                        (!i.Identified || (i is Gear && (i as Gear).Rarity == Rarity.Normal))))
            {
                return("2 Orbs of Alchemy - Same base type with normal, magic, rare, 20% quality and unidentified");
            }

            if (result.MatchedItems.All(i => i.Quality == 20))
            {
                return("1 Orb of Alchemy - Same base type with normal, magic, rare, 20% quality");
            }

            if (result.MatchedItems.All(i => !i.Identified || (i is Gear && (i as Gear).Rarity == Rarity.Normal)))
            {
                return("2 Orbs of Augmentation - Same base type with normal, magic, rare, unidentified");
            }

            return("1 Orb of Augmentation - Same base type with normal, magic, and rare"); // base case
        }
Example #2
0
        public override IEnumerable <RecipeResult> Matches(IEnumerable <Item> items)
        {
            List <RecipeResult> recipeSets = new List <RecipeResult>();

            var candidateGems = items.OfType <Gem>().Where(
                gem => gem.Corrupted && gem.TypeLine.StartsWith("Vaal ", StringComparison.CurrentCultureIgnoreCase))
                                .Cast <Item>().ToList();

            var fragments = items.Where(
                x => x.TypeLine.StartsWith("Sacrifice at", StringComparison.CurrentCultureIgnoreCase)).ToList();

            while (candidateGems.Count > 0)
            {
                var recipeResult = new RecipeResult()
                {
                    Instance     = this,
                    MatchedItems = new List <Item>(),
                    Missing      = new List <string>(),
                    IsMatch      = true
                };

                for (int i = candidateGems.Count - 1; i >= 0; i--)
                {
                    var candidateGem = candidateGems[i];
                    if (recipeResult.MatchedItems.Count == NeededVaalGems)
                    {
                        break;
                    }

                    recipeResult.MatchedItems.Add(candidateGem);
                    candidateGems.Remove(candidateGem);
                }

                var numberOfMissingGems = NeededVaalGems - recipeResult.MatchedItems.Count;

                if (numberOfMissingGems == 1)
                {
                    recipeResult.Missing.Add("1 Vaal Skill gem");
                }
                else if (numberOfMissingGems >= 2)
                {
                    recipeResult.Missing.Add($"{numberOfMissingGems} Vaal Skill gems");
                }

                if (fragments.Any())
                {
                    recipeResult.MatchedItems.Add(fragments.First());
                    fragments.RemoveAt(0);
                }
                else
                {
                    recipeResult.Missing.Add("Sacrifice Fragment");
                }

                recipeResult.PercentMatch = recipeResult.MatchedItems.Count / TotalNumberOfNeededItems * 100;
                recipeSets.Add(recipeResult);
            }

            return(recipeSets);
        }
Example #3
0
        private RecipeResult getResult(Combination currentSet)
        {
            RecipeResult result = new RecipeResult();

            result.MatchedItems = currentSet.Match.Cast <Item>().ToList();
            result.Instance     = this;
            result.IsMatch      = true;

            decimal total = currentSet.Total;
            decimal match = 0;

            if (currentSet.Match.Count > 1)
            {
                match = (total / REQUIREDQUALITY) * 100;
            }
            else
            {
                match = (total / SINGLEITEMREQUIREDQUALITY) * 100;
            }

            result.IsMatch      = match >= base.ReturnMatchesGreaterThan;
            result.PercentMatch = match;
            if (match < 100)
            {
                result.Missing = new List <string>()
                {
                    getMissingCombinationText(REQUIREDQUALITY, total)
                }
            }
            ;

            return(result);
        }
    }
        public override string GetResultName(RecipeResult result)
        {
            if (result.MatchedItems.Any(i => i.ItemType == ItemType.Gear
                && (i as Gear).Rarity == Rarity.Unique))
            {
                return "5 Orbs of Chance - Same base type with normal, magic, rare, and unique";
            }

            // All items have 20% quality and are either unidentified or normal rarity.
            if (result.MatchedItems.All(i => i.Quality == 20
                && (!i.Identified || (i is Gear && (i as Gear).Rarity == Rarity.Normal))))
            {
                return "2 Orbs of Alchemy - Same base type with normal, magic, rare, 20% quality and unidentified";
            }

            if (result.MatchedItems.All(i => i.Quality == 20))
            {
                return "1 Orb of Alchemy - Same base type with normal, magic, rare, 20% quality";
            }

            if (result.MatchedItems.All(i => !i.Identified || (i is Gear && (i as Gear).Rarity == Rarity.Normal)))
            {
                return "2 Orbs of Augmentation - Same base type with normal, magic, rare, unidentified";
            }

            return "1 Orb of Augmentation - Same base type with normal, magic, and rare"; // base case
        }
Example #5
0
        private IEnumerable <RecipeResult> getNextResult(Dictionary <string, List <Gear> > buckets, Func <Gear, bool> constraint)
        {
            foreach (var baseTypeBucket in buckets)
            {
                List <Gear> gears = baseTypeBucket.Value; // though, technically, gear is a mass noun

                if (gears == null || gears.Count == 0)
                {
                    continue;
                }

                bool stop = false;
                while (!stop)
                {
                    RecipeResult result = new RecipeResult();
                    result.MatchedItems = new List <Item>();
                    result.Missing      = new List <string>();
                    result.PercentMatch = 0;
                    result.Instance     = this;

                    Dictionary <Rarity, Gear> set = new Dictionary <Rarity, Gear>();
                    set.Add(Rarity.Normal, gears.FirstOrDefault(g => g.Rarity == Rarity.Normal && constraint(g)));
                    set.Add(Rarity.Magic, gears.FirstOrDefault(g => g.Rarity == Rarity.Magic && constraint(g)));
                    set.Add(Rarity.Rare, gears.FirstOrDefault(g => g.Rarity == Rarity.Rare && constraint(g)));
                    // TODO: Handle case with a unique item.

                    decimal numKeys = set.Keys.Count;
                    foreach (var pair in set)
                    {
                        Rarity rarity = pair.Key;
                        Gear   gear   = pair.Value;
                        if (gear != null)
                        {
                            result.PercentMatch += (decimal)100.0 / numKeys;
                            result.MatchedItems.Add(gear);
                        }
                        else
                        {
                            result.Missing.Add(string.Format("Item with {0} rarity", rarity.ToString()));
                        }
                    }

                    result.IsMatch = result.PercentMatch > base.ReturnMatchesGreaterThan;
                    if (result.IsMatch) // only remove the items if they are in a "match" -- close enough to show in the UI
                    {
                        foreach (var pair in set)
                        {
                            gears.Remove(pair.Value);
                        }
                        yield return(result);
                    }

                    if (result.Missing.Count > 0 || gears.Count == 0)
                    {
                        stop = true;
                    }
                }
            }
        }
Example #6
0
        private IEnumerable<RecipeResult> getNextResult(Dictionary<string, List<Gear>> buckets, Func<Gear, bool> constraint)
        {
            foreach(var baseTypeBucket in buckets)
            {
                List<Gear> gears = baseTypeBucket.Value; // though, technically, gear is a mass noun

                if (gears == null || gears.Count == 0)
                    continue;

                bool stop = false;
                while (!stop)
                {
                    RecipeResult result = new RecipeResult();
                    result.MatchedItems = new List<Item>();
                    result.Missing = new List<string>();
                    result.PercentMatch = 0;
                    result.Instance = this;

                    Dictionary<Rarity, Gear> set = new Dictionary<Rarity, Gear>();
                    set.Add(Rarity.Normal, gears.FirstOrDefault(g => g.Rarity == Rarity.Normal && constraint(g)));
                    set.Add(Rarity.Magic, gears.FirstOrDefault(g => g.Rarity == Rarity.Magic && constraint(g)));
                    set.Add(Rarity.Rare, gears.FirstOrDefault(g => g.Rarity == Rarity.Rare && constraint(g)));
                    // TODO: Handle case with a unique item.

                    decimal numKeys = set.Keys.Count;
                    foreach (var pair in set)
                    {
                        Rarity rarity = pair.Key;
                        Gear gear = pair.Value;
                        if (gear != null)
                        {
                            result.PercentMatch += (decimal)100.0 / numKeys;
                            result.MatchedItems.Add(gear);
                        }
                        else
                        {
                            result.Missing.Add(string.Format("Item with {0} rarity", rarity.ToString()));
                        }
                    }

                    result.IsMatch = result.PercentMatch > base.ReturnMatchesGreaterThan;
                    if (result.IsMatch) // only remove the items if they are in a "match" -- close enough to show in the UI
                    {
                        foreach (var pair in set)
                            gears.Remove(pair.Value);
                        yield return result;
                    }

                    if (result.Missing.Count > 0 || gears.Count == 0)
                        stop = true;
                }
            }
        }
Example #7
0
        private RecipeResult getResult(Gear item)
        {
            RecipeResult result = new RecipeResult();
            result.Instance = this;

            result.PercentMatch = 100;
            result.IsMatch = true;
            result.MatchedItems = new List<Item> { item };
            result.Missing = new List<string>();

            return result;
        }
        public override IEnumerable <RecipeResult> Matches(IEnumerable <POEApi.Model.Item> items)
        {
            List <T> candidateItems = getCandidateItems(items).ToList();

            bool canContinue = true;

            while (canContinue)
            {
                getCombinations(candidateItems, REQUIREDQUALITY);

                Combination perfect = combinations.Find(c => c.Perfect);
                if (perfect != null)
                {
                    perfect.Match.ForEach(g => candidateItems.Remove(g));
                    yield return(getResult(perfect));

                    continue;
                }

                Combination        leastOver = null;
                List <Combination> over      = combinations.FindAll(c => !c.Perfect);
                if (over != null && over.Count > 0)
                {
                    leastOver = over.OrderBy(c => c.Total).First();
                }

                if (leastOver != null)
                {
                    leastOver.Match.ForEach(g => candidateItems.Remove(g));
                    yield return(getResult(leastOver));

                    continue;
                }

                if (leastOver == null)
                {
                    canContinue = false;
                }
            }

            Combination remaining = new Combination()
            {
                Match = candidateItems, Total = candidateItems.Sum(a => a.Quality), Perfect = false
            };
            RecipeResult leftOver = getResult(remaining);

            if (leftOver.IsMatch)
            {
                yield return(leftOver);
            }
        }
Example #9
0
        private RecipeResult getResult(Gear item)
        {
            RecipeResult result = new RecipeResult();

            result.Instance = this;

            result.PercentMatch = 100;
            result.IsMatch      = true;
            result.MatchedItems = new List <Item> {
                item
            };
            result.Missing = new List <string>();

            return(result);
        }
Example #10
0
        public override IEnumerable <RecipeResult> Matches(IEnumerable <Item> items)
        {
            List <Gear> allGear = items.OfType <Gear>().ToList();

            bool isShaperWanted = _setType == SetType.Shaper;
            bool isElderWanted  = _setType == SetType.Elder;

            Dictionary <string, List <Gear> > buckets =
                allGear.Where(g => g.Rarity == Rarity.Rare &&
                              g.ItemLevel <= maximumItemLevel &&
                              g.ItemLevel >= minimumItemLevel &&
                              g.Identified == itemsIdentified &&
                              g.Shaper == isShaperWanted &&
                              g.Elder == isElderWanted)
                .GroupBy(g => g.GearType)
                .ToDictionary(g => g.Key.ToString(), g => g.ToList());

            GearType[] oneHandedOnlyGearTypes = { GearType.Claw, GearType.Dagger, GearType.Sceptre, GearType.Wand,
                                                  GearType.Shield };
            GearType[] twoHandedOnlyGearTypes = { GearType.Bow, GearType.Staff, GearType.FishingRod };
            GearType[] mixedGearTypes         = { GearType.Axe, GearType.Mace, GearType.Sword };

            moveSelectedBucketsContents(buckets, "Two Handed", twoHandedOnlyGearTypes);
            resortSelectedBuckets(buckets, "Two Handed", g => g.Properties.Any(
                                      pr => pr.Name.Contains("Two Handed")), mixedGearTypes);
            moveSelectedBucketsContents(buckets, "One Handed", oneHandedOnlyGearTypes);
            moveSelectedBucketsContents(buckets, "One Handed", mixedGearTypes);

            foreach (KeyValuePair <string, List <Gear> > bucket in buckets)
            {
                bucket.Value.Sort((x, y) => x.ItemLevel.CompareTo(y.ItemLevel));
            }

            RecipeResult result = getNextResult(buckets);

            while (result.IsMatch)
            {
                yield return(result);

                result = getNextResult(buckets);
            }
        }
Example #11
0
        private RecipeResult getNextResult(Dictionary <string, List <Gear> > buckets)
        {
            RecipeResult result = new RecipeResult();

            result.Instance = this;

            MatchedSet set = new MatchedSet();

            set.Amulet    = pullValue(buckets, GearType.Amulet.ToString());
            set.Armour    = pullValue(buckets, GearType.Chest.ToString());
            set.Belt      = pullValue(buckets, GearType.Belt.ToString());
            set.Boots     = pullValue(buckets, GearType.Boots.ToString());
            set.Gloves    = pullValue(buckets, GearType.Gloves.ToString());
            set.Helm      = pullValue(buckets, GearType.Helmet.ToString());
            set.RingLeft  = pullValue(buckets, GearType.Ring.ToString());
            set.RingRight = pullValue(buckets, GearType.Ring.ToString());

            // Use two one-handed items or one two-handed item, based on which has the lowest item level.
            int oneHandedItemLevel = buckets.ContainsKey("One Handed") && buckets["One Handed"].Count > 1 ?
                                     buckets["One Handed"][0].ItemLevel : int.MaxValue;
            int twoHandedItemLevel = buckets.ContainsKey("Two Handed") && buckets["Two Handed"].Count > 0 ?
                                     buckets["Two Handed"][0].ItemLevel : int.MaxValue;

            if (oneHandedItemLevel <= twoHandedItemLevel)
            {
                // Includes the case where buckets["Two Handed"] is empty and buckets["One Handed"] has one item.
                set.Weapon  = pullValue(buckets, "One Handed");
                set.Offhand = pullValue(buckets, "One Handed");
            }
            else
            {
                set.Weapon  = pullValue(buckets, "Two Handed");
                set.Offhand = set.Weapon;
            }

            result.PercentMatch = set.Match();
            result.IsMatch      = result.PercentMatch > base.ReturnMatchesGreaterThan;
            result.MatchedItems = set.GetAll().Cast <Item>().ToList();
            result.Missing      = set.GetMissing();

            return(result);
        }
Example #12
0
        public override IEnumerable <RecipeResult> Matches(IEnumerable <Item> items)
        {
            List <Gear> allGear = items.OfType <Gear>().ToList();
            Dictionary <string, List <Gear> > buckets = allGear.Where(g => g.Rarity == Rarity.Rare && g.ItemLevel <maximumItemLevel && g.ItemLevel> minimumItemLevel && g.Identified == itemsIdentified)
                                                        .GroupBy(g => g.GearType)
                                                        .ToDictionary(g => g.Key.ToString(), g => g.ToList());

            mergeKeys(buckets, "One Handed", g => g.Properties.Any(pr => pr.Name.Contains("One Handed")), GearType.Axe, GearType.Bow, GearType.Claw, GearType.Dagger, GearType.Mace, GearType.Sceptre, GearType.Staff, GearType.Sword, GearType.Wand);
            mergeKeys(buckets, "Two Handed", g => g.Properties.Any(pr => pr.Name.Contains("Two Handed")), GearType.Axe, GearType.Bow, GearType.Claw, GearType.Dagger, GearType.Mace, GearType.Sceptre, GearType.Staff, GearType.Sword, GearType.Wand);
            removeKeys(buckets, GearType.Axe, GearType.Bow, GearType.Claw, GearType.Dagger, GearType.Mace, GearType.Sceptre, GearType.Staff, GearType.Sword, GearType.Wand);

            RecipeResult result = getNextResult(buckets);

            while (result.IsMatch)
            {
                yield return(result);

                result = getNextResult(buckets);
            }
        }
Example #13
0
        private RecipeResult getNextResult(Dictionary <string, List <Gear> > buckets)
        {
            RecipeResult result = new RecipeResult();

            result.Instance = this;

            MatchedSet set = new MatchedSet();

            set.Amulet    = pullValue(buckets, GearType.Amulet.ToString());
            set.Armour    = pullValue(buckets, GearType.Chest.ToString());
            set.Belt      = pullValue(buckets, GearType.Belt.ToString());
            set.Boots     = pullValue(buckets, GearType.Boots.ToString());
            set.Gloves    = pullValue(buckets, GearType.Gloves.ToString());
            set.Helm      = pullValue(buckets, GearType.Helmet.ToString());
            set.RingLeft  = pullValue(buckets, GearType.Ring.ToString());
            set.RingRight = pullValue(buckets, GearType.Ring.ToString());

            if (buckets["One Handed"].Count > 0 && buckets.ContainsKey(GearType.Shield.ToString()) && buckets[GearType.Shield.ToString()].Count > 0)
            {
                set.Weapon  = pullValue(buckets, "One Handed");
                set.Offhand = pullValue(buckets, GearType.Shield.ToString());
            }
            else if (buckets["One Handed"].Count > 1)
            {
                set.Weapon  = pullValue(buckets, "One Handed");
                set.Offhand = pullValue(buckets, "One Handed");
            }
            else
            {
                set.Weapon  = pullValue(buckets, "Two Handed");
                set.Offhand = set.Weapon;
            }

            result.PercentMatch = set.Match();
            result.IsMatch      = result.PercentMatch > base.ReturnMatchesGreaterThan;
            result.MatchedItems = set.GetAll().Cast <Item>().ToList();
            result.Missing      = set.GetMissing();

            return(result);
        }
Example #14
0
        private RecipeResult getNextResult(Dictionary<string, List<Gear>> buckets)
        {
            RecipeResult result = new RecipeResult();
            result.Instance = this;

            MatchedSet set = new MatchedSet();

            set.Amulet = pullValue(buckets, GearType.Amulet.ToString());
            set.Armour = pullValue(buckets, GearType.Chest.ToString());
            set.Belt = pullValue(buckets, GearType.Belt.ToString());
            set.Boots = pullValue(buckets, GearType.Boots.ToString());
            set.Gloves = pullValue(buckets, GearType.Gloves.ToString());
            set.Helm = pullValue(buckets, GearType.Helmet.ToString());
            set.RingLeft = pullValue(buckets, GearType.Ring.ToString());
            set.RingRight = pullValue(buckets, GearType.Ring.ToString());

            if (buckets["One Handed"].Count > 0 && buckets.ContainsKey(GearType.Shield.ToString()) && buckets[GearType.Shield.ToString()].Count > 0)
            {
                set.Weapon = pullValue(buckets, "One Handed");
                set.Offhand = pullValue(buckets, GearType.Shield.ToString());
            }
            else if (buckets["One Handed"].Count > 1)
            {
                set.Weapon = pullValue(buckets, "One Handed");
                set.Offhand = pullValue(buckets, "One Handed");
            }
            else
            {
                set.Weapon = pullValue(buckets, "Two Handed");
                set.Offhand = set.Weapon;
            }

            result.PercentMatch = set.Match();
            result.IsMatch = result.PercentMatch > base.ReturnMatchesGreaterThan;
            result.MatchedItems = set.GetAll().Cast<Item>().ToList();
            result.Missing = set.GetMissing();

            return result;
        }
        public override IEnumerable <RecipeResult> Matches(IEnumerable <Item> items)
        {
            var isShaperWanted = _setType == SetType.Shaper;
            var isElderWanted  = _setType == SetType.Elder;

            var uniqueRings = items.OfType <Gear>().Where(x => x.GearType == GearType.Ring &&
                                                          x.Rarity == Rarity.Unique &&
                                                          x.Shaper == isShaperWanted &&
                                                          x.Elder == isElderWanted)
                              .ToList();

            var recipeResults = new List <RecipeResult>();

            while (uniqueRings.Any())
            {
                var recipe = new RecipeResult {
                    Instance = this, MatchedItems = new List <Item>()
                };

                for (var i = uniqueRings.Count - 1; i >= 0; i--)
                {
                    recipe.MatchedItems.Add(uniqueRings[i]);

                    uniqueRings.RemoveAt(i);

                    if (recipe.MatchedItems.Count == TOTAL_NEEDED_RINGS)
                    {
                        break;
                    }
                }

                recipe.PercentMatch = recipe.MatchedItems.Count / TOTAL_NEEDED_RINGS * 100;
                recipe.IsMatch      = recipe.PercentMatch >= ReturnMatchesGreaterThan;

                recipeResults.Add(recipe);
            }

            return(recipeResults);
        }
Example #16
0
        private IEnumerable <RecipeResult> findDuplicates(IEnumerable <POEApi.Model.Item> items, int setCount)
        {
            // Gear and AbyssJewel both have Rarity, but do not inherit it from a common parent class, so we need to
            // handle each subclass separately.
            IEnumerable <Item> gear = items.Where(i => i.Name != string.Empty &&
                                                  ((i is Gear && (i as Gear).Rarity != Rarity.Unique) ||
                                                   (i is AbyssJewel && (i as AbyssJewel).Rarity != Rarity.Unique)));

            List <RecipeResult> matches = new List <RecipeResult>();

            var itemKeys = gear.GroupBy(i => i.Name).Where(g => g.Count() > 1);

            foreach (var item in itemKeys)
            {
                var matchedItems = gear.Where(g => g.Name == item.Key)
                                   .Select(g => g as Item).ToList();

                while (matchedItems.Count > 0)
                {
                    var currentSet = matchedItems.Take(setCount).ToList();
                    matchedItems.RemoveRange(0, currentSet.Count);
                    Decimal percentMatch   = ((Decimal)currentSet.Count / setCount) * 100;
                    var     candidateMatch = new RecipeResult()
                    {
                        Instance     = this,
                        IsMatch      = percentMatch > base.ReturnMatchesGreaterThan,
                        MatchedItems = currentSet,
                        Missing      = new List <string>(),
                        PercentMatch = percentMatch
                    };
                    if (candidateMatch.IsMatch)
                    {
                        matches.Add(candidateMatch);
                    }
                }
            }

            return(matches);
        }
Example #17
0
 public virtual string GetResultName(RecipeResult result)
 {
     return(Name);
 }
Example #18
0
 public virtual string GetResultName(RecipeResult result)
 {
     return Name;
 }
Example #19
0
        public override string GetResultName(RecipeResult result)
        {
            bool useShortRecipeDescriptions = GetShouldUseShortRecipeDescriptions();

            if (result.MatchedItems.Any(i => i.ItemType == ItemType.Gear &&
                                        (i as Gear).Rarity == Rarity.Unique))
            {
                if (useShortRecipeDescriptions)
                {
                    return("5 Orbs of Chance - SBT, NMRU");
                }
                else
                {
                    return("5 Orbs of Chance - Same base type with normal, magic, rare, and unique");
                }
            }

            // All items have 20% quality and are either unidentified or normal rarity.
            if (result.MatchedItems.All(i => i.Quality == 20 &&
                                        (!i.Identified || (i is Gear && (i as Gear).Rarity == Rarity.Normal))))
            {
                if (useShortRecipeDescriptions)
                {
                    return("2 Orbs of Alchemy - SBT, NMR, 20% (U)");
                }
                else
                {
                    return("2 Orbs of Alchemy - Same base type with normal, magic, rare, 20% quality and unidentified");
                }
            }

            if (result.MatchedItems.All(i => i.Quality == 20))
            {
                if (useShortRecipeDescriptions)
                {
                    return("1 Orb of Alchemy - SBT, NMR, 20%");
                }
                else
                {
                    return("1 Orb of Alchemy - Same base type with normal, magic, rare, 20% quality");
                }
            }

            if (result.MatchedItems.All(i => !i.Identified || (i is Gear && (i as Gear).Rarity == Rarity.Normal)))
            {
                if (useShortRecipeDescriptions)
                {
                    return("2 Orbs of Augmentation - SBT, NMR, (U)");
                }
                else
                {
                    return("2 Orbs of Augmentation - Same base type with normal, magic, rare, unidentified");
                }
            }

            // base case
            if (useShortRecipeDescriptions)
            {
                return("1 Orb of Augmentation - SBT, NMR");
            }
            else
            {
                return("1 Orb of Augmentation - Same base type with normal, magic, and rare");
            }
        }