Esempio n. 1
0
        private float RotationMultiplier(SpellRotation rot)
        {
            if (rot == null)
            {
                return(0);
            }

            float manaCostPerCycle = rot.manaPerCycle - rot.currentCycleDuration *
                                     (calculatedStats.Mp5Points / 5 +
                                      InnervateManaPerSecond(rot) +
                                      MementoManaPerSecond(rot) +
                                      LessManaPerCastInManaPerSecond(rot) +
                                      ManaPerCastInManaPerSecond(rot) +
                                      BlueDragonInManaPerSecond(rot) +
                                      BangleInManaPerSecond(rot)
                                     );

            float HPSMultiplier = 1.0f;

            if (manaCostPerCycle > 0)
            {
                HPSMultiplier = (rot.currentCycleDuration * calculatedStats.BasicStats.Mana / manaCostPerCycle) / (calcOpts.FightLength * 60);
                if (HPSMultiplier > 1.0f)
                {
                    HPSMultiplier = 1.0f;
                }
            }

            return(HPSMultiplier);
        }
Esempio n. 2
0
        private float BangleInManaPerSecond(SpellRotation rot)
        {
            // Bangle of Endless Blessings - x% mana regen for 15 sec with 10% proc, 45 sec internal cooldown
            float secondsPerSpell = rot.currentCycleDuration / rot.numberOfSpells;
            float secondsPerProc  = secondsPerSpell / 0.1f + 45f;

            return(0.15f * calculatedStats.BasicStats.BangleProc * calculatedStats.OS5SRRegen / secondsPerProc);
        }
Esempio n. 3
0
        private float BlueDragonInManaPerSecond(SpellRotation rot)
        {
            // Darkmoon Card: Blue Dragon - let's assume no internal cooldown, no proc while the effect is up and no proc during innervate
            float secondsPerSpell = rot.currentCycleDuration / rot.numberOfSpells;
            float secondsPerProc  = 100f * secondsPerSpell / calculatedStats.BasicStats.FullManaRegenFor15SecOnSpellcast + 15f;

            return(15f * (calculatedStats.OS5SRRegen - calculatedStats.IS5SRRegen) / secondsPerProc);
        }
Esempio n. 4
0
        private float ManaPerCastInManaPerSecond(SpellRotation rot)
        {
            float secondsPerSpell = rot.currentCycleDuration / rot.numberOfSpells;
            // IED 5% proc-rate, 15 sec cooldown
            // Source: http://elitistjerks.com/f31/t19181-shaman_how_heal_like_pro/p53/#post759589
            float secondsPerProc = secondsPerSpell * 20f + 15f;

            return(calculatedStats.BasicStats.ManaRestorePerCast_5_15 / secondsPerProc);
        }
Esempio n. 5
0
        private float InnervateManaPerSecond(SpellRotation rot)
        {
            float innervateMana = 0f;

            if (calcOpts.InnervateSelf)
            {
                float manaGain = calculatedStats.OS5SRRegen * 5 * 20 - calculatedStats.IS5SRRegen * 20;
                float manaUsed = rot.manaPerCycle / rot.currentCycleDuration * 20;
                if (manaGain > calculatedStats.BasicStats.Mana + manaUsed)
                {
                    manaGain = calculatedStats.BasicStats.Mana + manaUsed;
                }
                innervateMana = manaGain / (calcOpts.InnervateDelay * 60);
            }
            return(innervateMana);
        }
Esempio n. 6
0
        private SpellRotation GetBestRotation()
        {
            SpellRotation bestRotation = null;
            float         bestScore    = 0f;

            foreach (SpellRotation rot in baseRotations)
            {
                float maxLength      = calcOpts.MaxCycleDuration * calcOpts.NumCyclesPerRotation;
                float bestLocalScore = 0f;
                float granularity    = 0.1f;

                rot.currentCycleDuration = ((float)Math.Ceiling(rot.tightCycleDuration * 10)) / 10f;

                // No use trying all combinations if we already have a better score than the theoretical max
                if (bestLocalScore > rot.healPerCycle / rot.tightCycleDuration)
                {
                    continue;
                }

                float multiplier;
                do
                {
                    multiplier = RotationMultiplier(rot);
                    float score = rot.healPerCycle / rot.currentCycleDuration * multiplier;

                    if (score > bestLocalScore)
                    {
                        bestLocalScore        = score;
                        rot.bestCycleDuration = rot.currentCycleDuration;
                    }

                    rot.currentCycleDuration += granularity;
                } while (rot.currentCycleDuration < maxLength && multiplier < 1f);

                if (bestLocalScore > bestScore)
                {
                    bestRotation = rot;
                    bestScore    = bestLocalScore;
                }
            }
            bestRotation.currentCycleDuration = bestRotation.bestCycleDuration;

            return(bestRotation);
        }
Esempio n. 7
0
        private float LessManaPerCastInManaPerSecond(SpellRotation rot)
        {
            float secondsPerSpell = rot.currentCycleDuration / rot.numberOfSpells;

            return(calculatedStats.BasicStats.ManacostReduceWithin15OnUse1Min / (4 * secondsPerSpell));
        }
Esempio n. 8
0
 private float MementoManaPerSecond(SpellRotation rot)
 {
     return(calculatedStats.BasicStats.MementoProc * 3 / (45 + rot.currentCycleDuration / rot.numberOfSpells * 5));
 }