Beispiel #1
0
        // Computes accuracy.
        public void AccuracyRating(AttributeSet attrs)
        {
            Accuracy = attrs["+# Accuracy Rating"][0];
            // Local weapon accuracy bonus.
            if (Local.ContainsKey("+# to Accuracy Rating"))
            {
                Accuracy += Local["+# to Accuracy Rating"][0];
            }
            float incAcc = 0;

            // Local weapon accuracy bonus.
            if (Local.ContainsKey("#% increased Accuracy Rating"))
            {
                incAcc += Local["#% increased Accuracy Rating"][0];
            }
            // Gems & global bonuses.
            if (attrs.ContainsKey("+# to Accuracy Rating"))
            {
                Accuracy += attrs["+# to Accuracy Rating"][0];
            }
            if (attrs.ContainsKey("#% increased Accuracy Rating"))
            {
                incAcc += attrs["#% increased Accuracy Rating"][0];
            }
            if (attrs.ContainsKey("#% reduced Accuracy Rating"))
            {
                incAcc += attrs["#% reduced Accuracy Rating"][0];
            }
            foreach (var attr in attrs.Matches(ReIncreasedAccuracyRatingWithWeaponType))
            {
                Match      m = ReIncreasedAccuracyRatingWithWeaponType.Match(attr.Key);
                WeaponType weaponType;
                if (WithWeaponType.TryGetValue(m.Groups[2].Value, out weaponType) && Nature.Is(weaponType))
                {
                    incAcc += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                }
            }
            if (Compute.IsDualWielding && attrs.ContainsKey("#% increased Accuracy Rating while Dual Wielding"))
            {
                incAcc += attrs["#% increased Accuracy Rating while Dual Wielding"][0];
            }
            if (incAcc != 0)
            {
                Accuracy = IncreaseValueByPercentage(Accuracy, incAcc);
            }
        }
Beispiel #2
0
        List <float> GetValuePairOf(string gemName, string attr, int level, int quality = 0)
        {
            AttributeSet attrs = ItemDB.AttributesOf(gemName, level, quality);

            return(attrs.ContainsKey(attr) ? ItemDB.AttributesOf(gemName, level, quality)[attr] : new List <float> {
                float.NaN, float.NaN
            });
        }
Beispiel #3
0
            // Computes critical strike chance and multiplier.
            public void CriticalStrike(AttributeSet attrs)
            {
                // Critical chance.
                if (ResoluteTechnique) CriticalChance = 0;
                else
                {
                    if (CriticalChance > 0)
                    {
                        float incCC = 0;
                        if (attrs.ContainsKey("#% increased Critical Strike Chance"))
                            incCC += attrs["#% increased Critical Strike Chance"][0];
                        if (attrs.ContainsKey("#% increased Global Critical Strike Chance"))
                            incCC += attrs["#% increased Global Critical Strike Chance"][0];
                        if (IsWieldingStaff && attrs.ContainsKey("#% increased Global Critical Strike Chance while wielding a Staff"))
                            incCC += attrs["#% increased Global Critical Strike Chance while wielding a Staff"][0];
                        if (Nature.Is(DamageSource.Spell))
                        {
                            if (attrs.ContainsKey("#% increased Critical Strike Chance for Spells"))
                                incCC += attrs["#% increased Critical Strike Chance for Spells"][0];
                            if (attrs.ContainsKey("#% increased Global Critical Strike Chance for Spells"))
                                incCC += attrs["#% increased Global Critical Strike Chance for Spells"][0];
                        }
                        else // Attack
                        {
                            foreach (var attr in attrs.Matches(ReIncreasedCriticalChanceWithWeaponType))
                            {
                                Match m = ReIncreasedCriticalChanceWithWeaponType.Match(attr.Key);
                                if (WithWeaponType.ContainsKey(m.Groups[2].Value) && Nature.Is(WithWeaponType[m.Groups[2].Value]))
                                    incCC += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                            }
                            if (IsDualWielding && attrs.ContainsKey("#% increased Weapon Critical Strike Chance while Dual Wielding"))
                                incCC += attrs["#% increased Weapon Critical Strike Chance while Dual Wielding"][0];
                        }
                        // Form specific.
                        foreach (var attr in attrs.Matches(ReIncreasedCriticalChanceForm))
                        {
                            Match m = ReIncreasedCriticalChanceForm.Match(attr.Key);
                            if (DamageNature.Forms.ContainsKey(m.Groups[2].Value) && Nature.Is(DamageNature.Forms[m.Groups[2].Value]))
                                incCC += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                        }
                        if (incCC > 0)
                            CriticalChance = IncreaseValueByPercentage(CriticalChance, incCC);

                        // Critical chance can not be less than 5% nor more than 95%.
                        // @see http://pathofexile.gamepedia.com/Critical_Strike
                        if (CriticalChance < 5) CriticalChance = 5;
                        else if (CriticalChance > 95) CriticalChance = 95;

                        float incCM = 0;
                        if (attrs.ContainsKey("#% increased Critical Strike Multiplier"))
                            incCM += attrs["#% increased Critical Strike Multiplier"][0];
                        if (attrs.ContainsKey("#% increased Global Critical Strike Multiplier"))
                            incCM += attrs["#% increased Global Critical Strike Multiplier"][0];
                        if (IsWieldingStaff && attrs.ContainsKey("#% increased Global Critical Strike Multiplier while wielding a Staff"))
                            incCM += attrs["#% increased Global Critical Strike Multiplier while wielding a Staff"][0];
                        if (Nature.Is(DamageSource.Spell))
                        {
                            if (attrs.ContainsKey("#% increased Critical Strike Multiplier for Spells"))
                                incCM += attrs["#% increased Critical Strike Multiplier for Spells"][0];
                            if (attrs.ContainsKey("#% increased Global Critical Strike Multiplier for Spells"))
                                incCM += attrs["#% increased Global Critical Strike Multiplier for Spells"][0];
                        }
                        else // Attack
                        {
                            foreach (var attr in attrs.Matches(ReIncreasedCriticalMultiplierWithWeaponType))
                            {
                                Match m = ReIncreasedCriticalMultiplierWithWeaponType.Match(attr.Key);
                                if (WithWeaponType.ContainsKey(m.Groups[2].Value) && Nature.Is(WithWeaponType[m.Groups[2].Value]))
                                    incCM += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                            }
                            if (IsDualWielding && attrs.ContainsKey("#% increased Weapon Critical Strike Multiplier while Dual Wielding"))
                                incCM += attrs["#% increased Weapon Critical Strike Multiplier while Dual Wielding"][0];
                        }
                        // Form specific.
                        foreach (var attr in attrs.Matches(ReIncreasedCriticalMultiplierForm))
                        {
                            Match m = ReIncreasedCriticalMultiplierForm.Match(attr.Key);
                            if (DamageNature.Forms.ContainsKey(m.Groups[2].Value) && Nature.Is(DamageNature.Forms[m.Groups[2].Value]))
                                incCM += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                        }
                        if (incCM > 0)
                            CriticalMultiplier = IncreaseValueByPercentage(CriticalMultiplier, incCM);
                    }
                }
            }
