示例#1
0
文件: Charting.cs 项目: tsebalj1/rawr
        public static ICollection <ComparisonCalculationBase> CalculateMAPSChart(Character character, CalculationsRestoSham baseCalculations)
        {
            List <ComparisonCalculationBase> list = new List <ComparisonCalculationBase>();
            CharacterCalculationsRestoSham   calc = baseCalculations.GetCharacterCalculations(character) as CharacterCalculationsRestoSham;

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

            StatRelativeWeight[] stats = new StatRelativeWeight[] {
                new StatRelativeWeight("Intellect", new Stats()
                {
                    Intellect = 10f
                }),
                new StatRelativeWeight("Haste Rating", new Stats()
                {
                    HasteRating = 10f
                }),
                new StatRelativeWeight("Spellpower", new Stats()
                {
                    SpellPower = 10f
                }),
                new StatRelativeWeight("MP5", new Stats()
                {
                    Mp5 = 10f
                }),
                new StatRelativeWeight("Crit Rating", new Stats()
                {
                    CritRating = 10f
                })
            };

            // Get the percentage total healing is changed by a change in a single stat:
            foreach (StatRelativeWeight weight in stats)
            {
                CharacterCalculationsRestoSham statCalc = (CharacterCalculationsRestoSham)baseCalculations.GetCharacterCalculations(character, null, weight.Stat);
                weight.Change = (statCalc.MAPS - calc.MAPS);
            }

            // Create the chart data points:
            foreach (StatRelativeWeight weight in stats)
            {
                ComparisonCalculationRestoSham comp = new ComparisonCalculationRestoSham(weight.Name);
                comp.OverallPoints = weight.Change;
                comp.SubPoints     = new float[] { 0f, weight.Change, 0f };
                comp.Description   = string.Format("If you added 10 more {0}.", weight.Name);
                list.Add(comp);
            }

            return(list);
        }
