예제 #1
0
        /// <summary>
        /// Get Character Stats for multiple calls.  Allowing means by which to stack different sets/Special effects.
        /// </summary>
        /// <param name="character"></param>
        /// <param name="additionalItem"></param>
        /// <param name="sType">Enum describing which set of stats we want.</param>
        /// <returns></returns>
        private StatsDK GetCharacterStats(Character character, Item additionalItem, StatType sType, TankDKChar TDK, Rotation rot = null)
        {
            StatsDK statsTotal = new StatsDK();
            if (null == character.CalculationOptions)
            {
                // Possibly put some error text here.
                return statsTotal;
            }
            // Warning TDK can be blank at this point.
            TDK.Char = character;
            TDK.calcOpts = character.CalculationOptions as CalculationOptionsTankDK;
            TDK.bo = character.BossOptions;

            // Start populating data w/ Basic racial & class baseline.
            Stats BStats = BaseStats.GetBaseStats(character);
            statsTotal.Accumulate(BStats);
            statsTotal.BaseAgility = BStats.Agility;

            AccumulateItemStats(statsTotal, character, additionalItem);
            // Stack only the info we care about.
            statsTotal = GetRelevantStatsLocal(statsTotal);

            AccumulateBuffsStats(statsTotal, character.ActiveBuffs);
            AccumulateSetBonusStats(statsTotal, character.SetBonusCount);

            #region Tier Bonuses: Tank
            #region T11
            int tierCount;
            if (character.SetBonusCount.TryGetValue("Magma Plated Battlearmor", out tierCount))
            {
                if (tierCount >= 2) { statsTotal.b2T11_Tank = true; }
                if (tierCount >= 4) { statsTotal.b4T11_Tank = true; }
            }
            if (statsTotal.b4T11_Tank)
                statsTotal.AddSpecialEffect(_SE_IBF[1]);
            else
                statsTotal.AddSpecialEffect(_SE_IBF[0]);
            #endregion
            #region T12
            if (character.SetBonusCount.TryGetValue("Elementium Deathplate Battlearmor", out tierCount))
            {
                if (tierCount >= 2) { statsTotal.b2T12_Tank = true; }
                if (tierCount >= 4) { statsTotal.b4T12_Tank = true; }
            }
            if (statsTotal.b2T12_Tank)
            {
                // Your melee attacks cause Burning Blood on your target, 
                // which deals 800 Fire damage every 2 for 6 sec and 
                // causes your abilities to behave as if you had 2 diseases 
                // present on the target.
                // Implemented in CombatState DiseaseCount

                statsTotal.FireDamage = 800 / 2;
            }
            if (statsTotal.b4T12_Tank)
            {
                // Your when your Dancing Rune Weapon expires, it grants 15% additional parry chance for 12 sec.
                // Implemented in DRW talent Static Special Effect.
            }
            #endregion
            #region T13
            if (character.SetBonusCount.TryGetValue("Necrotic Boneplate Armor", out tierCount))
            {
                if (tierCount >= 2) { statsTotal.b2T13_Tank = true; }
                if (tierCount >= 4) { statsTotal.b4T13_Tank = true; }
            }
            if (statsTotal.b2T13_Tank)
            {
                // When an attack drops your health below 35%, one of your Blood Runes 
                // will immediately activate and convert into a Death Rune for the next 
                // 20 sec. This effect cannot occur more than once every 45 sec.
            }
            if (statsTotal.b4T13_Tank)
            {
                // Your Vampiric Blood ability also affects all party and raid members 
                // for 50% of the effect it has on you.
            }
            #endregion
            #endregion

            Rawr.DPSDK.CalculationsDPSDK.RemoveDuplicateRunes(statsTotal, character, true/*statsTotal.bDW*/);
            Rawr.DPSDK.CalculationsDPSDK.AccumulateTalents(statsTotal, character);
            Rawr.DPSDK.CalculationsDPSDK.AccumulatePresenceStats(statsTotal, Presence.Blood, character.DeathKnightTalents);


            statsTotal.ArcaneResistance += statsTotal.ArcaneResistanceBuff; statsTotal.ArcaneResistanceBuff = 0f;
            statsTotal.FireResistance   += statsTotal.FireResistanceBuff;   statsTotal.FireResistanceBuff   = 0f;
            statsTotal.FrostResistance  += statsTotal.FrostResistanceBuff;  statsTotal.FrostResistanceBuff  = 0f;
            statsTotal.NatureResistance += statsTotal.NatureResistanceBuff; statsTotal.NatureResistanceBuff = 0f;
            statsTotal.ShadowResistance += statsTotal.ShadowResistanceBuff; statsTotal.ShadowResistanceBuff = 0f;

            /* At this point, we're combined all the data from gear and talents and all that happy jazz.
             * However, we haven't applied any special effects nor have we applied any multipliers.
             * Many special effects are now getting dependant upon combat info (rotations).
             */
            StatsDK PreRatingsBase = statsTotal.Clone() as StatsDK;
            // Apply the ratings to actual stats.
            ProcessRatings(statsTotal);
            ProcessAvoidance(statsTotal, TDK.bo.Level, TDK.Char, PreRatingsBase);
            statsTotal.EffectiveParry = 0;
            if (character.MainHand != null)
            {
                statsTotal.EffectiveParry = statsTotal.Parry;
            }
            float fChanceToGetHit = 1f - Math.Min(1f, statsTotal.Miss + statsTotal.Dodge + statsTotal.EffectiveParry);

            // Now comes the special handling for secondary stats passes that are dependant upon Boss & Rotation values.
            if (sType != StatType.Unbuffed
                && (null != TDK.bo && null != rot)) // Make sure we have the rotation and Boss info.
            {
                #region Special Effects
                #region Talent: Bone Shield
                if (character.DeathKnightTalents.BoneShield > 0)
                {
                    int BSStacks = 4;  // The number of bones by default.  
                    if (Rawr.Properties.GeneralSettings.Default.PTRMode)
                        BSStacks = 6;  // The number of bones by default.  
                    float BoneLossRate = Math.Max(2f, TDK.bo.DynamicCompiler_Attacks.AttackSpeed / fChanceToGetHit);  // 2 sec internal cooldown on loosing bones so the DK can't get spammed to death.  
                    float moveVal = character.DeathKnightTalents.GlyphofBoneShield ? 0.15f : 0f;
                    SpecialEffect primary = new SpecialEffect(Trigger.Use,
                        new Stats() { DamageTakenReductionMultiplier = 0.20f, BonusDamageMultiplier = 0.02f, MovementSpeed = moveVal, },
                        BoneLossRate * BSStacks, 60) {BypassCache = true,};
                    statsTotal.AddSpecialEffect(primary);
                }
                #endregion
                #region Vengeance
                // Vengence has the chance to increase AP.
                int iVengenceMax = (int)(statsTotal.Stamina + (BaseStats.GetBaseStats(character).Health) * .1);
                int iAttackPowerMax = (int)statsTotal.AttackPower + iVengenceMax;
                float mitigatedDPS = TDK.bo.GetDPSByType(TDK.role, 0, statsTotal.DamageTakenReductionMultiplier,
                    0, .14f, statsTotal.Miss, statsTotal.Dodge, statsTotal.EffectiveParry, 0, 0,
                    0, 0, 0, 0, 0);
                    //statsTotal.ArcaneResistance, statsTotal.FireResistance, statsTotal.FrostResistance, statsTotal.NatureResistance, statsTotal.ShadowResistance);
                mitigatedDPS = mitigatedDPS * (1 - (float)StatConversion.GetArmorDamageReduction(TDK.bo.Level, statsTotal.Armor, 0f, 0f));
                float APStackSingle = mitigatedDPS * 0.05f * TDK.bo.DynamicCompiler_Attacks.AttackSpeed;
                int APStackCountMax = (int)Math.Floor(iVengenceMax / APStackSingle);
                SpecialEffect seVeng = new SpecialEffect(Trigger.DamageTaken,
                    new Stats() { AttackPower = APStackSingle },
                    2 * 10,
                    0,
                    1,
                    APStackCountMax) { BypassCache = true, };
                Dictionary<Trigger, float> triggerInterval = new Dictionary<Trigger,float>();
                Dictionary<Trigger, float> triggerChance = new Dictionary<Trigger,float>();
                triggerInterval.Add(Trigger.DamageTaken, TDK.bo.DynamicCompiler_Attacks.AttackSpeed);
                triggerChance.Add(Trigger.DamageTaken, 1f); // MitigatedDPS already factors in avoidance.
                statsTotal.VengenceAttackPower = seVeng.GetAverageStats(triggerInterval, triggerChance).AttackPower;
                statsTotal.AttackPower += statsTotal.VengenceAttackPower * TDK.calcOpts.VengeanceWeight;
                #endregion
                statsTotal.AddSpecialEffect(_SE_DeathPact);
                // For now we just factor them in once.
                Rawr.DPSDK.StatsSpecialEffects se = new Rawr.DPSDK.StatsSpecialEffects(rot.m_CT, rot, TDK.bo);
                StatsDK statSE = new StatsDK();

                foreach (SpecialEffect effect in statsTotal.SpecialEffects())
                {
                    if (HasRelevantStats(effect.Stats))
                    {
                        statSE.Accumulate(se.getSpecialEffects(effect));
//                        statsTotal.Accumulate(se.getSpecialEffects(effect)); // This is done further down.
                    }
                }

                // Darkmoon card greatness procs
                if (statSE.HighestStat > 0 || statSE.Paragon > 0)
                {
                    if (statSE.Strength >= statSE.Agility) { statSE.Strength += statSE.HighestStat + statSE.Paragon; }
                    else if (statSE.Agility > statSE.Strength) { statSE.Agility += statSE.HighestStat + statSE.Paragon; }
                    statSE.HighestStat = 0;
                    statSE.Paragon = 0;
                }

                // Any Modifiers from stats need to be applied to statSE
                statSE.Strength = StatConversion.ApplyMultiplier(statSE.Strength, statsTotal.BonusStrengthMultiplier);
                statSE.Agility = StatConversion.ApplyMultiplier(statSE.Agility, statsTotal.BonusAgilityMultiplier);
                statSE.Stamina = StatConversion.ApplyMultiplier(statSE.Stamina, statsTotal.BonusStaminaMultiplier);
                //            statSE.Stamina = (float)Math.Floor(statSE.Stamina);
                statSE.Armor = StatConversion.ApplyMultiplier(statSE.Armor, statsTotal.BaseArmorMultiplier);
                statSE.AttackPower = StatConversion.ApplyMultiplier(statSE.AttackPower, statsTotal.BonusAttackPowerMultiplier);
                statSE.BonusArmor = StatConversion.ApplyMultiplier(statSE.BonusArmor, statsTotal.BonusArmorMultiplier);

                statSE.Armor += statSE.BonusArmor;
                statSE.Health += StatConversion.GetHealthFromStamina(statSE.Stamina) + statSE.BattlemasterHealthProc;
                statSE.Health = statSE.Health * (1 + statSE.BonusHealthMultiplier);
                statsTotal.BonusHealthMultiplier = ((1 + statsTotal.BonusHealthMultiplier) * (1 + statSE.BonusHealthMultiplier)) - 1 ;
                if (character.DeathKnightTalents.BladedArmor > 0)
                {
                    statSE.AttackPower += (statSE.Armor / 180f) * (float)character.DeathKnightTalents.BladedArmor;
                }
                statSE.AttackPower += StatConversion.ApplyMultiplier((statSE.Strength * 2), statsTotal.BonusAttackPowerMultiplier);
                statSE.ParryRating += statSE.Strength * 0.27f;

                // Any Modifiers from statSE need to be applied to stats
                statsTotal.Strength = StatConversion.ApplyMultiplier(statsTotal.Strength, statSE.BonusStrengthMultiplier);
                statsTotal.Agility = StatConversion.ApplyMultiplier(statsTotal.Agility, statSE.BonusAgilityMultiplier);
                statsTotal.Stamina = StatConversion.ApplyMultiplier(statsTotal.Stamina, statSE.BonusStaminaMultiplier);
                //            stats.Stamina = (float)Math.Floor(stats.Stamina);
                statsTotal.Armor = StatConversion.ApplyMultiplier(statsTotal.Armor, statSE.BaseArmorMultiplier);
                statsTotal.AttackPower = StatConversion.ApplyMultiplier(statsTotal.AttackPower, statSE.BonusAttackPowerMultiplier);
                statsTotal.BonusArmor = StatConversion.ApplyMultiplier(statsTotal.BonusArmor, statSE.BonusArmorMultiplier);

                statsTotal.Accumulate(statSE);
                PreRatingsBase.Miss += statSE.Miss;
                PreRatingsBase.Dodge += statSE.Dodge;
                PreRatingsBase.Parry += statSE.Parry;
#if DEBUG
                if (float.IsNaN(statsTotal.Stamina))
                    throw new Exception("Something very wrong in stats.");
#endif
                #endregion // Special effects
            }
            // Apply the Multipliers
            ProcessStatModifiers(statsTotal, character.DeathKnightTalents.BladedArmor, character);
            ProcessAvoidance(statsTotal, TDK.bo.Level, TDK.Char, PreRatingsBase);
            if (character.MainHand != null)
            {
                statsTotal.EffectiveParry = statsTotal.Parry;
            }
            return (statsTotal);
        }