Beispiel #4
0
            // Computes attacks or casts per second.
            public void AttackSpeed(AttackSkill skill, AttributeSet attrs)
            {
                if (Nature.Is(DamageSource.Attack))
                {
                    // If gem has own Attacks per Second, use it instead of weapon one.
                    if (skill.Local.ContainsKey("Attacks per Second: #"))
                    {
                        APS = skill.Local["Attacks per Second: #"][0];
                        // Apply local increased attack speed of weapon.
                        if (Local.ContainsKey("#% increased Attack Speed"))
                            APS = IncreaseValueByPercentage(APS, Local["#% increased Attack Speed"][0]);
                    }

                    float incAS = 0;
                    if (attrs.ContainsKey("#% increased Attack Speed"))
                        incAS += attrs["#% increased Attack Speed"][0];
                    if (attrs.ContainsKey("#% reduced Attack Speed"))
                        incAS -= attrs["#% reduced Attack Speed"][0];
                    if (attrs.ContainsKey("#% increased Attack and Cast Speed"))
                        incAS += attrs["#% increased Attack and Cast Speed"][0];
                    if (attrs.ContainsKey("#% reduced Attack and Cast Speed"))
                        incAS -= attrs["#% reduced Attack and Cast Speed"][0];
                    foreach (var attr in attrs.MatchesAny(new Regex[] { ReIncreasedAttackSpeedWithWeaponHandOrType, ReIncreasedAttackSpeedType }))
                    {
                        Match m = ReIncreasedAttackSpeedWithWeaponHandOrType.Match(attr.Key);
                        if (m.Success)
                        {
                            if (WithWeaponHand.ContainsKey(m.Groups[2].Value) && Nature.Is(WithWeaponHand[m.Groups[2].Value]))
                                incAS += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                            else if (WithWeaponType.ContainsKey(m.Groups[2].Value) && Nature.Is(WithWeaponType[m.Groups[2].Value]))
                                incAS += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                        }
                        else
                        {
                            m = ReIncreasedAttackSpeedType.Match(attr.Key);
                            if (m.Success)
                            {
                                // XXX: Not sure there are any mods with WeaponType here (Melee string in mod is DamageForm now, maybe Unarmed should be form as well).
                                if (Weapon.Types.ContainsKey(m.Groups[2].Value) && Nature.Is(Weapon.Types[m.Groups[2].Value]))
                                    incAS += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                                else
                                    if (DamageNature.Forms.ContainsKey(m.Groups[2].Value) && Nature.Is(DamageNature.Forms[m.Groups[2].Value]))
                                        incAS += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                            }
                        }
                    }
                    if (IsDualWielding && attrs.ContainsKey("#% increased Attack Speed while Dual Wielding"))
                        incAS += attrs["#% increased Attack Speed while Dual Wielding"][0];
                    if (incAS != 0)
                        APS = IncreaseValueByPercentage(APS, incAS);

                    float moreAS = 0;
                    if (attrs.ContainsKey("#% more Attack Speed"))
                        moreAS += attrs["#% more Attack Speed"][0];
                    if (attrs.ContainsKey("#% less Attack Speed"))
                        moreAS -= attrs["#% less Attack Speed"][0];
                    foreach (var attr in attrs.Matches(ReMoreAttackSpeedType))
                    {
                        Match m = ReMoreAttackSpeedType.Match(attr.Key);
                        if (m.Success)
                        {
                            // XXX: Not sure there are any mods with WeaponType here (Melee string in mod is DamageForm now, maybe Unarmed should be form as well).
                            if (Weapon.Types.ContainsKey(m.Groups[2].Value) && Nature.Is(Weapon.Types[m.Groups[2].Value]))
                                moreAS += m.Groups[1].Value == "more" ? attr.Value[0] : -attr.Value[0];
                            else if (DamageNature.Forms.ContainsKey(m.Groups[2].Value) && Nature.Is(DamageNature.Forms[m.Groups[2].Value]))
                                moreAS += m.Groups[1].Value == "more" ? attr.Value[0] : -attr.Value[0];
                        }
                    }
                    if (moreAS != 0)
                        APS = IncreaseValueByPercentage(APS, moreAS);

                    APS = RoundHalfDownEvenValue(APS, 2);
                }
                else // Spell (use Cast Time directly).
                {
                    float incCS = 0;
                    if (attrs.ContainsKey("#% increased Cast Speed"))
                        incCS += attrs["#% increased Cast Speed"][0];
                    if (attrs.ContainsKey("#% reduced Cast Speed"))
                        incCS -= attrs["#% reduced Cast Speed"][0];
                    if (attrs.ContainsKey("#% increased Attack and Cast Speed"))
                        incCS += attrs["#% increased Attack and Cast Speed"][0];
                    if (attrs.ContainsKey("#% reduced Attack and Cast Speed"))
                        incCS -= attrs["#% reduced Attack and Cast Speed"][0];
                    if (IsDualWielding && attrs.ContainsKey("#% increased Cast Speed while Dual Wielding"))
                        incCS += attrs["#% increased Cast Speed while Dual Wielding"][0];
                    if (incCS != 0)
                        CastTime = RoundValue(CastTime / ((100 + incCS) / 100), 3);

                    float moreCS = 0;
                    if (attrs.ContainsKey("#% more Cast Speed"))
                        moreCS += attrs["#% more Cast Speed"][0];
                    if (attrs.ContainsKey("#% less Cast Speed"))
                        moreCS -= attrs["#% less Cast Speed"][0];
                    if (moreCS != 0)
                        CastTime = FloorValue(CastTime / ((100 + moreCS) / 100), 3);

                    APS = RoundValue(1 / CastTime, 2);
                }
            }
