public static FilterEconomyRuleSet Generate(ConcreteEconomyRules ruleHost, string segment)
        {
            float valueMultiplierEffectiveness = 0.4f;

            var builder = new RuleSetBuilder(ruleHost)
                          .SetSection(segment)
                          .UseCustomQuery(((s) => ruleHost.EconomyInformation.EconomyTierlistOverview["generalcrafting"][s]))
                          .AddDefaultPostProcessing()
                          .OverrideMinimalExaltedPriceThreshhold(60)
                          .AddDefaultIntegrationTarget();

            builder.AddRule("t1-86-economy", "eco",
                            new Func <string, bool>((string s) =>
            {
                if (!FilterPolishConfig.SpecialBases.Contains(s))
                {
                    return(false);
                }

                var price = Math.Max(GetPrice(86), GetPrice(85));
                return(price > FilterPolishConfig.BaseTypeT1BreakPoint * 1.5f);
            }));

            builder.AddRule("rest", "rest",
                            new Func <string, bool>((string s) =>
            {
                return(true);
            }));

            return(builder.Build());

            float GetPrice(int level)
            {
                if (level > 86)
                {
                    return(0);
                }

                if (builder.Item.ftPrice.ContainsKey(level))
                {
                    return(builder.Item.ftPrice[level]);
                }
                else
                {
                    return(GetPrice(level + 1));
                }
            }
        }
        public static FilterEconomyRuleSet Generate(ConcreteEconomyRules ruleHost)
        {
            var builder = new RuleSetBuilder(ruleHost)
                          .SetSection("currency")
                          // .SkipInEarlyLeague()
                          // .LimitExecutionMode(ExecutionMode.Function)
                          .UseDefaultQuery()
                          .OverrideMinimalExaltedPriceThreshhold(40)
                          .AddDefaultPostProcessing()
                          .AddDefaultIntegrationTarget();

            builder.AddRule("No Tiering", "???",
                            new Func <string, bool>((string s) =>
            {
                var isTierable = builder.Item.HasAspect("TierableCurrencyAspect");
                if (isTierable)
                {
                    return(false);
                }

                return(true);
            }));

            builder.AddSimpleComparisonRule("ExTier", "t11", FilterPolishConfig.ExaltedOrbPrice / 2);
            builder.AddSimpleComparisonRule("DivineTier", "t12", FilterPolishConfig.ExaltedOrbPrice / 5);
            builder.AddSimpleComparisonRule("SextantTier", "t21", 1.5f);

            // chaos level rules
            builder.AddSimpleComparisonRule("ChaosTier", "t22", 0.60f);
            builder.AddSimpleAspectContainerRule("ChaosBottom", "t22", "ChaosBottomAspect");

            // alchemy level rules
            builder.AddSimpleComparisonRule("AlchemyTier", "t23", 0.30f);
            builder.AddSimpleAspectContainerRule("AlchemyBottom", "t23", "AlchemyButtomAspect");
            builder.AddEarlyLeagueHandling("t23");

            builder.AddSimpleComparisonRule("SilverAltTier", "t31", 0.16f);
            builder.AddSimpleAspectContainerRule("AlchemyBottom", "t23", "SilverBottomAspect");

            builder.AddSimpleComparisonRule("ChanceTier", "t32", 0.06f);
            builder.AddSimpleAspectContainerRule("ChanceBottom", "t32", "ChanceBottomAspect");

            builder.AddExplicitRest("TransmuteTier", "t33");

            return(builder.Build());
        }