예제 #2
0
        /// <summary>
        /// GetCharacterStats is the 2nd-most calculation intensive method in a model. Here the model will
        /// combine all of the information about the character, including race, gear, enchants, buffs,
        /// calculationoptions, etc., to form a single combined Stats object. Three of the methods below
        /// can be called from this method to help total up stats: GetItemStats(character, additionalItem),
        /// GetEnchantsStats(character), and GetBuffsStats(character.ActiveBuffs).
        /// </summary>
        /// <param name="character">The character whose stats should be totaled.</param>
        /// <param name="additionalItem">An additional item to treat the character as wearing.
        /// This is used for gems, which don't have a slot on the character to fit in, so are just
        /// added onto the character, in order to get gem calculations.</param>
        /// <returns>A Stats object containing the final totaled values of all character stats.</returns>
        public override Stats GetCharacterStats(Character character, Item additionalItem) 
        {
            StatsDK statsTotal = new StatsDK();
            if (null == character)
            {
#if DEBUG
                throw new Exception("Character is Null");
#else
                return statsTotal;
#endif
            }
            CalculationOptionsDPSDK calcOpts = character.CalculationOptions as CalculationOptionsDPSDK;
            if (null == calcOpts) { calcOpts = new CalculationOptionsDPSDK(); }
            DeathKnightTalents talents = character.DeathKnightTalents;
            if (null == talents) { return statsTotal; }

            statsTotal.Accumulate(GetRaceStats(character));
            AccumulateItemStats(statsTotal, character, additionalItem);
            statsTotal = GetRelevantStats(statsTotal) as StatsDK; // GetRel removes any stats specific to the StatsDK object.

            statsTotal.bDW = false;
            if (character.MainHand != null && character.OffHand != null) statsTotal.bDW = true;
            RemoveDuplicateRunes(statsTotal, character, statsTotal.bDW);
            AccumulateBuffsStats(statsTotal, character.ActiveBuffs);

            #region Tank
            #region T11
            int tierCount;
            if (character.SetBonusCount.TryGetValue("Magma Plated Battlearmor", out tierCount))
            {
                if (tierCount >= 2) { statsTotal.b2T11_Tank = true; }
                if (tierCount >= 4) { statsTotal.b4T11_Tank = true; }
            }
            if (statsTotal.b4T11_Tank)
                statsTotal.AddSpecialEffect(_SE_IBF[1]);
            else
                statsTotal.AddSpecialEffect(_SE_IBF[0]);
            #endregion
            #region T12
            if (character.SetBonusCount.TryGetValue("Elementium Deathplate Battlearmor", out tierCount))
            {
                if (tierCount >= 2) { statsTotal.b2T12_Tank = true; }
                if (tierCount >= 4) { statsTotal.b4T12_Tank = true; }
            }
            if (statsTotal.b2T12_Tank)
            {
                // Your melee attacks cause Burning Blood on your target, 
                // which deals 800 Fire damage every 2 for 6 sec and 
                // causes your abilities to behave as if you had 2 diseases 
                // present on the target.

                // Implemented in CombatState DiseaseCount
                statsTotal.FireDamage = 800 / 2;
            }
            if (statsTotal.b4T12_Tank)
            {
                // Your Dancing Rune Weapon grants 15% additional parry chance.
                // Implemented in DRW talent Static Special Effect.
            }
            #endregion
            #region T13
            if (character.SetBonusCount.TryGetValue("Necrotic Boneplate Armor", out tierCount))
            {
                if (tierCount >= 2) { statsTotal.b2T13_Tank = true; }
                if (tierCount >= 4) { statsTotal.b4T13_Tank = true; }
            }
            if (statsTotal.b2T13_Tank)
            {
                // When an attack drops your health below 35%, one of your Blood Runes 
                // will immediately activate and convert into a Death Rune for the next 
                // 20 sec. This effect cannot occur more than once every 45 sec.
            }
            if (statsTotal.b4T13_Tank)
            {
                // Your Vampiric Blood ability also affects all party and raid members 
                // for 50% of the effect it has on you.
            }
            #endregion
            #endregion
            #region DPS
            #region T11
            if (character.SetBonusCount.TryGetValue("Magma Plated Battlegear", out tierCount))
            {
                if (tierCount >= 2)
                {
                    statsTotal.b2T11_DPS = true;
                    if (tierCount >= 4) { statsTotal.b4T11_DPS = true; }
                }
                if (statsTotal.b2T11_DPS)
                {
                    // increase the crit chance of your DeathCoil & FS by 5%
                    statsTotal.BonusCritChanceDeathCoil += .05f;
                    statsTotal.BonusCritChanceFrostStrike += .05f;
                }
                if (statsTotal.b4T11_DPS)
                {
                    // Each time you gain a Death Rune or trigger your Killing Machine talent, 
                    // you also gain 1% increased attack power for 30 sec. Stacks up to 3 times.
                    statsTotal.AddSpecialEffect(new SpecialEffect(Trigger.DeathRuneGained,
                        new Stats() { BonusAttackPowerMultiplier = 0.01f, },
                        30, 0, 1f, 3));
                    statsTotal.AddSpecialEffect(new SpecialEffect(Trigger.KillingMachine,
                        new Stats() { BonusAttackPowerMultiplier = 0.01f, },
                        30, 0, 1f, 3));
                }
            }
            #endregion
            #region T12
            if (character.SetBonusCount.TryGetValue("Elementium Deathplate Battlegear", out tierCount))
            {
                if (tierCount >= 2)
                {
                    statsTotal.b2T12_DPS = true;
                    if (tierCount >= 4)
                    {
                        
                        statsTotal.b4T12_DPS = true;
                    }
                }
            }
            if (statsTotal.b2T12_DPS)
            {
                // Horn of Winter also grats 3 RPp5
                statsTotal.RPp5 += 3;
            }
            if (statsTotal.b4T12_DPS)
            {
                // Your Obliterate and Scourge Strike abilities instantly deal 6% additional damage as Fire damage.
                // Implemented in Oblit and SS classes.
            }
            #endregion
            #region T13
            if (character.SetBonusCount.TryGetValue("Necrotic Boneplate Battlegear", out tierCount))
            {
                if (tierCount >= 2) { statsTotal.b2T13_DPS = true; }
                if (tierCount >= 4) { statsTotal.b4T13_DPS = true; }
            }
            if (statsTotal.b2T13_DPS)
            {
                // Sudden Doom has a 30% chance and Rime has a 60% chance 
                // to grant 2 charges when triggered instead of 1.
            }
            if (statsTotal.b4T13_DPS)
            {
                // Runic Empowerment has a 25% chance and Runic Corruption 
                // has a 40% chance to also grant 710 mastery rating for 12 sec when activated.
            }
            #endregion
            #endregion

            AccumulateTalents(statsTotal, character);
            AccumulatePresenceStats(statsTotal, calcOpts.presence, talents);

            return (statsTotal);
        }