Beispiel #5
0
 // Computes accuracy.
 public void AccuracyRating(AttributeSet attrs)
 {
     Accuracy = attrs["+# Accuracy Rating"][0];
     // Local weapon accuracy bonus.
     if (Local.ContainsKey("+# to Accuracy Rating"))
         Accuracy += Local["+# to Accuracy Rating"][0];
     float incAcc = 0;
     // Local weapon accuracy bonus.
     if (Local.ContainsKey("#% increased Accuracy Rating"))
         incAcc += Local["#% increased Accuracy Rating"][0];
     // Gems & global bonuses.
     if (attrs.ContainsKey("+# to Accuracy Rating"))
         Accuracy += attrs["+# to Accuracy Rating"][0];
     if (attrs.ContainsKey("#% increased Accuracy Rating"))
         incAcc += attrs["#% increased Accuracy Rating"][0];
     if (attrs.ContainsKey("#% reduced Accuracy Rating"))
         incAcc += attrs["#% reduced Accuracy Rating"][0];
     foreach (var attr in attrs.Matches(ReIncreasedAccuracyRatingWithWeaponType))
     {
         Match m = ReIncreasedAccuracyRatingWithWeaponType.Match(attr.Key);
         if (Nature.Is(WithWeaponType[m.Groups[2].Value]))
             incAcc += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
     }
     if (IsDualWielding && attrs.ContainsKey("#% increased Accuracy Rating while Dual Wielding"))
         incAcc += attrs["#% increased Accuracy Rating while Dual Wielding"][0];
     if (incAcc != 0)
         Accuracy = IncreaseValueByPercentage(Accuracy, incAcc);
 }
