Esempio n. 1
0
        public static void solve(CharacterCalculationsElemental calculatedStats, CalculationOptionsElemental calcOpts, BossOptions bossOpts)
        {
            Stats stats = calculatedStats.BasicStats;
            Character character = calculatedStats.LocalCharacter;
            ShamanTalents talents = character.ShamanTalents;

            /* Effects:
             * Clearcasting (-40% mana cost next 2 spells)
             * Glyph of flame shock or not
             * Clearcasting (5/10% more total damage)
             * Elemental Mastery (+15% haste chance, 15 sec/3 min cd)
             * Trinkets
             * 
             * Assume LvB used on CD and FS either after LvB, on dot drop or before LvB
             * Filler: LB 
             * NYI Optional: use of CL
             */
            Estimation e;
            Rotation rot;
            float damage;
            Stats procStats;
            float FightDuration = bossOpts.BerserkTimer;

            // WITHOUT PROCS
            e = new Estimation(stats, new Stats{}, talents, calcOpts);
            rot = e.getPriorityRotation(calcOpts.RotationType);
            // WITH PROCS
            int nPasses = 2, k;
            for (k = 0; k < nPasses; k++)
            {
                procStats = DoSpecialEffects(character, stats, rot, FightDuration);
                //procStats = getTrinketStats(character, stats, calcOpts.FightDuration, rot);
                e.Update(stats, procStats, talents, calcOpts);
                rot = e.getPriorityRotation(calcOpts.RotationType);
            }

            // Thunderstorm usage
            float thunderstormRegen = 0f;
            #region Thunderstorm
            if (calcOpts.UseThunderstorm)
            {
                float procsPerSecond = Thunderstorm.getProcsPerSecond(talents.GlyphofThunder, (int)FightDuration);
                thunderstormRegen += (talents.GlyphofThunderstorm ? .1f : .08f) * stats.Mana * procsPerSecond * 5;
            }
            #endregion

            /* Regen variables: (divide by 5 for regen per second)
             * While casting: ManaRegInFSR
             * During regen: ManaRegOutFSR */
            #region Calculate Regen
            float spiRegen = 5 * StatConversion.GetSpiritRegenSec(stats.Spirit, stats.Intellect);
            float replenishRegen = 5 * stats.Mana * stats.ManaRestoreFromMaxManaPerSecond;
            float judgementRegen = 0;// 5 * rot.GetBaseCastTime() / rot.Duration * stats.ManaRestoreFromBaseManaPPM / 60f * BaseStats.GetBaseStats(character).Mana;
            float ManaRegInFSR = /*spiRegen * stats.SpellCombatManaRegeneration +*/ stats.Mp5 + replenishRegen + judgementRegen + thunderstormRegen;
            float ManaRegOutFSR = spiRegen + stats.Mp5 + replenishRegen + thunderstormRegen;
            float ManaRegen = ManaRegInFSR;
            #endregion

            // TotalDamage, CastFraction, TimeUntilOOM
            #region Calculate total damage in the fight
            float TimeUntilOOM = 0;
            float effectiveMPS = rot.MPS - ManaRegen / 5f;
            if (effectiveMPS <= 0) TimeUntilOOM = FightDuration;
            else TimeUntilOOM = (calculatedStats.BasicStats.Mana) / effectiveMPS;
            if (TimeUntilOOM > FightDuration) TimeUntilOOM = FightDuration;

            #region SpecialEffects from procs etc.
            procStats = DoSpecialEffects(character, stats, rot, FightDuration);
            //procStats = getTrinketStats(character, stats, calcOpts.FightDuration, rot);
            //damage procs (Thunder Capacitor etc.) are effected by spellcrit and damage debuffs
            damage = procStats.ArcaneDamage * (1 + stats.BonusArcaneDamageMultiplier) + procStats.NatureDamage * (1 + stats.BonusNatureDamageMultiplier) + procStats.FireDamage * (1 + stats.BonusFireDamageMultiplier) + procStats.ShadowDamage * (1 + stats.BonusShadowDamageMultiplier);
            if (damage > 0)
            {
                damage *= (1 + stats.SpellCrit * .5f); // but only with the normal 50% dmg bonus
                rot.DPS += damage;
            }
            #endregion

            float TotalDamage = TimeUntilOOM * rot.DPS;
            float TimeToRegenFull = 5f * calculatedStats.BasicStats.Mana / ManaRegOutFSR;
            float TimeToBurnAll = calculatedStats.BasicStats.Mana / effectiveMPS;
            float CastFraction = 1f;
            if (ManaRegOutFSR > 0 && FightDuration > TimeUntilOOM)
            {
                float timeLeft = FightDuration - TimeUntilOOM;
                if (TimeToRegenFull + TimeToBurnAll == 0)
                    CastFraction = 0;
                else
                    CastFraction = TimeToBurnAll / (TimeToRegenFull + TimeToBurnAll);
                TotalDamage += timeLeft * rot.DPS * CastFraction;
            }
            #endregion

            float bsRatio = ((float)calcOpts.BSRatio) * 0.01f;
            calculatedStats.BurstPoints = (1f - bsRatio) * 2f * rot.DPS;
            calculatedStats.SustainedPoints = bsRatio * 2f * TotalDamage / FightDuration;
            calculatedStats.OverallPoints = calculatedStats.BurstPoints + calculatedStats.SustainedPoints;

            calculatedStats.CombatStats = stats.Clone();
            calculatedStats.CombatStats.Accumulate(procStats);
            calculatedStats.ManaRegenInFSR = ManaRegInFSR;
            calculatedStats.ReplenishMP5 = replenishRegen;
            calculatedStats.LightningBolt = rot.LB;
            calculatedStats.ChainLightning = rot.CL;
            calculatedStats.FlameShock = rot.FS;
            calculatedStats.LavaBurst = rot.LvB;
            calculatedStats.EarthShock = rot.ES;
            calculatedStats.FrostShock = rot.FrS;
            // asd
            calculatedStats.FireNova = rot.FN;
            calculatedStats.SearingTotem = rot.ST;
            calculatedStats.MagmaTotem = rot.MT;
            calculatedStats.TimeToOOM = TimeUntilOOM;
            calculatedStats.CastRegenFraction = CastFraction;
            calculatedStats.CastsPerSecond = rot.getCastsPerSecond();
            calculatedStats.CritsPerSecond = rot.getWeightedCritchance() * rot.getCastsPerSecond();
            calculatedStats.MissesPerSecond = rot.getCastsPerSecond() * (1f - rot.getWeightedHitchance());
            calculatedStats.LvBPerSecond = rot.getCastsPerSecond(typeof(LavaBurst));
            calculatedStats.LBPerSecond = rot.getCastsPerSecond(typeof(LightningBolt));
            calculatedStats.FSPerSecond = rot.getCastsPerSecond(typeof(FlameShock));
            calculatedStats.LatencyPerSecond = rot.LatencyPerSecond;
            calculatedStats.RotationDPS = rot.DPS;
            calculatedStats.RotationMPS = rot.MPS;
            calculatedStats.TotalDPS = TotalDamage / FightDuration;
            rot.ClearCasting.TryGetValue(typeof(FlameShock), out calculatedStats.ClearCast_FlameShock);
            rot.ClearCasting.TryGetValue(typeof(LavaBurst), out calculatedStats.ClearCast_LavaBurst);
            rot.ClearCasting.TryGetValue(typeof(LightningBolt), out calculatedStats.ClearCast_LightningBolt);
            calculatedStats.Rotation = rot.ToString();
            calculatedStats.RotationDetails = rot.ToDetailedString();
        }