예제 #3
0
        /// <summary>Build the talent effects.</summary>
        public static void AccumulateTalents(StatsDK FullCharacterStats, Character character)
        {
            Stats newStats = new Stats();
            FullCharacterStats.Mastery += StatConversion.GetMasteryFromRating(FullCharacterStats.MasteryRating);
            // Runic Focus:
            FullCharacterStats.SpellHit += 0.09f;

            // Which talent tree focus?
            #region Talent Speciality
            Rotation.Type r = GetSpec(character.DeathKnightTalents);
            switch (r)
            {
                case Rotation.Type.Blood:
                    {
                        // Special abilities for being blood
                        // Heart Strike
                        // Veteran of the third war
                        // Stamina +9%
                        FullCharacterStats.BonusStaminaMultiplier += .09f;
                        // Expertise +6
                        FullCharacterStats.Expertise += 6;
                        // Blood Rites
                        // Whenever you hit with Death Strike or Obliterate, the Frost and Unholy Runes 
                        // will become Death Runes when they activate.  Death Runes count as a Blood, Frost or Unholy Rune.
                        // Vengence
                        // Each time you take damage, you gain 5% of the damage taken as attack power, up to a maximum of 10% of your health.
                        // Mastery: Blood Shield
                        // Each Time you heal yourself w/ DS you gain a shield worth 50% of the amount healed
                        // Each Point of Mastery increases the shield by 6.25%
                        break;
                    }
                case Rotation.Type.Frost:
                    {
                        // Special abilities for being Frost
                        // Frost Strike
                        // Icy Talons
                        // Melee Attack speed +20%
                        FullCharacterStats.PhysicalHaste = AddStatMultiplierStat(FullCharacterStats.PhysicalHaste, .2f);
                        FullCharacterStats.BonusRuneRegeneration -= .2f; // Only this haste doesn't affect Rune Regen.  

                        // Blood of the North
                        // Blood runes are death runes.
                        // Mastery: Frozen Heart
                        // Increases all frost damage by 16%.  
                        // Each point of mastery increases frost damage by an additional 2.0%
                        FullCharacterStats.BonusFrostDamageMultiplier += .16f + (.02f * FullCharacterStats.Mastery);
                        break;
                    }
                case Rotation.Type.Unholy:
                    {
                        // Special abilities for being Unholy
                        // Scourge Strike
                        // Master of Ghouls
                        // Reduces the CD on Raise dead by 60 sec.
                        // The ghoul summoned is considered your pet w/o a limited duration.
                        // Reaping
                        // Whenever you hit with Blood strike, pestilence, or Festering strike, the runes spent will 
                        // become death runes when they activate.
                        // Unholy Might
                        // Str +25%
                        FullCharacterStats.BonusStrengthMultiplier += .25f;
                        // Mastery: Dreadblade.
                        // Increases shadow damage by 20% + 
                        // Each point of mastery increases shadow damage by an additional 2.5%
                        FullCharacterStats.BonusShadowDamageMultiplier += .2f + (.025f * FullCharacterStats.Mastery);
                        break;
                    }
            }
            #endregion

            #region Blood Talents
            // Butchery
            // 1RPp5 per Point
            if (character.DeathKnightTalents.Butchery > 0)
            {
                FullCharacterStats.RPp5 += 1 * character.DeathKnightTalents.Butchery;
            }

            // Blade Barrier
            // Reduce damage by 2% per point for 10 sec.
            if (character.DeathKnightTalents.BladeBarrier > 0)
            {
                // If you don't have your Blood Runes on CD, you're doing it wrong. 
                FullCharacterStats.DamageTakenReductionMultiplier = 1f - (1f - FullCharacterStats.DamageTakenReductionMultiplier) * (1f - .02f * character.DeathKnightTalents.BladeBarrier);
            }

            // Bladed Armor
            // 2 AP per point per 180 Armor
            if (character.DeathKnightTalents.BladedArmor > 0)
            {
                // If you don't have your Blood Runes on CD, you're doing it wrong. 
                FullCharacterStats.AttackPower += (2 * character.DeathKnightTalents.BladedArmor) * (FullCharacterStats.Armor / 180);
            }

            // Improved Blood Tap
            // Reduces Blood tap CD by 15 sec * pts.
           
            // Scent of Blood
            // 15% after Dodge, Parry or damage received causing 1 melee hit per point to generate 10 runic power.
            // Implemented in WhiteSwing.

            // Scarlet Fever
            // Those hit by BB do have a 50/100% chance to reduce damage dealt by 10% for 30 sec.
            if (character.DeathKnightTalents.ScarletFever > 0)
            {
                // Like Blade Barrier, this should always be up.
                // Be sure to put this in the rotation solver for Tanking Rotations.
                // JOTHAY TODO: Isn't this conflicting with the Buffs pane?
                FullCharacterStats.DamageTakenReductionMultiplier = 1f - (1f - FullCharacterStats.DamageTakenReductionMultiplier) * (1f - .05f * character.DeathKnightTalents.ScarletFever);
            }

            // Hand of Doom
            // Reduces the CD for Strangulate by 30/60 sec.

            if (r == Rotation.Type.Blood)
            {
                // Blood-Caked Blade
                // 10% chance per point to cause Blood-Caked strike
                // Implmented in WhiteDamage ability file.
                
                // Bone Shield
                // 6 Bones 
                // Takes 20% less damage from all sources
                // Does 2% more damage to target
                // Each damaging attack consumes a bone.
                // Lasts 5 mins

                // Toughness
                // Increases Armor Value from items by 3% per point.
                if (character.DeathKnightTalents.Toughness > 0)
                {
                    FullCharacterStats.BaseArmorMultiplier = AddStatMultiplierStat(FullCharacterStats.BaseArmorMultiplier, (.03f * character.DeathKnightTalents.Toughness));
                }

                // Abominations Might
                // increase AP by 5%/10% of raid.
                // 1% per point increase to str.
                if (character.DeathKnightTalents.AbominationsMight > 0)
                {
                    // This happens no matter what:
                    FullCharacterStats.BonusStrengthMultiplier += (0.01f * character.DeathKnightTalents.AbominationsMight);
                    // This happens only if there isn't Trueshot Aura/Unleashed Rage/Abom's might  available:
                    if (!(character.ActiveBuffsContains("Trueshot Aura") || character.ActiveBuffsContains("Unleashed Rage") || character.ActiveBuffsContains("Abomination's Might")))
                    {
                        FullCharacterStats.BonusAttackPowerMultiplier += (.05f * character.DeathKnightTalents.AbominationsMight);
                    }
                }

                // Sanguine Fortitude
                // Buff's IBF:
                // While Active, your IBF reduces Dam taken by 15/30% and costs 50/100% less RP to activate.
                // CD duration? 3min suggested on pwnwear.
                // Cost?  This is a CD stacker.
                // TODO: look into CD stacking code./max v average values.

                // Blood Parasite
                // Melee Attacks have 5% * PTS chance of spawning a blood worm.
                // Blood worm attacks your enemies, gorging itself on blood
                // until it bursts to heal nearby allies. Lasts 20 sec.
                if (character.DeathKnightTalents.BloodParasite > 0)
                {
                    float fDamageDone = 200f; // TODO: Put this in a way to increase DPS.
                    float fBWAttackSpeed = 1.4f; // TODO: Validate this speed.
                    float fBWDuration = 20f;
                    float avgstacks = 5; // TODO: Figure out the best way to determine avg Stacks of BloodGorged
                    float WormHealth = (FullCharacterStats.Health * 0.35f);
                    _SE_Bloodworms = new SpecialEffect[] {
                        null,
                        new SpecialEffect(Trigger.MeleeAttack, new Stats() { Healed = ((avgstacks * WormHealth * .05f) / fBWDuration), PhysicalDamage = (fDamageDone/fBWAttackSpeed) }, fBWDuration, 0, .05f * 1),
                        new SpecialEffect(Trigger.MeleeAttack, new Stats() { Healed = ((avgstacks * WormHealth * .05f) / fBWDuration), PhysicalDamage = (fDamageDone/fBWAttackSpeed) }, fBWDuration, 0, .05f * 2),
                    };
                    FullCharacterStats.AddSpecialEffect(_SE_Bloodworms[character.DeathKnightTalents.BloodParasite]);
                }

                // Improved Blood Presence
                // Reduces chance to be critically hit while in blood presence by 3/6%
                // In addition while in Frost or Unholy, retain the 2/4% Dam reduction. 
                // Implemented in AccumulatePresenceStats()

                // Will of the Necropolis
                // Dam that takes you below 35% health or while at less than 35% is reduced by 5% per point.  
                if (character.DeathKnightTalents.WillOfTheNecropolis > 0)
                {
                    // Need to factor in the damage taken aspect of the trigger.
                    // Using the assumption that the tank will be at < 35% health about that % of the time.
                    FullCharacterStats.AddSpecialEffect(_SE_WillOfTheNecropolis[character.DeathKnightTalents.WillOfTheNecropolis]);
                }

                // Rune Tap
                // Convert 1 BR to 10% health.
                if (character.DeathKnightTalents.RuneTap > 0)
                {
                    FullCharacterStats.AddSpecialEffect(_SE_RuneTap);
                }

                // Vampiric Blood
                // temp 15% of max health and
                // increases health generated by 25% for 10 sec.
                // 1 min CD. 
                if (character.DeathKnightTalents.VampiricBlood > 0)
                {
                    FullCharacterStats.AddSpecialEffect(_SE_VampiricBlood[character.DeathKnightTalents.GlyphofVampiricBlood ? 1 : 0]);
                }

                // Improved Death Strike
                if (character.DeathKnightTalents.ImprovedDeathStrike > 0)
                {
                    FullCharacterStats.BonusDamageDeathStrike += (.40f * character.DeathKnightTalents.ImprovedDeathStrike);
                    // Also improves DS Healing.  Implemented in TankDK heals section.
                }

                // Crimson Scourge 
                // Increases the damage dealt by your Blood Boil by 20/40%, and when you Plague Strike a target that is already
                // infected with your Blood Plague, there is a 50/100% chance that your next Blood Boil will consume no runes.
                if (character.DeathKnightTalents.CrimsonScourge > 0)
                {
                    // Part 1 implmented in BB Ability
                    // TODO: Part 2 implement in rotation.
                }

                // Dancing Rune Weapon
                if (character.DeathKnightTalents.DancingRuneWeapon > 0)
                {
                    uint u4T12 = FullCharacterStats.b4T12_Tank ? 1u : 0u;
                    uint uGDRW = character.DeathKnightTalents.GlyphofDancingRuneWeapon ? 1u : 0u;
                    FullCharacterStats.AddSpecialEffect(_SE_DRW[u4T12][uGDRW]);
                }
            }
            #endregion

            #region Frost Talents

            // Runic Power Mastery
            // Increases Max RP by 10 per point
            if (character.DeathKnightTalents.RunicPowerMastery > 0)
            {
                FullCharacterStats.BonusMaxRunicPower += 10 * character.DeathKnightTalents.RunicPowerMastery;
            }

            // Icy Reach
            // Increases range of IT & CoI and HB by 5 yards per point.

            // Nerves of Cold Steel
            // Increase hit w/ 1H weapons by 1% per point
            // Increase damage done by off hand weapons by 8/16/25% per point
            // Implement off-hand weapon buff in combat shot roation
            if (character.MainHand != null && 
                (character.MainHand.Slot == ItemSlot.MainHand
                || character.MainHand.Slot == ItemSlot.OneHand))
            {
                FullCharacterStats.PhysicalHit += (character.DeathKnightTalents.NervesOfColdSteel * .01f);
            }

            // Lichborne
            // for 10 sec, immune to charm, fear, sleep
            // CD 2 Mins

            // On a Pale Horse
            // Reduce duration of Movement slowing effects by 15% per point
            // increase mount speed by 10% per point
            if (character.DeathKnightTalents.OnAPaleHorse > 0)
            {
                // Now w/ boss handler, reduce the duration of the movement slowing effects. 
            }

            // Endless Winter
            // Mind Freeze RP cost is reduced by 50% per point.
            if (character.DeathKnightTalents.EndlessWinter > 0)
            {  }

            if (r == Rotation.Type.Frost)
            {
                // Merciless Combat
                // addtional 6% per point damage for IT, HB, Oblit, and FS
                // on targets of less than 35% health.
                if (character.DeathKnightTalents.MercilessCombat > 0)
                {
                    // implemented in the abilities section (increase the damage done by 15% * 35%)
                }

                // Chill of the Grave
                // CoI, HB, IT and Oblit generate 5 RP per point.
                if (character.DeathKnightTalents.ChillOfTheGrave > 0)
                {
                    // Implemented in the abilities.
                }

                // Killing Machine
                // Melee attacks have a chance to make OB, or FS a crit.
                // increased proc per point.
                // Research Suggests 5 PPM at 3/3
                if (character.DeathKnightTalents.KillingMachine > 0)
                {
//                    FullCharacterStats.AddSpecialEffect(_KM[character.DeathKnightTalents.KillingMachine]);
                    // Implemented in Frost Rotation
                }


                // Rime
                // Oblit has a 15% per point your next IT or HB consumes no runes
                if (character.DeathKnightTalents.Rime > 0)
                {
                    // Implemented in FrostRotation.
                }

                // Pillar of Frost
                // 1 min CD, 20 sec dur
                // Str +20%
                if (character.DeathKnightTalents.PillarOfFrost > 0)
                {
                    FullCharacterStats.AddSpecialEffect(_SE_PillarOfFrost);
                }

                // Improved Icy Talons
                // increases the melee haste of the group/raid by 10%
                // increases your haste by 5% all the time.
                if (character.DeathKnightTalents.ImprovedIcyTalons > 0)
                {
                    FullCharacterStats.PhysicalHaste = AddStatMultiplierStat(FullCharacterStats.PhysicalHaste, 0.05f);
                    if (!character.ActiveBuffsContains("Improved Icy Talons")
                        && !character.ActiveBuffsContains("Windfury Totem"))
                    {
                        FullCharacterStats.PhysicalHaste = AddStatMultiplierStat(FullCharacterStats.PhysicalHaste, .1f);
                        FullCharacterStats.RangedHaste += .1f;
                    }
                }

                // Brittle Bones:
                // Str +2% per point
                // FF chills the bones of its victims increasing damage taken by 2% per point.
                if (character.DeathKnightTalents.BrittleBones > 0)
                {
                    FullCharacterStats.BonusStrengthMultiplier += .02f * character.DeathKnightTalents.BrittleBones;
                    FullCharacterStats.BonusDamageMultiplier += .02f * character.DeathKnightTalents.BrittleBones;
                }

                // Chilblains
                // FF victimes are movement reduced 25% per point

                // Hungering Cold
                // Spell that freezes all enemies w/ 10 yards.


                // Improved Frost Presence
                // Increases your bonus damage while in Frost Presence by an additional 2% per point.  
                // In addition, while in Blood Presence or Unholy Presence, you retain 2% per point increased runic power generation from Frost Presence.
                if (character.DeathKnightTalents.ImprovedFrostPresence > 0)
                {
                    FullCharacterStats.BonusDamageMultiplier += (0.02f * character.DeathKnightTalents.ImprovedFrostPresence);
                }

                // Threat of Thassarian: 
                // When dual-wielding, your Death Strikes, Obliterates, Plague Strikes, 
                // Blood Strikes and Frost Strikes and Rune Strike (as of 3.2.2) have a 30/60/100% chance 
                // to also deal damage with your off-hand weapon. 
                if (character.DeathKnightTalents.ThreatOfThassarian > 0)
                { 
                    // implemented in the abilities
                }

                // Might of the Frozen Wastes
                // When wielding a two-handed weapon, your autoattacks have a 15% chance to generate 10 Runic Power.
                if (character.DeathKnightTalents.MightOfTheFrozenWastes > 0)
                {
                    // WhiteDamage Bonus in WhiteDamage Ability.
                    if (character.MainHand != null && character.MainHand.Slot == ItemSlot.TwoHand)
                        FullCharacterStats.BonusPhysicalDamageMultiplier += (.1f/3) * character.DeathKnightTalents.MightOfTheFrozenWastes;
                }

                // Howling Blast.
            }
            #endregion

            #region UnHoly Talents
            // Unholy Command
            // reduces CD of DG by 5 sec per point

            // Virulence
            // 
            if (character.DeathKnightTalents.Virulence > 0)
            {
                FullCharacterStats.BonusDiseaseDamageMultiplier += (.1f * character.DeathKnightTalents.Virulence);
            }

            // Epidemic
            // Increases Duration of BP and FF by 4 sec per point
            // Implemented in the abilities page.

            // Desecration
            // PS and SS cause Desecrated Ground effect.
            // Targets are slowed by 25% per point
            // Not Implemented.
            
            // Resilient Infection
            // When your diseases are dispelled you have a 50/100% to activate a 
            // Frost rune if FF was dispelled
            // Unholy rune if BP was dispelled
            // Not Implemented

            // Morbidity
            // increases dam & healing of DC by 5% per point
            // increases dam of DnD by 10% sec per point
            if (character.DeathKnightTalents.Morbidity > 0)
            {
                // implemented in abilities.
            }

            if (r == Rotation.Type.Unholy)
            {
                // Runic Corruption
                // Reduces the cost of your Death Coil by 3 per point, and causes 
                // your Runic Empowerment ability to no longer refresh a depleted 
                // rune, but instead to increase your rune regeneration rate by 50/100% for 3 sec.
                if (character.DeathKnightTalents.RunicCorruption > 0)
                {
                    // Implmented in rotation.
                }

                // Unholy Frenzy
                // Induces a friendly unit into a killing frenzy for 30 sec.  
                // The target is Enraged, which increases their melee and ranged haste by 20%, 
                // but causes them to lose health equal to 2% of their maximum health every 3 sec.
                // TODO:

                // Contagion
                // Increases the damage of your diseases spread via Pestilence by 50/100%.
                if (character.DeathKnightTalents.Contagion > 0)
                    FullCharacterStats.BonusDiseaseDamageMultiplier += .5f * character.DeathKnightTalents.Contagion;

                // Shadow Infusion
                // When you cast Death Coil, you have a 33% per point chance to empower your active Ghoul, 
                // increasing its damage dealt by 10% for 30 sec.  Stacks up to 5 times.
                // TODO: Implement in Rotation & Ghoul

                // Magic Suppression
                // AMS absorbs additional 8, 16, 25% of spell damage.

                // Rage of Rivendare
                // Increases the damage of your Plague Strike, Scourge Strike, and Festering Strike abilities by 15% per point.
                if (character.DeathKnightTalents.RageOfRivendare > 0)
                {
                    // Implemented in the abilities.
                }

                // Unholy Blight
                // Causes the victims of your Death Coil to be surrounded by a vile swarm of unholy insects, 
                // taking 10% of the damage done by the Death Coil over 10 sec, and preventing any diseases on the victim from being dispelled.
                // Implemented in the DeathCoil ability.

                // AntiMagic Zone
                // Creates a zone where party/raid members take 75% less spell damage
                // Lasts 10 secs or X damage.  
                if (character.DeathKnightTalents.AntiMagicZone > 0)
                {
                    FullCharacterStats.AddSpecialEffect(_SE_AntiMagicZone);
                }

                // Improved Unholy Presence
                // Grants you an additional 2% haste while in Unholy Presence.  
                // In addition, while in Blood Presence or Frost Presence, you retain 8% increased movement speed from Unholy Presence.
                // Implemented in Presence Stats.

                // Dark Transformation
                // Consume 5 charges of Shadow Infusion on your Ghoul to transform it into a powerful 
                // undead monstrosity for 30 sec.  The Ghoul's abilities are empowered and take on new 
                // functions while the transformation is active.
                // TODO: implement in Ghoul

                // Ebon Plaguebringer
                // Your Plague Strike, Icy Touch, Chains of Ice, and Outbreak abilities also infect 
                // their target with Ebon Plague, which increases damage taken from your diseases 
                // by 15/30% and all magic damage taken by an additional 8%.
                if (character.DeathKnightTalents.EbonPlaguebringer > 0)
                {
                    if (!character.ActiveBuffsContains("Earth and Moon")
                        && !character.ActiveBuffsContains("Curse of the Elements")
                        && !character.ActiveBuffsContains("Ebon Plaguebringer"))
                    {
                        float fBonus = .08f;
                        FullCharacterStats.BonusArcaneDamageMultiplier += fBonus;
                        FullCharacterStats.BonusFireDamageMultiplier += fBonus;
                        FullCharacterStats.BonusFrostDamageMultiplier += fBonus;
                        FullCharacterStats.BonusHolyDamageMultiplier += fBonus;
                        FullCharacterStats.BonusNatureDamageMultiplier += fBonus;
                        FullCharacterStats.BonusShadowDamageMultiplier += fBonus;
                    }
                    FullCharacterStats.BonusDiseaseDamageMultiplier += (.15f * character.DeathKnightTalents.EbonPlaguebringer);
                }

                // Sudden Doom
                // Your auto attacks have a 5% per point chance to make your next Death Coil cost no runic power.
                // TODO: To Implment in DeathCoil

                // Summon Gargoyle
            }
            #endregion
        }