Beispiel #6
0
        // Initializes structures.
        public static void Initialize(SkillTree skillTree, ItemAttributes itemAttrs)
        {
            Items = itemAttrs.Equip.ToList();

            MainHand = new Weapon(WeaponHand.Main, Items.Find(i => i.Class == ItemClass.MainHand));
            OffHand = new Weapon(WeaponHand.Off, Items.Find(i => i.Class == ItemClass.OffHand));

            // If main hand weapon has Counts as Dual Wielding modifier, then clone weapon to off hand.
            // @see http://pathofexile.gamepedia.com/Wings_of_Entropy
            if (MainHand.Attributes.ContainsKey("Counts as Dual Wielding"))
                OffHand = MainHand.Clone(WeaponHand.Off);

            IsDualWielding = MainHand.IsWeapon() && OffHand.IsWeapon();
            if (IsDualWielding)
            {
                // Set dual wielded bit on weapons.
                MainHand.Hand |= WeaponHand.DualWielded;
                OffHand.Hand |= WeaponHand.DualWielded;
            }
            IsWieldingShield = MainHand.Is(WeaponType.Shield) || OffHand.Is(WeaponType.Shield);
            IsWieldingStaff = MainHand.Is(WeaponType.Staff);

            Level = skillTree.Level;
            if (Level < 1) Level = 1;
            else if (Level > 100) Level = 100;

            Global = new AttributeSet();

            Tree = new AttributeSet(skillTree.SelectedAttributesWithoutImplicit);
            Global.Add(Tree);

            // Keystones.
            Acrobatics = Tree.ContainsKey("#% Chance to Dodge Attacks. #% less Armour and Energy Shield, #% less Chance to Block Spells and Attacks");
            AvatarOfFire = Tree.ContainsKey("Deal no Non-Fire Damage");
            BloodMagic = Tree.ContainsKey("Removes all mana. Spend Life instead of Mana for Skills");
            ChaosInoculation = Tree.ContainsKey("Maximum Life becomes #, Immune to Chaos Damage");
            IronGrip = Tree.ContainsKey("The increase to Physical Damage from Strength applies to Projectile Attacks as well as Melee Attacks");
            IronReflexes = Tree.ContainsKey("Converts all Evasion Rating to Armour. Dexterity provides no bonus to Evasion Rating");
            NecromanticAegis = Tree.ContainsKey("All bonuses from an equipped Shield apply to your Minions instead of you");
            ResoluteTechnique = Tree.ContainsKey("Never deal Critical Strikes");
            VaalPact = Tree.ContainsKey("Life Leech applies instantly at #% effectiveness. Life Regeneration has no effect.");
            ZealotsOath = Tree.ContainsKey("Life Regeneration applies to Energy Shield instead of Life");

            Equipment = new AttributeSet();
            foreach (ItemAttributes.Attribute attr in itemAttrs.NonLocalMods)
                Equipment.Add(attr.TextAttribute, new List<float>(attr.Value));

            if (NecromanticAegis && OffHand.IsShield())
            {
                // Remove all bonuses of shield from equipment set.
                // @see http://pathofexile.gamepedia.com/Necromantic_Aegis
                foreach (var attr in OffHand.Attributes)
                    Equipment.Remove(attr);
                // Remove all bonuses from shield itself.
                OffHand.Attributes.Clear();
            }

            Global.Add(Equipment);

            CoreAttributes();

            Implicit = new AttributeSet(SkillTree.ImplicitAttributes(Global, Level));
            Global.Add(Implicit);

            // Innate dual wielding bonuses.
            // @see http://pathofexile.gamepedia.com/Dual_wielding
            if (IsDualWielding)
            {
                Global["#% more Attack Speed"] = new List<float>() { 10 };
                Global["#% more Physical Damage with Weapons"] = new List<float>() { 20 };
            }
        }