예제 #3
0
        public static FilterEconomyRuleSet Generate(ConcreteEconomyRules ruleHost)
        {
            var builder = new RuleSetBuilder(ruleHost)
                          .SetSection("currency->prophecy")
                          .UseDefaultQuery()
                          .AddDefaultPostProcessing()
                          .AddDefaultIntegrationTarget();

            builder.AddRule("ANCHOR", "ANCHOR",
                            new Func <string, bool>((string s) =>
            {
                return(builder.RuleSet.DefaultSet.HasAspect("AnchorAspect"));
            }));

            builder.AddRule("t1", "t1",
                            new Func <string, bool>((string s) =>
            {
                var price = builder.RuleSet.DefaultSet.LowestPrice;
                return(price > FilterPolishConfig.DiviT1BreakPoint);
            }));

            builder.AddRule("MultiBase", "t2",
                            new Func <string, bool>((string s) =>
            {
                var price = builder.RuleSet.DefaultSet.HighestPrice;
                return(price > FilterPolishConfig.DiviT1BreakPoint);
            }));

            builder.AddRule("t2", "t2",
                            new Func <string, bool>((string s) =>
            {
                var price = builder.RuleSet.DefaultSet.LowestPrice;
                return(price > FilterPolishConfig.DiviT2BreakPoint);
            }));

            builder.AddRule("rest", "rest",
                            new Func <string, bool>((string s) =>
            {
                return(true);
            }));

            return(builder.Build());
        }
예제 #4
0
        public static FilterEconomyRuleSet Generate(ConcreteEconomyRules ruleHost)
        {
            var builder = new RuleSetBuilder(ruleHost)
                          .SetSection("currency->prophecy")
                          .UseDefaultQuery()
                          .AddDefaultPostProcessing()
                          .AddDefaultIntegrationTarget();

            builder.AddRule("t1", "t1",
                            new Func <string, bool>((string s) =>
            {
                var price = builder.Item.LowestPrice;
                return(price > FilterPolishConfig.DiviT1BreakPoint);
            }));

            builder.AddRule("MultiBase", "t2",
                            new Func <string, bool>((string s) =>
            {
                var price = builder.Item.HighestPrice;
                return(price > FilterPolishConfig.DiviT1BreakPoint);
            }));

            builder.AddRule("t2", "t2",
                            new Func <string, bool>((string s) =>
            {
                var price = builder.Item.LowestPrice;
                return(price > FilterPolishConfig.DiviT2BreakPoint);
            }));

            builder.AddRule("t3mapping", "t3mapping",
                            new Func <string, bool>((string s) =>
            {
                return(builder.Item.HasAspect("MapUpgradeProphecyAspect"));
            }));

            builder.AddRule("t3", "t3",
                            new Func <string, bool>((string s) =>
            {
                var price = builder.Item.HighestPrice;

                if (price <= 1f)
                {
                    return(false);
                }

                var isDrop    = builder.Item.HasAspect("ItemDropProphecyAspect") ? 1.2f : 1f;
                var isCheap   = builder.Item.HasAspect("CheapProphecyAspect") ? 0.5f : 1f;
                var isUpgrade = builder.Item.HasAspect("ItemUpgradeProphecyAspect") ? 1.2f : 1f;

                // MapUpgrade Prophecies should be weighted towards the t3mapping tier
                // Doesn't matter right now since, mapping prophecies have priority over t3
                var mapUpgrade = builder.Item.HasAspect("MapUpgradeProphecyAspect") && !builder.Item.HasAspect("TimelessProphecyAspect") ? 0.5f : 1f;

                return(mapUpgrade * isUpgrade * price * isDrop * isCheap * 0.5f > FilterPolishConfig.DiviT5BreakPoint);
            }));

            builder.AddRule("t3timeless", "t3",
                            new Func <string, bool>((string s) =>
            {
                return(builder.Item.HasAspect("TimelessProphecyAspect") || builder.Item.HasAspect("PreventHidingAspect"));
            }));

            builder.AddRule("t4upgrade", "t4upgrade",
                            new Func <string, bool>((string s) =>
            {
                return(builder.Item.HasAspect("ItemUpgradeProphecyAspect"));
            }));

            builder.AddRule("t4drop", "t4drop",
                            new Func <string, bool>((string s) =>
            {
                return(builder.Item.HasAspect("ItemDropProphecyAspect"));
            }));

            builder.AddRule("t4", "t4",
                            new Func <string, bool>((string s) =>
            {
                return(true);
            }));

            return(builder.Build());
        }
