Exemple #1
0
        /// <summary>
        /// Instant, 1 min cd, Self (Any)
        /// Generates 10 rage at the cost of health and then generates an additional 10 rage over 10 sec.
        /// </summary>
        /// <TalentsAffecting>Improved Bloodrge [+(25*Pts)% Rage Generated], Intensify Rage [-(1/9*Pts]% Cooldown]</TalentsAffecting>
        /// <GlyphsAffecting>Glyph of Bloodrage [-100% Health Cost]</GlyphsAffecting>
        public Bloodrage(Character c, Stats s, CombatFactors cf, WhiteAttacks wa, CalculationOptionsDPSWarr co, BossOptions bo)
        {
            Char = c; StatS = s; combatFactors = cf; Whiteattacks = wa; CalcOpts = co; BossOpts = bo;
            //
            Name         = "Bloodrage";
            Description  = "Generates 10 rage at the cost of health and then generates an additional 10 rage over 10 sec.";
            AbilIterater = (int)Rawr.DPSWarr.CalculationOptionsDPSWarr.Maintenances.Bloodrage_;
            Cd           = 60f * (1f - 1f / 9f * Talents.IntensifyRage); // In Seconds
            Duration     = 10f;                                          // In Seconds
            // Rage is actually reversed in the rotation
            RageCost = -(20f                                             // Base
                         + 10f)                                          // Over Time
                       * (1f + Talents.ImprovedBloodrage * 0.25f);       // Talent Bonus
            StanceOkArms = StanceOkDef = StanceOkFury = true;
            Stats Base       = BaseStats.GetBaseStats(Char.Level, CharacterClass.Warrior, Char.Race);
            float baseHealth = Base.Health + StatConversion.GetHealthFromStamina(Base.Stamina, CharacterClass.Warrior);

            HealingBase  = -1f * (float)Math.Floor(baseHealth) * 0.16f;
            HealingBonus = (Talents.GlyphOfBloodrage ? 0f : 1f);
            UseHitTable  = false;
            UsesGCD      = false;
            UseReact     = true;
            //
            Initialize();
        }
Exemple #2
0
        public override Stats GetCharacterStats(Character character, Item additionalItem)
        {
            CalculationOptionsHealPriest calcOpts = character.CalculationOptions as CalculationOptionsHealPriest;

            StatsPriest statsTotal = new StatsPriest()
            {
                SpellHaste = PriestInformation.GetDarkness(character.PriestTalents.Darkness),
                InnerFire  = true,
                BonusIntellectMultiplier = 0.05f,   // Cloth bonus.
                PriestSpec = PriestSpec.GetPriestSpec(character.PriestTalents),
            };

            if (statsTotal.PriestSpec == ePriestSpec.Spec_Disc)
            {
                statsTotal.SpellCombatManaRegeneration = 0.5f;
                statsTotal.BonusIntellectMultiplier    = 0.15f;
            }
            else if (statsTotal.PriestSpec == ePriestSpec.Spec_Holy)
            {
                statsTotal.SpellCombatManaRegeneration = 0.5f + PriestInformation.GetHolyConcentration(character.PriestTalents.HolyConcentration);
                statsTotal.BonusHealingDoneMultiplier  = 0.15f;
            }
            else if (statsTotal.PriestSpec == ePriestSpec.Spec_ERROR)
            {
                throw new Exception("Unpossible Talent Spec!");
            }

            statsTotal.Accumulate(BaseStats.GetBaseStats(character));
            statsTotal.Accumulate(GetItemStats(character, additionalItem));
            statsTotal.Accumulate(GetBuffsStats(character, calcOpts));


            statsTotal.Stamina     = (float)Math.Floor((statsTotal.Stamina) * (1 + statsTotal.BonusStaminaMultiplier));
            statsTotal.Intellect   = (float)Math.Floor((statsTotal.Intellect) * (1 + statsTotal.BonusIntellectMultiplier));
            statsTotal.Spirit      = (float)Math.Floor((statsTotal.Spirit) * (1 + statsTotal.BonusSpiritMultiplier));
            statsTotal.SpellPower += (statsTotal.InnerFire ? PriestInformation.GetInnerFireSpellPowerBonus(character) : 0) + (statsTotal.Intellect - 10);
            statsTotal.SpellPower *= (1f + statsTotal.BonusSpellPowerMultiplier);
            statsTotal.Mana       += StatConversion.GetManaFromIntellect(statsTotal.Intellect);
            statsTotal.Mana       *= (1f + statsTotal.BonusManaMultiplier);
            statsTotal.Health     += StatConversion.GetHealthFromStamina(statsTotal.Stamina);
            statsTotal.Health      = (float)Math.Floor(statsTotal.Health * (1f + statsTotal.BonusHealthMultiplier));
            statsTotal.SpellCrit  += StatConversion.GetSpellCritFromIntellect(statsTotal.Intellect)
                                     + StatConversion.GetSpellCritFromRating(statsTotal.CritRating);
            statsTotal.SpellHaste = (1f + statsTotal.SpellHaste) * (1f + StatConversion.GetSpellHasteFromRating(statsTotal.HasteRating)) - 1f;
            statsTotal.Armor     *= (1 + (statsTotal.InnerFire ? PriestInformation.GetInnerFireArmorBonus(character) : 0));

            if (statsTotal.PriestSpec == ePriestSpec.Spec_Disc)
            {
                statsTotal.ShieldDiscipline = (PriestInformation.DisciplineMasteryBase + StatConversion.GetMasteryFromRating(statsTotal.MasteryRating)) * PriestInformation.DisciplineMasteryEffect;
            }
            else if (statsTotal.PriestSpec == ePriestSpec.Spec_Holy)
            {
                statsTotal.EchoofLight = (PriestInformation.HolyMasteryBase + StatConversion.GetMasteryFromRating(statsTotal.MasteryRating)) * PriestInformation.HolyMasteryEffect;
            }

            return(statsTotal);
        }