Beispiel #7
0
        // Computes critical strike chance and multiplier.
        public void CriticalStrike(AttributeSet attrs)
        {
            // Critical chance.
            if (Compute.ResoluteTechnique)
            {
                CriticalChance = 0;
            }
            else
            {
                if (CriticalChance > 0)
                {
                    float incCC = 0;
                    if (attrs.ContainsKey("#% increased Critical Strike Chance"))
                    {
                        incCC += attrs["#% increased Critical Strike Chance"][0];
                    }
                    if (attrs.ContainsKey("#% increased Global Critical Strike Chance"))
                    {
                        incCC += attrs["#% increased Global Critical Strike Chance"][0];
                    }
                    if (Compute.IsWieldingStaff && attrs.ContainsKey("#% increased Global Critical Strike Chance while wielding a Staff"))
                    {
                        incCC += attrs["#% increased Global Critical Strike Chance while wielding a Staff"][0];
                    }
                    if (Nature.Is(DamageSource.Spell))
                    {
                        if (attrs.ContainsKey("#% increased Critical Strike Chance for Spells"))
                        {
                            incCC += attrs["#% increased Critical Strike Chance for Spells"][0];
                        }
                        if (attrs.ContainsKey("#% increased Global Critical Strike Chance for Spells"))
                        {
                            incCC += attrs["#% increased Global Critical Strike Chance for Spells"][0];
                        }
                    }
                    else // Attack
                    {
                        foreach (var attr in attrs.Matches(ReIncreasedCriticalChanceWithWeaponType))
                        {
                            Match m = ReIncreasedCriticalChanceWithWeaponType.Match(attr.Key);
                            if (WithWeaponType.ContainsKey(m.Groups[2].Value) && Nature.Is(WithWeaponType[m.Groups[2].Value]))
                            {
                                incCC += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                            }
                        }
                        if (Compute.IsDualWielding && attrs.ContainsKey("#% increased Weapon Critical Strike Chance while Dual Wielding"))
                        {
                            incCC += attrs["#% increased Weapon Critical Strike Chance while Dual Wielding"][0];
                        }
                    }
                    // Form specific.
                    foreach (var attr in attrs.Matches(ReIncreasedCriticalChanceForm))
                    {
                        Match m = ReIncreasedCriticalChanceForm.Match(attr.Key);
                        if (DamageNature.Forms.ContainsKey(m.Groups[2].Value) && Nature.Is(DamageNature.Forms[m.Groups[2].Value]))
                        {
                            incCC += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                        }
                    }
                    if (incCC > 0)
                    {
                        CriticalChance = IncreaseValueByPercentage(CriticalChance, incCC);
                    }

                    // Critical chance can not be less than 5% nor more than 95%.
                    // @see http://pathofexile.gamepedia.com/Critical_Strike
                    if (CriticalChance < 5)
                    {
                        CriticalChance = 5;
                    }
                    else if (CriticalChance > 95)
                    {
                        CriticalChance = 95;
                    }

                    float incCM = 0;
                    if (attrs.ContainsKey("+#% to Critical Strike Multiplier"))
                    {
                        incCM += attrs["+#% to Critical Strike Multiplier"][0];
                    }
                    if (attrs.ContainsKey("+#% to Global Critical Strike Multiplier"))
                    {
                        incCM += attrs["+#% to Global Critical Strike Multiplier"][0];
                    }
                    if (Compute.IsWieldingStaff && attrs.ContainsKey("+#% to Global Critical Strike Multiplier while wielding a Staff"))
                    {
                        incCM += attrs["+#% to Global Critical Strike Multiplier while wielding a Staff"][0];
                    }
                    if (Nature.Is(DamageSource.Spell))
                    {
                        if (attrs.ContainsKey("+#% to Critical Strike Multiplier for Spells"))
                        {
                            incCM += attrs["+#% to Critical Strike Multiplier for Spells"][0];
                        }
                        if (attrs.ContainsKey("+#% to Global Critical Strike Multiplier for Spells"))
                        {
                            incCM += attrs["+#% to Global Critical Strike Multiplier for Spells"][0];
                        }
                    }
                    else // Attack
                    {
                        foreach (var attr in attrs.Matches(ReIncreasedCriticalMultiplierWithWeaponType))
                        {
                            Match m = ReIncreasedCriticalMultiplierWithWeaponType.Match(attr.Key);
                            if (WithWeaponType.ContainsKey(m.Groups[2].Value) && Nature.Is(WithWeaponType[m.Groups[2].Value]))
                            {
                                incCM += m.Groups[1].Value == "+" ? attr.Value[0] : -attr.Value[0];
                            }
                        }
                        if (Compute.IsDualWielding && attrs.ContainsKey("+#% to Weapon Critical Strike Multiplier while Dual Wielding"))
                        {
                            incCM += attrs["+#% to Weapon Critical Strike Multiplier while Dual Wielding"][0];
                        }
                    }
                    // Form specific.
                    foreach (var attr in attrs.Matches(ReIncreasedCriticalMultiplierForm))
                    {
                        Match m = ReIncreasedCriticalMultiplierForm.Match(attr.Key);
                        if (DamageNature.Forms.ContainsKey(m.Groups[2].Value) && Nature.Is(DamageNature.Forms[m.Groups[2].Value]))
                        {
                            incCM += m.Groups[1].Value == "+" ? attr.Value[0] : -attr.Value[0];
                        }
                    }
                    CriticalMultiplier += incCM;
                    if (attrs.ContainsKey("No Critical Strike Multiplier"))
                    {
                        CriticalMultiplier = 100;
                    }
                }
            }
        }