Esempio n. 2
0
        public static void solve(CharacterCalculationsElemental calculatedStats, CalculationOptionsElemental calcOpts, BossOptions bossOpts)
        {
            Stats         stats     = calculatedStats.BasicStats;
            Character     character = calculatedStats.LocalCharacter;
            ShamanTalents talents   = character.ShamanTalents;

            /* Effects:
             * Clearcasting (-40% mana cost next 2 spells)
             * Glyph of flame shock or not
             * Clearcasting (5/10% more total damage)
             * Elemental Mastery (+15% haste chance, 15 sec/3 min cd)
             * Trinkets
             *
             * Assume LvB used on CD and FS either after LvB, on dot drop or before LvB
             * Filler: LB
             * NYI Optional: use of CL
             */
            Estimation e;
            Rotation   rot;
            float      damage;
            Stats      procStats;

#if RAWR3 || SILVERLIGHT
            float FightDuration = bossOpts.BerserkTimer;
#else
            float FightDuration = calcOpts.FightDuration;
#endif

            // WITHOUT PROCS
            e   = new Estimation(stats, new Stats {
            }, talents, calcOpts);
            rot = e.getPriorityRotation(calcOpts.RotationType);
            // WITH PROCS
            int nPasses = 2, k;
            for (k = 0; k < nPasses; k++)
            {
                procStats = DoSpecialEffects(character, stats, rot, FightDuration);
                //procStats = getTrinketStats(character, stats, calcOpts.FightDuration, rot);
                e.Update(stats, procStats, talents, calcOpts);
                rot = e.getPriorityRotation(calcOpts.RotationType);
            }

            // Thunderstorm usage
            float thunderstormRegen = 0f;
            #region Thunderstorm
            if (calcOpts.UseThunderstorm)
            {
                float procsPerSecond = Thunderstorm.getProcsPerSecond(talents.GlyphofThunder, (int)FightDuration);
                thunderstormRegen += (talents.GlyphofThunderstorm ? .1f : .08f) * stats.Mana * procsPerSecond * 5;
            }
            #endregion

            /* Regen variables: (divide by 5 for regen per second)
             * While casting: ManaRegInFSR
             * During regen: ManaRegOutFSR */
            #region Calculate Regen
            float spiRegen       = 5 * StatConversion.GetSpiritRegenSec(stats.Spirit, stats.Intellect);
            float replenishRegen = 5 * stats.Mana * stats.ManaRestoreFromMaxManaPerSecond;
            float judgementRegen = 5 * rot.GetBaseCastTime() / rot.Duration * stats.ManaRestoreFromBaseManaPPM / 60f * BaseStats.GetBaseStats(character).Mana;
            float ManaRegInFSR   = spiRegen * stats.SpellCombatManaRegeneration + stats.Mp5 + replenishRegen + judgementRegen + thunderstormRegen;
            float ManaRegOutFSR  = spiRegen + stats.Mp5 + replenishRegen + thunderstormRegen;
            float ManaRegen      = ManaRegInFSR;
            #endregion

            // TotalDamage, CastFraction, TimeUntilOOM
            #region Calculate total damage in the fight
            float TimeUntilOOM = 0;
            float effectiveMPS = rot.MPS - ManaRegen / 5f;
            if (effectiveMPS <= 0)
            {
                TimeUntilOOM = FightDuration;
            }
            else
            {
                TimeUntilOOM = (calculatedStats.BasicStats.Mana) / effectiveMPS;
            }
            if (TimeUntilOOM > FightDuration)
            {
                TimeUntilOOM = FightDuration;
            }

            #region SpecialEffects from procs etc.
            procStats = DoSpecialEffects(character, stats, rot, FightDuration);
            //procStats = getTrinketStats(character, stats, calcOpts.FightDuration, rot);
            //damage procs (Thunder Capacitor etc.) are effected by spellcrit and damage debuffs
            damage = procStats.ArcaneDamage * (1 + stats.BonusArcaneDamageMultiplier) + procStats.NatureDamage * (1 + stats.BonusNatureDamageMultiplier) + procStats.FireDamage * (1 + stats.BonusFireDamageMultiplier) + procStats.ShadowDamage * (1 + stats.BonusShadowDamageMultiplier);
            if (damage > 0)
            {
                damage  *= (1 + stats.SpellCrit * .5f); // but only with the normal 50% dmg bonus
                rot.DPS += damage;
            }
            #endregion

            float TotalDamage     = TimeUntilOOM * rot.DPS;
            float TimeToRegenFull = 5f * calculatedStats.BasicStats.Mana / ManaRegOutFSR;
            float TimeToBurnAll   = calculatedStats.BasicStats.Mana / effectiveMPS;
            float CastFraction    = 1f;
            if (ManaRegOutFSR > 0 && FightDuration > TimeUntilOOM)
            {
                float timeLeft = FightDuration - TimeUntilOOM;
                if (TimeToRegenFull + TimeToBurnAll == 0)
                {
                    CastFraction = 0;
                }
                else
                {
                    CastFraction = TimeToBurnAll / (TimeToRegenFull + TimeToBurnAll);
                }
                TotalDamage += timeLeft * rot.DPS * CastFraction;
            }
            #endregion

            float bsRatio = ((float)calcOpts.BSRatio) * 0.01f;
            calculatedStats.BurstPoints     = (1f - bsRatio) * 2f * rot.DPS;
            calculatedStats.SustainedPoints = bsRatio * 2f * TotalDamage / FightDuration;
            calculatedStats.OverallPoints   = calculatedStats.BurstPoints + calculatedStats.SustainedPoints;

            calculatedStats.CombatStats = stats.Clone();
            calculatedStats.CombatStats.Accumulate(procStats);

            calculatedStats.ManaRegenInFSR    = ManaRegInFSR;
            calculatedStats.ManaRegenOutFSR   = ManaRegOutFSR;
            calculatedStats.ReplenishMP5      = replenishRegen;
            calculatedStats.LightningBolt     = rot.LB;
            calculatedStats.ChainLightning    = rot.CL;
            calculatedStats.FlameShock        = rot.FS;
            calculatedStats.LavaBurst         = rot.LvB;
            calculatedStats.EarthShock        = rot.ES;
            calculatedStats.FrostShock        = rot.FrS;
            calculatedStats.FireNova          = rot.FN;
            calculatedStats.SearingTotem      = rot.ST;
            calculatedStats.MagmaTotem        = rot.MT;
            calculatedStats.TimeToOOM         = TimeUntilOOM;
            calculatedStats.CastRegenFraction = CastFraction;
            calculatedStats.CastsPerSecond    = rot.getCastsPerSecond();
            calculatedStats.CritsPerSecond    = rot.getWeightedCritchance() * rot.getCastsPerSecond();
            calculatedStats.MissesPerSecond   = rot.getCastsPerSecond() * (1f - rot.getWeightedHitchance());
            calculatedStats.LvBPerSecond      = rot.getCastsPerSecond(typeof(LavaBurst));
            calculatedStats.LBPerSecond       = rot.getCastsPerSecond(typeof(LightningBolt));
            calculatedStats.FSPerSecond       = rot.getCastsPerSecond(typeof(FlameShock));
            calculatedStats.LatencyPerSecond  = rot.LatencyPerSecond;
            calculatedStats.RotationDPS       = rot.DPS;
            calculatedStats.RotationMPS       = rot.MPS;
            calculatedStats.TotalDPS          = TotalDamage / FightDuration;
            rot.ClearCasting.TryGetValue(typeof(FlameShock), out calculatedStats.ClearCast_FlameShock);
            rot.ClearCasting.TryGetValue(typeof(LavaBurst), out calculatedStats.ClearCast_LavaBurst);
            rot.ClearCasting.TryGetValue(typeof(LightningBolt), out calculatedStats.ClearCast_LightningBolt);
            calculatedStats.Rotation        = rot.ToString();
            calculatedStats.RotationDetails = rot.ToDetailedString();
        }