예제 #4
0
        public override Stats GetRelevantStats(Stats stats)
        {
            StatsDK s = new StatsDK()
            {
                // Core stats
                Strength = stats.Strength,
                Agility = stats.Agility,
                Stamina = stats.Stamina,
                ExpertiseRating = stats.ExpertiseRating,
                AttackPower = stats.AttackPower,
                MasteryRating = stats.MasteryRating,
                // Other Base Stats
                HasteRating = stats.HasteRating,
                HitRating = stats.HitRating,
                CritRating = stats.CritRating,
                Armor = stats.Armor,
                BonusArmor = stats.BonusArmor,
                Resilience = stats.Resilience,

                // Secondary Stats
                Health = stats.Health,
                SpellHaste = stats.SpellHaste,
                PhysicalCrit = stats.PhysicalCrit,
                PhysicalHaste = stats.PhysicalHaste,
                PhysicalHit = stats.PhysicalHit,
                SpellCrit = stats.SpellCrit,
                SpellCritOnTarget = stats.SpellCritOnTarget,
                SpellHit = stats.SpellHit,
                SpellPenetration = stats.SpellPenetration,

                // Dam stats
                WeaponDamage = stats.WeaponDamage,
                PhysicalDamage = stats.PhysicalDamage,
                ShadowDamage = stats.ShadowDamage,
                ArcaneDamage = stats.ArcaneDamage,
                FireDamage = stats.FireDamage,
                FrostDamage = stats.FrostDamage,
                HolyDamage = stats.HolyDamage,
                NatureDamage = stats.NatureDamage,

                // Bonus to stat
                BonusHealthMultiplier = stats.BonusHealthMultiplier,
                BonusStrengthMultiplier = stats.BonusStrengthMultiplier,
                BonusStaminaMultiplier = stats.BonusStaminaMultiplier,
                BonusAgilityMultiplier = stats.BonusAgilityMultiplier,
                BonusCritDamageMultiplier = stats.BonusCritDamageMultiplier,
                BonusAttackPowerMultiplier = stats.BonusAttackPowerMultiplier,

                // Bonus to Dam
                // *Dam
                BonusWhiteDamageMultiplier = stats.BonusWhiteDamageMultiplier,
                BonusDamageMultiplier = stats.BonusDamageMultiplier,
                BonusPhysicalDamageMultiplier = stats.BonusPhysicalDamageMultiplier,
                BonusShadowDamageMultiplier = stats.BonusShadowDamageMultiplier,
                BonusFrostDamageMultiplier = stats.BonusFrostDamageMultiplier,
                BonusDiseaseDamageMultiplier = stats.BonusDiseaseDamageMultiplier,
                // +Dam
                BonusFrostWeaponDamage = stats.BonusFrostWeaponDamage,
                BonusDamageScourgeStrike = stats.BonusDamageScourgeStrike,
                BonusDamageBloodStrike = stats.BonusDamageBloodStrike,
                BonusDamageDeathCoil = stats.BonusDamageDeathCoil, 
                BonusDamageDeathStrike =  stats.BonusDamageDeathStrike,
                BonusDamageFrostStrike = stats.BonusDamageFrostStrike,
                BonusDamageHeartStrike = stats.BonusDamageHeartStrike,
                BonusDamageIcyTouch = stats.BonusDamageIcyTouch,
                BonusDamageObliterate = stats.BonusDamageObliterate,
                // Crit
                BonusCritChanceDeathCoil = stats.BonusCritChanceDeathCoil,
                BonusCritChanceFrostStrike = stats.BonusCritChanceFrostStrike,
                BonusCritChanceObliterate = stats.BonusCritChanceObliterate,
                // Other
                CinderglacierProc = stats.CinderglacierProc,
                HighestStat = stats.HighestStat,
                HighestSecondaryStat = stats.HighestSecondaryStat,
                Paragon = stats.Paragon,
                ThreatIncreaseMultiplier = stats.ThreatIncreaseMultiplier,
                ThreatReductionMultiplier = stats.ThreatReductionMultiplier,
                TargetArmorReduction = stats.TargetArmorReduction,
                // BossHandler
                SnareRootDurReduc = stats.SnareRootDurReduc,
                FearDurReduc = stats.FearDurReduc,
                StunDurReduc = stats.StunDurReduc,
                MovementSpeed = stats.MovementSpeed,
            };

            foreach (SpecialEffect effect in stats.SpecialEffects())
            {
                if (HasRelevantStats(effect.Stats))
                {
                    if (effect.Trigger == Trigger.DamageDone ||
                        effect.Trigger == Trigger.DamageOrHealingDone ||
                        effect.Trigger == Trigger.DamageSpellCast ||
                        effect.Trigger == Trigger.DamageSpellCrit ||
                        effect.Trigger == Trigger.DamageSpellHit ||
                        effect.Trigger == Trigger.SpellCast ||
                        effect.Trigger == Trigger.SpellCrit ||
                        effect.Trigger == Trigger.SpellHit ||
                        effect.Trigger == Trigger.DoTTick ||
                        effect.Trigger == Trigger.MeleeCrit ||
                        effect.Trigger == Trigger.MeleeHit ||
                        effect.Trigger == Trigger.CurrentHandHit ||
                        effect.Trigger == Trigger.MainHandHit ||
                        effect.Trigger == Trigger.OffHandHit ||
                        effect.Trigger == Trigger.PhysicalCrit ||
                        effect.Trigger == Trigger.PhysicalHit ||
                        effect.Trigger == Trigger.PhysicalAttack ||
                        effect.Trigger == Trigger.BloodStrikeHit ||
                        effect.Trigger == Trigger.HeartStrikeHit ||
                        effect.Trigger == Trigger.ScourgeStrikeHit ||
                        effect.Trigger == Trigger.ObliterateHit ||
                        effect.Trigger == Trigger.DeathStrikeHit ||
                        effect.Trigger == Trigger.IcyTouchHit ||
                        effect.Trigger == Trigger.PlagueStrikeHit ||
                        effect.Trigger == Trigger.RuneStrikeHit ||
                        effect.Trigger == Trigger.DeathRuneGained ||
                        effect.Trigger == Trigger.Use)
                    {
                        s.AddSpecialEffect(effect);
                    }
                }
            }

            return s;
        }