Beispiel #8
0
        // Computes attacks or casts per second.
        public void AttackSpeed(AttackSkill skill, AttributeSet attrs)
        {
            if (Nature.Is(DamageSource.Attack))
            {
                // If gem has own Attacks per Second, use it instead of weapon one.
                if (skill.Local.ContainsKey("Attacks per Second: #"))
                {
                    APS = skill.Local["Attacks per Second: #"][0];
                    // Apply local increased attack speed of weapon.
                    if (Local.ContainsKey("#% increased Attack Speed"))
                    {
                        APS = IncreaseValueByPercentage(APS, Local["#% increased Attack Speed"][0]);
                    }
                }

                float incAS = 0;
                if (attrs.ContainsKey("#% increased Attack Speed"))
                {
                    incAS += attrs["#% increased Attack Speed"][0];
                }
                if (attrs.ContainsKey("#% reduced Attack Speed"))
                {
                    incAS -= attrs["#% reduced Attack Speed"][0];
                }
                if (attrs.ContainsKey("#% increased Attack and Cast Speed"))
                {
                    incAS += attrs["#% increased Attack and Cast Speed"][0];
                }
                if (attrs.ContainsKey("#% reduced Attack and Cast Speed"))
                {
                    incAS -= attrs["#% reduced Attack and Cast Speed"][0];
                }
                foreach (var attr in attrs.MatchesAny(new Regex[] { ReIncreasedAttackSpeedWithWeaponHandOrType, ReIncreasedAttackSpeedType }))
                {
                    Match m = ReIncreasedAttackSpeedWithWeaponHandOrType.Match(attr.Key);
                    if (m.Success)
                    {
                        if (WithWeaponHand.ContainsKey(m.Groups[2].Value) && Nature.Is(WithWeaponHand[m.Groups[2].Value]))
                        {
                            incAS += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                        }
                        else if (WithWeaponType.ContainsKey(m.Groups[2].Value) && Nature.Is(WithWeaponType[m.Groups[2].Value]))
                        {
                            incAS += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                        }
                    }
                    else
                    {
                        m = ReIncreasedAttackSpeedType.Match(attr.Key);
                        if (m.Success)
                        {
                            // XXX: Not sure there are any mods with WeaponType here (Melee string in mod is DamageForm now, maybe Unarmed should be form as well).
                            if (Weapon.Types.ContainsKey(m.Groups[2].Value) && Nature.Is(Weapon.Types[m.Groups[2].Value]))
                            {
                                incAS += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                            }
                            else
                            if (DamageNature.Forms.ContainsKey(m.Groups[2].Value) && Nature.Is(DamageNature.Forms[m.Groups[2].Value]))
                            {
                                incAS += m.Groups[1].Value == "increased" ? attr.Value[0] : -attr.Value[0];
                            }
                        }
                    }
                }
                if (Compute.IsDualWielding && attrs.ContainsKey("#% increased Attack Speed while Dual Wielding"))
                {
                    incAS += attrs["#% increased Attack Speed while Dual Wielding"][0];
                }
                if (Compute.OffHand.IsShield() && attrs.ContainsKey("#% increased Attack Speed while holding a Shield"))
                {
                    incAS += attrs["#% increased Attack Speed while holding a Shield"][0];
                }
                if (incAS != 0)
                {
                    APS = IncreaseValueByPercentage(APS, incAS);
                }

                float moreAS = 1;
                if (attrs.ContainsKey("#% more Attack Speed"))
                {
                    moreAS *= 1 + attrs["#% more Attack Speed"][0] / 100;
                }
                if (attrs.ContainsKey("#% less Attack Speed"))
                {
                    moreAS *= 1 - attrs["#% less Attack Speed"][0] / 100;
                }
                foreach (var attr in attrs.Matches(ReMoreAttackSpeedType))
                {
                    Match m = ReMoreAttackSpeedType.Match(attr.Key);
                    if (m.Success)
                    {
                        // XXX: Not sure there are any mods with WeaponType here (Melee string in mod is DamageForm now, maybe Unarmed should be form as well).
                        if (Weapon.Types.ContainsKey(m.Groups[2].Value) && Nature.Is(Weapon.Types[m.Groups[2].Value]) ||
                            DamageNature.Forms.ContainsKey(m.Groups[2].Value) && Nature.Is(DamageNature.Forms[m.Groups[2].Value]))
                        {
                            moreAS *= m.Groups[1].Value == "more" ? 1 + attr.Value[0] / 100 : 1 - attr.Value[0] / 100;
                        }
                    }
                }
                APS = APS * moreAS;
                APS = RoundHalfDownEvenValue(APS, 2);
            }
            else // Spell (use Cast Time directly).
            {
                float incCS = 0;
                if (attrs.ContainsKey("#% increased Cast Speed"))
                {
                    incCS += attrs["#% increased Cast Speed"][0];
                }
                if (attrs.ContainsKey("#% reduced Cast Speed"))
                {
                    incCS -= attrs["#% reduced Cast Speed"][0];
                }
                if (attrs.ContainsKey("#% increased Attack and Cast Speed"))
                {
                    incCS += attrs["#% increased Attack and Cast Speed"][0];
                }
                if (attrs.ContainsKey("#% reduced Attack and Cast Speed"))
                {
                    incCS -= attrs["#% reduced Attack and Cast Speed"][0];
                }
                if (Compute.IsDualWielding && attrs.ContainsKey("#% increased Cast Speed while Dual Wielding"))
                {
                    incCS += attrs["#% increased Cast Speed while Dual Wielding"][0];
                }
                if (incCS != 0)
                {
                    CastTime = RoundValue(CastTime / ((100 + incCS) / 100), 3);
                }

                float moreCS = 0;
                if (attrs.ContainsKey("#% more Cast Speed"))
                {
                    moreCS += attrs["#% more Cast Speed"][0];
                }
                if (attrs.ContainsKey("#% less Cast Speed"))
                {
                    moreCS -= attrs["#% less Cast Speed"][0];
                }
                if (moreCS != 0)
                {
                    CastTime = FloorValue(CastTime / ((100 + moreCS) / 100), 3);
                }

                APS = RoundValue(1 / CastTime, 2);
            }
        }
