private float CalcRaidBuff() { float raidBuff = 0f; float perSP = CalcOpts.PerSP; if (perSP > 0 && Pet != null) { if (CalcOpts.ConvertTotem) { float curTotem = StatUtils.GetActiveBuff(Character.ActiveBuffs, "Spell Power", s => s.SpellPower); if (curTotem == 144f || curTotem == 165f) { raidBuff += CalcOpts.PerFlametongue; } } } if (CastSpells.ContainsKey("Curse Of The Elements")) { raidBuff += CalcOpts.PerMagicBuff; } raidBuff += CalcOpts.PerCritBuff * (CalcAddedCritBuff() / .05f); raidBuff += CalcOpts.PerHealth * CalculationsWarlock.CalcPetHealthBuff(CalcOpts.Pet, Talents, Character.ActiveBuffs, CalcOpts); return(raidBuff); }
private float CalcAddedCritBuff() { // If the 5% crit debuff is not already being maintained by // somebody else (i.e. it's not selected in the buffs tab), we // may supply it via Improved Shadow Bolt. if (Talents.ShadowAndFlame == 0 || StatUtils.GetActiveBuff(Character.ActiveBuffs, "Spell Critical Strike Taken", s => s.SpellCritOnTarget) > 0) { return(0f); } float casts = 0f; if (CastSpells.ContainsKey("Shadow Bolt")) { casts += CastSpells["Shadow Bolt"].GetNumCasts(); } if (CastSpells.ContainsKey("Shadow Bolt (Instant)")) { casts += CastSpells["Shadow Bolt (Instant)"].GetNumCasts(); } if (casts == 0) { return(0f); } float uprate = Spell.CalcUprate( Talents.ShadowAndFlame * .33f, // proc rate 30f, // duration BossOpts.BerserkTimer / casts); // trigger period float benefit = .05f - Stats.SpellCritOnTarget; return(benefit * uprate); }
private Stats CalcCritProcs() { if (Options.NoProcs) { return(new Stats()); } Dictionary <int, float> periods = new Dictionary <int, float>(); Dictionary <int, float> chances = new Dictionary <int, float>(); PopulateTriggers(periods, chances); Stats procStats = new Stats(); foreach (SpecialEffect effect in Stats.SpecialEffects()) { if (!periods.ContainsKey((int)effect.Trigger)) { continue; } Stats proc = CalcNormalProc(effect, periods, chances); procStats.Accumulate(proc); if (effect.Trigger == Trigger.Use && !IsDoublePot(effect)) { ExtraCritAtMax += StatUtils.CalcSpellCrit(effect.Stats) - StatUtils.CalcSpellCrit(proc); } } return(procStats); }
public static float CalcPetHealthBuff(string pet, WarlockTalents talents, List <Buff> activeBuffs, CalculationOptionsWarlock options) { if (!pet.Equals("Imp")) { return(0f); } //spell ID 6307, effect ID 2190 float SCALE = 1.3200000525f; return(StatUtils.GetBuffEffect(activeBuffs, SCALE * buffBaseValues[options.PlayerLevel - 80], "Health", s => s.Health)); }
public static float CalcPetMP5Buff(string pet, WarlockTalents talents, List <Buff> activeBuffs, CalculationOptionsWarlock options) { if (!pet.Equals("Felhunter")) { return(0f); } //spell ID 54424, effect ID 47203 float SCALE = 0.7360000014f; return(StatUtils.GetBuffEffect(activeBuffs, SCALE * buffBaseValues[options.PlayerLevel - 80], "Mana Regeneration", s => s.Mp5)); }
public static float CalcPetHealthBuff( string pet, WarlockTalents talents, List <Buff> activeBuffs) { if (!pet.Equals("Imp")) { return(0f); } return(StatUtils.GetBuffEffect( activeBuffs, 1330f * (1 + talents.ImprovedImp * .1f), "Health", s => s.Health)); }
public static float CalcPetSpiBuff( string pet, WarlockTalents talents, List <Buff> activeBuffs) { if (!pet.Equals("Felhunter")) { return(0f); } return(StatUtils.GetBuffEffect( activeBuffs, 64f * (1 + talents.ImprovedFelhunter * .05f), "Spirit", s => s.Spirit)); }
public float GetSpecialSpeed() { return(SpecialCooldown + SpecialCastTime / StatUtils.CalcSpellHaste(Stats)); }
public float CalcMeleeCrit() { return(StatUtils.CalcPhysicalCrit( Stats, .00019f, Mommy.Options.TargetLevel - 80)); }
public float CalcAttackPower() { return(StatUtils.CalcAttackPower(Stats, 1f, 0f)); }
public float CalcSpellCrit() { return(StatUtils.CalcSpellCrit(Stats)); }
public float CalcSpellPower() { return(StatUtils.CalcSpellPower(Stats)); }
public float CalcIntellect() { return(StatUtils.CalcIntellect(Stats)); }
/// <summary> /// Builds a dictionary containing the values to display for each of the /// calculations defined in CharacterDisplayCalculationLabels. The key /// should be the Label of each display calculation, and the value /// should be the value to display, optionally appended with '*' /// followed by any string you'd like displayed as a tooltip on the /// value. /// </summary> /// <returns> /// A Dictionary<string, string> containing the values to display for /// each of the calculations defined in /// CharacterDisplayCalculationLabels. /// </returns> public override Dictionary <string, string> GetCharacterDisplayCalculationValues() { Dictionary <string, string> dictValues = new Dictionary <string, string>(); dictValues.Add("Personal DPS", string.Format("{0:0}", PersonalDps)); dictValues.Add("Pet DPS", string.Format("{0:0}", PetDps)); dictValues.Add("Total DPS", string.Format("{0:0}", OverallPoints)); dictValues.Add("Health", string.Format("{0:0}*{1:0} stamina", CalcHealth(), CalcStamina())); dictValues.Add("Mana", string.Format("{0:0}*{1:0} intellect", CalcMana(), CalcIntellect())); dictValues.Add("Spell Power", string.Format("{0:0.0}*{1:0.0}\tBefore Procs", CalcSpellPower(), StatUtils.CalcSpellPower(PreProcStats, BaseIntellect, CalcOpts.PlayerLevel))); #region Hit Rating float onePercentOfHitRating = (1 / StatUtils.GetSpellHitFromRating(1, CalcOpts.PlayerLevel)); float hitFromRating = StatUtils.GetSpellHitFromRating(Stats.HitRating, CalcOpts.PlayerLevel); float hitFromBuffs = (CalcSpellHit() - hitFromRating); float targetHit = CalcOpts.GetBaseHitRate() / 100f; float totalHit = targetHit + CalcSpellHit(); float missChance = totalHit > 1 ? 0 : (1 - totalHit); dictValues.Add( "Hit Rating", string.Format( "{0}*{1:0.00%} Hit Chance (max 100%) | {2:0.00%} Miss Chance \r\n\r\n" + "{3:0.00%}\t Base Hit Chance on a Level {4:0} target\r\n" + "{5:0.00%}\t from {6:0} Hit Rating [gear, food and/or flasks]\r\n" + "{7:0.00%}\t from Buffs: Racial and/or Spell Hit Chance Taken\r\n\r\n" + "You are {8} hit rating {9} the hard cap [no hit from gear, talents or buffs]\r\n\r\n", Stats.HitRating, totalHit, missChance, targetHit, CalcOpts.TargetLevel, hitFromRating, Stats.HitRating, hitFromBuffs, Math.Ceiling(Math.Abs((totalHit - 1) * onePercentOfHitRating)), (totalHit > 1) ? "above" : "below")); #endregion dictValues.Add("Crit Chance", string.Format("{0:0.00%}*{1:0.00%}\tBefore Procs", CalcSpellCrit(), StatUtils.CalcSpellCrit(PreProcStats, BaseIntellect, CalcOpts.PlayerLevel))); dictValues.Add("Average Haste", string.Format( "{0:0.00}%*" + "{1:0.00}%\tfrom {2:0.0} Haste rating\r\n" + "{3:0.00}%\tfrom Buffs\r\n" + "{4:0.0}ish%\tfrom Procs\r\n" + "\r\n" + "{5:0.00}s\tGlobal Cooldown\r\n", (AvgHaste - 1f) * 100f, StatUtils.GetSpellHasteFromRating(Stats.HasteRating, CalcOpts.PlayerLevel) * 100f, Stats.HasteRating, Stats.SpellHaste * 100f, (AvgHaste - StatUtils.CalcSpellHaste(PreProcStats, CalcOpts.PlayerLevel)) * 100f, Math.Max(1.0f, 1.5f / AvgHaste))); dictValues.Add("Mastery", string.Format("{0:0.0}*from {1:0.0} Mastery Rating", CalcMastery(), Stats.MasteryRating)); if (Pet == null) { dictValues.Add("Pet Mana", "-"); dictValues.Add("Basic Melee Damage", "-"); dictValues.Add("Basic Melee DPS", "-"); dictValues.Add("Attack Power", "-"); dictValues.Add("Basic Melee Speed", "-"); dictValues.Add("Spell Damage", "-"); } else { dictValues.Add("Pet Mana", string.Format("{0:0.0}", Pet.CalcMana())); dictValues.Add("Basic Melee Damage", string.Format("{0:0.0}", Pet.CalcMeleeDamage())); dictValues.Add("Basic Melee DPS", string.Format("{0:0.0}", Pet.CalcMeleeDps())); dictValues.Add("Attack Power", string.Format("{0:0.0}", Pet.CalcAttackPower())); dictValues.Add("Basic Melee Speed", string.Format("{0:0.0}", Pet.CalcMeleeSpeed())); dictValues.Add("Spell Damage", string.Format("{0:0.0}", Pet.CalcSpellPower())); } if (Pet is Felhunter) { dictValues.Add("Shadow Bite (Fel Hunter)", string.Format("{0:0.0}", Pet.GetSpecialDamage())); } else { dictValues.Add("Shadow Bite (Fel Hunter)", "-"); } if (Pet is Imp) { dictValues.Add("Fire Bolt (Imp)", string.Format("{0:0.0}", Pet.GetSpecialDamage())); } else { dictValues.Add("Fire Bolt (Imp)", "-"); } if (Pet is Succubus) { dictValues.Add("Lash of Pain (Succubus)", string.Format("{0:0.0}", Pet.GetSpecialDamage())); } else { dictValues.Add("Lash of Pain (Succubus)", "-"); } if (Pet is Felguard) { dictValues.Add("Legion Strike (Felguard)", string.Format("{0:0.0}", Pet.GetSpecialDamage())); } else { dictValues.Add("Legion Strike (Felguard)", "-"); } // Spell Stats foreach (string spellName in Spell.ALL_SPELLS) { if (CastSpells.ContainsKey(spellName)) { dictValues.Add(spellName, CastSpells[spellName].GetToolTip()); } else { dictValues.Add(spellName, "-"); } } return(dictValues); }
public float GetPactProcBenefit() { float pact = .02f * Mommy.Talents.DemonicPact; if (pact == 0) { return(0f); } float buff = StatUtils.GetBuffEffect( Mommy.Character.ActiveBuffs, Mommy.CalcSpellPower() * pact, "Spell Power", s => s.SpellPower); if (buff == 0) { return(0f); } SpecialEffect pactEffect = new SpecialEffect(0, null, 45f, 20f); float meleeRate; if (BaseMeleeDamage == 0) { meleeRate = 0f; } else { meleeRate = 1 / CalcMeleeSpeed(); } float spellRate; if (SpecialDamagePerSpellPower == 0) { spellRate = 0f; float specialSpeed = GetSpecialSpeed(); if (specialSpeed > 0) { meleeRate += 1 / GetSpecialSpeed(); } } else { spellRate = 1 / GetSpecialSpeed(); } float triggerRate = 1 / (meleeRate + spellRate); float uprate = pactEffect.GetAverageUptime( triggerRate, Utilities.GetWeightedSum( Mommy.HitChance * CalcSpellCrit(), spellRate, CalcMeleeCrit(), meleeRate), triggerRate, Mommy.Options.Duration); return(uprate * buff); }
GetCharacterDisplayCalculationValues() { Dictionary <string, string> dictValues = new Dictionary <string, string>(); dictValues.Add("Personal DPS", string.Format("{0:0}", PersonalDps)); dictValues.Add("Pet DPS", string.Format("{0:0}", PetDps)); dictValues.Add("Total DPS", string.Format("{0:0}", OverallPoints)); dictValues.Add( "Health", string.Format( "{0:0.0}*{1:0.0} stamina", CalcHealth(), CalcStamina())); dictValues.Add( "Mana", string.Format( "{0:0.0}*{1:0.0} intellect", CalcMana(), CalcIntellect())); dictValues.Add( "Spirit", string.Format("{0:0.0}", CalcSpirit())); dictValues.Add( "Bonus Damage", string.Format( "{0:0.0}*{1:0.0}\tBefore Procs", CalcSpellPower(), StatUtils.CalcSpellPower(PreProcStats))); #region Hit Rating float onePercentOfHitRating = (1 / StatConversion.GetSpellHitFromRating(1)); float hitFromRating = StatConversion.GetSpellHitFromRating(Stats.HitRating); float hitFromTalents = Talents.Suppression * 0.01f; float hitFromBuffs = (CalcSpellHit() - hitFromRating - hitFromTalents); float targetHit = Options.GetBaseHitRate() / 100f; float totalHit = targetHit + CalcSpellHit(); float missChance = totalHit > 1 ? 0 : (1 - totalHit); dictValues.Add( "Hit Rating", string.Format( "{0}*{1:0.00%} Hit Chance (max 100%) | {2:0.00%} Miss Chance \r\n\r\n" + "{3:0.00%}\t Base Hit Chance on a Level {4:0} target\r\n" + "{5:0.00%}\t from {6:0} Hit Rating [gear, food and/or flasks]\r\n" + "{7:0.00%}\t from Talent: Suppression\r\n" + "{8:0.00%}\t from Buffs: Racial and/or Spell Hit Chance Taken\r\n\r\n" + "You are {9} hit rating {10} the 446 hard cap [no hit from gear, talents or buffs]\r\n\r\n" + "Hit Rating soft caps:\r\n" + "420 - Heroic Presence\r\n" + "368 - Suppression\r\n" + "342 - Suppression and Heroic Presence\r\n" + "289 - Suppression, Improved Faerie Fire / Misery\r\n" + "263 - Suppression, Improved Faerie Fire / Misery and Heroic Presence", Stats.HitRating, totalHit, missChance, targetHit, Options.TargetLevel, hitFromRating, Stats.HitRating, hitFromTalents, hitFromBuffs, Math.Ceiling( Math.Abs((totalHit - 1) * onePercentOfHitRating)), (totalHit > 1) ? "above" : "below")); #endregion dictValues.Add( "Crit Chance", string.Format( "{0:0.00%}*{1:0.00%}\tBefore Procs", CalcSpellCrit(), StatUtils.CalcSpellCrit(PreProcStats))); dictValues.Add( "Average Haste", string.Format( "{0:0.00}%*" + "{1:0.00}%\tfrom {2:0.0} Haste rating\r\n" + "{3:0.00}%\tfrom Buffs\r\n" + "{4:0.0}ish%\tfrom Procs\r\n" + "\r\n" + "{5:0.00}s\tGlobal Cooldown\r\n", (AvgHaste - 1f) * 100f, StatConversion.GetSpellHasteFromRating(Stats.HasteRating) * 100f, Stats.HasteRating, Stats.SpellHaste * 100f, (AvgHaste - StatUtils.CalcSpellHaste(PreProcStats)) * 100f, Math.Max(1.0f, 1.5f / AvgHaste))); // Pet Stats if (Pet == null) { dictValues.Add("Pet Stamina", "-"); dictValues.Add("Pet Intellect", "-"); dictValues.Add("Pet Health", "-"); } else { dictValues.Add( "Pet Stamina", string.Format("{0:0.0}", Pet.CalcStamina())); dictValues.Add( "Pet Intellect", string.Format("{0:0.0}", Pet.CalcIntellect())); dictValues.Add( "Pet Health", string.Format("{0:0.0}", Pet.CalcHealth())); } // Spell Stats foreach (string spellName in Spell.ALL_SPELLS) { if (CastSpells.ContainsKey(spellName)) { dictValues.Add( spellName, CastSpells[spellName].GetToolTip()); } else { dictValues.Add(spellName, "-"); } } return(dictValues); }
private float CalcPersonalDps() { // SP & Crit: lock before pet (both affected by procs) // Procs after crit if (Options.GetActiveRotation().GetError() != null) { return(0f); } CalcHasteAndManaProcs(); AvgTimeUsed = Spell.GetTimeUsed( CalculationsWarlock.AVG_UNHASTED_CAST_TIME, 0f, Haste, Options.Latency); float timeRemaining = Options.Duration; float totalMana = CalcUsableMana(timeRemaining); float maxMana = StatUtils.CalcMana(PreProcStats); float manaFromEffects = totalMana - maxMana; float manaUsed = 0f; #region Calculate NumCasts for each spell // execute stage collision delays Spell execute = null; float executePercent = GetExecutePercentage(); string executeName = Options.GetActiveRotation().Execute; if (executePercent > 0) { execute = GetSpell(executeName); SetupSpells(true); RecordCollisionDelays( new CastingState(this, execute, executePercent)); } // normal collision delays Spell filler = GetSpell(Options.GetActiveRotation().Filler); SetupSpells(false); RecordCollisionDelays(new CastingState(this, filler, 1f - executePercent)); // calc numcasts foreach (Spell spell in Priorities) { float numCasts = spell.GetNumCasts(); timeRemaining -= numCasts * spell.GetAvgTimeUsed(); manaUsed += numCasts * spell.ManaCost; } LifeTap lifeTap = (LifeTap)GetSpell("Life Tap"); if (executePercent > 0) { float executeTime = executePercent * timeRemaining; float taps = lifeTap.AddCastsForRegen( timeRemaining * executePercent, maxMana + (manaFromEffects - manaUsed) * executePercent, execute); executeTime -= taps * lifeTap.GetAvgTimeUsed(); manaUsed += taps * lifeTap.ManaCost; execute.Spam(executeTime); timeRemaining -= executeTime; manaUsed += execute.ManaCost * execute.GetNumCasts(); CastSpells.Add(Options.GetActiveRotation().Execute, execute); } timeRemaining -= lifeTap.GetAvgTimeUsed() * lifeTap.AddCastsForRegen( timeRemaining, totalMana - manaUsed, filler); filler.Spam(timeRemaining); CastSpells.Add(Options.GetActiveRotation().Filler, filler); foreach (Spell spell in CastSpells.Values) { spell.AdjustAfterCastingIsSet(); } #endregion #region Calculate spell modifiers, Part 1 // add procs to RawStats if (CastSpells.ContainsKey("Curse Of The Elements")) { // If the raid is already providing this debuff, the curse will // not actually end up casting, so this will not double-count // the debuff. Stats.BonusFireDamageMultiplier = Stats.BonusShadowDamageMultiplier = Stats.BonusHolyDamageMultiplier = Stats.BonusFrostDamageMultiplier = Stats.BonusNatureDamageMultiplier = PetBuffs.BonusFireDamageMultiplier = PetBuffs.BonusShadowDamageMultiplier = PetBuffs.BonusHolyDamageMultiplier = PetBuffs.BonusFrostDamageMultiplier = PetBuffs.BonusNatureDamageMultiplier = .13f; } float critBuff = CalcAddedCritBuff(); Stats.SpellCritOnTarget += critBuff; PetBuffs.SpellCritOnTarget += critBuff; Stats.SpellPower += lifeTap.GetAvgBonusSpellPower(); // create the SpellModifiers object SpellModifiers = new SpellModifiers(); SpellModifiers.AddMultiplicativeMultiplier( Stats.BonusDamageMultiplier); SpellModifiers.AddMultiplicativeMultiplier( Talents.Malediction * .01f); SpellModifiers.AddMultiplicativeMultiplier( Talents.DemonicPact * .02f); SpellModifiers.AddCritOverallMultiplier( Stats.BonusCritMultiplier); if (Talents.Metamorphosis > 0) { SpellModifiers.AddMultiplicativeMultiplier( GetMetamorphosisBonus()); } if (Pet is Felguard) { SpellModifiers.AddMultiplicativeMultiplier( Talents.MasterDemonologist * .01f); } Add4pT10(SpellModifiers); Stats critProcs = CalcCritProcs(); Stats.CritRating += critProcs.CritRating; Stats.SpellCrit += critProcs.SpellCrit; Stats.SpellCritOnTarget += critProcs.SpellCritOnTarget; SpellModifiers.AddCritChance(CalcSpellCrit()); if (Pet != null) { Pet.CalcStats1(); Stats.SpellPower += Talents.DemonicKnowledge * .04f * (Pet.CalcStamina() + Pet.CalcIntellect()); } #endregion float damageDone = CalcRemainingProcs(); #region Calculate Spell Modifiers, Part 2 if (Pet != null) { Pet.CalcStats2(); Stats.SpellPower += Pet.ApplyPactProcBenefit(); } // finilize each spell's modifiers. // Start with Conflagrate, since pyroclasm depends on its results. if (CastSpells.ContainsKey("Conflagrate")) { CastSpells["Conflagrate"].FinalizeSpellModifiers(); } foreach (Spell spell in CastSpells.Values) { if (!(spell is Conflagrate)) { spell.FinalizeSpellModifiers(); } } #endregion #region Calculate damage done for each spell Spell conflagrate = null; float spellPower = CalcSpellPower(); foreach (KeyValuePair <string, Spell> pair in CastSpells) { Spell spell = pair.Value; if (pair.Key.Equals("Conflagrate")) { conflagrate = spell; continue; // save until we're sure immolate is done } spell.SetDamageStats(spellPower); damageDone += spell.GetNumCasts() * spell.AvgDamagePerCast; } if (conflagrate != null) { conflagrate.SetDamageStats(spellPower); damageDone += conflagrate.GetNumCasts() * conflagrate.AvgDamagePerCast; } #endregion return(damageDone / Options.Duration); }
public float CalcSpellHaste() { return(StatUtils.CalcSpellHaste(Stats)); }
public float CalcUsableMana(float fightLen) { return(StatUtils.CalcUsableMana(Stats, fightLen)); }
public float CalcHealth() { return(StatUtils.CalcHealth(Stats)); }
public float CalcSpellPower() { return(StatUtils.CalcSpellPower(Stats, BaseIntellect, CalcOpts.PlayerLevel)); }
public float CalcSpellHaste() { return(StatUtils.CalcSpellHaste(Stats, CalcOpts.PlayerLevel)); }
public float CalcUsableMana(float fightLen) { return(StatUtils.CalcUsableMana(Stats, fightLen, BaseIntellect, CalcOpts.PlayerLevel)); }
public float CalcStamina() { return(StatUtils.CalcStamina(Stats)); }
private void CalcHasteAndManaProcs() { float nonProcHaste = StatUtils.CalcSpellHaste(PreProcStats); if (Options.NoProcs) { WeightedStat staticHaste = new WeightedStat(); staticHaste.Chance = 1f; staticHaste.Value = nonProcHaste; Haste = new List <WeightedStat> { staticHaste }; AvgHaste = nonProcHaste; return; } // the trigger rates are all guestimates at this point, since the // real values depend on haste (which obviously has not been // finalized yet) Dictionary <int, float> periods = new Dictionary <int, float>(); Dictionary <int, float> chances = new Dictionary <int, float>(); float corruptionPeriod = 0f; if (Options.GetActiveRotation().Contains("Corruption")) { corruptionPeriod = 3.1f; if (Talents.GlyphQuickDecay) { corruptionPeriod /= nonProcHaste; } } PopulateTriggers( periods, chances, CalculationsWarlock.AVG_UNHASTED_CAST_TIME / nonProcHaste + Options.Latency, 1 / 1.5f, corruptionPeriod, 1f); // calculate the haste procs Haste = new List <WeightedStat>(); WeightedStat[] percentages = GetUptimes( Stats, periods, chances, s => s.SpellHaste, (a, b, c, d, e, f, g, h) => SpecialEffect .GetAverageCombinedUptimeCombinationsMultiplicative( a, b, c, d, e, f, g, h)); WeightedStat[] ratings = GetUptimes( Stats, periods, chances, s => s.HasteRating, (a, b, c, d, e, f, g, h) => SpecialEffect.GetAverageCombinedUptimeCombinations( a, b, c, d, e, f, g, h)); for (int p = percentages.Length, f = 0; --p >= 0;) { if (percentages[p].Chance == 0) { continue; } for (int r = ratings.Length; --r >= 0; ++f) { if (ratings[r].Chance == 0) { continue; } WeightedStat s = new WeightedStat(); s.Chance = percentages[p].Chance * ratings[r].Chance; s.Value = (1 + percentages[p].Value) * (1 + StatConversion.GetSpellHasteFromRating( ratings[r].Value + Stats.HasteRating)) * (1 + Stats.SpellHaste); Haste.Add(s); AvgHaste += s.Chance * s.Value; } } // calculate mana procs Stats procStats = new Stats(); foreach (SpecialEffect effect in Stats.SpecialEffects()) { if (!periods.ContainsKey((int)effect.Trigger)) { continue; } Stats proc = effect.GetAverageStats( periods[(int)effect.Trigger], chances[(int)effect.Trigger], CalculationsWarlock.AVG_UNHASTED_CAST_TIME, Options.Duration); if (proc.ManaRestore > 0) { proc.ManaRestore *= Options.Duration; } procStats.Accumulate(proc); } Stats.Mana += procStats.Mana; Stats.ManaRestore += procStats.ManaRestore; Stats.ManaRestoreFromBaseManaPPM += procStats.ManaRestoreFromBaseManaPPM; Stats.ManaRestoreFromMaxManaPerSecond += procStats.ManaRestoreFromMaxManaPerSecond; Stats.Mp5 += procStats.Mp5; }
public float CalcMastery() { return(StatUtils.CalcMastery(Stats, CalcOpts.PlayerLevel)); }
public float GetSpecialSpeed() { return(SpecialCooldown + SpecialCastTime / StatUtils.CalcSpellHaste(Stats, Mommy.CalcOpts.PlayerLevel)); }
public float CalcMana() { return(StatUtils.CalcMana(Stats, BaseIntellect, CalcOpts.PlayerLevel)); }