Exemple #3
0
        private void ConvertRatings(Stats stats, PaladinTalents talents, CalculationOptionsHealadin calcOpts)
        {
            stats.Stamina *= 1f + stats.BonusStaminaMultiplier;

            // Intellect is used to calculate initial mana pool.
            // To avoid temporary intellect from highest stat procs changing initial mana pool
            // we track temporary intellect separatly in HighestStat property and combine it with intellect
            // when needed.
            // TODO: However this doesn't help to deal with pure temporary intellect procs (if there are any).
            // NOTE: If we add highest stat to intellect after we calculate mana, the only visible change
            // will be the displayed intellect for the character.
            stats.Intellect   *= (1f + stats.BonusIntellectMultiplier);
            stats.HighestStat *= (1f + stats.BonusIntellectMultiplier);

            stats.SpellCrit = stats.SpellCrit +
                              StatConversion.GetSpellCritFromIntellect(
                stats.Intellect + stats.HighestStat,
                CharacterClass.Paladin) +
                              StatConversion.GetSpellCritFromRating(stats.CritRating, CharacterClass.Paladin);

            // I want to track haste before talent seperately, going to use RangedHaste for that.
            // I plan to use this on the "Stats" page so I can report sources of haste seperatly
            stats.RangedHaste = (1f + stats.SpellHaste) *
                                (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin))
                                - 1f;

            // calculating physical haste for use in melee attacks, which will generate mana
            // can also divide spellhaste / physicalhaste to get orignal value of spellhaste, which is from buffs as far as I can tell
            stats.PhysicalHaste = (1f + talents.JudgementsOfThePure * 0.03f) *
                                  (1f + talents.SpeedOfLight * 0.01f) *
                                  (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin))
                                  - 1f;

            stats.SpellHaste = (1f + talents.JudgementsOfThePure * 0.03f) *
                               (1f + talents.SpeedOfLight * 0.01f) *
                               (1f + stats.SpellHaste) *
                               (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin))
                               - 1f;

            // GetManaFromIntellect/GetHealthFromStamina account for the fact
            // that the first 20 Int/Sta only give 1 Mana/Health each.
            stats.Mana += StatConversion.GetManaFromIntellect(stats.Intellect, CharacterClass.Paladin) *
                          (1f + stats.BonusManaMultiplier);
            stats.Health += StatConversion.GetHealthFromStamina(stats.Stamina, CharacterClass.Paladin);

            stats.PhysicalHit += StatConversion.GetPhysicalHitFromRating(
                stats.HitRating,
                CharacterClass.Paladin);
        }
        private void ConvertRatings(Stats stats, PaladinTalents talents, CalculationOptionsHealadin calcOpts)
        {
            stats.Stamina *= 1f + stats.BonusStaminaMultiplier;

            // Intellect is used to calculate initial mana pool.
            // To avoid temporary intellect from highest stat procs changing initial mana pool
            // we track temporary intellect separatly in HighestStat property and combine it with intellect
            // when needed.
            // TODO: However this doesn't help to deal with pure temporary intellect procs (if there are any).
            // NOTE: If we add highest stat to intellect after we calculate mana, the only visible change
            // will be the displayed intellect for the character.
            stats.Intellect   *= (1f + stats.BonusIntellectMultiplier) * (1f + talents.DivineIntellect * .02f);
            stats.HighestStat *= (1f + stats.BonusIntellectMultiplier) * (1f + talents.DivineIntellect * .02f);

            stats.SpellPower += 0.04f * (stats.Intellect + stats.HighestStat) * talents.HolyGuidance;
            stats.SpellCrit   = stats.SpellCrit +
                                StatConversion.GetSpellCritFromIntellect(
                stats.Intellect + stats.HighestStat,
                CharacterClass.Paladin) +
                                StatConversion.GetSpellCritFromRating(stats.CritRating, CharacterClass.Paladin) +
                                talents.SanctityOfBattle * .01f +
                                talents.Conviction * .01f;

            stats.SpellHaste = (1f + talents.JudgementsOfThePure * (calcOpts.JotP ? .03f : 0f)) *
                               (1f + stats.SpellHaste) *
                               (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin))
                               - 1f;

            // GetManaFromIntellect/GetHealthFromStamina account for the fact
            // that the first 20 Int/Sta only give 1 Mana/Health each.
            stats.Mana += StatConversion.GetManaFromIntellect(stats.Intellect, CharacterClass.Paladin) *
                          (1f + stats.BonusManaMultiplier);
            stats.Health += StatConversion.GetHealthFromStamina(stats.Stamina, CharacterClass.Paladin);

            stats.PhysicalHit += StatConversion.GetPhysicalHitFromRating(
                stats.HitRating,
                CharacterClass.Paladin);
        }
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string> dictValues = new Dictionary <string, string>();

            dictValues.Add("DPS Points", DPS.ToString("F2", CultureInfo.InvariantCulture));
            dictValues.Add("Survivability Points", Survivability.ToString("F2", CultureInfo.InvariantCulture));
            dictValues.Add("Overall Points", OverallPoints.ToString("F2", CultureInfo.InvariantCulture));

            dictValues.Add("Health", BasicStats.Health.ToString("F0", CultureInfo.InvariantCulture));
            dictValues.Add("Mana", BasicStats.Mana.ToString("F0", CultureInfo.InvariantCulture));
            dictValues.Add("Strength", String.Format("{0}*Increases Attack Power by {1}",
                                                     BasicStats.Strength.ToString("F0", CultureInfo.InvariantCulture),
                                                     (BasicStats.Strength - 10f).ToString("F0", CultureInfo.InvariantCulture)));
            dictValues.Add("Agility", String.Format("{0}*Increases Attack Power by {1}\r\nIncreases Critical Hit chance by {2}%",
                                                    BasicStats.Agility.ToString("F0", CultureInfo.InvariantCulture),
                                                    ((BasicStats.Agility * 2f) - 20f).ToString("F0", CultureInfo.InvariantCulture),
                                                    (StatConversion.GetCritFromAgility(BasicStats.Agility, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Stamina", String.Format("{0}*Increase Health by {1}",
                                                    BasicStats.Stamina.ToString("F0", CultureInfo.InvariantCulture),
                                                    (StatConversion.GetHealthFromStamina(BasicStats.Stamina)).ToString("F0", CultureInfo.InvariantCulture)));
            dictValues.Add("Intellect", String.Format("{0}*Increases Mana by {1}\r\nIncreases Spell Power by {2}\r\nIncreases Spell Critical Hit chance by {3}%",
                                                      BasicStats.Intellect.ToString("F0", CultureInfo.InvariantCulture),
                                                      (StatConversion.GetManaFromIntellect(BasicStats.Intellect)).ToString("F0", CultureInfo.InvariantCulture),
                                                      (BasicStats.Intellect - 10f).ToString("F0", CultureInfo.InvariantCulture),
                                                      (StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Spirit", String.Format("{0}*Increases mana regeneration by {1} every 5 seconds while not casting",
                                                   BasicStats.Spirit.ToString("F0", CultureInfo.InvariantCulture),
                                                   (StatConversion.GetSpiritRegenSec(BasicStats.Spirit, BasicStats.Intellect) * 5f).ToString("F0", CultureInfo.InvariantCulture)));
            dictValues.Add("Mastery", String.Format("{0}*Mastery rating of {1} adds {2} Mastery\r\nIncreases all Fire, Frost, and Nature Damage by {3}%.",
                                                    (8f + StatConversion.GetMasteryFromRating(BasicStats.MasteryRating)).ToString("F2", CultureInfo.InvariantCulture),
                                                    BasicStats.MasteryRating.ToString("F0", CultureInfo.InvariantCulture),
                                                    (StatConversion.GetMasteryFromRating(BasicStats.MasteryRating)).ToString("F2", CultureInfo.InvariantCulture),
                                                    ((8f + StatConversion.GetMasteryFromRating(BasicStats.MasteryRating)) * 2.5f).ToString("F2", CultureInfo.InvariantCulture)));

            //dictValues.Add("Damage"
            //dictValues.Add("DPS"
            dictValues.Add("Attack Power", BasicStats.AttackPower.ToString("F0", CultureInfo.InvariantCulture));
            //dictValues.Add("Speed"
            dictValues.Add("Melee Haste", String.Format("{0}%*Haste Rating of {1} adds {2}% Haste",
                                                        (StatConversion.GetHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                        BasicStats.HasteRating.ToString("F0", CultureInfo.InvariantCulture),
                                                        (StatConversion.GetHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Melee Hit", String.Format("{0}%*Hit Rating of {1} adds {2}% Hit chance\r\n{3}% Draenei Hit Bonus",
                                                      (StatConversion.GetHitFromRating(BasicStats.HitRating) * 100f + DraeneiHitBonus * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                      BasicStats.HitRating.ToString("F0", CultureInfo.InvariantCulture),
                                                      (StatConversion.GetHitFromRating(BasicStats.HitRating) * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                      DraeneiHitBonus * 100f));
            dictValues.Add("Melee Crit", String.Format("{0}%*Crit Rating of {1} adds {2}% Crit chance",
                                                       ((StatConversion.GetCritFromRating(BasicStats.CritRating, CharacterClass.Shaman) * 100f) + (StatConversion.GetCritFromAgility(BasicStats.Agility, CharacterClass.Shaman) * 100f)).ToString("F2", CultureInfo.InvariantCulture),
                                                       BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
                                                       (StatConversion.GetCritFromRating(BasicStats.CritRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Expertise", getExpertiseString());// String.Format("{0} / {1}*Reduces chance to be dodged or parried by {2}% / {3}%\r\nExpertise Rating of {4} adds {5} Expertise",

            dictValues.Add("Spell Power", BasicStats.SpellPower.ToString("F0", CultureInfo.InvariantCulture));
            dictValues.Add("Spell Haste", String.Format("{0}%*Haste Rating of {1} adds {2}% Haste",
                                                        (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                        BasicStats.HasteRating.ToString("F0", CultureInfo.InvariantCulture),
                                                        (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Spell Hit", String.Format("{0}%*Hit Rating of {1} adds {2}% Hit chance\r\n{3}% Draenei Hit Bonus",
                                                      (StatConversion.GetSpellHitFromRating(BasicStats.HitRating + ElemPrecMod) * 100f + DraeneiHitBonus * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                      (BasicStats.HitRating + ElemPrecMod).ToString("F0", CultureInfo.InvariantCulture),
                                                      (StatConversion.GetSpellHitFromRating(BasicStats.HitRating + ElemPrecMod) * 100f).ToString("F2", CultureInfo.InvariantCulture),
                                                      DraeneiHitBonus * 100f));
            dictValues.Add("Spell Crit", String.Format("{0}%*Crit Rating of {1} adds {2}% Crit chance",
                                                       ((StatConversion.GetSpellCritFromRating(BasicStats.CritRating, CharacterClass.Shaman) * 100f) + (StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect, CharacterClass.Shaman) * 100f)).ToString("F2", CultureInfo.InvariantCulture),
                                                       BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
                                                       (StatConversion.GetSpellCritFromRating(BasicStats.CritRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Combat Regen", String.Format("{0}*{0} mana regenerated every 5 seconds while in combat",
                                                         BaseRegen.ToString("F0", CultureInfo.InvariantCulture)));

            //dictValues.Add("Avg Agility", _attackPower.ToString("F0", CultureInfo.InvariantCulture));
            //dictValues.Add("Avg Intellect"
            //dictValues.Add("Avg Mastery"
            //dictValues.Add("Avg Attack Power"
            dictValues.Add("Avg Speed", String.Format("{0} / {1}", AvMHSpeed.ToString("F2", CultureInfo.InvariantCulture), AvOHSpeed.ToString("F2", CultureInfo.InvariantCulture)));
            //dictValues.Add("Avg Melee Haste"
            //dictValues.Add("Avg Melee Hit"
            //dictValues.Add("Avg Melee Crit"
            //dictValues.Add("Avg Expertise"
            //dictValues.Add("Avg Spell Power"
            //dictValues.Add("Avg Spell Haste"
            //dictValues.Add("Avg Spell Hit"
            //dictValues.Add("Avg Spell Crit"
            dictValues.Add("Avg Combat Regen", ManaRegen.ToString("F0", CultureInfo.InvariantCulture));

            /*dictValues.Add("White Hit", WhiteHit.ToString("F2", CultureInfo.InvariantCulture) + "%");
             * if (YellowHit < 100f && TotalExpertiseMH < 26)
             * {
             *  float ratingRequired = (float)Math.Ceiling(4f * StatConversion.GetRatingFromExpertise(100f - YellowHit));
             *  dictValues.Add("Yellow Hit", String.Format("{0}% (Under Cap)*You need {1} more expertise to cap specials (WF,SS)",
             *      YellowHit.ToString("F2", CultureInfo.InvariantCulture),
             *      ratingRequired.ToString("F0", CultureInfo.InvariantCulture)));
             * }
             * else
             * {
             *  if (ParriedAttacks > 0)
             *  {
             *      float ratingRequired = (float)Math.Ceiling(4f * StatConversion.GetRatingFromExpertise(100f - YellowHit));
             *      dictValues.Add("Yellow Hit", String.Format("{0}%*Being in front of boss allows your attacks to be parried\r\nYou would need {1} more expertise to cap specials (WF,SS)",
             *         YellowHit.ToString("F2", CultureInfo.InvariantCulture),
             *         ratingRequired.ToString("F0", CultureInfo.InvariantCulture)));
             *  }
             *  else
             *      dictValues.Add("Yellow Hit", YellowHit.ToString("F2", CultureInfo.InvariantCulture) + "%");
             * }
             * if (OverSpellHitCap > 0.38f) // only warn if more than .38% over cap (equivalent to 10 hit rating)
             *  dictValues.Add("Spell Hit", String.Format("{0}% (Over Cap)*Over Spell Hit Cap by {1}%",
             *      SpellHit.ToString("F2", CultureInfo.InvariantCulture),
             *      OverSpellHitCap.ToString("F2", CultureInfo.InvariantCulture)));
             * else
             * {
             *  if (SpellHit < 100f)
             *  {
             *      float ratingRequired = (float)Math.Ceiling(StatConversion.GetRatingFromSpellHit(1f - SpellHit/100f));
             *      dictValues.Add("Spell Hit", String.Format("{0}% (Under Cap)*You need {1} more hit rating to cap spells (ES, LB etc)",
             *          SpellHit.ToString("F2", CultureInfo.InvariantCulture),
             *          ratingRequired.ToString("F0", CultureInfo.InvariantCulture)));
             *  }
             *  else
             *      dictValues.Add("Spell Hit", SpellHit.ToString("F2", CultureInfo.InvariantCulture) + "%");
             * }*/
            /*if (OverMeleeCritCap > 0.21f) // only warn if more than .21% over cap (equivalent to 10 crit rating)
             *  dictValues.Add("Melee Crit", String.Format("{0} (Over Cap)*Crit Rating {1} (+{2}% crit chance)\r\nOver Soft Cap by {3}%",
             *      MeleeCrit.ToString("F2", CultureInfo.InvariantCulture) + "%",
             *      BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
             *      (StatConversion.GetCritFromRating(BasicStats.CritRating) * 100f).ToString("F2", CultureInfo.InvariantCulture),
             *      OverMeleeCritCap.ToString("F2", CultureInfo.InvariantCulture)));
             * else
             *  dictValues.Add("Melee Crit", String.Format("{0}*Crit Rating {1} (+{2}% crit chance)",
             *      MeleeCrit.ToString("F2", CultureInfo.InvariantCulture) + "%",
             *      BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
             *      (StatConversion.GetCritFromRating(BasicStats.CritRating) * 100f).ToString("F2", CultureInfo.InvariantCulture)));
             *
             * dictValues.Add("Spell Crit", String.Format("{0}*Crit Rating {1} (+{2}% crit chance)",
             *  SpellCrit.ToString("F2", CultureInfo.InvariantCulture) + "%",
             *  BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture),
             *  (StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f).ToString("F2", CultureInfo.InvariantCulture)));*/

            float spellMiss = 100 - SpellHit;

            dictValues.Add("Avoided Attacks", String.Format("{0}%*{1}% Boss Dodged\r\n{2}% Boss Parried\r\n{3}% Spell Misses\r\n{4}% White Misses",
                                                            AvoidedAttacks.ToString("F2", CultureInfo.InvariantCulture),
                                                            DodgedAttacks.ToString("F2", CultureInfo.InvariantCulture),
                                                            ParriedAttacks.ToString("F2", CultureInfo.InvariantCulture),
                                                            spellMiss.ToString("F2", CultureInfo.InvariantCulture),
                                                            MissedAttacks.ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Armor Mitigation", ArmorMitigation.ToString("F2", CultureInfo.InvariantCulture) + "%*Amount of physical damage lost due to boss armor");

            dictValues.Add("ED Uptime", String.Format("{0}%*{1}% ED Bonus Crit",
                                                      EDUptime.ToString("F2", CultureInfo.InvariantCulture),
                                                      EDBonusCrit.ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("Flurry Uptime", FlurryUptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Avg Time to 5 Stack", String.Format("{0} sec*{1} PPM",
                                                                SecondsTo5Stack.ToString("F2", CultureInfo.InvariantCulture),
                                                                _MWPPM.ToString("F2", CultureInfo.InvariantCulture)));
            dictValues.Add("MH Enchant Uptime", MHEnchantUptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("OH Enchant Uptime", OHEnchantUptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Trinket 1 Uptime", Trinket1Uptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Trinket 2 Uptime", Trinket2Uptime.ToString("F2", CultureInfo.InvariantCulture) + "%");
            dictValues.Add("Fire Totem Uptime", FireTotemUptime.ToString("F2", CultureInfo.InvariantCulture) + "%");

            dictValues.Add("White Damage", dpsOutputFormat(SwingDamage, DPS, true));
            dictValues.Add("Windfury Attack", dpsOutputFormat(WindfuryAttack, DPS, true));
            dictValues.Add("Flametongue Attack", dpsOutputFormat(FlameTongueAttack, DPS, true));
            dictValues.Add("Stormstrike", dpsOutputFormat(Stormstrike, DPS, true));
            dictValues.Add("Lava Lash", dpsOutputFormat(LavaLash, DPS, true));
            dictValues.Add("Searing/Magma Totem", dpsOutputFormat(SearingMagma, DPS, false));
            dictValues.Add("Earth Shock", dpsOutputFormat(EarthShock, DPS, false));
            dictValues.Add("Flame Shock", dpsOutputFormat(FlameShock, DPS, false));
            dictValues.Add("Lightning Bolt", dpsOutputFormat(LightningBolt, DPS, false));
            dictValues.Add("Unleash Wind", dpsOutputFormat(UnleashWind, DPS, true));
            dictValues.Add("Unleash Flame", dpsOutputFormat(UnleashFlame, DPS, false));
            dictValues.Add("Lightning Shield", dpsOutputFormat(LightningShield, DPS, false));
            dictValues.Add("Chain Lightning", dpsOutputFormat(ChainLightning, DPS, false));
            dictValues.Add("Fire Nova", dpsOutputFormat(FireNova, DPS, false));
            dictValues.Add("Fire Elemental", FireElemental.getDPSOutput());
            dictValues.Add("Spirit Wolf", dpsOutputFormat(SpiritWolf, DPS, true));
            dictValues.Add("Other", dpsOutputFormat(Other, DPS, false));
            dictValues.Add("Total DPS", DPS.ToString("F2", CultureInfo.InvariantCulture));

            /*dictValues.Add("Status", String.Format("Enhance Model : DPS Points {0}, Survivability Points {1}, Overall Points {2}",
             *  DPS.ToString("F2", CultureInfo.InvariantCulture),
             *  Survivability.ToString("F2", CultureInfo.InvariantCulture),
             *  OverallPoints.ToString("F2", CultureInfo.InvariantCulture)));*/

            return(dictValues);
        }
Exemple #6
0
 public static float CalcHealth(Stats stats)
 {
     return((float)Math.Round((stats.Health + StatConversion.GetHealthFromStamina(CalcStamina(stats))) * (1 + stats.BonusHealthMultiplier) - 0.00001f));
 }
Exemple #7
0
        public override Stats GetCharacterStats(Character character, Item additionalItem)
        {
            CalculationOptionsElemental calcOpts = character.CalculationOptions as CalculationOptionsElemental;

            Stats statsRace  = BaseStats.GetBaseStats(character);
            Stats statsItems = GetItemStats(character, additionalItem);
            Stats statsBuffs = GetBuffsStats(character, calcOpts);

            Stats statsTotal = statsRace + statsItems + statsBuffs;

            if (statsTotal.HighestStat > 0)
            {
                if (statsTotal.Spirit > statsTotal.Intellect)
                {
                    statsTotal.Spirit += (statsTotal.HighestStat * 15f / 50f);
                }
                else
                {
                    statsTotal.Intellect += (statsTotal.HighestStat * 15f / 50f);
                }
            }

            statsTotal.Strength  *= 1 + statsTotal.BonusStrengthMultiplier;
            statsTotal.Agility   *= 1 + statsTotal.BonusAgilityMultiplier;
            statsTotal.Stamina   *= 1 + statsTotal.BonusStaminaMultiplier;
            statsTotal.Intellect *= 1 + statsTotal.BonusIntellectMultiplier;
            statsTotal.Spirit    *= 1 + statsTotal.BonusSpiritMultiplier;

            statsTotal.Strength  = (float)Math.Floor(statsTotal.Strength);
            statsTotal.Agility   = (float)Math.Floor(statsTotal.Agility);
            statsTotal.Stamina   = (float)Math.Floor(statsTotal.Stamina);
            statsTotal.Intellect = (float)Math.Floor(statsTotal.Intellect);
            statsTotal.Spirit    = (float)Math.Floor(statsTotal.Spirit);

            if (Character.ValidateArmorSpecialization(character, ItemType.Mail))
            {
                statsTotal.Intellect *= 1.05f;
            }

            statsTotal.AttackPower += statsTotal.Strength + statsTotal.Agility;

            statsTotal.Mana += StatConversion.GetManaFromIntellect(statsTotal.Intellect);
            statsTotal.Mana *= (float)Math.Round(1f + statsTotal.BonusManaMultiplier);

            statsTotal.Health += StatConversion.GetHealthFromStamina(statsTotal.Stamina);
            statsTotal.Health *= (float)Math.Round(1f + statsTotal.BonusHealthMultiplier);

            statsTotal.SpellCrit += StatConversion.GetSpellCritFromRating(statsTotal.CritRating);
            statsTotal.SpellCrit += StatConversion.GetSpellCritFromIntellect(statsTotal.Intellect);
            statsTotal.SpellCrit += statsTotal.SpellCritOnTarget;
            statsTotal.SpellHit  += StatConversion.GetSpellHitFromRating(statsTotal.HitRating +
                                                                         ((.33f * character.ShamanTalents.ElementalPrecision) * statsTotal.Spirit));

            // Flametongue weapon assumed
            statsTotal.SpellPower += (float)Math.Floor(747.78 * (1f + character.ShamanTalents.ElementalWeapons * .2f));
            if (character.ShamanTalents.GlyphofFlametongueWeapon)
            {
                statsTotal.SpellCrit += .02f;
            }

            // Water shield assumed
            statsTotal.Mp5 += 100;
            if (character.ShamanTalents.GlyphofWaterShield)
            {
                statsTotal.Mp5 += 30;
            }

            return(statsTotal);
        }
Exemple #8
0
        public override Stats GetCharacterStats(Character character, Item additionalItem)
        {
            PriestTalents talents = character.PriestTalents;

            Stats statsTotal = new Stats();

            Stats baseStats = BaseStats.GetBaseStats(character.Level, character.Class, character.Race);
            Stats itemStats = GetItemStats(character, additionalItem);
            Stats buffStats = GetBuffsStats(character, _calculationOptions);

            // Get the gear/enchants/buffs stats loaded in
            statsTotal.Accumulate(baseStats);
            statsTotal.Accumulate(itemStats);
            statsTotal.Accumulate(buffStats);

            Stats statsTalents = new Stats()
            {
                // we can only wear items that are cloth so we always have our specialization, even naked.
                BonusIntellectMultiplier = 0.05f,

                BonusShadowDamageMultiplier = (1 + 0.02f * talents.TwinDisciplines) *
                                              (1 + 0.02f * talents.TwistedFaith) *
                                              (1 + 0.15f * talents.Shadowform) - 1,

                BonusHolyDamageMultiplier = (1 + 0.02f * talents.TwinDisciplines) - 1,

                // this is the shadow priest model so they must have 'Shadow Power'
                BonusSpellPowerMultiplier = .15f,
            };

            statsTotal.Accumulate(statsTalents);

            statsTotal.Stamina    = (float)Math.Floor(statsTotal.Stamina * (1 + statsTotal.BonusStaminaMultiplier));
            statsTotal.Intellect += (float)Math.Floor(itemStats.Intellect * statsTotal.BonusIntellectMultiplier);
            statsTotal.Spirit     = (float)Math.Round(statsTotal.Spirit * (1 + statsTotal.BonusSpiritMultiplier));

            statsTotal.Health += (float)Math.Floor(StatConversion.GetHealthFromStamina(statsTotal.Stamina) * (1f + statsTotal.BonusHealthMultiplier));

            statsTotal.Mana = (float)Math.Round(statsTotal.Mana + StatConversion.GetManaFromIntellect(statsTotal.Intellect));
            statsTotal.Mana = (float)Math.Round(statsTotal.Mana * (1f + statsTotal.BonusManaMultiplier));

            statsTotal.SpellPower += statsTotal.Intellect - 10;

            float hasteFromRating = StatConversion.GetSpellHasteFromRating(statsTotal.HasteRating);
            float talentedHaste   = (1 + hasteFromRating) * (1 + talents.Darkness * .01f) - 1;

            statsTotal.SpellHaste += character.Race == CharacterRace.Goblin ? talentedHaste * 1.01f : talentedHaste;

            float baseBonus = (float)Math.Floor(baseStats.Spirit * statsTotal.BonusSpiritMultiplier);
            float itemBonus = (float)Math.Floor(itemStats.Spirit * statsTotal.BonusSpiritMultiplier);
            float spiritFromItemsAndEffects = baseBonus + itemBonus + itemStats.Spirit;
            float hitRatingFromSpirit       = (0.5f * talents.TwistedFaith) * Math.Max(0f, spiritFromItemsAndEffects);

            statsTotal.HitRating += hitRatingFromSpirit;
            statsTotal.SpellHit  += StatConversion.GetSpellHitFromRating(statsTotal.HitRating);

            // ignoring the base crit percentage here as the in-game tooltip says that the int -> crit conversion contains the base.
            float critFromInt    = StatConversion.GetSpellCritFromIntellect(statsTotal.Intellect) + 0.012375f;
            float critFromRating = StatConversion.GetSpellCritFromRating(statsTotal.CritRating);

            statsTotal.SpellCrit = character.Race == CharacterRace.Worgen ? (critFromInt + critFromRating) + .01f : (critFromInt + critFromRating);

            // Armor
            statsTotal.Armor      = statsTotal.Armor * (1f + statsTotal.BaseArmorMultiplier);
            statsTotal.BonusArmor = statsTotal.BonusArmor * (1f + statsTotal.BonusArmorMultiplier);
            statsTotal.Armor     += statsTotal.BonusArmor;
            statsTotal.Armor      = (float)Math.Round(statsTotal.Armor);

            return(statsTotal);
        }
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string> dictValues = new Dictionary <string, string>();
            string format   = "";
            int    LevelDif = combatFactors.levelDif;

            // Base Stats
            dictValues.Add("Health and Stamina", string.Format("{0:##,##0} : {1:##,##0}*" +
                                                               "{2:00,000} : Base Health" +
                                                               "\r\n{3:00,000} : Stam Bonus",
                                                               AverageStats.Health, AverageStats.Stamina,
                                                               BaseHealth,
                                                               StatConversion.GetHealthFromStamina(AverageStats.Stamina)));
            dictValues.Add("Armor", string.Format("{0}*Increases Attack Power by {1}", Armor, TeethBonus));
            #region Strength
            {
                int    formIter  = 1;
                string theFormat = "";

                float[] passiveContrsVals = new float[] {
                    combatFactors.Char.WarriorTalents.StrengthOfArms * 0.02f,
                    (combatFactors.FuryStance ? combatFactors.Char.WarriorTalents.ImprovedBerserkerStance * 0.04f : 0f),
                    BuffsStats.Strength,
                    BuffsStats.BonusStrengthMultiplier,
                };

                string[] passiveContrs = new string[] {
                    "Strength of Arms",
                    "Improved Berserker Stance",
                    "Buffs : Simple",
                    "Buffs : Multi",
                };

                theFormat += "{0:0.#}*"; // Averaged % and Averaged Rating
                theFormat += "The Pane shows Averaged Values";
                theFormat += "\r\n";
                theFormat += "\r\n= Your Passive Contributions =";
                theFormat += "\r\n{" + formIter.ToString() + ":00.#%} : " + passiveContrs[0]; formIter++;
                theFormat += "\r\n{" + formIter.ToString() + ":00.#%} : " + passiveContrs[1]; formIter++;
                theFormat += "\r\n{" + formIter.ToString() + ":0.#} : " + passiveContrs[2]; formIter++;
                theFormat += "\r\n{" + formIter.ToString() + ":00.#%} : " + passiveContrs[3]; formIter++;
                theFormat += "\r\n";
                theFormat += "\r\n= UnProc'd =";
                theFormat += "\r\nValue: {" + formIter.ToString() + ":0.#}"; formIter++;
                theFormat += "\r\nIncreases Attack Power by {" + formIter.ToString() + ":0.#}"; formIter++;
                theFormat += "\r\n";
                theFormat += "\r\n= Proc'd =";
                theFormat += "\r\nValue: {" + formIter.ToString() + ":0.#}"; formIter++;
                theFormat += "\r\nIncreases Attack Power by {" + formIter.ToString() + ":0.#}"; formIter++;

                dictValues.Add("Strength", string.Format(theFormat,
                                                         // Averaged Stats
                                                         AverageStats.Strength,
                                                         // Passive Contributions
                                                         passiveContrsVals[0], passiveContrsVals[1], passiveContrsVals[2], passiveContrsVals[3],
                                                         // UnProc'd Stats
                                                         BuffedStats.Strength,
                                                         BuffedStats.Strength * 2f,
                                                         // Proc'd Stats
                                                         MaximumStats.Strength,
                                                         MaximumStats.Strength * 2f
                                                         ));
            }
            #endregion
            dictValues.Add("Attack Power", string.Format("{0}*" +
                                                         "Increases White DPS by {1:0.0}\r\n" +
                                                         "\r\n" +
                                                         "Buffed: {2:0}\r\n" +
                                                         "Proc'd: {3:0}\r\n", (int)AverageStats.AttackPower, AverageStats.AttackPower / 14f,
                                                         BuffedStats.AttackPower, MaximumStats.AttackPower));
            #region Agility
            {
                int    formIter  = 1;
                string theFormat = "";

                float[] passiveContrsVals = new float[] {
                    BuffsStats.Agility,
                    BuffsStats.BonusAgilityMultiplier,
                };

                string[] passiveContrs = new string[] { "Buffs : Simple", "Buffs : Multi" };

                theFormat += "{0:0.#}*"; // Averaged % and Averaged Rating
                theFormat += "The Pane shows Averaged Values";
                theFormat += "\r\n";
                theFormat += "\r\n= Your Passive Contributions =";
                theFormat += "\r\n{" + formIter.ToString() + ":0.#} : " + passiveContrs[0]; formIter++;
                theFormat += "\r\n{" + formIter.ToString() + ":00.#%} : " + passiveContrs[1]; formIter++;
                theFormat += "\r\n";
                theFormat += "\r\n= UnProc'd =";
                theFormat += "\r\nIncreases Crit by {" + formIter.ToString() + ":0.#%}"; formIter++;
                theFormat += "\r\nIncreases Armor by {" + formIter.ToString() + ":0.#}"; formIter++;
                theFormat += "\r\n";
                theFormat += "\r\n= Proc'd =";
                theFormat += "\r\nIncreases Crit by {" + formIter.ToString() + ":0.#%}"; formIter++;
                theFormat += "\r\nIncreases Armor by {" + formIter.ToString() + ":0.#}"; formIter++;

                dictValues.Add("Agility", string.Format(theFormat,
                                                        // Averaged Stats
                                                        AverageStats.Agility,
                                                        // Passive Contributions
                                                        passiveContrsVals[0], passiveContrsVals[1],
                                                        // UnProc'd Stats
                                                        StatConversion.GetCritFromAgility(BuffedStats.Agility, CharacterClass.Warrior),
                                                        StatConversion.GetArmorFromAgility(BuffedStats.Agility),
                                                        // Proc'd Stats
                                                        StatConversion.GetCritFromAgility(MaximumStats.Agility, CharacterClass.Warrior),
                                                        StatConversion.GetArmorFromAgility(MaximumStats.Agility)
                                                        ));
            }
            #endregion
            #region Crit
            {
                // sub to add neg number as pos, for overcapping to compensate
                // for boss level on yellows (or whites, I dont remember which)
                // Whites clip crit cap with glances, dodges, parries, misses
                float WhCritCap = 1f;// +StatConversion.NPC_LEVEL_CRIT_MOD[LevelDif];
                //float YwCritCap = 1f + StatConversion.NPC_LEVEL_CRIT_MOD[LevelDif];
                if (combatFactors.useOH)
                {
                    WhCritCap -= (Whites.OHAtkTable.Glance + Whites.OHAtkTable.AnyNotLand);
                    //    YwCritCap -= (new AttackTable(combatFactors.Char, BuffedStats, combatFactors, combatFactors.CalcOpts, FW, false, false, false)).AnyNotLand;
                }
                else
                {
                    WhCritCap -= (Whites.MHAtkTable.Glance + Whites.MHAtkTable.AnyNotLand);
                    // Yellows clip crit cap with dodges, parries, misses
                    //    YwCritCap -= (new AttackTable(combatFactors.Char, BuffedStats, combatFactors, combatFactors.CalcOpts, FW, true, false, false)).AnyNotLand;
                }
                float useRamp = 0f;
                if (combatFactors.Char.WarriorTalents.Rampage > 0f)
                {
                    useRamp = 0.05f;
                }
                float[] passiveContrsVals = new float[] {
                    0.03192f,
                    AgilityCritBonus,
                    StatConversion.GetCritFromRating(BuffedStats.CritRating + BuffedStats.DeathbringerProc),
                    combatFactors.Char.WarriorTalents.Cruelty * 0.01f,
                    (combatFactors.FuryStance ? 0.03f : 0f),
                    (combatFactors.FuryStance ? AverageStats.BonusWarrior_T9_2P_Crit : 0f),
                    BonusCritPercPoleAxeSpec,
                    BuffsStats.PhysicalCrit + useRamp,
                };
                float passiveContrsTtlVal = passiveContrsVals[0] + passiveContrsVals[1] + passiveContrsVals[2]
                                            + passiveContrsVals[3] + passiveContrsVals[4] + passiveContrsVals[5]
                                            + passiveContrsVals[6] + passiveContrsVals[7];
                string[] passiveContrs = new string[] { "Base Crit", "From Agility", "From Crit Rating", "Cruelty",
                                                        "Berserker Stance", "T9 2P Set Bonus", "Poleaxe Specialization",
                                                        "Buffs" };

                //float WhUnProcdCrit = StatConversion.GetCritFromRating(BuffedStats.CritRating + BuffedStats.DeathbringerProc);
                float WhProcdCrit            = StatConversion.GetCritFromRating(MaximumStats.CritRating + MaximumStats.DeathbringerProc - BuffedStats.CritRating - BuffedStats.DeathbringerProc);
                bool  isWhUnProcdOverCap     = passiveContrsTtlVal > WhCritCap;
                bool  isWhProcdOverCap       = passiveContrsTtlVal + WhProcdCrit > WhCritCap;
                float amountWhUnProcdOverCap = Math.Abs(StatConversion.GetRatingFromCrit(WhCritCap - passiveContrsTtlVal));
                float amountWhProcdOverCap   = Math.Abs(StatConversion.GetRatingFromCrit(WhCritCap - (passiveContrsTtlVal + WhProcdCrit)));

                float YwUnProcdCrit = StatConversion.GetCritFromRating(BuffedStats.CritRating + BuffedStats.DeathbringerProc);
                float YwProcdCrit   = StatConversion.GetCritFromRating(MaximumStats.CritRating + MaximumStats.DeathbringerProc);
                //bool isYwUnProcdOverCap = passiveContrsTtlVal + YwUnProcdCrit > YwCritCap;
                //bool isYwProcdOverCap = passiveContrsTtlVal + YwProcdCrit > YwCritCap;
                //float amountYwUnProcdOverCap = Math.Abs(StatConversion.GetRatingFromCrit(YwCritCap - (passiveContrsTtlVal + YwUnProcdCrit)));
                //float amountYwProcdOverCap = Math.Abs(StatConversion.GetRatingFromCrit(YwCritCap - (passiveContrsTtlVal + YwProcdCrit)));

                string theFormat = GenFormattedString(passiveContrs, true,
                                                      isWhUnProcdOverCap, isWhProcdOverCap
                                                      //isYwUnProcdOverCap, isYwProcdOverCap
                                                      );

                dictValues.Add("Crit", string.Format(theFormat,
                                                     // Averaged Stats
                                                     CritPercent, AverageStats.CritRating,
                                                     // Passive Contributions
                                                     passiveContrsVals[0], passiveContrsVals[1], passiveContrsVals[2],
                                                     passiveContrsVals[3], passiveContrsVals[4], passiveContrsVals[5],
                                                     passiveContrsVals[6], passiveContrsVals[7],
                                                     // UnProc'd Stats
                                                     BuffedStats.CritRating + BuffedStats.DeathbringerProc,
                                                     Math.Min(WhCritCap, passiveContrsTtlVal), amountWhUnProcdOverCap,
                                                     //Math.Min(YwCritCap, passiveContrsTtlVal + YwUnProcdCrit), amountYwUnProcdOverCap,
                                                     // Proc'd Stats
                                                     MaximumStats.CritRating + MaximumStats.DeathbringerProc,
                                                     Math.Min(WhCritCap, passiveContrsTtlVal + WhProcdCrit), amountWhProcdOverCap
                                                     //Math.Min(YwCritCap, passiveContrsTtlVal + YwProcdCrit), amountYwProcdOverCap
                                                     ));
            }
            #endregion
            #region Armor Penetration
            {
                float   ArPCap            = 1.00f;
                float[] passiveContrsVals = new float[] {
                    (!combatFactors.FuryStance ? 0.10f : 0f),
                    (!combatFactors.FuryStance ? AverageStats.BonusWarrior_T9_2P_ArP : 0f),
                    ArmorPenetrationMaceSpec
                };
                float    passiveContrsTtlVal  = passiveContrsVals[0] + passiveContrsVals[1] + passiveContrsVals[2];
                string[] passiveContrs        = new string[] { "Battle Stance", "T9 2P Set Bonus", "Mace Specialization" };
                float    UnProcdArP           = StatConversion.GetArmorPenetrationFromRating(BuffedStats.ArmorPenetrationRating);
                float    ProcdArP             = StatConversion.GetArmorPenetrationFromRating(MaximumStats.ArmorPenetrationRating);
                bool     isUnProcdOverCap     = passiveContrsTtlVal + UnProcdArP > ArPCap;
                bool     isProcdOverCap       = passiveContrsTtlVal + ProcdArP > ArPCap;
                float    amountUnProcdOverCap = Math.Abs(StatConversion.GetRatingFromArmorPenetration(ArPCap - (passiveContrsTtlVal + UnProcdArP)));
                float    amountProcdOverCap   = Math.Abs(StatConversion.GetRatingFromArmorPenetration(ArPCap - (passiveContrsTtlVal + ProcdArP)));
                string   theFormat            = GenFormattedString(passiveContrs, true, isUnProcdOverCap, isProcdOverCap);
                dictValues.Add("Armor Penetration", string.Format(theFormat,
                                                                  // Averaged Stats
                                                                  ArmorPenetration, AverageStats.ArmorPenetrationRating,
                                                                  // Passive Contributions
                                                                  passiveContrsVals[0], passiveContrsVals[1], passiveContrsVals[2],
                                                                  // UnProc'd Stats
                                                                  BuffedStats.ArmorPenetrationRating,
                                                                  Math.Min(ArPCap, passiveContrsTtlVal + UnProcdArP),
                                                                  amountUnProcdOverCap,
                                                                  // Proc'd Stats
                                                                  MaximumStats.ArmorPenetrationRating,
                                                                  Math.Min(ArPCap, passiveContrsTtlVal + ProcdArP),
                                                                  amountProcdOverCap
                                                                  ));
            }
            #endregion
            #region Haste
            {
                // Haste has no cap? Shouldn't there be a 100% cap or something?
                // We should also state the before/after effects of haste on white swings
                // Maybe a good point to show how much swing time is lost to Slams too?
                float heroism = 0f;
                if (BuffsStats._rawSpecialEffectData != null)
                {
                    foreach (SpecialEffect effect in BuffsStats._rawSpecialEffectData)
                    {
                        if (effect != null && effect.Stats.PhysicalHaste > 0)
                        {
                            heroism = effect.GetAverageStats().PhysicalHaste;
                        }
                    }
                }
                float[] passiveContrsVals = new float[] {
                    combatFactors.Char.WarriorTalents.BloodFrenzy * 0.05f,
                        BuffsStats.PhysicalHaste,
                        heroism,
                };
                float passiveContrsTtlVal = (1f + passiveContrsVals[0])
                                            * (1f + passiveContrsVals[1])
                                            * (1f + passiveContrsVals[2])
                                            - 1f;
                string[] passiveContrs = new string[] { "Blood Frenzy", "Buffs", "Heroism (Averaged)" };
                float    UnProcdHaste  = StatConversion.GetHasteFromRating(BuffedStats.HasteRating, CharacterClass.Warrior);
                float    ProcdHaste    = StatConversion.GetHasteFromRating(MaximumStats.HasteRating, CharacterClass.Warrior);
                string   theFormat     = GenFormattedString(passiveContrs);

                dictValues.Add("Haste", string.Format(theFormat,
                                                      // Averaged Stats
                                                      HastePercent, AverageStats.HasteRating,
                                                      // Passive Contributions
                                                      passiveContrsVals[0], passiveContrsVals[1], passiveContrsVals[2],
                                                      // UnProc'd Stats
                                                      BuffedStats.HasteRating,
                                                      (1f + passiveContrsTtlVal) * (1f + UnProcdHaste) - 1f,
                                                      // Proc'd Stats
                                                      MaximumStats.HasteRating,
                                                      (1f + passiveContrsTtlVal) * (1f + ProcdHaste) - 1f
                                                      ));
            }
            #endregion
            #region Hit
            {
                // old
                float HitPercent   = StatConversion.GetHitFromRating(HitRating);
                float HitPercBonus = AverageStats.PhysicalHit;
                // Hit Soft Cap ratings check, how far from it
                float capA1         = StatConversion.WHITE_MISS_CHANCE_CAP[LevelDif];
                float convcapA1     = (float)Math.Ceiling(StatConversion.GetRatingFromHit(capA1));
                float sec2lastNumA1 = (convcapA1 - StatConversion.GetRatingFromHit(HitPercent) - StatConversion.GetRatingFromHit(HitPercBonus)) * -1;
                //float lastNumA1    = StatConversion.GetRatingFromExpertise((convcapA1 - Math.Min(MhExpertise, (OhExpertise != 0 ? OhExpertise : MhExpertise))) * -1);
                // Hit Hard Cap ratings check, how far from it
                float capA2         = StatConversion.WHITE_MISS_CHANCE_CAP_DW[LevelDif];
                float convcapA2     = (float)Math.Ceiling(StatConversion.GetRatingFromHit(capA2));
                float sec2lastNumA2 = (convcapA2 - StatConversion.GetRatingFromHit(HitPercent) - StatConversion.GetRatingFromHit(HitPercBonus)) * -1;
                //float lastNumA2   = StatConversion.GetRatingFromExpertise((sec2lastNumA2 - Math.Min(MhExpertise, (OhExpertise != 0 ? OhExpertise : MhExpertise))) * -1);
                dictValues.Add("Hit",
                               string.Format("{0:00.00%} : {1}*" + "{2:0.00%} : From Other Bonuses" +
                                             "\r\n{3:0.00%} : Total Hit % Bonus" +
                                             "\r\n\r\nWhite Two-Hander Cap: " +
                                             (sec2lastNumA1 > 0 ? "You can free {4:0} Rating"
                                                       : "You need {4:0} more Rating") +
                                             "\r\nWhite Dual Wield Cap: " +
                                             (sec2lastNumA2 > 0 ? "You can free {5:0} Rating"
                                                       : "You need {5:0} more Rating"),
                                             StatConversion.GetHitFromRating(AverageStats.HitRating),
                                             AverageStats.HitRating,
                                             HitPercBonus,
                                             HitPercent + HitPercBonus,
                                             (sec2lastNumA1 > 0 ? sec2lastNumA1 : sec2lastNumA1 * -1),
                                             (sec2lastNumA2 > 0 ? sec2lastNumA2 : sec2lastNumA2 * -1)
                                             ));
            }
            #endregion
            #region Expertise
            {
                // Dodge Cap ratings check, how far from it, uses lesser of MH and OH
                // Also factors in Weapon Mastery
                float capB1         = StatConversion.YELLOW_DODGE_CHANCE_CAP[LevelDif] - WeapMastPerc;
                float convcapB1     = (float)Math.Ceiling(StatConversion.GetExpertiseFromDodgeParryReduc(capB1));
                float sec2lastNumB1 = (convcapB1 - Math.Min(MhExpertise, (OhExpertise != 0 ? OhExpertise : MhExpertise))) * -1;
                float lastNumB1     = StatConversion.GetRatingFromExpertise((convcapB1 - WeapMastPerc - Math.Min(MhExpertise, (OhExpertise != 0 ? OhExpertise : MhExpertise))) * -1);
                // Parry Cap ratings check, how far from it, uses lesser of MH and OH
                float capB2         = StatConversion.YELLOW_PARRY_CHANCE_CAP[LevelDif];
                float convcapB2     = (float)Math.Ceiling(StatConversion.GetExpertiseFromDodgeParryReduc(capB2));
                float sec2lastNumB2 = (convcapB2 - Math.Min(MhExpertise, (OhExpertise != 0 ? OhExpertise : MhExpertise))) * -1;
                float lastNumB2     = StatConversion.GetRatingFromExpertise((convcapB2 - Math.Min(MhExpertise, (OhExpertise != 0 ? OhExpertise : MhExpertise))) * -1);
                dictValues.Add("Expertise",
                               string.Format("{0:00.00%} : {1:00.00} : {2}*" +
                                             "Following includes Racial bonus and Strength of Arms" +
                                             "\r\n{3:00.00%} Weapon Mastery (Dodge Only)" +
                                             "\r\n{4:00.00%} : {5:00.00} : MH" +
                                             "\r\n{6:00.00%} : {7:00.00} : OH" +
                                             "\r\n\r\n" + "Dodge Cap: " +
                                             (lastNumB1 > 0 ? "You can free {8:0} Expertise ({9:0} Rating)"
                                 : "You need {8:0} more Expertise ({9:0} Rating)") +
                                             "\r\n" + "Parry Cap: " +
                                             (lastNumB2 > 0 ? "You can free {10:0} Expertise ({11:0} Rating)"
                                 : "You need {10:0} more Expertise ({11:0} Rating)"),
                                             StatConversion.GetDodgeParryReducFromExpertise(Expertise),
                                             Expertise,
                                             AverageStats.ExpertiseRating,
                                             WeapMastPerc,
                                             StatConversion.GetDodgeParryReducFromExpertise(MhExpertise), MhExpertise,
                                             StatConversion.GetDodgeParryReducFromExpertise(OhExpertise), OhExpertise,
                                             (sec2lastNumB1 > 0 ? sec2lastNumB1 : sec2lastNumB1 * -1), (lastNumB1 > 0 ? lastNumB1 : lastNumB1 * -1),
                                             (sec2lastNumB2 > 0 ? sec2lastNumB2 : sec2lastNumB2 * -1), (lastNumB2 > 0 ? lastNumB2 : lastNumB2 * -1)
                                             ));
            }
            #endregion

            dictValues.Add("Description", string.Format("DPS : PerHit : #ActsD"));
            // DPS Abilities
            format = "{0:0000} : {1:00000} : {2:000.00}";
            if (TotalDPS < 0f)
            {
                TotalDPS = 0f;
            }
            foreach (Rawr.DPSWarr.Rotation.AbilWrapper aw in Rot.GetAbilityList())
            {
                if (!aw.ability.Name.Equals("Invalid"))
                {
                    dictValues.Add(aw.ability.Name, string.Format(format, aw.allDPS, aw.ability.DamageOnUse, aw.allNumActivates)
                                   + aw.ability.GenTooltip(aw.allNumActivates, aw.allDPS / TotalDPS));
                }
            }
            // DPS General
            dictValues.Add("White DPS", string.Format("{0:0000} : {1:00000}", WhiteDPS, WhiteDmg) + Whites.GenTooltip(WhiteDPSMH, WhiteDPSOH, TotalDPS));
            dictValues.Add("Deep Wounds", string.Format("{0:0000}*{1:00.0%} of DPS", Rot.DW.TickSize, Rot.DW.TickSize / TotalDPS));
            dictValues.Add("Special DMG Procs", string.Format("{0:0000}*{1:00.0%} of DPS", SpecProcDPS, SpecProcDPS / TotalDPS));
            dictValues.Add("Total DPS", string.Format("{0:#,##0} : {1:#,###,##0}*" + Rot.GCDUsage, TotalDPS, TotalDPS * Duration));
            // Rage
            format = "{0:0000}";
            dictValues.Add("Total Generated Rage", string.Format("{0:00} = {1:0} + {2:0}", WhiteRage + OtherRage, WhiteRage, OtherRage));
            dictValues.Add("Needed Rage for Abilities", string.Format(format, NeedyRage));
            dictValues.Add("Available Free Rage", string.Format(format, FreeRage));
#if (!RAWR3 && DEBUG)
            dictValues.Add("Calculation Time", string.Format("{0}", calculationTime));
#endif
            return(dictValues);
        }
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string> dictValues = new Dictionary <string, string>();

            try {
                string format   = "";
                int    LevelDif = CombatFactors.LevelDif;

                // Base Stats
                #region Health & Stamina
                dictValues.Add("Health and Stamina", string.Format("{0:##,##0} : {1:##,##0}*" +
                                                                   "{2:00,000} : Base Health" +
                                                                   "\r\n{3:00,000} : Stam Bonus",
                                                                   AverageStats.Health, AverageStats.Stamina,
                                                                   BaseHealth,
                                                                   StatConversion.GetHealthFromStamina(AverageStats.Stamina)));
                #endregion
                dictValues.Add("Armor", string.Format("{0}", Armor));
                #region Strength
                {
                    int    formIter  = 1;
                    string theFormat = "";

                    float[] passiveContrsVals = new float[] {
                        BuffsStats.Strength,
                        BuffsStats.BonusStrengthMultiplier,
                        PlateSpecValid ? 0.05f : 0.00f,
                    };

                    string[] passiveContrs = new string[] {
                        "Buffs : Simple",
                        "Buffs : Multi",
                        "Plate Specialization",
                    };

                    theFormat += "{0:0.#}*"; // Averaged % and Averaged Rating
                    theFormat += "The Pane shows Averaged Values*";
                    //theFormat += "\r\n";
                    theFormat += "\r\n= Your Passive Contributions =";
                    theFormat += "\r\n{" + string.Format("{0}", formIter) + ":0.#} : " + passiveContrs[0]; formIter++;
                    theFormat += "\r\n{" + string.Format("{0}", formIter) + ":00.#%} : " + passiveContrs[1]; formIter++;
                    theFormat += "\r\n{" + string.Format("{0}", formIter) + ":00.#%} : " + passiveContrs[2]; formIter++;
                    theFormat += "\r\n";
                    theFormat += "\r\n= UnProc'd =";
                    theFormat += "\r\nValue: {" + string.Format("{0}", formIter) + ":0.#}"; formIter++;
                    theFormat += "\r\nIncreases Attack Power by {" + string.Format("{0}", formIter) + ":0.#}"; formIter++;
                    theFormat += "\r\n";
                    theFormat += "\r\n= Proc'd =";
                    theFormat += "\r\nValue: {" + string.Format("{0}", formIter) + ":0.#}"; formIter++;
                    theFormat += "\r\nIncreases Attack Power by {" + string.Format("{0}", formIter) + ":0.#}"; formIter++;

                    dictValues.Add("Strength", string.Format(theFormat,
                                                             // Averaged Stats
                                                             AverageStats.Strength,
                                                             // Passive Contributions
                                                             passiveContrsVals[0], passiveContrsVals[1], passiveContrsVals[2],
                                                             // UnProc'd Stats
                                                             BuffedStats.Strength,
                                                             BuffedStats.Strength * 2f,
                                                             // Proc'd Stats
                                                             MaximumStats.Strength,
                                                             MaximumStats.Strength * 2f
                                                             ));
                }
                #endregion
                #region Attack Power
                dictValues.Add("Attack Power", string.Format("{0}*" +
                                                             "Increases White DPS by {1:0.0}\r\n" +
                                                             "\r\n" +
                                                             "Buffed: {2:0}\r\n" +
                                                             "Proc'd: {3:0}", (int)AverageStats.AttackPower, AverageStats.AttackPower / 14f,
                                                             BuffedStats.AttackPower, MaximumStats.AttackPower));
                #endregion
                #region Agility
                {
                    int    formIter  = 1;
                    string theFormat = "";

                    float[] passiveContrsVals = new float[] {
                        BuffsStats.Agility,
                        BuffsStats.BonusAgilityMultiplier,
                    };

                    string[] passiveContrs = new string[] { "Buffs : Simple", "Buffs : Multi" };

                    theFormat += "{0:0.#}*"; // Averaged % and Averaged Rating
                    theFormat += "The Pane shows Averaged Values*";
                    //theFormat += "\r\n";
                    theFormat += "\r\n= Your Passive Contributions =";
                    theFormat += "\r\n{" + string.Format("{0}", formIter) + ":0.#} : " + passiveContrs[0]; formIter++;
                    theFormat += "\r\n{" + string.Format("{0}", formIter) + ":00.#%} : " + passiveContrs[1]; formIter++;
                    theFormat += "\r\n";
                    theFormat += "\r\n= UnProc'd =";
                    theFormat += "\r\nIncreases Crit by {" + string.Format("{0}", formIter) + ":0.#%}"; formIter++;
                    //theFormat += "\r\nIncreases Armor by {" + string.Format("{0}", formIter) + ":0.#}"; formIter++;
                    theFormat += "\r\n";
                    theFormat += "\r\n= Proc'd =";
                    theFormat += "\r\nIncreases Crit by {" + string.Format("{0}", formIter) + ":0.#%}"; formIter++;
                    //theFormat += "\r\nIncreases Armor by {" + string.Format("{0}", formIter) + ":0.#}"; formIter++;

                    dictValues.Add("Agility", string.Format(theFormat,
                                                                                                                                            // Averaged Stats
                                                            AverageStats.Agility,
                                                                                                                                            // Passive Contributions
                                                            passiveContrsVals[0], passiveContrsVals[1],
                                                                                                                                            // UnProc'd Stats
                                                            StatConversion.GetCritFromAgility(BuffedStats.Agility, CharacterClass.Warrior),
                                                                                                                                            //StatConversion.GetArmorFromAgility(BuffedStats.Agility),
                                                                                                                                            // Proc'd Stats
                                                            StatConversion.GetCritFromAgility(MaximumStats.Agility, CharacterClass.Warrior) //,
                                                                                                                                            //StatConversion.GetArmorFromAgility(MaximumStats.Agility)
                                                            ));
                }
                #endregion
                #region Crit
                {
                    // sub to add neg number as pos, for overcapping to compensate
                    // for boss level on yellows (or whites, I dont remember which)
                    // Whites clip crit cap with glances, dodges, parries, misses
                    float WhCritCap = 1f;// +StatConversion.NPC_LEVEL_CRIT_MOD[LevelDif];
                    //float YwCritCap = 1f + StatConversion.NPC_LEVEL_CRIT_MOD[LevelDif];
                    if (CombatFactors.useOH)
                    {
                        WhCritCap -= (Whites.OHAtkTable.Glance + Whites.OHAtkTable.AnyNotLand);
                        //    YwCritCap -= (new AttackTable(combatFactors.Char, BuffedStats, combatFactors, combatFactors.CalcOpts, FW, false, false, false)).AnyNotLand;
                    }
                    else
                    {
                        WhCritCap -= (Whites.MHAtkTable.Glance + Whites.MHAtkTable.AnyNotLand);
                        // Yellows clip crit cap with dodges, parries, misses
                        //    YwCritCap -= (new AttackTable(combatFactors.Char, BuffedStats, combatFactors, combatFactors.CalcOpts, FW, true, false, false)).AnyNotLand;
                    }
                    float useRamp = 0f;
                    if (CombatFactors.Char.WarriorTalents.Rampage > 0f)
                    {
                        useRamp = 0.05f + 0.02f;
                    }
                    float[] passiveContrsVals = new float[] {
                        0.03192f,
                        AgilityCritBonus,
                        StatConversion.GetCritFromRating(BuffedStats.CritRating),
                        BuffsStats.PhysicalCrit + useRamp,
                    };
                    float passiveContrsTtlVal = passiveContrsVals[0] + passiveContrsVals[1]
                                                + passiveContrsVals[2] + passiveContrsVals[3];
                    string[] passiveContrs = new string[] { "Base Crit", "From Agility", "From Crit Rating", "Buffs" };

                    //float WhUnProcdCrit = StatConversion.GetCritFromRating(BuffedStats.CritRating + BuffedStats.DeathbringerProc);
                    float WhProcdCrit            = StatConversion.GetCritFromRating(MaximumStats.CritRating - BuffedStats.CritRating);
                    bool  isWhUnProcdOverCap     = passiveContrsTtlVal > WhCritCap;
                    bool  isWhProcdOverCap       = passiveContrsTtlVal + WhProcdCrit > WhCritCap;
                    float amountWhUnProcdOverCap = Math.Abs(StatConversion.GetRatingFromCrit(WhCritCap - passiveContrsTtlVal));
                    float amountWhProcdOverCap   = Math.Abs(StatConversion.GetRatingFromCrit(WhCritCap - (passiveContrsTtlVal + WhProcdCrit)));

                    //float YwUnProcdCrit = StatConversion.GetCritFromRating(BuffedStats.CritRating + BuffedStats.DeathbringerProc);
                    //float YwProcdCrit = StatConversion.GetCritFromRating(MaximumStats.CritRating + MaximumStats.DeathbringerProc);
                    //bool isYwUnProcdOverCap = passiveContrsTtlVal + YwUnProcdCrit > YwCritCap;
                    //bool isYwProcdOverCap = passiveContrsTtlVal + YwProcdCrit > YwCritCap;
                    //float amountYwUnProcdOverCap = Math.Abs(StatConversion.GetRatingFromCrit(YwCritCap - (passiveContrsTtlVal + YwUnProcdCrit)));
                    //float amountYwProcdOverCap = Math.Abs(StatConversion.GetRatingFromCrit(YwCritCap - (passiveContrsTtlVal + YwProcdCrit)));

                    string theFormat = GenFormattedString(passiveContrs, true,
                                                          isWhUnProcdOverCap, isWhProcdOverCap
                                                          //isYwUnProcdOverCap, isYwProcdOverCap
                                                          );

                    dictValues.Add("Crit", string.Format(theFormat,
                                                         // Averaged Stats
                                                         CritPercent, AverageStats.CritRating,
                                                         // Passive Contributions
                                                         passiveContrsVals[0], passiveContrsVals[1],
                                                         passiveContrsVals[2], passiveContrsVals[3],
                                                         // UnProc'd Stats
                                                         BuffedStats.CritRating,
                                                         Math.Min(WhCritCap, passiveContrsTtlVal), amountWhUnProcdOverCap,
                                                         //Math.Min(YwCritCap, passiveContrsTtlVal + YwUnProcdCrit), amountYwUnProcdOverCap,
                                                         // Proc'd Stats
                                                         MaximumStats.CritRating,
                                                         Math.Min(WhCritCap, passiveContrsTtlVal + WhProcdCrit), amountWhProcdOverCap
                                                         //Math.Min(YwCritCap, passiveContrsTtlVal + YwProcdCrit), amountYwProcdOverCap
                                                         ));
                }
                #endregion
                #region Armor Penetration
                {
                    //float ArPCap = 1.00f;
                    //float[] passiveContrsVals = new float[] { 1.00f };
                    //float passiveContrsTtlVal = passiveContrsVals[0];
                    //string[] passiveContrs = new string[] { "Colossus Smash (6 sec/20 sec). Sudden Death resets cooldown sooner." };
                    //float UnProcdArP = StatConversion.GetArmorPenetrationFromRating(BuffedStats.ArmorPenetrationRating);
                    //float ProcdArP = StatConversion.GetArmorPenetrationFromRating(MaximumStats.ArmorPenetrationRating);
                    //bool isUnProcdOverCap = passiveContrsTtlVal + UnProcdArP > ArPCap;
                    //bool isProcdOverCap = passiveContrsTtlVal + ProcdArP > ArPCap;
                    //float amountUnProcdOverCap = Math.Abs(StatConversion.GetRatingFromArmorPenetration(ArPCap - (passiveContrsTtlVal + UnProcdArP)));
                    //float amountProcdOverCap = Math.Abs(StatConversion.GetRatingFromArmorPenetration(ArPCap - (passiveContrsTtlVal + ProcdArP)));
                    //string theFormat = GenFormattedString(passiveContrs, true, isUnProcdOverCap, isProcdOverCap);
                    dictValues.Add("Armor Penetration", string.Format("{0:0%}",                                        //theFormat,
                                                                                                                       // Averaged Stats
                                                                      ArmorPenetration + AverageStats.ArmorPenetration //, AverageStats.ArmorPenetrationRating,
                                                                                                                       // Passive Contributions
                                                                                                                       //passiveContrsVals[0],
                                                                                                                       // UnProc'd Stats
                                                                                                                       //BuffedStats.ArmorPenetrationRating,
                                                                                                                       //Math.Min(ArPCap, passiveContrsTtlVal + UnProcdArP),
                                                                                                                       //amountUnProcdOverCap,
                                                                                                                       // Proc'd Stats
                                                                                                                       //MaximumStats.ArmorPenetrationRating,
                                                                                                                       //Math.Min(ArPCap, passiveContrsTtlVal + ProcdArP),
                                                                                                                       //amountProcdOverCap
                                                                      ));
                }
                #endregion
                #region Haste
                {
                    // Haste has no cap? Shouldn't there be a 100% cap or something?
                    // We should also state the before/after effects of haste on white swings
                    // Maybe a good point to show how much swing time is lost to Slams too?
                    float heroism = 0f;
                    if (BuffsStats._rawSpecialEffectData != null)
                    {
                        foreach (SpecialEffect effect in BuffsStats._rawSpecialEffectData)
                        {
                            if (effect != null && effect.Stats.PhysicalHaste > 0)
                            {
                                heroism = effect.GetAverageStats().PhysicalHaste;
                            }
                        }
                    }
                    float[] passiveContrsVals = new float[] {
                        CombatFactors.Char.WarriorTalents.BloodFrenzy * 0.025f,
                            BuffsStats.PhysicalHaste,
                            heroism,
                    };
                    float passiveContrsTtlVal = (1f + passiveContrsVals[0])
                                                * (1f + passiveContrsVals[1])
                                                * (1f + passiveContrsVals[2])
                                                - 1f;
                    string[] passiveContrs = new string[] { "Blood Frenzy", "Buffs", "Heroism (Averaged)" };
                    float    UnProcdHaste  = StatConversion.GetHasteFromRating(BuffedStats.HasteRating, CharacterClass.Warrior);
                    float    ProcdHaste    = StatConversion.GetHasteFromRating(MaximumStats.HasteRating, CharacterClass.Warrior);
                    string   theFormat     = GenFormattedString(passiveContrs);

                    dictValues.Add("Haste", string.Format(theFormat,
                                                          // Averaged Stats
                                                          HastePercent, AverageStats.HasteRating,
                                                          // Passive Contributions
                                                          passiveContrsVals[0], passiveContrsVals[1], passiveContrsVals[2],
                                                          // UnProc'd Stats
                                                          BuffedStats.HasteRating,
                                                          (1f + passiveContrsTtlVal) * (1f + UnProcdHaste) - 1f,
                                                          // Proc'd Stats
                                                          MaximumStats.HasteRating,
                                                          (1f + passiveContrsTtlVal) * (1f + ProcdHaste) - 1f
                                                          ));
                }
                #endregion
                #region Hit
                {
                    // old
                    float HitPercent   = StatConversion.GetHitFromRating(HitRating);
                    float HitPercBonus = AverageStats.PhysicalHit;
                    // Hit Soft Cap ratings check, how far from it
                    float capA1         = StatConversion.WHITE_MISS_CHANCE_CAP[LevelDif];
                    float convcapA1     = (float)Math.Ceiling(StatConversion.GetRatingFromHit(capA1));
                    float sec2lastNumA1 = (convcapA1 - StatConversion.GetRatingFromHit(HitPercent) - StatConversion.GetRatingFromHit(HitPercBonus)) * -1;
                    //float lastNumA1    = StatConversion.GetRatingFromExpertise((convcapA1 - Math.Min(MhExpertise, (OhExpertise != 0 ? OhExpertise : MhExpertise))) * -1);
                    // Hit Hard Cap ratings check, how far from it
                    float capA2         = StatConversion.WHITE_MISS_CHANCE_CAP_DW[LevelDif];
                    float convcapA2     = (float)Math.Ceiling(StatConversion.GetRatingFromHit(capA2));
                    float sec2lastNumA2 = (convcapA2 - StatConversion.GetRatingFromHit(HitPercent) - StatConversion.GetRatingFromHit(HitPercBonus)) * -1;
                    //float lastNumA2   = StatConversion.GetRatingFromExpertise((sec2lastNumA2 - Math.Min(MhExpertise, (OhExpertise != 0 ? OhExpertise : MhExpertise))) * -1);
                    dictValues.Add("Hit",
                                   string.Format("{0:000.00%} : {1}*" + "{2:0.00%} : From Other Bonuses" +
                                                 "\r\n{3:0.00%} : Total Hit % Bonus" +
                                                 "\r\n\r\nWhite Two-Hander Cap: " +
                                                 (sec2lastNumA1 > 0 ? "You can free {4:0} Rating"
                                                           : "You need {4:0} more Rating") +
                                                 "\r\nWhite Dual Wield Cap: " +
                                                 (sec2lastNumA2 > 0 ? "You can free {5:0} Rating"
                                                           : "You need {5:0} more Rating"),
                                                 StatConversion.GetHitFromRating(AverageStats.HitRating),
                                                 AverageStats.HitRating,
                                                 HitPercBonus,
                                                 HitPercent + HitPercBonus,
                                                 (sec2lastNumA1 > 0 ? sec2lastNumA1 : sec2lastNumA1 * -1),
                                                 (sec2lastNumA2 > 0 ? sec2lastNumA2 : sec2lastNumA2 * -1)
                                                 ));
                }
                #endregion
                #region Expertise
                {
                    // Dodge Cap ratings check, how far from it, uses lesser of MH and OH
                    // Also factors in Weapon Mastery
                    float capB1         = StatConversion.YELLOW_DODGE_CHANCE_CAP[LevelDif];
                    float convcapB1     = (float)Math.Ceiling(StatConversion.GetExpertiseFromDodgeParryReduc(capB1));
                    float sec2lastNumB1 = (convcapB1 - Math.Min(MHExpertise, (OHExpertise != 0 ? OHExpertise : MHExpertise))) * -1;
                    float lastNumB1     = StatConversion.GetRatingFromExpertise((convcapB1 - Math.Min(MHExpertise, (OHExpertise != 0 ? OHExpertise : MHExpertise))) * -1);
                    // Parry Cap ratings check, how far from it, uses lesser of MH and OH
                    float capB2         = StatConversion.YELLOW_PARRY_CHANCE_CAP[LevelDif];
                    float convcapB2     = (float)Math.Ceiling(StatConversion.GetExpertiseFromDodgeParryReduc(capB2));
                    float sec2lastNumB2 = (convcapB2 - Math.Min(MHExpertise, (OHExpertise != 0 ? OHExpertise : MHExpertise))) * -1;
                    float lastNumB2     = StatConversion.GetRatingFromExpertise((convcapB2 - Math.Min(MHExpertise, (OHExpertise != 0 ? OHExpertise : MHExpertise))) * -1);
                    dictValues.Add("Expertise",
                                   string.Format("{0:000.00%} : {1:00.00} : {2}*" +
                                                 "Following includes Racial bonus" +
                                                 "\r\n{3:00.00%} : {4:00.00} : MH" +
                                                 "\r\n{5:00.00%} : {6:00.00} : OH" +
                                                 "\r\n\r\n" + "Dodge Cap: " +
                                                 (lastNumB1 > 0 ? "You can free {7:0} Expertise ({8:0} Rating)"
                                     : "You need {7:0} more Expertise ({8:0} Rating)") +
                                                 "\r\n" + "Parry Cap: " +
                                                 (lastNumB2 > 0 ? "You can free {9:0} Expertise ({10:0} Rating)"
                                     : "You need {9:0} more Expertise ({10:0} Rating)"),
                                                 StatConversion.GetDodgeParryReducFromExpertise(Expertise),
                                                 Expertise,
                                                 AverageStats.ExpertiseRating,
                                                 StatConversion.GetDodgeParryReducFromExpertise(MHExpertise), MHExpertise,
                                                 StatConversion.GetDodgeParryReducFromExpertise(OHExpertise), OHExpertise,
                                                 (sec2lastNumB1 > 0 ? sec2lastNumB1 : sec2lastNumB1 * -1), (lastNumB1 > 0 ? lastNumB1 : lastNumB1 * -1),
                                                 (sec2lastNumB2 > 0 ? sec2lastNumB2 : sec2lastNumB2 * -1), (lastNumB2 > 0 ? lastNumB2 : lastNumB2 * -1)
                                                 ));
                }
                #endregion
                #region Mastery
                {
                    dictValues.Add("Mastery",
                                   string.Format("{0:000.00} : {1:00.00}*" + "The Pane shows Averaged Values*", MasteryVal, AverageStats.MasteryRating)
                                   + (CombatFactors.FuryStance ?
                                      string.Format(
                                          @"As a Fury Warrior, you are being granted the Unshackled Fury ability.
Increases the benefit of abilities that cause or require you to be enraged by (44.8%+{0:0.0%}={1:0.0%}).
Each point of Mastery increases enrage effects by an additional 5.60%.

Also, it is changing the following:
Increases the Weapon Damage of Raging Blow
Increases the damage bonus of Death Wish and Enrage
Increases the healing of Enraged Regeneration
Increases the Rage generated by Berserker Rage through Glyph of Berserker Rage
(Might increase rage generation through damage taken with Berserker Rage active,
I'm not sure, and it's a bit hard for me to test, any input on this would be appreciated.)",
                                          MasteryVal * 0.056f, 8f * 0.056f + MasteryVal * 0.056f)
                         :
                                      string.Format(
                                          @"As an Arms Warrior, you are being granted the Strikes of Opportunity ability.
Grants a (16%+{0:0.0%}={1:0.0%}) chance for your melee attacks to instantly
trigger an additional melee attack for {2:0%} normal damage. Each point of
Mastery increases this chance by 2%.",
                                          MasteryVal * Skills.StrikesOfOpportunity.BonusChance,
                                          Skills.StrikesOfOpportunity.BaseChance + MasteryVal * Skills.StrikesOfOpportunity.BonusChance,
                                          Skills.StrikesOfOpportunity.DamageModifier)
                                      )

                                   /*// Averaged Stats
                                    * AverageStats.Mastery,
                                    * // Passive Contributions
                                    * passiveContrsVals[0], passiveContrsVals[1], passiveContrsVals[2],
                                    * // UnProc'd Stats
                                    * BuffedStats.Mastery,
                                    * BuffedStats.Mastery * 2f,
                                    * // Proc'd Stats
                                    * MaximumStats.Mastery,
                                    * StatConversion.GetMasteryFromRating MaximumStats.Mastery * 2f*/
                                   );
                }
                #endregion

                dictValues.Add("Description 1", string.Format("DPS  : PerHit  : #ActsD"));
                dictValues.Add("Description 2", string.Format("DPS  : PerHit  : #ActsD"));
                dictValues.Add("Description 3", string.Format("DPS  : PerHit  : #ActsD"));
                // DPS Abilities
                format = "{0:0000} : {1:00000} : {2:000.00}";
                if (TotalDPS < 0f)
                {
                    TotalDPS = 0f;
                }
                foreach (AbilityWrapper aw in Rot.TheAbilityList)
                {
                    if (aw.Ability is Skills.Rend)
                    {
                        AbilityWrapper TH     = Rot.GetWrapper <Skills.ThunderClap>();
                        Skills.Rend    rend   = (aw.Ability as Skills.Rend);
                        float          DPSO20 = rend.GetDPS(aw.NumActivatesO20, TH.NumActivatesO20, rend.TimeOver20Perc);
                        float          DPSU20 = rend.GetDPS(aw.NumActivatesU20, TH.NumActivatesU20, rend.TimeUndr20Perc);
                        float          allDPS = DPSU20 > 0 ? DPSO20 * rend.TimeOver20Perc + DPSU20 * rend.TimeUndr20Perc : DPSO20; // Average above and below
                        dictValues.Add(aw.Ability.Name, string.Format(format, allDPS, rend.TickSize * rend.NumTicks, aw.AllNumActivates)
                                       + rend.GenTooltip(aw.AllNumActivates, DPSO20, DPSU20, allDPS / TotalDPS));
                    }
                    else
                    {
                        dictValues.Add(aw.Ability.Name, string.Format(format, aw.AllDPS, aw.Ability.DamageOnUse, aw.AllNumActivates)
                                       + aw.Ability.GenTooltip(aw.AllNumActivates, aw.DPS_O20, aw.DPS_U20, aw.AllDPS / TotalDPS));
                    }
                }
                // DPS General
                dictValues.Add("Deep Wounds", string.Format("{0:0000}*{1:00.0%} of DPS", Rot.DW.TickSize, Rot.DW.TickSize <= 0f || TotalDPS <= 0f ? 0f : Rot.DW.TickSize / TotalDPS));
                dictValues.Add("Special DMG Procs", string.Format("{0:0000} : {1:00000} : {2:000.00}*{3:00.0%} of DPS",
                                                                  SpecProcDPS, SpecProcDmgPerHit, SpecProcActs,
                                                                  SpecProcDPS <= 0f || TotalDPS <= 0f ? 0f : SpecProcDPS / TotalDPS));
                dictValues.Add("White DPS", string.Format("{0:0000} : {1:00000} : {2:000.00}", WhiteDPS, WhiteDmg, Whites.MHActivatesAll + Whites.OHActivatesAll)
                               + Whites.GenTooltip(WhiteDPSMH, WhiteDPSOH, TotalDPS, WhiteDPSMH_U20, WhiteDPSOH_U20));
                dictValues.Add("Total DPS", string.Format("{0:#,##0} : {1:#,###,##0}*" + ((!string.IsNullOrEmpty(Rot.GCDUsage) ? Rot.GCDUsage : "No GCD Usage*") + (CombatFactors.FuryStance ? "Fury isn't Cata Ready" : "")), TotalDPS, TotalDPS * Duration));
                // Rage
                format = "{0:0000}";
                dictValues.Add("Description 4", string.Format("Gen'd: Need : Avail"));
                dictValues.Add("Rage Above 20%", string.Format("{0:0000} : {1:0000} : {2:0000}", WhiteRageO20 + OtherRageO20, NeedyRageO20, FreeRageO20));
                dictValues.Add("Rage Below 20%", string.Format("{0:0000} : {1:0000} : {2:0000}", WhiteRageU20 + OtherRageU20, NeedyRageU20, FreeRageU20));
            } catch (Exception ex) {
                new Base.ErrorBox()
                {
                    Title        = "Error in creating Stat Pane Dictionaries",
                    Function     = "GetCharacterDisplayCalculationValues()",
                    TheException = ex,
                }.Show();
            }
            return(dictValues);
        }
Exemple #11
0
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string> dictValues = new Dictionary <string, string>();

            //string format = "";
            CalcOpts = character.CalculationOptions as CalculationOptionsHunter;

            // Basic Stats
            dictValues.Add("Health and Stamina", string.Format("{0:##,##0} : {1:##,##0}*{2:00,000} : Base Health" +
                                                               "\r\n{3:00,000} : Stam Bonus",
                                                               BasicStats.Health, BasicStats.Stamina, BaseHealth, StatConversion.GetHealthFromStamina(BasicStats.Stamina)));
            dictValues.Add("Mana", BasicStats.Mana.ToString("F0"));
            dictValues.Add("Armor", BasicStats.Armor.ToString("F0"));
            dictValues.Add("Agility", BasicStats.Agility.ToString("F0"));
            dictValues.Add("Ranged Attack Power", string.Format("{0:0000}*Includes:" +
                                                                "\r\n{1:0000} : Base" +
                                                                "\r\n{2:0000} : Agility" +
                                                                "\r\n{3:0000} : Gear" +
                                                                "\r\nProcs were averaged out and added",
                                                                apTotal, apFromBase, apFromAGI, apFromGear));
            dictValues.Add("Intellect", BasicStats.Intellect.ToString("F0"));
            // old
            float HitPercent   = StatConversion.GetHitFromRating(BasicStats.HitRating);
            float HitPercBonus = BasicStats.PhysicalHit - HitPercent;

            // Hit Soft Cap ratings check, how far from it
#if RAWR3 || SILVERLIGHT
            float capA1 = StatConversion.WHITE_MISS_CHANCE_CAP[BossOpts.Level - character.Level];
#else
            float capA1 = StatConversion.WHITE_MISS_CHANCE_CAP[CalcOpts.TargetLevel - character.Level];
#endif
            float convcapA1     = (float)Math.Ceiling(StatConversion.GetRatingFromHit(capA1));
            float sec2lastNumA1 = (convcapA1 - StatConversion.GetRatingFromHit(HitPercent) - StatConversion.GetRatingFromHit(HitPercBonus)) * -1;
            dictValues.Add("Hit",
                           string.Format("{0:00.00%} : {1}*" + "{2:0.00%} : From Other Bonuses" +
                                         Environment.NewLine + "{3:0.00%} : Total Hit % Bonus" +
                                         Environment.NewLine + Environment.NewLine + "Ranged Cap: " +
                                         (sec2lastNumA1 > 0 ? "You can free {4:0} Rating"
                                                   : "You need {4:0} more Rating"),
                                         StatConversion.GetHitFromRating(BasicStats.HitRating),
                                         BasicStats.HitRating,
                                         HitPercBonus,
                                         HitPercent + HitPercBonus,
                                         (sec2lastNumA1 > 0 ? sec2lastNumA1 : sec2lastNumA1 * -1)
                                         ));
            dictValues.Add("Crit", string.Format("{0:00.00%} : {1}*Includes:" +
                                                 "\r\n{2:00.00%} : Base Crit" +
                                                 "\r\n{3:00.00%} : Agility" +
                                                 "\r\n{4:00.00%} : Rating" +
                                                 "\r\n{5:00.00%} : Racial" +
                                                 "\r\n{6:00.00%} : Proc Effects" +
                                                 "\r\n{7:00.00%} : Lethal Shots" +
                                                 "\r\n{8:00.00%} : Killer Instincts" +
                                                 "\r\n{9:00.00%} : Master Marksman" +
                                                 "\r\n{10:00.00%} : Master Tactician" +
                                                 "\r\n{11:00.00%} : Buffs & Debuffs" +
                                                 "\r\n{12:00.00%} : Level Adjustment" +
                                                 "\r\n\r\nNote that individual Shots will handle their own crit caps",
                                                 critRateOverall, BasicStats.CritRating,
                                                 critBase, critFromAgi, critFromRating, critFromRacial,
                                                 critFromProcRating, critFromLethalShots, critFromKillerInstincts,
                                                 critFromMasterMarksman, critFromMasterTactician, critFromBuffs,
                                                 critFromDepression * -1f));
            dictValues.Add("Armor Penetration", string.Format("{0:00.00%} : {1}" + "*Enemy's Damage Reduction from armor: {2:00.00%}",
                                                              StatConversion.GetArmorPenetrationFromRating(BasicStats.ArmorPenetrationRating),
                                                              BasicStats.ArmorPenetrationRating,
                                                              damageReductionFromArmor));
            dictValues.Add("Haste", string.Format("{0:00.00%} : {1:0}*Includes:" +
                                                  "\r\n{2:00.00%} : Base" +
                                                  "\r\n{3:00.00%} : Rating" +
                                                  "\r\n{4:00.00%} : Serpent's Swiftness" +
                                                  "\r\n{5:00.00%} : Buffs" +
                                                  "\r\n{6:00.00%} : Rapid Fire" +
                                                  "\r\n{7:00.00%} : Proc Effects",
                                                  BasicStats.PhysicalHaste, BasicStats.HasteRating,
                                                  hasteFromBase, hasteFromRating, hasteFromTalentsStatic, hasteFromRangedBuffs,
                                                  hasteFromRapidFire, hasteFromProcs));
            dictValues.Add("Attack Speed", BaseAttackSpeed.ToString("F2"));

            // Pet Stats
            dictValues.Add("Pet Attack Power", pet.PetStats.AttackPower.ToString("F0") +
                           string.Format("*Full Pet Stats:\r\n"
                                         + "Strength: {0:0.0}\r\n"
                                         + "Agility: {1:0.0}\r\n"
                                         + "Hit: {2:0.00%}\r\n"
                                         + "PhysCrit: {3:0.00%}\r\n"
                                         + "PhysHaste: {4:0.00%}\r\n",
                                         pet.PetStats.Strength,
                                         pet.PetStats.Agility,
                                         pet.PetStats.PhysicalHit,
                                         pet.PetStats.PhysicalCrit,
                                         pet.PetStats.PhysicalHaste));
            dictValues.Add("Pet Hit %", petHitTotal.ToString("P2"));
            dictValues.Add("Pet Dodge %", petTargetDodge.ToString("P2"));
            dictValues.Add("Pet Melee Crit %", petCritTotalMelee.ToString("P2") + "*includes:\n" +
                           petCritFromBase.ToString("P2") + " from base\n" +
                           petCritFromAgility.ToString("P2") + " from agility\n" +
                           petCritFromSpidersBite.ToString("P2") + " from Spider's Bite\n" +
                           petCritFromFerocity.ToString("P2") + " from Ferocity\n" +
                           petCritFromGear.ToString("P2") + " from gear\n" +
                           petCritFromBuffs.ToString("P2") + " from buffs\n" +
                           petCritFromTargetDebuffs.ToString("P2") + " from target debuffs\n" +
                           petCritFromDepression.ToString("P2") + " from depression");
            dictValues.Add("Pet Specials Crit %", petCritTotalSpecials.ToString("P2") + "*includes:\n" +
                           petCritTotalMelee.ToString("P2") + " from melee crit\n" +
                           petCritFromCobraStrikes.ToString("P2") + " from Cobra Strikes");
            dictValues.Add("Pet White DPS", petWhiteDPS.ToString("F2"));
            dictValues.Add("Pet Kill Command DPS", petKillCommandDPS.ToString("F2"));
            dictValues.Add("Pet Specials DPS", petSpecialDPS.ToString("F2") /*+
                                                                             * string.Format("Breakout:\r\n"
                                                                             + "Furious Howl: Use {0} DPS {1:0.00}"
                                                                             + "Bite: Use {2} DPS {3:0.00}",
                                                                             + pet.priorityRotation.getSkillFrequency(PetAttacks.FuriousHowl), 0f,
                                                                             + pet.priorityRotation.getSkillFrequency(PetAttacks.Bite), pet.priorityRotation.dps - petWhiteDPS)*/);

            // Shot Stats
            dictValues.Add("Aimed Shot", aimedShot.GenTooltip());
            dictValues.Add("Arcane Shot", arcaneShot.GenTooltip());
            dictValues.Add("Multi Shot", multiShot.GenTooltip());
            dictValues.Add("Silencing Shot", silencingShot.GenTooltip());
            dictValues.Add("Steady Shot", steadyShot.GenTooltip());
            dictValues.Add("Kill Shot", killShot.GenTooltip());
            dictValues.Add("Explosive Shot", explosiveShot.GenTooltip());
            dictValues.Add("Black Arrow", blackArrow.GenTooltip());
            dictValues.Add("Volley", volley.GenTooltip());
            dictValues.Add("Chimera Shot", chimeraShot.GenTooltip());

            //dictValues.Add("Rapid Fire", rapidFire.GenTooltip());
            //dictValues.Add("Readiness", readiness.GenTooltip());
            //dictValues.Add("Bestial Wrath", bestialWrath.GenTooltip());

            // Sting Stats
            dictValues.Add("Serpent Sting", serpentSting.GenTooltip());
            dictValues.Add("Scorpid Sting", scorpidSting.GenTooltip());
            dictValues.Add("Viper Sting", viperSting.GenTooltip());

            // Trap Stats
            dictValues.Add("Immolation Trap", immolationTrap.GenTooltip());
            dictValues.Add("Explosive Trap", explosiveTrap.GenTooltip());
            dictValues.Add("Freezing Trap", freezingTrap.GenTooltip());
            dictValues.Add("Frost Trap", frostTrap.GenTooltip());

            // Mana
            dictValues.Add("Mana Usage Per Second", manaUsageTotal.ToString("F2") + "*includes:\n" +
                           manaUsageRotation.ToString("F2") + " from shot rotation\n" +
                           manaUsageKillCommand.ToString("F2") + " from Kill Command");
            dictValues.Add("Mana Regen Per Second", manaRegenTotal.ToString("F2") + "*includes:\n" +
                           (manaRegenGearBuffs + manaRegenConstantViper + manaRegenViper + manaRegenRoarOfRecovery
                            + manaRegenRapidRecuperation + manaRegenChimeraViperProc + manaRegenInvigoration
                            + manaRegenHuntingParty + manaRegenTargetDebuffs + manaRegenFromPots > 0f ?
                            (manaRegenGearBuffs != 0 ? manaRegenGearBuffs.ToString("F2") + " from Gear and Buffs\n" : "") +
                            (manaRegenConstantViper != 0 ? manaRegenConstantViper.ToString("F2") + " from Constant Aspect of the Viper\n" : "") +
                            (manaRegenViper != 0 ? manaRegenViper.ToString("F2") + " from Aspect of the Viper\n" : "") +
                            (manaRegenRoarOfRecovery != 0 ? manaRegenRoarOfRecovery.ToString("F2") + " from Roar of Recovery\n" : "") +
                            (manaRegenRapidRecuperation != 0 ? manaRegenRapidRecuperation.ToString("F2") + " from Rapid Recuperation\n" : "") +
                            (manaRegenChimeraViperProc != 0 ? manaRegenChimeraViperProc.ToString("F2") + " from Chimera Viper String Proc\n" : "") +
                            (manaRegenInvigoration != 0 ? manaRegenInvigoration.ToString("F2") + " from Invigoration\n" : "") +
                            (manaRegenHuntingParty != 0 ? manaRegenHuntingParty.ToString("F2") + " from Hunting Party\n" : "") +
                            (manaRegenTargetDebuffs != 0 ? manaRegenTargetDebuffs.ToString("F2") + " from Target Debuffs\n" : "") +
                            (manaRegenFromPots != 0 ? manaRegenFromPots.ToString("F2") + " from Pots" : "")
                : "Nothing to add")
                           );
            dictValues.Add("Normal Change", manaChangeDuringNormal.ToString("F2"));
            dictValues.Add("Change during Viper", manaChangeDuringViper.ToString("F2"));
            dictValues.Add("Time to OOM", manaTimeToOOM.ToString("F2"));
            dictValues.Add("Time to Full", manaTimeToFull.ToString("F2"));
            dictValues.Add("Viper Damage Penalty", aspectViperPenalty.ToString("P2"));
            dictValues.Add("Viper Uptime", aspectUptimeViper.ToString("P2"));
            dictValues.Add("No Mana Damage Penalty", NoManaDPSDownTimePerc.ToString("P2"));

            // Hunter DPS
            dictValues.Add("Autoshot DPS", AutoshotDPS.ToString("F2"));
            dictValues.Add("Priority Rotation DPS", CustomDPS.ToString("F2"));
            dictValues.Add("Wild Quiver DPS", WildQuiverDPS.ToString("F2"));
            dictValues.Add("Kill Shot low HP gain", killShotSub20FinalGain.ToString("F2") + "*" +
                           "Kill Shot freq: " + killShot.Freq.ToString("F2") + " -> " + killShot.start_freq.ToString("F2") + "\n" +
                           "Steady Shot freq: " + steadyShot.Freq.ToString("F2") + " -> " + killShotSub20NewSteadyFreq.ToString("F2") + "\n" +
                           "Kill Shot DPS: " + killShot.DPS.ToString("F2") + " -> " + killShotSub20NewDPS.ToString("F2") + "\n" +
                           "Steady Shot DPS: " + steadyShot.DPS.ToString("F2") + " -> " + killShotSub20NewSteadyDPS.ToString("F2") + "\n" +
                           "DPS Gain when switched: " + killShotSub20Gain.ToString("F2") + "\n" +
                           "Time spent sub-20%: " + killShotSub20TimeSpent.ToString("P2"));
            dictValues.Add("Aspect Loss", aspectBeastLostDPS.ToString("F2") + "*" +
                           "Hawk Uptime: " + aspectUptimeHawk.ToString("P2") + "\n" +
                           "Viper Uptime: " + aspectUptimeViper.ToString("P2") + "\n" +
                           "Beast Uptime: " + aspectUptimeBeast.ToString("P2"));
            dictValues.Add("Piercing Shots DPS", PiercingShotsDPS.ToString("F2") + "*" +
                           "Steady Shot: " + PiercingShotsDPSSteadyShot.ToString("F2") + "\n" +
                           "Aimed Shot: " + PiercingShotsDPSAimedShot.ToString("F2") + "\n" +
                           "Chimera Shot: " + PiercingShotsDPSChimeraShot.ToString("F2") + "\n");
            dictValues.Add("Special DMG Procs DPS", SpecProcDPS.ToString("F2"));

            // Combined DPS
            string zod = (BonusAttackProcsDPS != 0 ? string.Format("*Includes:\r\nZod's Proc: {0:0.0}", BonusAttackProcsDPS) : "");
            dictValues.Add("Hunter DPS", HunterDpsPoints.ToString("F2") + zod);
            dictValues.Add("Pet DPS", PetDpsPoints.ToString("F2"));
            dictValues.Add("Total DPS", OverallPoints.ToString("F2"));

            return(dictValues);
        }