Beispiel #9
0
        // Applies item modifiers.
        public void Apply(Item item)
        {
            // Add skill gem attributes.
            Local.Add(GemDB.Instance.AttributesOf(Gem, item));

            CreateSources();

            // Lists of damage added, increased and multipliers to apply.
            List <Damage.Added>     adds      = new List <Damage.Added>();
            List <Damage.Increased> increases = new List <Damage.Increased>();
            List <Damage.More>      mores     = new List <Damage.More>();

            // Collect damage conversions from gems, equipment and tree.
            // Collect damage added from gems and equipment.
            foreach (var attr in Local)
            {
                Damage.Converted conv = Damage.Converted.Create(DamageConversionSource.Gem, attr);
                if (conv != null)
                {
                    Converts.Add(conv);
                }

                // Damage added from gems is always applied.
                Damage.Added added = Damage.Added.Create(Nature.Source, attr);
                if (added != null)
                {
                    adds.Add(added);
                }
            }

            foreach (var attr in Equipment)
            {
                Damage.Converted conv = Damage.Converted.Create(DamageConversionSource.Equipment, attr);
                if (conv != null)
                {
                    Converts.Add(conv);
                }

                // Whether damage added from equipment applies to the current DamageSource is decided in Create().
                Damage.Added added = Damage.Added.Create(Nature.Source, attr);
                if (added != null)
                {
                    adds.Add(added);
                }
            }

            foreach (var attr in Tree)
            {
                Damage.Converted conv = Damage.Converted.Create(DamageConversionSource.Tree, attr);
                if (conv != null)
                {
                    Converts.Add(conv);
                }
            }

            // Merge local gems and global attributes.
            AttributeSet attrs = Compute.Global.Merge(Local);

            // Iron Grip.
            if (Compute.IronGrip || attrs.ContainsKey("Strength's damage bonus applies to Projectile Attacks made with Supported Skills"))
            {
                // Create projectile attack damage bonus from value of implicit melee physical damage increase.
                float bonus = Implicit["#% increased Melee Physical Damage"][0];
                attrs.AddAsSum("#% increased Projectile Weapon Damage", bonus);
            }

            // Iron Will.
            if (attrs.ContainsKey("Strength's damage bonus applies to Spell Damage as well for Supported Skills"))
            {
                // Create spell damage bonus from value of implicit melee physical damage increase.
                float bonus = Implicit["#% increased Melee Physical Damage"][0];
                attrs.AddAsSum("#% increased Spell Damage", bonus);
            }

            // Collect damage gains, increases and multipliers.
            foreach (var attr in attrs)
            {
                var gained = Damage.Gained.Create(attr);
                if (gained != null)
                {
                    Gains.Add(gained);
                }

                var increased = Damage.Increased.Create(attr);
                if (increased != null)
                {
                    increases.Add(increased);
                }

                var more = Damage.More.Create(attr, Compute);
                if (more != null)
                {
                    mores.Add(more);
                }
            }

            foreach (AttackSource source in Sources)
            {
                ApplyAttackSource(adds, increases, mores, attrs, source);
            }
        }
