Exemple #1
0
        public void AddRule(string propertyName, RuleType ruleType)
        {
            var propertiesWithDuplicatesAllowed = new HashSet <ItemProperty>
            {
                ItemProperty.ElementalDamage,
                ItemProperty.SkillDamage
            };

            Func <ItemProperty, bool> allowedToAdd = p => Rules.All(r => r.ItemProperty != p) || propertiesWithDuplicatesAllowed.Contains(p);

            ItemProperty property;

            Core.Logger.Log("Attempting to Add {0} Type={1}", propertyName, ruleType);

            if (!Enum.TryParse(propertyName, out property))
            {
                return;
            }

            var allowed = allowedToAdd(property);

            if (property != ItemProperty.Unknown && allowed)
            {
                var id        = (int)property;
                var statRange = GetItemStatRange(property);
                if (statRange != null)
                {
                    Core.Logger.Verbose($"Stats Min = {statRange.AbsMin} Max = {statRange.AbsMax} Step = {statRange.AbsStep}");
                }

                Rules.Add(new LRule
                {
                    Id              = id,
                    ItemStatRange   = statRange,
                    ItemReference   = ItemReference,
                    TrinityItemType = TrinityItemType,
                    RuleType        = ruleType,
                    Value           = LRule.GetDefaultValue(property)
                });

                OnPropertyChanged(nameof(Rules));
                OnPropertyChanged(ruleType + "Rules");
            }
            else
            {
                if (!allowed)
                {
                    Core.Logger.Log("{0} has already been added and duplicates are not allowed", propertyName);
                }
            }
        }
        internal static bool ShouldStashItem(Item referenceItem, ACDItem cItem, bool test = false)
        {
            var id = referenceItem.Id;

            if (cItem.IsCrafted)
            {
                Core.Logger.Debug("  >>  Crafted Item {0} {1} - Auto-keeping", cItem.Name, id);
                return(true);
            }

            if (test)
            {
                var props = ItemDataUtils.GetPropertiesForItem(referenceItem);

                Core.Logger.Verbose($"------- Starting Test of {props.Count} supported properties for {cItem.Name}");

                foreach (var prop in props)
                {
                    if (prop == ItemProperty.Attribute)
                    {
                        continue;
                    }

                    var   range = ItemDataUtils.GetItemStatRange(referenceItem, prop);
                    float newValue;

                    var testrule = new LRule(prop)
                    {
                        Value = (float)range.AncientMax,
                    };

                    EvaluateProperty(testrule, cItem, out newValue);
                }

                Core.Logger.Verbose("------- Finished Test for {0} against max value", cItem.Name);
            }

            var itemSetting = Core.Settings.ItemList.SelectedItems.FirstOrDefault(i => referenceItem.Id == i.Id);

            if (itemSetting != null)
            {
                return(EvaluateRules(cItem, itemSetting, test));
            }

            Core.Logger.Log($"  >>  Unselected ListItem {cItem.Name} {cItem.ActorSnoId} GbId={cItem.GameBalanceId} IsValid={cItem.IsValid}");
            return(false);
        }
        internal static bool EvaluateProperty(LRule itemRule, ACDItem item, out float newValue)
        {
            var prop    = itemRule.ItemProperty;
            var value   = (float)itemRule.Value;
            var variant = itemRule.Variant;

            var    result          = false;
            string friendlyVariant = string.Empty;
            float  itemValue       = 0;
            float  ruleValue       = 0;
            float  returnValue     = -1;

            switch (prop)
            {
            case ItemProperty.PassivePower:
                itemValue   = ItemDataUtils.GetPassivePowerValue(item);
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.Ancient:
                itemValue   = item.Stats.IsAncient ? 1 : 0;
                ruleValue   = value;
                result      = item.Stats.IsAncient && Math.Abs(value - 1) < double.Epsilon;
                returnValue = ruleValue;
                break;

            case ItemProperty.PrimaryStat:
                itemValue   = item.Stats.HighestPrimaryAttribute;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.CriticalHitChance:
                itemValue   = item.Stats.CritPercent;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.CriticalHitDamage:
                itemValue   = item.Stats.CritDamagePercent;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.AttackSpeed:
                itemValue = item.Stats.AttackSpeedPercent;
                // TODO: Check if this is required.
                if (Math.Abs(itemValue) < double.Epsilon)
                {
                    itemValue = item.AttacksPerSecondItemPercent;
                }
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.ResourceCost:
                itemValue   = item.Stats.ResourceCostReductionPercent;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.Cooldown:
                itemValue   = item.Stats.PowerCooldownReductionPercent;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.ResistAll:
                itemValue   = item.Stats.ResistAll;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.Sockets:
                itemValue   = item.Stats.Sockets;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = ruleValue;
                break;

            case ItemProperty.Vitality:
                itemValue   = item.Stats.Vitality;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.AreaDamage:
                itemValue   = item.SplashDamageEffectPercent * 100f;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.Thorns:
                itemValue   = item.Stats.Thorns;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.FireSkills:
                itemValue   = item.Stats.FireSkillDamagePercentBonus;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.ColdSkills:
                itemValue   = item.Stats.ColdSkillDamagePercentBonus;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.LightningSkills:
                itemValue   = item.Stats.LightningSkillDamagePercentBonus;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.ArcaneSkills:
                itemValue   = item.Stats.ArcaneSkillDamagePercentBonus;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.HolySkills:
                itemValue   = item.Stats.HolySkillDamagePercentBonus;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.PoisonSkills:
                itemValue   = item.Stats.PosionSkillDamagePercentBonus;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.PhysicalSkills:
                itemValue   = item.Stats.PhysicalSkillDamagePercentBonus;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.DamageAgainstElites:
                itemValue   = item.Stats.DamagePercentBonusVsElites;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.DamageFromElites:
                itemValue   = item.Stats.DamagePercentReductionFromElites;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.BaseMaxDamage:
                itemValue   = item.Stats.MaxDamage;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.SkillDamage:
                var skillId = variant;
                var skill   = ItemDataUtils.GetSkillsForItemType(item.GetTrinityItemType(), Core.Player.ActorClass).FirstOrDefault(s => s.Id == skillId);
                if (skill != null)
                {
                    friendlyVariant = skill.Name;
                    itemValue       = item.SkillDamagePercent(skill.SNOPower) * 100;
                }
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.ElementalDamage:
                var elementId = variant;
                var element   = (Element)elementId;
                if (element != Element.Unknown)
                {
                    var damageType = TypeConversions.GetDamageType(element);
                    friendlyVariant = ((EnumValue <Element>)element).Name;
                    itemValue       = item.GetElementalDamage(damageType);
                }
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.PercentDamage:
                itemValue   = item.Stats.WeaponDamagePercent;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.CriticalHitsGrantArcane:
                itemValue   = item.Stats.ArcaneOnCrit;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.Armor:
                itemValue   = item.Stats.ArmorBonus;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.ChanceToBlock:
                itemValue   = item.Stats.BlockChanceBonus;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.ChanceToBlockTotal:
                itemValue   = item.Stats.BlockChance;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.HatredRegen:
                itemValue   = item.Stats.HatredRegen;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.LifePercent:
                itemValue   = item.Stats.LifePercent;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.LifePerHit:
                itemValue   = item.Stats.LifeOnHit;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.RegenerateLifePerSecond:
                itemValue   = item.Stats.HealthPerSecond;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.ManaRegen:
                itemValue   = item.Stats.ManaRegen;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.MovementSpeed:
                itemValue   = item.Stats.MovementSpeed;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.SpiritRegen:
                itemValue   = item.Stats.SpiritRegen;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.WrathRegen:
                itemValue   = item.Stats.FaithRegen;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.LifePerFury:
                itemValue   = item.Stats.HealPerFury;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.LifePerSpirit:
                itemValue   = item.Stats.HealPerSpirit;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.LifePerWrath:
                itemValue   = item.Stats.HealPerFaith;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.MaximumArcane:
                itemValue   = item.Stats.MaxArcanum;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.MaximumSpirit:
                itemValue   = item.Stats.MaxSpirit;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.MaximumDiscipline:
                itemValue   = item.Stats.MaxDiscipline;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.MaximumFury:
                itemValue   = item.Stats.MaxFury;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.MaximumMana:
                itemValue   = item.Stats.MaxMana;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.MaximumWrath:
                itemValue   = item.Stats.MaxFaith;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.ChanceToBlind:
                itemValue   = item.Stats.WeaponOnHitBlindProcChance;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.ChanceToFreeze:
                itemValue   = item.Stats.WeaponOnHitFreezeProcChance;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.ChanceToImmobilize:
                itemValue   = item.Stats.WeaponOnHitImmobilizeProcChance;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.ChanceToStun:
                itemValue   = item.Stats.WeaponOnHitStunProcChance;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.MaximumEssence:
                itemValue   = item.ResourceMaxEssence;
                ruleValue   = value;
                result      = itemValue >= ruleValue;
                returnValue = itemValue;
                break;

            case ItemProperty.Attribute:

                try
                {
                    friendlyVariant = $"{itemRule.AttributeKey} {itemRule.AttributeModifier} {itemRule.AttributeValue}";

                    var error = string.Empty;
                    var key   = itemRule.AttributeKey.Trim();
                    var mod   = itemRule.AttributeModifier.Trim();
                    var val   = itemRule.AttributeValue.Trim();

                    if (!Enum.TryParse(key, true, out ActorAttributeType attribute))
                    {
                        error += $"No ActorAttributeType exists with key '{itemRule.AttributeKey}'. ";
                    }

                    var modifierId = -1;
                    if (!string.IsNullOrEmpty(mod))
                    {
                        if (!int.TryParse(mod, out modifierId))
                        {
                            error += $"Modifier '{itemRule.AttributeModifier}' is not a number. ";
                        }
                    }

                    if (!float.TryParse(val, out value))
                    {
                        error += $"Value '{itemRule.AttributeModifier}' is not a number. ";
                    }

                    if (!string.IsNullOrEmpty(error))
                    {
                        Core.Logger.Warn($"Attribute specified in ItemList is invalid. {friendlyVariant} - {error}");
                        break;
                    }

                    itemValue   = item.GetAttribute <float>(attribute, modifierId);
                    ruleValue   = value;
                    result      = itemValue >= ruleValue;
                    returnValue = itemValue;
                }
                catch (Exception ex)
                {
                    Core.Logger.Error($"Exception evaluating ItemList rule Attribute {ex}");
                }
                break;
            }

            Core.Logger.Verbose($"  >>  Evaluated {item.Name} -- {prop.ToString().AddSpacesToSentence()} {friendlyVariant} (Item: {itemValue} -v- Rule: {ruleValue}) = {result}");
            newValue = returnValue;
            return(result);
        }