public override CharacterCalculationsBase GetCharacterCalculations(Character character, Item additionalItem)
        {
            Stats stats     = GetCharacterStats(character, additionalItem);
            Stats statsRace = GetRaceStats(character);
            CharacterCalculationsShadowPriest calculatedStats    = new CharacterCalculationsShadowPriest();
            CalculationOptionsShadowPriest    calculationOptions = character.CalculationOptions as CalculationOptionsShadowPriest;

            calculatedStats.BasicStats         = stats;
            calculatedStats.Talents            = character.Talents;
            calculatedStats.CalculationOptions = calculationOptions;

            calculatedStats.BasicStats.Spirit = statsRace.Spirit + (calculatedStats.BasicStats.Spirit - statsRace.Spirit) * (1 + character.Talents.GetTalent("Spirit of Redemption").PointsInvested * 0.05f);

            calculatedStats.SpiritRegen = (float)Math.Floor(5 * 0.0093271 * calculatedStats.BasicStats.Spirit * Math.Sqrt(calculatedStats.BasicStats.Intellect));
            calculatedStats.RegenInFSR  = (float)Math.Floor((calculatedStats.BasicStats.Mp5 + character.Talents.GetTalent("Meditation").PointsInvested * 0.1f * calculatedStats.SpiritRegen * (1 + calculatedStats.BasicStats.SpellCombatManaRegeneration)));
            calculatedStats.RegenOutFSR = calculatedStats.BasicStats.Mp5 + calculatedStats.SpiritRegen;

            calculatedStats.BasicStats.SpellCrit = (float)Math.Round((calculatedStats.BasicStats.Intellect / 80) +
                                                                     (calculatedStats.BasicStats.SpellCritRating / 22.08) + 1.85, 2);

            calculatedStats.BasicStats.SpellDamageRating += calculatedStats.BasicStats.Spirit * character.Talents.GetTalent("Spiritual Guidance").PointsInvested * 0.05f;

            Solver solver = new Solver(stats, character.Talents, calculationOptions);

            solver.Calculate();

            calculatedStats.DpsPoints = solver.OverallDps;
            //int hitcap = GetSpellHitCap(character.Talents);
            //calculatedStats.DpsPoints = calculatedStats.BasicStats.SpellDamageRating + calculatedStats.BasicStats.SpellShadowDamageRating
            //    + (calculatedStats.BasicStats.SpellHasteRating)
            //    + (calculatedStats.BasicStats.SpellCritRating / 5.57f)
            //    + (calculatedStats.BasicStats.Spirit * 0.11f)
            //    + (calculatedStats.BasicStats.Intellect * 0.055f)
            //    - (calculatedStats.BasicStats.SpellHitRating < hitcap ? (hitcap - calculatedStats.BasicStats.SpellHitRating) * 1.364f: 0);

            calculatedStats.SurvivalPoints = calculatedStats.BasicStats.Stamina / 10;
            calculatedStats.OverallPoints  = calculatedStats.DpsPoints + calculatedStats.SurvivalPoints;

            return(calculatedStats);
        }
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string> dictValues = new Dictionary <string, string>();

            dictValues.Add("Health", BasicStats.Health.ToString());
            dictValues.Add("Stamina", BasicStats.Stamina.ToString());
            dictValues.Add("Mana", BasicStats.Mana.ToString());
            dictValues.Add("Intellect", BasicStats.Intellect.ToString());
            dictValues.Add("Spirit", Math.Floor(BasicStats.Spirit).ToString("0"));
            dictValues.Add("Shadow Damage", String.Format("{0}*Shadow: {1}\r\nSpell: {2}",
                                                          Math.Floor(BasicStats.SpellDamageRating + BasicStats.SpellShadowDamageRating),
                                                          Math.Floor(BasicStats.SpellShadowDamageRating),
                                                          Math.Floor(BasicStats.SpellDamageRating)));
            dictValues.Add("Regen", String.Format("{0}*InFSR: {0}\r\nOutFSR: {1}", RegenInFSR.ToString("0"), RegenOutFSR.ToString("0")));

            dictValues.Add("Spell Crit", string.Format("{0}%*{1} Spell Crit rating ({3}%)\r\n{2} ({4}%) points in Shadow Power",
                                                       BasicStats.SpellCrit + talents.GetTalent("Shadow Power").PointsInvested * 3,
                                                       BasicStats.SpellCritRating.ToString(),
                                                       talents.GetTalent("Shadow Power").PointsInvested, BasicStats.SpellCrit, talents.GetTalent("Shadow Power").PointsInvested * 3));

            int i = (int)Math.Round(CalculationsShadowPriest.GetSpellHitCap(talents) - BasicStats.SpellHitRating);

            dictValues.Add("Spell Hit", string.Format("{0}*{1}",
                                                      BasicStats.SpellHitRating,
                                                      (i > 0)? i + " requires to reach hit cap": i == 0? "Exactly hit cap": (-i) + " over hit cap"));


            dictValues.Add("Spell Haste", string.Format("{0}%*{1} Spell Haste rating\n",
                                                        Math.Round(BasicStats.SpellHasteRating / 15.7, 2), BasicStats.SpellHasteRating.ToString()));
            dictValues.Add("Global Cooldown", Spell.GetGlobalCooldown(BasicStats).ToString("0.00"));

            dictValues.Add("Shadow Word Pain", new ShadowWordPain(BasicStats, talents).ToString());
            dictValues.Add("Shadow Word Death", new ShadowWordDeath(BasicStats, talents).ToString());
            dictValues.Add("Mind Blast", new MindBlast(BasicStats, talents).ToString());
            dictValues.Add("Power Word Shield", new PowerWordShield(BasicStats, talents).ToString());

            if (talents.GetTalent("Vampiric Embrace").PointsInvested > 0)
            {
                dictValues.Add("Vampiric Embrace", new VampiricEmbrace(BasicStats, talents).ToString());
            }
            else
            {
                dictValues.Add("Vampiric Embrace", "- *No required talents");
            }

            if (talents.GetTalent("Vampiric Touch").PointsInvested > 0)
            {
                dictValues.Add("Vampiric Touch", new VampiricTouch(BasicStats, talents).ToString());
            }
            else
            {
                dictValues.Add("Vampiric Touch", "- *No required talents");
            }

            if (talents.GetTalent("Mind Flay").PointsInvested > 0)
            {
                dictValues.Add("Mind Flay", new MindFlay(BasicStats, talents).ToString());
            }
            else
            {
                dictValues.Add("Mind Flay", "- *No required talents");
            }

            Solver solver = new Solver(BasicStats, talents, CalculationOptions);

            solver.Calculate();

            dictValues.Add("Damage done", solver.OverallDamage.ToString());
            dictValues.Add("Dps", solver.OverallDps.ToString());

            return(dictValues);
        }