Beispiel #10
0
        public Computation(SkillTree skillTree, ItemAttributes itemAttrs)
        {
            Items = itemAttrs.Equip.ToList();

            MainHand = new Weapon(WeaponHand.Main, itemAttrs.MainHand);
            OffHand  = new Weapon(WeaponHand.Off, itemAttrs.OffHand);

            // If main hand weapon has Counts as Dual Wielding modifier, then clone weapon to off hand.
            // @see http://pathofexile.gamepedia.com/Wings_of_Entropy
            if (MainHand.Attributes.ContainsKey("Counts as Dual Wielding"))
            {
                OffHand = MainHand.Clone(WeaponHand.Off);
            }

            IsDualWielding = MainHand.IsWeapon() && OffHand.IsWeapon();
            if (IsDualWielding)
            {
                // Set dual wielded bit on weapons.
                MainHand.Hand |= WeaponHand.DualWielded;
                OffHand.Hand  |= WeaponHand.DualWielded;
            }
            IsWieldingShield = MainHand.Is(WeaponType.Shield) || OffHand.Is(WeaponType.Shield);
            IsWieldingStaff  = MainHand.Is(WeaponType.Staff);

            Level = skillTree.Level;
            if (Level < 1)
            {
                Level = 1;
            }
            else if (Level > 100)
            {
                Level = 100;
            }

            Tree = new AttributeSet(skillTree?.SelectedAttributesWithoutImplicit);
            Global.Add(Tree);

            // Keystones.
            Acrobatics        = Tree.ContainsKey("#% Chance to Dodge Attacks. #% less Armour and Energy Shield, #% less Chance to Block Spells and Attacks");
            AvatarOfFire      = Tree.ContainsKey("Deal no Non-Fire Damage");
            BloodMagic        = Tree.ContainsKey("Removes all mana. Spend Life instead of Mana for Skills");
            ChaosInoculation  = Tree.ContainsKey("Maximum Life becomes #, Immune to Chaos Damage");
            IronGrip          = Tree.ContainsKey("The increase to Physical Damage from Strength applies to Projectile Attacks as well as Melee Attacks");
            IronReflexes      = Tree.ContainsKey("Converts all Evasion Rating to Armour. Dexterity provides no bonus to Evasion Rating");
            NecromanticAegis  = Tree.ContainsKey("All bonuses from an equipped Shield apply to your Minions instead of you");
            ResoluteTechnique = Tree.ContainsKey("Never deal Critical Strikes");
            VaalPact          = Tree.ContainsKey("Life Leech applies instantly at #% effectiveness. Life Regeneration has no effect.");
            ZealotsOath       = Tree.ContainsKey("Life Regeneration applies to Energy Shield instead of Life");

            foreach (var attr in itemAttrs.NonLocalMods)
            {
                Equipment.Add(attr.Attribute, new List <float>(attr.Value));
            }

            if (NecromanticAegis && OffHand.IsShield())
            {
                // Remove all bonuses of shield from equipment set.
                // @see http://pathofexile.gamepedia.com/Necromantic_Aegis
                foreach (var attr in OffHand.Attributes)
                {
                    Equipment.Remove(attr);
                }
                // Remove all bonuses from shield itself.
                OffHand.Attributes.Clear();
            }

            Global.Add(Equipment);

            if (Global.ContainsKey("Armour received from Body Armour is doubled") &&
                itemAttrs.Armor != null)
            {
                var armorProp = itemAttrs.Armor.Properties.FirstOrDefault(m => m.Attribute == "Armour: #");
                if (armorProp != null && armorProp.Value.Any())
                {
                    Global["Armour: #"][0] += armorProp.Value[0];
                }
            }

            ComputeCoreAttributes();

            Implicit = new AttributeSet(SkillTree.ImplicitAttributes(Global, Level));
            Global.Add(Implicit);

            // Innate dual wielding bonuses.
            // @see http://pathofexile.gamepedia.com/Dual_wielding
            if (IsDualWielding)
            {
                Global["#% more Attack Speed"] = new List <float>()
                {
                    10
                };
                Global["#% more Physical Damage with Weapons"] = new List <float>()
                {
                    20
                };
            }
        }
Beispiel #11
0
        // Chance to Evade = 1 - Attacker's Accuracy / ( Attacker's Accuracy + (Defender's Evasion / 4) ^ 0.8 )
        // @see http://pathofexile.gamepedia.com/Evasion
        public float ChanceToEvade(int level, float evasionRating)
        {
            if (Global.ContainsKey("Cannot Evade enemy Attacks"))
            {
                return(0);                                                  // The modifier can be from other source than Unwavering Stance.
            }
            int maa = MonsterAverageAccuracy[level];

            return(RoundValue((float)(1 - maa / (maa + Math.Pow(evasionRating / 4, 0.8))) * 100, 0));
        }