예제 #5
0
        public static FilterEconomyRuleSet Generate(ConcreteEconomyRules ruleHost, string segment)
        {
            float valueMultiplierEffectiveness = 0.2f;

            var builder = new RuleSetBuilder(ruleHost)
                          .SetSection(segment)
                          .UseDefaultQuery()
                          .AddDefaultPostProcessing()
                          .SkipInEarlyLeague()
                          .AddDefaultIntegrationTarget();

            builder.AddRule("unknown", "unknown",
                            new Func <string, bool>((string s) =>
            {
                return(!ruleHost.EconomyInformation.EconomyTierlistOverview[segment].ContainsKey(s));
            }));

            builder.AddRule("t1-82", "t1-1",
                            new Func <string, bool>((string s) =>
            {
                if (builder.Item.ValueMultiplier < 0.85f)
                {
                    return(false);
                }

                var price = GetPrice(82) * (1 + ((builder.Item.ValueMultiplier - 1) * valueMultiplierEffectiveness));
                return(price > FilterPolishConfig.BaseTypeT1BreakPoint);
            }), nextgroup: "t2");


            builder.AddRule("t1-84", "t1-2",
                            new Func <string, bool>((string s) =>
            {
                if (builder.Item.ValueMultiplier < 0.75f)
                {
                    return(false);
                }

                var price = GetPrice(84) * (1 + ((builder.Item.ValueMultiplier - 1) * valueMultiplierEffectiveness));
                return(price > FilterPolishConfig.BaseTypeT1BreakPoint);
            }), nextgroup: "t2");

            builder.AddRule("t1-86", "t1-3",
                            new Func <string, bool>((string s) =>
            {
                if (builder.Item.ValueMultiplier < 0.65f)
                {
                    return(false);
                }

                var price = GetPrice(86) * (1 + ((builder.Item.ValueMultiplier - 1) * valueMultiplierEffectiveness));
                return(price > FilterPolishConfig.BaseTypeT1BreakPoint);
            }), nextgroup: "t2");

            builder.AddRule("t2-80", "t2-1",
                            new Func <string, bool>((string s) =>
            {
                var price = GetPrice(82) * (1 + ((builder.Item.ValueMultiplier - 1) * valueMultiplierEffectiveness));
                return(price > FilterPolishConfig.BaseTypeT2BreakPoint * 1.2);
            }), group: "t2");


            builder.AddRule("t2-85", "t2-2",
                            new Func <string, bool>((string s) =>
            {
                var price = (GetPrice(85) + GetPrice(86) / 2) * (1 + ((builder.Item.ValueMultiplier - 1) * valueMultiplierEffectiveness));
                return(price > FilterPolishConfig.BaseTypeT2BreakPoint);
            }), group: "t2");

            builder.AddRule("rest", "rest",
                            new Func <string, bool>((string s) =>
            {
                return(true);
            }));

            return(builder.Build());

            float GetPrice(int level)
            {
                if (level > 86)
                {
                    return(0);
                }

                if (builder.Item.ftPrice?.ContainsKey(level) == true)
                {
                    return(builder.Item.ftPrice[level]);
                }
                else
                {
                    return(GetPrice(level + 1));
                }
            }
        }
        public static FilterEconomyRuleSet Generate(ConcreteEconomyRules ruleHost)
        {
            var builder = new RuleSetBuilder(ruleHost)
                          .SetSection("fragments")
                          .UseDefaultQuery()
                          .OverrideMinimalExaltedPriceThreshhold(40)
                          .AddDefaultPostProcessing()
                          .SkipInEarlyLeague()
                          .AddDefaultIntegrationTarget();

            builder.AddRule("No Tiering", "???",
                            new Func <string, bool>((string s) =>
            {
                var isTierable = builder.Item.HasAspect("TierableFragmentAspect");
                if (isTierable)
                {
                    return(false);
                }

                return(true);
            }));

            builder.AddRule("t1", "t1",
                            new Func <string, bool>((string s) =>
            {
                var isPredictable = builder.Item.HasAspect("PredictableDropAspect");

                if (isPredictable)
                {
                    return(false);
                }

                var price = builder.Item.LowestPrice;
                return(price > FilterPolishConfig.MiscT1BreakPoint * 1.25f);
            }));

            builder.AddRule("t1 predictable", "t1p",
                            new Func <string, bool>((string s) =>
            {
                var isPredictable = builder.Item.HasAspect("PredictableDropAspect");
                var price         = builder.Item.LowestPrice;

                return(isPredictable && price > FilterPolishConfig.MiscT1BreakPoint * 1.25f);
            }));

            builder.AddRule("t2", "t2",
                            new Func <string, bool>((string s) =>
            {
                var price = builder.Item.LowestPrice;
                return(price > FilterPolishConfig.MiscT2BreakPoint * 1.25f);
            }));

            builder.AddRule("t3", "t3",
                            new Func <string, bool>((string s) =>
            {
                var price = builder.Item.LowestPrice;
                return(price > FilterPolishConfig.MiscT3BreakPoint);
            }));

            builder.AddEarlyLeagueHandling("t3");

            builder.AddRule("HidingPrevented", "t3",
                            new Func <string, bool>((string s) =>
            {
                return(builder.Item.HasAspect("PreventHidingAspect"));
            }));

            builder.AddExplicitRest("t4", "t4");

            return(builder.Build());
        }
        public static FilterEconomyRuleSet Generate(ConcreteEconomyRules ruleHost)
        {
            var builder = new RuleSetBuilder(ruleHost)
                          .SetSection("uniques")
                          .UseDefaultQuery()
                          .AddDefaultPostProcessing()
                          .AddDefaultIntegrationTarget();

            //var set = builder.Rulebuilder.Item.DefaultSet;

            builder.AddRule("unknown", "unknown",
                            new Func <string, bool>((string s) =>
            {
                return(!ruleHost.EconomyInformation.EconomyTierlistOverview["uniques"].ContainsKey(s));
            }));

            builder.AddRule("t1", "t1",
                            new Func <string, bool>((string s) =>
            {
                return(builder.Item.LowestPrice > FilterPolishConfig.UniqueT1BreakPoint);
            }));

            builder.AddRule("t2", "t2",
                            new Func <string, bool>((string s) =>
            {
                return(builder.Item.LowestPrice > FilterPolishConfig.UniqueT2BreakPoint);
            }));

            // builder.AddSimpleAspectContainerRule("EARLYBuffAspect", "t2", "BuffAspect");

            // items with one expensive rare version and one common, less rare verison are handled by this rule.
            builder.AddRule("uncommon", "multispecial",
                            new Func <string, bool>((string s) =>
            {
                var fit = false;
                if (builder.Item.HighestPrice > FilterPolishConfig.UniqueT2BreakPoint)
                {
                    if (builder.Item.HasAspect("UncommonAspect"))
                    {
                        var relevantList = builder.Item.AspectCheck(new HashSet <string>()
                        {
                            "UncommonAspect"
                        }, new HashSet <string>()
                        {
                            "BossDropAspect", "NonDropAspect", "LeagueDropAspect", "NonEventDropAspect"
                        });

                        if (relevantList.Count > 0)
                        {
                            return(relevantList.OrderByDescending(x => x.CVal).First().CVal > FilterPolishConfig.UniqueT2BreakPoint * FilterPolishConfig.UncommonAspectMultiplier);
                        }
                    }
                }

                return(fit);
            }));

            // items with expensive and non-expensive commonly droppable versions.
            builder.AddRule("ExpensiveTwin", "multispecial",
                            new Func <string, bool>((string s) =>
            {
                var relevantList = builder.Item.AspectCheck(new HashSet <string>()
                {
                    "HandledAspect"
                }, new HashSet <string>()
                {
                    "UncommonAspect", "BossDropAspect", "NonDropAspect", "LeagueDropAspect", "ProphecyResultAspect", "NonEventDropAspect"
                });

                if (relevantList.Count > 1)
                {
                    if (relevantList.Max(x => x.CVal) > FilterPolishConfig.UniqueT2BreakPoint * FilterPolishConfig.CommonTwinAspectMultiplier)
                    {
                        return(true);
                    }
                }

                return(false);
            }));

            // items with expensive and non-expensive commonly droppable versions.
            builder.AddRule("Expensive-Single-NonLeagueTwin", "multispecial",
                            new Func <string, bool>((string s) =>
            {
                var relevantList = builder.Item.AspectCheck(new HashSet <string>()
                {
                    "HandledAspect"
                }, new HashSet <string>()
                {
                    "UncommonAspect", "BossDropAspect", "NonDropAspect", "LeagueDropAspect", "ProphecyResultAspect", "NonEventDropAspect"
                });

                if (relevantList.Count == 1)
                {
                    if (relevantList.Max(x => x.CVal) > FilterPolishConfig.UniqueT2BreakPoint)
                    {
                        return(true);
                    }
                }

                return(false);
            }));

            builder.AddRule("highVariety", "multispecial",
                            new Func <string, bool>((string s) =>
            {
                var fit = false;
                if (builder.Item.HighestPrice > FilterPolishConfig.UniqueT2BreakPoint * FilterPolishConfig.HighVarietyMultiplier)
                {
                    if (builder.Item.HasAspect("HighVarietyAspect"))
                    {
                        var relevantList = builder.Item.AspectCheck(new HashSet <string>(), new HashSet <string>()
                        {
                            "BossDropAspect", "NonDropAspect", "LeagueDropAspect", "NonEventDropAspect"
                        });

                        if (relevantList.Count > 0)
                        {
                            return(relevantList.OrderByDescending(x => x.CVal).First().CVal > FilterPolishConfig.UniqueT2BreakPoint * FilterPolishConfig.HighVarietyMultiplier);
                        }
                    }
                }

                return(fit);
            }));

            builder.AddRule("leagueDropAspect", "multispecial",
                            new Func <string, bool>((string s) =>
            {
                var fit = false;
                if (builder.Item.HighestPrice > FilterPolishConfig.UniqueT2BreakPoint)
                {
                    if (builder.Item.HasAspect("LeagueDropAspect"))
                    {
                        var relevantList = builder.Item.AspectCheck(new HashSet <string>()
                        {
                            "LeagueDropAspect"
                        }, new HashSet <string>()
                        {
                            "BossDropAspect", "NonDropAspect", "NonEventDropAspect"
                        });

                        if (relevantList.Count > 0)
                        {
                            return(relevantList.OrderByDescending(x => x.CVal).First().CVal > FilterPolishConfig.UniqueT2BreakPoint * FilterPolishConfig.LeagueDropAspectMultiplier);
                        }
                    }
                }

                return(fit);
            }));

            builder.AddRule("BossOnly", "multispecial",
                            new Func <string, bool>((string s) =>
            {
                var fit = false;
                if (builder.Item.HighestPrice > FilterPolishConfig.UniqueT2BreakPoint)
                {
                    var relevantList = builder.Item.AspectCheck(new HashSet <string> {
                    }, new HashSet <string>()
                    {
                        "NonDropAspect"
                    });

                    if (relevantList.Count > 0 && relevantList.AllItemsFullFill(new HashSet <string>()
                    {
                        "BossDropAspect"
                    }, new HashSet <string>()))
                    {
                        return(relevantList.OrderByDescending(x => x.CVal).First().CVal > FilterPolishConfig.UniqueT2BreakPoint * FilterPolishConfig.LeagueDropAspectMultiplier);
                    }
                }

                return(fit);
            }));

            builder.AddEarlyLeagueHandling("earlyleague");

            // extremely high value multibases that usually drop from boss encounters, but can also drop from special league events
            builder.AddRule("SuperLeagueUnique", "multispecial",
                            new Func <string, bool>((string s) =>
            {
                if (builder.Item.HighestPrice > FilterPolishConfig.UniqueT1BreakPoint)
                {
                    var relevantList = builder.Item.AspectCheck(new HashSet <string>()
                    {
                        "LeagueDropAspect"
                    }, new HashSet <string>()
                    {
                        "NonDropAspect", "NonEventDropAspect"
                    });

                    if (relevantList.Count > 0)
                    {
                        return(relevantList.OrderByDescending(x => x.CVal).First().CVal > FilterPolishConfig.SuperTierBreakPoint);
                    }
                }
                return(false);
            }));

            builder.AddRule("ExpensiveOrBoss", "t3boss",
                            new Func <string, bool>((string s) =>
            {
                var bossDrop = builder.Item.HasAspect("BossDropAspect");
                return(bossDrop || builder.Item.LowestPrice < FilterPolishConfig.UniqueT2BreakPoint && builder.Item.HighestPrice > FilterPolishConfig.UniqueT2BreakPoint);
            }));

            builder.AddRule("prophecy", "prophecy",
                            new Func <string, bool>((string s) =>
            {
                var aspects = builder.RuleHost.ItemInformation["uniques", s];
                if (aspects == null)
                {
                    return(false);
                }

                return(builder.Item.HasAspect("ProphecyMaterialAspect"));
            }));

            builder.AddSimpleAspectContainerRule("EARLYNerfAspect", "t3", "NerfAspect");
            builder.AddEarlyLeagueProtectionBlock("t2", new HashSet <string>()
            {
                "t1"
            }, "earlyProtHIGH");
            builder.AddEarlyLeagueProtectionBlock("t3", new HashSet <string>()
            {
                "t2"
            }, "earlyProtLOW");

            builder.AddRule("hideable-nondrop", "hideable2",
                            new Func <string, bool>((string s) =>
            {
                var aspectTest = builder.Item.AllItemsFullFill(new HashSet <string>()
                {
                }, new HashSet <string>()
                {
                    "HighVarietyAspect", "NonEventDropAspect", "PreventHidingAspect"
                });

                if (!aspectTest)
                {
                    return(false);
                }


                var relevantListNonDrop = builder.Item.AspectCheck(new HashSet <string>()
                {
                    "NonDropAspect"
                }, new HashSet <string>()
                {
                });
                var relevantListRest = builder.Item.AspectCheck(new HashSet <string>()
                {
                }, new HashSet <string>()
                {
                    "NonDropAspect"
                });

                if (relevantListNonDrop.Count > 0)
                {
                    if (relevantListRest.Count > 0 && relevantListRest.Max(x => x.CVal > FilterPolishConfig.UniqueT2BreakPoint * 0.5f))
                    {
                        return(false);
                    }

                    return(true);
                }

                return(false);
            }));

            builder.AddRule("hideable", "hideable",
                            new Func <string, bool>((string s) =>
            {
                var relevantList = builder.Item.AspectCheck(new HashSet <string>()
                {
                }, new HashSet <string>()
                {
                    "NonDropAspect", "PreventHidingAspect"
                });

                if (relevantList.Count == 0)
                {
                    return(false);
                }

                var maxprice = relevantList.Max(x => x.CVal);
                if (maxprice > FilterPolishConfig.UniqueT2BreakPoint * 0.35f)
                {
                    return(false);
                }

                if (builder.Item.AllItemsFullFill(new HashSet <string>()
                {
                }, new HashSet <string>()
                {
                    "HighVarietyAspect", "LeagueDropAspect", "NonEventDropAspect", "BossDropAspect", "UncommonAspect", "PreventHidingAspect"
                }))
                {
                    return(true);
                }

                return(false);
            }));

            builder.AddExplicitRest("t3", "t3");

            return(builder.Build());
        }