示例#2
0
文件: Charting.cs 项目: tsebalj1/rawr
        public static ICollection <ComparisonCalculationBase> CalculateSequencesChart(Character character, CalculationsRestoSham baseCalculations)
        {
            List <ComparisonCalculationBase> list            = new List <ComparisonCalculationBase>();
            CalculationOptionsRestoSham      originalOptions = character.CalculationOptions as CalculationOptionsRestoSham;

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

            CalculationOptionsRestoSham opts = originalOptions;

            string[] styles = new string[] { "CH Spam", "HW Spam", "LHW Spam", "RT+HW", "RT+CH", "RT+LHW" };
            string[] descs  = new string[] {
                "All chain heal, all the time.  \nMana available for use per minute added to sustained.",
                "All healing wave, all the time  \nMana available for use per minute added to sustained.",
                "All lesser healing wave, all the time  \nMana available for use per minute added to sustained.",
                "Riptide + Healing Wave.  \nMana available for use per minute added to sustained.",
                "Riptide + Chain Heal.  \nMana available for use per minute added to sustained.",
                "Riptide + Lesser Healing Wave.\nMana available for use per minute added to sustained."
            };
            for (int i = 0; i < styles.Length; i++)
            {
                opts.SustStyle  = styles[i];
                opts.BurstStyle = styles[i];
                character.CalculationOptions = opts;
                CharacterCalculationsRestoSham statCalc = (CharacterCalculationsRestoSham)baseCalculations.GetCharacterCalculations(character);

                // normalize the mana a bit to make a better chart
                float mana = statCalc.ManaUsed / (opts.FightLength);

                ComparisonCalculationRestoSham hsComp = new ComparisonCalculationRestoSham(styles[i]);
                hsComp.OverallPoints = statCalc.BurstHPS + statCalc.SustainedHPS + mana;
                hsComp.SubPoints     = new float[] { statCalc.BurstHPS, statCalc.SustainedHPS + mana, 0f };
                hsComp.Description   = descs[i];
                list.Add(hsComp);
            }

            return(list);
        }
        internal CharacterCalculationsBase GetCharacterCalculations(Character character)
        {
            CharacterCalculationsRestoSham calcs = new CharacterCalculationsRestoSham()
            {
                BasicStats = _TotalStats.Clone(),
                BurstSequence = _CalculationOptions.BurstStyle,
                SustainedSequence = _CalculationOptions.SustStyle,
                MailSpecialization = (GetArmorSpecializationStatus(character) ? 0.05f : 0f)
            };

            float healingCriticalScale = 1.5f * (1 + _TotalStats.BonusCritHealMultiplier);
            float dmgCriticalScale = 2f * (1 + _TotalStats.BonusCritDamageMultiplier);
            float hasteScale = 1f / (1f + _TotalStats.SpellHaste);

            calcs.SustainedHPS = 0f;
            calcs.BurstHPS = 0f;
            foreach (HealingSpell spell in _AvailableSpells.OfType<HealingSpell>())
            {
                spell.EffectModifier *= (1 + _TotalStats.BonusHealingDoneMultiplier);
                spell.CriticalScale = healingCriticalScale;
                spell.HasteScale = hasteScale;
                spell.Latency = _Latency;
                spell.GcdLatency = _GcdLatency;
                spell.SpellPower = _TotalStats.SpellPower;
                spell.CritRate = _TotalStats.SpellCrit;
                
                spell.Calculate();
                calcs.SustainedHPS += spell.EPS;

                if (spell is EarthShield)
                    calcs.ESHPS = spell.EPS;
            }
            foreach (LightningBolt spell in _AvailableSpells.OfType<LightningBolt>())
            {
                spell.EffectModifier *= (1 + _TotalStats.BonusDamageMultiplier);
                spell.CriticalScale = dmgCriticalScale;
                spell.HasteScale = hasteScale;
                spell.Latency = _Latency;
                spell.GcdLatency = _GcdLatency;
                spell.SpellPower = _TotalStats.SpellPower;
                spell.CritRate = _TotalStats.SpellCrit;
                spell.Calculate();
                calcs.LBRestore = spell.ManaBack - spell.ManaCost;
                calcs.LBCast = spell.CastTime;
            }

            float mp5 = _TotalStats.Mp5 + (_TotalStats.ManaRestoreFromMaxManaPerSecond * _TotalStats.Mana);
            if (_PerformSequencing)
            {
                {
                    StateMachine.StateGenerator gen = new StateMachine.StateGenerator(_AvailableSpells, StateMachine.SequenceType.Burst, _TotalStats.Mana, mp5);
                    List<State<Spell>> stateSpace = gen.GenerateStateSpace();
                    MarkovProcess<Spell> mp = new MarkovProcess<Spell>(stateSpace);
                    _BurstSpellSequence = new Dictionary<Spell, double>(mp.AbilityWeight);
                    _BurstSequenceDuration = mp.AverageTransitionDuration;
                }
                {
                    StateMachine.StateGenerator gen = new StateMachine.StateGenerator(_AvailableSpells, StateMachine.SequenceType.Sustained, _TotalStats.Mana, mp5);
                    List<State<Spell>> stateSpace = gen.GenerateStateSpace();
                    MarkovProcess<Spell> mp = new MarkovProcess<Spell>(stateSpace);
                    _SustSpellSequence = new Dictionary<Spell, double>(mp.AbilityWeight);
                    _SustSequenceDuration = mp.AverageTransitionDuration;
                }

                if (_PerformSequencing)
                    _SequencedStats = _TotalStats.Clone();
            }

            if (_BurstSpellSequence != null)
            {
                double avgHealing = 0d;
                string seq = "";
                string seqShort = "";
                foreach (var item in _BurstSpellSequence)
                {
                    if (item.Key is HealingSpell)
                    {
                        if (seq.Length > 0)
                        {
                            seqShort += ",";
                            seq += ", ";
                        }
                        seqShort += item.Key.SpellAbrv;
                        seq += item.Key.SpellName;
                        avgHealing += item.Key.Effect * item.Value;
                        if (item.Key is Hot)
                            avgHealing += ((Hot)item.Key).TotalHotEffect * item.Value;
                    }
                }
                double hps = avgHealing / _BurstSequenceDuration;
                calcs.BurstHPS = (float)hps;
                calcs.BurstSequence = seq;
                calcs.BurstSequenceShort = seqShort;
            }

            if (_SustSpellSequence != null)
            {
                double avgHealing = 0d;
                string seq = "";
                string seqShort = "";
                foreach (var item in _SustSpellSequence)
                {
                    if (item.Key is HealingSpell)
                    {
                        if (seq.Length > 0)
                        {
                            seqShort += ",";
                            seq += ", ";
                        }
                        seqShort += item.Key.SpellAbrv;
                        seq += item.Key.SpellName;
                        avgHealing += item.Key.Effect * item.Value;
                        if (item.Key is Hot)
                            avgHealing += ((Hot)item.Key).TotalHotEffect * item.Value;
                    }
                }
                double hps = avgHealing / _SustSequenceDuration;
                calcs.SustainedHPS = (float)hps;
                calcs.SustainedSequence = seq;
                calcs.SustainedSequenceShort = seqShort;
            }

            if (calcs.BurstHPS < 0f)
                calcs.BurstHPS = 0f;
            if (calcs.SustainedHPS < 0f)
                calcs.SustainedHPS = 0f;
            if (calcs.Survival < 0f)
                calcs.Survival = 0f;

            calcs.Survival = (calcs.BasicStats.Health + calcs.BasicStats.Hp5) * (_CalculationOptions.SurvivalPerc * .01f);
            
            // Set the sub categories
            calcs.SubPoints[0] = calcs.BurstHPS;
            calcs.SubPoints[1] = calcs.SustainedHPS;
            calcs.SubPoints[2] = calcs.Survival;
            
            // Sum up
            calcs.OverallPoints = 0f;
            for (short i = 0; i < calcs.SubPoints.Length; i++)
                calcs.OverallPoints += calcs.SubPoints[i];

            return calcs;
        }
