Example #1
0
        //
        // Data for custom charts:
        //
        public override ComparisonCalculationBase[] GetCustomChartData(Character character, string chartName)
        {
            CharacterCalculationsRestoSham calc = GetCharacterCalculations(character) as CharacterCalculationsRestoSham;

            if (calc == null)
            {
                calc = new CharacterCalculationsRestoSham();
            }

            CalculationOptionsRestoSham options = character.CalculationOptions as CalculationOptionsRestoSham;

            if (options == null)
            {
                options = new CalculationOptionsRestoSham();
            }

            List <ComparisonCalculationBase> list = new List <ComparisonCalculationBase>();

            switch (chartName)
            {
            case "Stat Relative Weights":
                StatRelativeWeight[] stats = new StatRelativeWeight[] {
                    new StatRelativeWeight("Int", new Stats()
                    {
                        Intellect = 1f
                    }),
                    new StatRelativeWeight("Spirit", new Stats()
                    {
                        Spirit = 1f
                    }),
                    new StatRelativeWeight("+Heal", new Stats()
                    {
                        Healing = 1f
                    }),
                    new StatRelativeWeight("Mp5", new Stats()
                    {
                        Mp5 = 1f
                    }),
                    new StatRelativeWeight("Spell Crit", new Stats()
                    {
                        SpellCritRating = 1f
                    })
                };

                // Get the percentage total healing is changed by a change in a single stat:

                float healPct = 0f;
                foreach (StatRelativeWeight weight in stats)
                {
                    CharacterCalculationsRestoSham statCalc = (CharacterCalculationsRestoSham)GetCharacterCalculations(character, null, weight.Stat);
                    weight.PctChange = (statCalc.TotalHealed - calc.TotalHealed) / calc.TotalHealed;
                    if (weight.Name == "+Heal")
                    {
                        healPct = weight.PctChange;
                    }
                }

                // Create the chart data points:

                foreach (StatRelativeWeight weight in stats)
                {
                    ComparisonCalculationRestoSham comp = new ComparisonCalculationRestoSham(weight.Name);
                    comp.OverallPoints = weight.PctChange / healPct;
                    comp.SubPoints[0]  = comp.OverallPoints;
                    list.Add(comp);
                }

                break;

            case "Healing Spell Ranks":
                // Healing Wave ranks:

                for (int i = 1; i <= 12; i++)
                {
                    HealingWave hw = new HealingWave(i);
                    hw.Calcluate(calc.BasicStats, character);
                    ComparisonCalculationRestoSham comp = new ComparisonCalculationRestoSham(hw.FullName);
                    comp.OverallPoints = hw.AverageHealed + hw.HealingWay;
                    comp.SubPoints[0]  = hw.AverageHealed;
                    comp.SubPoints[3]  = hw.HealingWay;
                    list.Add(comp);
                }

                // Lesser Healing Wave ranks:

                for (int i = 1; i <= 7; i++)
                {
                    LesserHealingWave lhw = new LesserHealingWave(i);
                    lhw.Calcluate(calc.BasicStats, character);
                    ComparisonCalculationRestoSham comp = new ComparisonCalculationRestoSham(lhw.FullName);
                    comp.OverallPoints = comp.SubPoints[0] = lhw.AverageHealed;
                    list.Add(comp);
                }

                // Chain Heal ranks:

                for (int i = 1; i <= 5; i++)
                {
                    ChainHeal ch = new ChainHeal(i);
                    ch.Calcluate(calc.BasicStats, character);
                    ComparisonCalculationRestoSham comp = new ComparisonCalculationRestoSham(ch.FullName);
                    comp.OverallPoints = ch.TotalHealed;
                    for (int j = 0; j < 3; j++)
                    {
                        comp.SubPoints[j] = ch.HealsOnTargets[j];
                    }
                    list.Add(comp);
                }

                // The Draenei racial:

                if (character.Race == Character.CharacterRace.Draenei)
                {
                    GiftOfTheNaaru gift = new GiftOfTheNaaru();
                    gift.Calcluate(calc.BasicStats, character);
                    ComparisonCalculationRestoSham comp = new ComparisonCalculationRestoSham(gift.FullName);
                    comp.OverallPoints = comp.SubPoints[0] = gift.AverageHealed;
                    list.Add(comp);
                }

                break;
            }

            ComparisonCalculationBase[] retVal = new ComparisonCalculationBase[list.Count];
            if (list.Count > 0)
            {
                list.CopyTo(retVal);
            }
            return(retVal);
        }