예제 #8
0
        public static FilterEconomyRuleSet Generate(ConcreteEconomyRules ruleHost)
        {
            var builder = new RuleSetBuilder(ruleHost)
                          .SetSection("uniques")
                          .UseDefaultQuery()
                          .AddDefaultPostProcessing()
                          .AddDefaultIntegrationTarget();

            //var set = builder.Rulebuilder.RuleSet.DefaultSet.DefaultSet;

            builder.AddRule("ANCHOR", "ANCHOR",
                            new Func <string, bool>((string s) =>
            {
                return(builder.RuleSet.DefaultSet.HasAspect("AnchorAspect"));
            }));

            builder.AddRule("unknown", "unknown",
                            new Func <string, bool>((string s) =>
            {
                return(!ruleHost.EconomyInformation.EconomyTierlistOverview["uniques"].ContainsKey(s));
            }));

            builder.AddRule("t1", "t1",
                            new Func <string, bool>((string s) =>
            {
                return(builder.RuleSet.DefaultSet.LowestPrice > FilterPolishConfig.UniqueT1BreakPoint);
            }));

            builder.AddRule("t2", "t2",
                            new Func <string, bool>((string s) =>
            {
                return(builder.RuleSet.DefaultSet.LowestPrice > FilterPolishConfig.UniqueT2BreakPoint);
            }));

            builder.AddRule("uncommon", "multispecial",
                            new Func <string, bool>((string s) =>
            {
                var fit = false;
                if (builder.RuleSet.DefaultSet.HighestPrice > FilterPolishConfig.UniqueT2BreakPoint)
                {
                    if (builder.RuleSet.DefaultSet.HasAspect("UncommonAspect"))
                    {
                        var relevantList = builder.RuleSet.DefaultSet.AspectCheck(new HashSet <string>()
                        {
                            "UncommonAspect"
                        }, new HashSet <string>()
                        {
                            "BossDropAspect", "NonDropAspect", "LeagueDropAspect", "NonEventDropAspect"
                        });

                        if (relevantList.Count > 0)
                        {
                            return(relevantList.OrderByDescending(x => x.CVal).First().CVal > FilterPolishConfig.UniqueT2BreakPoint * FilterPolishConfig.UncommonAspectMultiplier);
                        }
                    }
                }

                return(fit);
            }));

            builder.AddRule("ExpensiveTwin", "multispecial",
                            new Func <string, bool>((string s) =>
            {
                var relevantList = builder.RuleSet.DefaultSet.AspectCheck(new HashSet <string>()
                {
                    "HandledAspect"
                }, new HashSet <string>()
                {
                    "UncommonAspect", "BossDropAspect", "NonDropAspect", "LeagueDropAspect", "ProphecyResultAspect", "NonEventDropAspect"
                });

                if (relevantList.Count > 1)
                {
                    if (relevantList.Max(x => x.CVal) > FilterPolishConfig.UniqueT2BreakPoint * FilterPolishConfig.CommonTwinAspectMultiplier)
                    {
                        return(true);
                    }
                }

                return(false);
            }));

            builder.AddRule("highVariety", "multispecial",
                            new Func <string, bool>((string s) =>
            {
                var fit = false;
                if (builder.RuleSet.DefaultSet.HighestPrice > FilterPolishConfig.UniqueT2BreakPoint * FilterPolishConfig.HighVarietyMultiplier)
                {
                    if (builder.RuleSet.DefaultSet.HasAspect("HighVarietyAspect"))
                    {
                        var relevantList = builder.RuleSet.DefaultSet.AspectCheck(new HashSet <string>(), new HashSet <string>()
                        {
                            "BossDropAspect", "NonDropAspect", "LeagueDropAspect", "NonEventDropAspect"
                        });

                        if (relevantList.Count > 0)
                        {
                            return(relevantList.OrderByDescending(x => x.CVal).First().CVal > FilterPolishConfig.UniqueT2BreakPoint * FilterPolishConfig.HighVarietyMultiplier);
                        }
                    }
                }

                return(fit);
            }));

            builder.AddRule("leagueDropAspect", "multileague",
                            new Func <string, bool>((string s) =>
            {
                var fit = false;
                if (builder.RuleSet.DefaultSet.HighestPrice > FilterPolishConfig.UniqueT2BreakPoint)
                {
                    if (builder.RuleSet.DefaultSet.HasAspect("LeagueDropAspect"))
                    {
                        var relevantList = builder.RuleSet.DefaultSet.AspectCheck(new HashSet <string>()
                        {
                            "LeagueDropAspect"
                        }, new HashSet <string>()
                        {
                            "BossDropAspect", "NonDropAspect", "NonEventDropAspect"
                        });

                        if (relevantList.Count > 0)
                        {
                            return(relevantList.OrderByDescending(x => x.CVal).First().CVal > FilterPolishConfig.UniqueT2BreakPoint * FilterPolishConfig.LeagueDropAspectMultiplier);
                        }
                    }
                }

                return(fit);
            }));

            builder.AddRule("BossOnly", "multispecial",
                            new Func <string, bool>((string s) =>
            {
                var fit = false;
                if (builder.RuleSet.DefaultSet.HighestPrice > FilterPolishConfig.UniqueT2BreakPoint)
                {
                    var relevantList = builder.RuleSet.DefaultSet.AspectCheck(new HashSet <string> {
                    }, new HashSet <string>()
                    {
                        "NonDropAspect"
                    });

                    if (relevantList.Count > 0 && relevantList.AllItemsFullFill(new HashSet <string>()
                    {
                        "BossDropAspect"
                    }, new HashSet <string>()))
                    {
                        return(relevantList.OrderByDescending(x => x.CVal).First().CVal > FilterPolishConfig.UniqueT2BreakPoint * FilterPolishConfig.LeagueDropAspectMultiplier);
                    }
                }

                return(fit);
            }));

            // uniques that have changed in the latest league
            //builder.AddRule("Changed?", "metainfluenced",
            //    new Func<string, bool>((string s) =>
            //    {
            //        return builder.RuleSet.DefaultSet.HasAspect("ChangedAspect");
            //    }));

            // usually used for new leagues
            //builder.AddRule("MetaSave", "t2",
            //    new Func<string, bool>((string s) =>
            //    {
            //        return builder.RuleSet.DefaultSet.HasAspect("MetaBiasAspect");
            //    }));

            builder.AddRule("EarlyLeagueInterest", "metainfluenced",
                            new Func <string, bool>((string s) =>
            {
                return(builder.RuleSet.DefaultSet.HasAspect("EarlyLeagueInterestAspect"));
            }));

            // extremely high value multibases that usually drop from boss encounters, but can also drop from special league events
            builder.AddRule("SuperLeagueUnique", "multileague",
                            new Func <string, bool>((string s) =>
            {
                if (builder.RuleSet.DefaultSet.HighestPrice > FilterPolishConfig.UniqueT1BreakPoint)
                {
                    var relevantList = builder.RuleSet.DefaultSet.AspectCheck(new HashSet <string>()
                    {
                        "BossDropAspect", "LeagueDropAspect"
                    }, new HashSet <string>()
                    {
                        "NonDropAspect", "NonEventDropAspect"
                    });

                    if (relevantList.Count > 0)
                    {
                        return(relevantList.OrderByDescending(x => x.CVal).First().CVal > FilterPolishConfig.SuperTierBreakPoint);
                    }
                }
                return(false);
            }));

            //builder.AddRule("???", "???",
            //    new Func<string, bool>((string s) =>
            //    {
            //        var fit = false;
            //        if (builder.RuleSet.DefaultSet.HighestPrice > FilterPolishConstants.T2BreakPoint)
            //        {
            //            if (builder.RuleSet.DefaultSet.HasAspect("LeagueDropAspect"))
            //            {
            //                return builder.RuleSet.DefaultSet.OfAspect("LeagueDropAspect").OrderByDescending(x => x.CVal).First().CVal > FilterPolishConstants.T2BreakPoint;
            //            }
            //        }

            //        return fit;
            //    }));

            builder.AddRule("prophecy", "prophecy",
                            new Func <string, bool>((string s) =>
            {
                var aspects = builder.RuleHost.ItemInformation["uniques", s];
                if (aspects == null)
                {
                    return(false);
                }

                return(builder.RuleSet.DefaultSet.HasAspect("ProphecyMaterialAspect"));
            }));

            builder.AddRule("hideable", "hideable",
                            new Func <string, bool>((string s) =>
            {
                var maxprice = builder.RuleSet.DefaultSet.Max(x => x.CVal);
                if (maxprice > FilterPolishConfig.UniqueT2BreakPoint * 0.35f)
                {
                    return(false);
                }

                if (builder.RuleSet.DefaultSet.AllItemsFullFill(new HashSet <string>()
                {
                }, new HashSet <string>()
                {
                    "HighVarietyAspect", "LeagueDropAspect", "NonEventDropAspect", "BossDropAspect", "EarlyLeagueInterestAspect", "IgnoreAspect", "UncommonAspect", "MetaBiasAspect", "AnchorAspect"
                }))
                {
                    return(true);
                }

                return(false);
            }));

            builder.AddRule("rest", "rest",
                            new Func <string, bool>((string s) =>
            {
                return(true);
            }));

            return(builder.Build());
        }