示例#4
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);
        }
示例#5
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);
        }
示例#6
0
        internal CharacterCalculationsBase GetCharacterCalculations(Character character)
        {
            CharacterCalculationsRestoSham calcs = new CharacterCalculationsRestoSham()
            {
                BasicStats         = _TotalStats.Clone(),
                BurstSequence      = _CalculationOptions.BurstStyle,
                SustainedSequence  = _CalculationOptions.SustStyle,
                MailSpecialization = (GetArmorSpecializationStatus(character) ? 0.05f : 0f)
            };

            float healingCriticalScale = 1.5f * (1 + _TotalStats.BonusCritHealMultiplier);
            float dmgCriticalScale     = 2f * (1 + _TotalStats.BonusCritDamageMultiplier);
            float hasteScale           = 1f / (1f + _TotalStats.SpellHaste);

            calcs.SustainedHPS = 0f;
            calcs.BurstHPS     = 0f;
            foreach (HealingSpell spell in _AvailableSpells.OfType <HealingSpell>())
            {
                spell.EffectModifier *= (1 + _TotalStats.BonusHealingDoneMultiplier);
                spell.CriticalScale   = healingCriticalScale;
                spell.HasteScale      = hasteScale;
                spell.Latency         = _Latency;
                spell.GcdLatency      = _GcdLatency;
                spell.SpellPower      = _TotalStats.SpellPower;
                spell.CritRate        = _TotalStats.SpellCrit;

                spell.Calculate();
                calcs.SustainedHPS += spell.EPS;

                if (spell is EarthShield)
                {
                    calcs.ESHPS = spell.EPS;
                }
            }
            foreach (LightningBolt spell in _AvailableSpells.OfType <LightningBolt>())
            {
                spell.EffectModifier *= (1 + _TotalStats.BonusDamageMultiplier);
                spell.CriticalScale   = dmgCriticalScale;
                spell.HasteScale      = hasteScale;
                spell.Latency         = _Latency;
                spell.GcdLatency      = _GcdLatency;
                spell.SpellPower      = _TotalStats.SpellPower;
                spell.CritRate        = _TotalStats.SpellCrit;
                spell.Calculate();
                calcs.LBRestore = spell.ManaBack - spell.ManaCost;
                calcs.LBCast    = spell.CastTime;
            }

            float mp5 = _TotalStats.Mp5 + (_TotalStats.ManaRestoreFromMaxManaPerSecond * _TotalStats.Mana);

            if (_PerformSequencing)
            {
                {
                    StateMachine.StateGenerator gen        = new StateMachine.StateGenerator(_AvailableSpells, StateMachine.SequenceType.Burst, _TotalStats.Mana, mp5);
                    List <State <Spell> >       stateSpace = gen.GenerateStateSpace();
                    MarkovProcess <Spell>       mp         = new MarkovProcess <Spell>(stateSpace);
                    _BurstSpellSequence    = new Dictionary <Spell, double>(mp.AbilityWeight);
                    _BurstSequenceDuration = mp.AverageTransitionDuration;
                }
                {
                    StateMachine.StateGenerator gen        = new StateMachine.StateGenerator(_AvailableSpells, StateMachine.SequenceType.Sustained, _TotalStats.Mana, mp5);
                    List <State <Spell> >       stateSpace = gen.GenerateStateSpace();
                    MarkovProcess <Spell>       mp         = new MarkovProcess <Spell>(stateSpace);
                    _SustSpellSequence    = new Dictionary <Spell, double>(mp.AbilityWeight);
                    _SustSequenceDuration = mp.AverageTransitionDuration;
                }

                if (_PerformSequencing)
                {
                    _SequencedStats = _TotalStats.Clone();
                }
            }

            if (_BurstSpellSequence != null)
            {
                double avgHealing = 0d;
                string seq        = "";
                string seqShort   = "";
                foreach (var item in _BurstSpellSequence)
                {
                    if (item.Key is HealingSpell)
                    {
                        if (seq.Length > 0)
                        {
                            seqShort += ",";
                            seq      += ", ";
                        }
                        seqShort   += item.Key.SpellAbrv;
                        seq        += item.Key.SpellName;
                        avgHealing += item.Key.Effect * item.Value;
                        if (item.Key is Hot)
                        {
                            avgHealing += ((Hot)item.Key).TotalHotEffect * item.Value;
                        }
                    }
                }
                double hps = avgHealing / _BurstSequenceDuration;
                calcs.BurstHPS           = (float)hps;
                calcs.BurstSequence      = seq;
                calcs.BurstSequenceShort = seqShort;
            }

            if (_SustSpellSequence != null)
            {
                double avgHealing = 0d;
                string seq        = "";
                string seqShort   = "";
                foreach (var item in _SustSpellSequence)
                {
                    if (item.Key is HealingSpell)
                    {
                        if (seq.Length > 0)
                        {
                            seqShort += ",";
                            seq      += ", ";
                        }
                        seqShort   += item.Key.SpellAbrv;
                        seq        += item.Key.SpellName;
                        avgHealing += item.Key.Effect * item.Value;
                        if (item.Key is Hot)
                        {
                            avgHealing += ((Hot)item.Key).TotalHotEffect * item.Value;
                        }
                    }
                }
                double hps = avgHealing / _SustSequenceDuration;
                calcs.SustainedHPS           = (float)hps;
                calcs.SustainedSequence      = seq;
                calcs.SustainedSequenceShort = seqShort;
            }

            if (calcs.BurstHPS < 0f)
            {
                calcs.BurstHPS = 0f;
            }
            if (calcs.SustainedHPS < 0f)
            {
                calcs.SustainedHPS = 0f;
            }
            if (calcs.Survival < 0f)
            {
                calcs.Survival = 0f;
            }

            calcs.Survival = (calcs.BasicStats.Health + calcs.BasicStats.Hp5) * (_CalculationOptions.SurvivalPerc * .01f);

            // Set the sub categories
            calcs.SubPoints[0] = calcs.BurstHPS;
            calcs.SubPoints[1] = calcs.SustainedHPS;
            calcs.SubPoints[2] = calcs.Survival;

            // Sum up
            calcs.OverallPoints = 0f;
            for (short i = 0; i < calcs.SubPoints.Length; i++)
            {
                calcs.OverallPoints += calcs.SubPoints[i];
            }

            return(calcs);
        }