Example #2
0
        public CharacterCalculationsBase GetCharacterCalculations(Character character, Item additionalItem,
                                                                  Stats statModifier)
        {
            Stats stats = GetCharacterStats(character, additionalItem, statModifier);
            CharacterCalculationsRestoSham calcStats = new CharacterCalculationsRestoSham();

            calcStats.BasicStats = stats;

            calcStats.Mp5OutsideFSR = 5f * (.001f + (float)Math.Sqrt((double)stats.Intellect) * stats.Spirit * .009327f) + stats.Mp5;
            calcStats.SpellCrit     = .022f + ((stats.Intellect / 80f) / 100) + ((stats.SpellCritRating / 22.08f) / 100) +
                                      stats.SpellCrit;

            CalculationOptionsRestoSham options = character.CalculationOptions as CalculationOptionsRestoSham;

            // Total Mana Pool for the fight:

            float onUse = 0.0f;

            if (options.ManaPotTime > 0)
            {
                onUse += (float)Math.Truncate(options.FightLength / options.ManaPotTime) *
                         (options.ManaPotAmount * (1 + stats.BonusManaPotion));
            }
            if (options.ManaTideEveryCD)
            {
                onUse += ((float)Math.Truncate(options.FightLength / 5.025f) + 1) * (stats.Mana * .24f);
            }

            float mp5 = (stats.Mp5 * (1f - (options.OutsideFSRPct / 100f)));

            mp5 += (calcStats.Mp5OutsideFSR * (options.OutsideFSRPct / 100f));
            mp5 += options.SPriestMP5;
            if (character.ActiveBuffsContains("Mana Spring Totem"))
            {
                int points = GetTalentPoints("Restorative Totems", "Restoration", character.Talents);
                mp5 += 50f * (points * .05f);

                mp5 += stats.ManaSpringMp5Increase;
            }

            calcStats.TotalManaPool = stats.Mana + onUse + (mp5 * (60f / 5f) * options.FightLength);

            // Get a list of the heals we're casting, and assign relative weights to them:

            List <HealSpell> list       = new List <HealSpell>();
            float            totalRatio = options.HWRatio + options.LHWRatio + options.CHRatio;

            if (options.LHWRatio > 0)
            {
                LesserHealingWave lhw = new LesserHealingWave();
                lhw.Calcluate(stats, character);
                lhw.Weight = options.LHWWeight;
                list.Add(lhw);
            }

            if (options.HWRatio > 0)
            {
                if (options.HWDownrank.Ratio > 0)
                {
                    HealingWave hw = new HealingWave(options.HWDownrank.MaxRank);
                    hw.Calcluate(stats, character);
                    hw.Weight = options.HWWeight * (options.HWDownrank.Ratio / 100f);
                    list.Add(hw);
                }
                if (options.HWDownrank.Ratio < 100)
                {
                    HealingWave hw = new HealingWave(options.HWDownrank.MinRank);
                    hw.Calcluate(stats, character);
                    hw.Weight = options.HWWeight * ((100 - options.HWDownrank.Ratio) / 100f);
                    list.Add(hw);
                }
            }

            if (options.CHRatio > 0)
            {
                if (options.CHDownrank.Ratio > 0)
                {
                    ChainHeal ch = new ChainHeal(options.CHDownrank.MaxRank);
                    ch.Calcluate(stats, character);
                    ch.Weight = options.CHWeight * (options.CHDownrank.Ratio / 100f);
                    list.Add(ch);
                }
                if (options.CHDownrank.Ratio < 100)
                {
                    ChainHeal ch = new ChainHeal(options.CHDownrank.MinRank);
                    ch.Calcluate(stats, character);
                    ch.Weight = options.CHWeight * ((100 - options.CHDownrank.Ratio) / 100f);
                    list.Add(ch);
                }
            }

            // Now get weighted average heal, weighted average mana cost, and weighted average cast time:

            calcStats.AverageHeal     = 0;
            calcStats.AverageManaCost = 0;
            calcStats.AverageCastTime = 0;
            foreach (HealSpell spell in list)
            {
                calcStats.AverageHeal     += spell.AverageHealed * spell.Weight;
                calcStats.AverageCastTime += spell.CastTime * spell.Weight;
                calcStats.AverageManaCost += spell.ManaCost * spell.Weight;
            }
            calcStats.AverageManaCost -= stats.ManaRestorePerCast_5_15 * .02f;  // Insightful Earthstorm Diamond

            // Earth Shield computations:

            float esMana = 0f;
            float esHeal = 0f;
            float esNum  = 0f;

            if (options.ESInterval > 0)
            {
                EarthShield es = new EarthShield(options.ESRank);
                es.Calcluate(stats, character);
                esNum  = (float)Math.Round((options.FightLength / (options.ESInterval / 60f)) + 1, 0);
                esMana = es.ManaCost * esNum;
                esHeal = es.AverageHealed * esNum;
            }
            float numHeals = Math.Min((options.FightLength * 60) / calcStats.AverageCastTime, (calcStats.TotalManaPool - esMana) / calcStats.AverageManaCost);

            // Now, Shattered Sun Pendant of Restoration Aldor proc.  From what I understand, this has a
            //  4% proc rate with no cooldown. This is a rough estimation of the value of this proc, and
            //  doesn't take into account other things that might proc it (Gift of the Naaru, Earth Shield
            //  if cast on the shaman, etc):

            if (options.ExaltedFaction == Faction.Aldor && stats.ShatteredSunRestoProc > 0)
            {
                // Determine how many more "casts" we get from Chain Heal second / third targets
                //  and Earth Shield (assumption is Earth Shield procs it?):

                float ssNumHeals = numHeals;
                if (options.CHRatio > 0)
                {
                    ssNumHeals += numHeals * options.CHWeight * (options.NumCHTargets - 1);
                }
                ssNumHeals += esNum;
                float ssHeal = (((ssNumHeals * .04f) * 10f) / (options.FightLength * 60f)) * 220f;

                // Now, we have to recalculate the amount healed based on the proc's addition to healing bonus:

                stats.Healing        += ssHeal;
                calcStats.AverageHeal = 0f;
                foreach (HealSpell spell in list)
                {
                    spell.Calcluate(stats, character);
                    calcStats.AverageHeal += spell.AverageHealed * spell.Weight;
                }
                stats.Healing -= ssHeal;
            }

            calcStats.TotalHealed = (numHeals * calcStats.AverageHeal) + esHeal;

            // Shattered Sun Pendant of Restoration Scryers proc. This is going to be a best case
            //  scenario (procs every cooldown, and the proc actually heals someone. Healers using
            //  a mouseover healing system (like Clique) might not benefit at all from this proc):

            if (options.ExaltedFaction == Faction.Scryers && stats.ShatteredSunRestoProc > 0)
            {
                float numProcs = (float)Math.Round((options.FightLength / 60f) / 45f, 0) + 1f;
                float crit     = .022f + ((stats.Intellect / 80f) / 100) + ((stats.SpellCritRating / 22.08f) / 100) +
                                 stats.SpellCrit;
                float critRate = 1 + 0.5f * crit;
                float ssHealed = numProcs * 650 * critRate;

                calcStats.TotalHealed += ssHealed;
            }

            calcStats.FightHPS = calcStats.TotalHealed / (options.FightLength * 60);

            calcStats.OverallPoints = calcStats.TotalHealed / 10f;
            calcStats.SubPoints[0]  = calcStats.TotalHealed / 10f;

            return(calcStats);
        }