public CurseOfAgony(CharacterCalculationsWarlock calculations) : base("Curse of Agony", MagicSchool.Shadow, SpellTree.Affliction, 0, 0, 1356, 24, 1.5f, 265) { BonusMultiplier *= 1 + 0.05f * calculations.CalculationOptions.ImprovedCurseOfAgony; BonusMultiplier *= 1 + 0.01f * calculations.CalculationOptions.Contagion; DotDamageCoefficient = 1.2f; }
public Incinerate(CharacterCalculationsWarlock calculations) : base("Incinerate", MagicSchool.Fire, SpellTree.Destruction, 555, 642, 0, 0, 2.5f, 355) { BaseCastTime *= 1 - 0.02f * calculations.CalculationOptions.Emberstorm; DirectDamageCoefficient += 0.04f * calculations.CalculationOptions.ShadowAndFlame; BonusMultiplier *= 1 + calculations.BasicStats.BonusWarlockNukeMultiplier; }
public ShadowBolt(CharacterCalculationsWarlock calculations) : base("Shadow Bolt", MagicSchool.Shadow, SpellTree.Destruction, 541, 603, 0, 0, 3, 420) { BaseCastTime -= 0.1f * calculations.CalculationOptions.Bane; DirectDamageCoefficient += 0.04f * calculations.CalculationOptions.ShadowAndFlame; BonusMultiplier *= 1 + calculations.BasicStats.BonusWarlockNukeMultiplier; }
public override void Calculate(CharacterCalculationsWarlock calculations) { float chanceToHit = CalculationsWarlock.ChanceToHit(calculations.CalculationOptions.TargetLevel, HitPercent); DirectShadowHitsPerSecond = (1 / MbFrequency + 1f / 12f) * chanceToHit; EffectiveCritRate = 0; }
public Pet( CharacterCalculationsWarlock mommy, float baseHealth, float healthPerStamina) { Mommy = mommy; TotalModifiers = new SpellModifiers(); MeleeModifiers = new SpellModifiers(); SpecialModifiers = new SpellModifiers(); BaseStamina = 328f; StaminaCoef = .75f; HealthPerStamina = healthPerStamina; BaseHealth = baseHealth; BaseIntellect = 150f; IntellectCoef = .3f; ManaPerIntellect = 11.55f; BaseMana = 1343f; BaseSpellCrit = .03333f; BaseSpellPower = 0f; SpellPowerCoef = .15f; BaseAttackPower = 294f; AttackPowerCoef = .57f; }
public float CalculateISBUptime(CharacterCalculationsWarlock calculations) { float chanceToHit = CalculationsWarlock.ChanceToHit(calculations.CalculationOptions.TargetLevel, calculations.HitPercent); float myDirectShadowHitsPerSecond = calculations.SpellRotation.ShadowBoltCastRatio / calculations.SpellRotation.ShadowBoltCastTime * chanceToHit; float myEffectiveCritRate = myDirectShadowHitsPerSecond * calculations.CritPercent; float raidDirectShadowHitsPerSecond = 0, raidEffectiveCritRate = 0, raidShadowDps = 0; //for (int i = 0; i <= lastEnabledWarlock; i++) //{ // WarlockControl currentWarlock = (WarlockControl)this.groupBoxWarlocks.Controls["suWarlock" + (i + 1)]; // currentWarlock.Calculate(calculations); // raidDirectShadowHitsPerSecond += currentWarlock.DirectShadowHitsPerSecond; // raidEffectiveCritRate += currentWarlock.EffectiveCritRate; // raidShadowDps += currentWarlock.ShadowDps; //} //for (int i = 0; i <= lastEnabledShadowPriest; i++) //{ // ShadowPriestControl currentSp = (ShadowPriestControl)this.groupBoxShadowPriests.Controls["suShadowPriest" + (i + 1)]; // currentSp.Calculate(calculations); // raidDirectShadowHitsPerSecond += currentSp.DirectShadowHitsPerSecond; // raidShadowDps += currentSp.ShadowDps; //} float raidIsbUptime = 1 - (float)Math.Pow(raidEffectiveCritRate, 4); float totalIsbUptime = 1 - (float)Math.Pow(raidEffectiveCritRate + myEffectiveCritRate, 4); calculations.RaidDpsFromIsb = raidShadowDps * 1.2f * (totalIsbUptime - raidIsbUptime); return(totalIsbUptime); }
public Voidwalker(CharacterCalculationsWarlock mommy) : base( mommy, 1671f, // baseHealth, 11f) // healthPerStamina { BaseMeleeDamage = (297f + 448f) / 2f; DamagePerAttackPower = .13f; }
public override void Calculate(CharacterCalculationsWarlock calculations) { if (HitPercent != 0 && CritPercent != 0 && SbCastTime != 0 && SbCastRatio != 0) { float chanceToHit = CalculationsWarlock.ChanceToHit(calculations.CalculationOptions.TargetLevel, HitPercent); DirectShadowHitsPerSecond = SbCastRatio / SbCastTime * chanceToHit; EffectiveCritRate = CritPercent * DirectShadowHitsPerSecond; } }
//public float HealthPerSecond { get; set; } public void CalculateDerivedStats(CharacterCalculationsWarlock calculations) { //hit rate ChanceToHit = CalculationsWarlock.ChanceToHit(calculations.CalculationOptions.TargetLevel, calculations.HitPercent); if (SpellTree == SpellTree.Affliction) { ChanceToHit = Math.Min(0.99f, ChanceToHit + 2 * calculations.CalculationOptions.Suppression); } //cast time CastTime = BaseCastTime / (1 + 0.01f * calculations.HastePercent); if (calculations.BasicStats.Bloodlust > 0) { CastTime /= (1 + 0.3f * 40 / 600); } CastTime += calculations.CalculationOptions.Latency; if (CastTime < calculations.GlobalCooldown + calculations.CalculationOptions.Latency) { CastTime = calculations.GlobalCooldown + calculations.CalculationOptions.Latency; } //for DoTs, factor in the chance to miss (because you have to re-apply) if (BaseDotDuration != 0) { CastTime /= ChanceToHit; } if (CastTime < calculations.GlobalCooldown + calculations.CalculationOptions.Latency) { CastTime = calculations.GlobalCooldown + calculations.CalculationOptions.Latency; } //frequency if (BaseDotDuration == 0) { Frequency = CastTime; } else { Frequency = BaseDotDuration + CastTime + calculations.CalculationOptions.DotGap - (BaseCastTime + calculations.CalculationOptions.Latency); } //mana cost ManaCost = BaseManaCost; if (SpellTree == SpellTree.Destruction) { ManaCost *= (1 - 0.01f * calculations.CalculationOptions.Cataclysm); } if (BaseDotDuration != 0) { ManaCost /= ChanceToHit; } ManaCost = (float)Math.Round(ManaCost); ManaPerSecond = ManaCost / Frequency; //cast ratio CastRatio = CastTime / Frequency; }
public Felguard(CharacterCalculationsWarlock mommy) : base( mommy, 1820f, // baseHealth, 11f) // healthPerStamina { BaseMeleeDamage = (410f + 627f) / 2f; DamagePerAttackPower = .187f; SpecialCooldown = 6f; }
// init public Pet(CharacterCalculationsWarlock mommy, float baseHealth, float healthPerStamina) { Mommy = mommy; TotalModifiers = new SpellModifiers(); MeleeModifiers = new SpellModifiers(); SpecialModifiers = new SpellModifiers(); BaseMana = 1343f; BaseAttackPower = 886f; Stats = new Stats(); }
public void CalculateDamage(CharacterCalculationsWarlock calculations) { if (calculations.BasicStats.BonusSpellCritMultiplier > 0) { CritBonus = 1.09f; } CritBonus *= 0.5f + 0.5f * calculations.CalculationOptions.Ruin; float plusDamage = 0; switch (MagicSchool) { case MagicSchool.Shadow: plusDamage = calculations.ShadowDamage; BonusMultiplier *= calculations.BasicStats.BonusSpellPowerMultiplier * calculations.BasicStats.BonusShadowSpellPowerMultiplier * (1 + 0.2f * calculations.IsbUptime); break; case MagicSchool.Fire: plusDamage = calculations.FireDamage; BonusMultiplier *= calculations.BasicStats.BonusSpellPowerMultiplier * calculations.BasicStats.BonusFireSpellPowerMultiplier; break; } float averageDamage = (BaseMinDamage + BaseMaxDamage) / 2; float dotDamage = BasePeriodicDamage; if (averageDamage > 0 && BasePeriodicDamage > 0) { DirectDamageCoefficient *= averageDamage / (averageDamage + dotDamage); DotDamageCoefficient *= dotDamage / (averageDamage + dotDamage); } if (averageDamage != 0) { averageDamage += plusDamage * DirectDamageCoefficient; averageDamage *= 1 + 0.01f * calculations.CritPercent * CritBonus; if (BaseDotDuration == 0) { averageDamage *= ChanceToHit; } else if (this is Immolate) { averageDamage *= 1 + 0.05f * calculations.CalculationOptions.ImprovedImmolate; } } if (dotDamage != 0) { dotDamage += plusDamage * DotDamageCoefficient; } Damage = (float)Math.Round((averageDamage + dotDamage) * BonusMultiplier); }
public Corruption(CharacterCalculationsWarlock calculations) : base("Corruption", MagicSchool.Shadow, SpellTree.Affliction, 0, 0, 900, 18, 2, 370) { BaseCastTime -= 0.4f * calculations.CalculationOptions.ImprovedCorruption; if (BaseCastTime < 1.5f) { BaseCastTime = 1.5f; } BaseDotDuration += calculations.BasicStats.BonusWarlockDotExtension; BonusMultiplier *= 1 + 0.01f * calculations.CalculationOptions.Contagion; DotDamageCoefficient = 0.94f + 0.12f * calculations.CalculationOptions.EmpoweredCorruption; }
public Felguard(CharacterCalculationsWarlock mommy) : base( mommy, 5395f, // baseHealth, 11f) // healthPerStamina { BaseMeleeDamage = 926.3f; DamagePerAttackPower = .187f; SpecialDamagePerSpellPower = 0.5f * 2f * 0.264f; SpecialCooldown = 6f; }
public Succubus(CharacterCalculationsWarlock mommy) : base( mommy, 1671f, // baseHealth, 9f) // healthPerStamina { BaseMeleeDamage = (363f + 546f) / 2f; DamagePerAttackPower = .157f; //spellID 7814, effectID 3106 SpecialBaseDamage = WARLOCKSPELLBASEVALUES[Mommy.CalcOpts.PlayerLevel - 80] * 0.2010000050f; SpecialDamagePerSpellPower = .5f * .612f; }
public CastingState(CastingState toCopy) { Mommy = toCopy.Mommy; Probability = toCopy.Probability; Cooldowns = new Dictionary<Spell, float>(toCopy.Cooldowns); SeriesPriorities = new List<int>(toCopy.SeriesPriorities); Series = new List<Spell>(toCopy.Series); SeriesTimes = new List<float>(toCopy.SeriesTimes); SeriesHits = new List<bool>(toCopy.SeriesHits); BackdraftCharges = toCopy.BackdraftCharges; MoltenCoreCharges = toCopy.MoltenCoreCharges; }
public CastingState(CastingState toCopy) { Mommy = toCopy.Mommy; Probability = toCopy.Probability; Cooldowns = new Dictionary <Spell, float>(toCopy.Cooldowns); SeriesPriorities = new List <int>(toCopy.SeriesPriorities); Series = new List <Spell>(toCopy.Series); SeriesTimes = new List <float>(toCopy.SeriesTimes); SeriesHits = new List <bool>(toCopy.SeriesHits); BackdraftCharges = toCopy.BackdraftCharges; MoltenCoreCharges = toCopy.MoltenCoreCharges; }
public Succubus(CharacterCalculationsWarlock mommy) : base( mommy, 1671f, // baseHealth, 9f) // healthPerStamina, { BaseMeleeDamage = (363f + 546f) / 2f; DamagePerAttackPower = .157f; SpecialBaseDamage = 248f; SpecialDamagePerSpellPower = .5f; SpecialCooldown = 12f - Mommy.Talents.DemonicPower * 3f; }
public Felhunter(CharacterCalculationsWarlock mommy) : base( mommy, 1671f, // baseHealth, 9.5f) // healthPerStamina, { BaseMeleeDamage = (277f + 416f) / 2f; DamagePerAttackPower = .12f; SpecialBaseDamage = (112f + 159f) / 2f; SpecialDamagePerSpellPower = .5f; SpecialCooldown = 6f - Mommy.Talents.ImprovedFelhunter * 2f; }
public Felhunter(CharacterCalculationsWarlock mommy) : base( mommy, 5395f, // baseHealth 9.5f) // healthPerStamina { BaseMeleeDamage = 926.3f; DamagePerAttackPower = .086786f; //not sure why // 19072 base mana //spellid 54049, effectid 46748-9 SpecialBaseDamage = WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * 0.126f; SpecialDamagePerSpellPower = 1.228f; SpecialCooldown = 6f; }
public CastingState(CharacterCalculationsWarlock mommy, Spell precedingSpell, float probability) { Mommy = mommy; Probability = probability; Cooldowns = new Dictionary<Spell, float>(); SeriesPriorities = new List<int>(); Series = new List<Spell>(); SeriesTimes = new List<float>(); SeriesHits = new List<bool>(); if (precedingSpell != null) { Elapsed = precedingSpell.GetAvgTimeUsed(); } }
public CastingState(CharacterCalculationsWarlock mommy, Spell precedingSpell, float probability) { Mommy = mommy; Probability = probability; Cooldowns = new Dictionary <Spell, float>(); SeriesPriorities = new List <int>(); Series = new List <Spell>(); SeriesTimes = new List <float>(); SeriesHits = new List <bool>(); if (precedingSpell != null) { Elapsed = precedingSpell.GetAvgTimeUsed(); } }
public Imp(CharacterCalculationsWarlock mommy) : base( mommy, 2877f, // baseHealth, 8.4f) // healthPerStamina, { BaseStamina = 118f; BaseIntellect = 368f; ManaPerIntellect = 4.95f; BaseMana = 1052f; BaseSpellCrit = .01f; SpecialBaseDamage = (213f + 239f) / 2f; SpecialDamagePerSpellPower = .79f; SpecialCastTime = 2.5f - Mommy.Talents.DemonicPower * .25f; }
public Imp(CharacterCalculationsWarlock mommy) : base( mommy, 5026f, // baseHealth, 8.4f) // healthPerStamina { BaseStamina = 118f; BaseIntellect = 368f; ManaPerIntellect = 4.95f; BaseMana = 1052f; BaseSpellCrit = .01f; //spellID 3110, effectID 929, 92747 SpecialBaseDamage = WARLOCKSPELLBASEVALUES[Mommy.CalcOpts.PlayerLevel - 80] * 0.1230000034f; SpecialDamagePerSpellPower = .657f * .5f; SpecialCastTime = 2.5f - Mommy.Talents.DarkArts * .25f; }
public static void CalculateRaidIsbUptime(CharacterCalculationsWarlock calculations) { if (calculations.CalculationOptions.IsbMethod == IsbMethod.Raid) { float chanceToHit = CalculationsWarlock.ChanceToHit(calculations.CalculationOptions.TargetLevel, calculations.HitPercent); float myDirectShadowHitsPerSecond = calculations.SpellRotation.ShadowBoltCastRatio / calculations.SpellRotation.ShadowBoltCastTime * chanceToHit; float myEffectiveCritRate = myDirectShadowHitsPerSecond * calculations.CritPercent; float raidDirectShadowHitsPerSecond = 0, raidEffectiveCritRate = 0, raidShadowDps = 0; for (int i = 0; i < calculations.CalculationOptions.NumRaidWarlocks; i++) { SUWarlock currentWarlock = calculations.CalculationOptions.RaidWarlocks[i]; currentWarlock.Calculate(calculations); raidDirectShadowHitsPerSecond += currentWarlock.DirectShadowHitsPerSecond; raidEffectiveCritRate += currentWarlock.EffectiveCritRate; raidShadowDps += currentWarlock.ShadowDps; } for (int i = 0; i < calculations.CalculationOptions.NumRaidShadowPriests; i++) { SUShadowPriest currentSp = calculations.CalculationOptions.RaidShadowPriests[i]; currentSp.Calculate(calculations); raidDirectShadowHitsPerSecond += currentSp.DirectShadowHitsPerSecond; raidShadowDps += currentSp.ShadowDps; } myEffectiveCritRate /= 100; raidEffectiveCritRate /= 100; float raidIsbUptime = 1 - (float)Math.Pow(1 - (raidEffectiveCritRate / raidDirectShadowHitsPerSecond), 4); float totalIsbUptime = 1 - (float)Math.Pow(1 - ((raidEffectiveCritRate + myEffectiveCritRate) / (raidDirectShadowHitsPerSecond + myDirectShadowHitsPerSecond)), 4); calculations.RaidDpsFromIsb = raidShadowDps * 0.2f * (totalIsbUptime - raidIsbUptime); calculations.IsbUptime = totalIsbUptime; } else { calculations.RaidDpsFromIsb = 0; calculations.IsbUptime = calculations.CalculationOptions.CustomIsbUptime; } }
public SiphonLife(CharacterCalculationsWarlock calculations) : base("Siphon Life", MagicSchool.Shadow, SpellTree.Affliction, 0, 0, 630, 30, 1.5f, 410) { DotDamageCoefficient /= 2; }
public FelFlameWithFelSpark(CharacterCalculationsWarlock mommy) : base(mommy) { SpellModifiers.AddMultiplicativeDirectMultiplier(3f); }
public LifeTap(CharacterCalculationsWarlock calculations) : base("Life Tap", MagicSchool.Shadow, SpellTree.Affliction, 0, 0, 0, 0, 1.5f, -580) { BaseManaCost -= calculations.ShadowDamage * 0.8f; BaseManaCost *= (1 + 0.1f * calculations.CalculationOptions.ImprovedLifeTap); }
public CurseOfTheElements(CharacterCalculationsWarlock mommy) : base( mommy, 0, // magic school SpellTree.Affliction, // spell tree .1f, // percent base mana 0f, // cast time 0f, // cooldown 300f, // recast period true) // can miss { GCDBonus = mommy.Talents.Pandemic * .25f; }
public DrainSoul(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Shadow, SpellTree.Affliction, .14f, //percent base mana 15f, //base cast time 0f, //cooldown 0f, //recast period WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE, //baseTickDamage (int)((5f * mommy.AvgHaste) + 0.5f), // hasted num ticks COEFF, //tickCoefficient 1f, //addedTickMultiplier (assuming this is only used during execute) true, //canTickCrit 0f, //bonusCritChance 1f) //bonusCritMultiplier { }
public Immolate(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Fire, SpellTree.Destruction, .08f, // percentBaseMana, 2f - talentValues[mommy.Talents.Bane], // baseCastTime, 0f, // cooldown, 15f + (mommy.Talents.Inferno > 0 ? 6f : 0f), // recastPeriod, true, // canMiss, WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * DIRECTSCALE, // avgDirectDamage, DIRECTCOEFF, // directCoefficient, mommy.Talents.ImprovedImmolate * .1f, // addedDirectMultiplier, WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * TICKSCALE, // baseTickDamage, (int)(((5f + (mommy.Talents.Inferno > 0 ? 2f : 0f)) * mommy.AvgHaste) + 0.5f), // numTicks, TICKCOEFF, // tickCoefficient, (mommy.Talents.GlyphOfImmolate ? .1f : 0f) + mommy.Talents.ImprovedImmolate * .1f, // addedTickMultiplier, true, // canTickCrit, 0f, // bonusCritChance, 1f) // bonusCritMultiplier { RecordMissesSeparately = true; }
public BaneOfAgony(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Shadow, // magic school SpellTree.Affliction, // spell tree .1f, // percent base mana 0f, // cast time 0f, // cooldown mommy.Talents.GlyphOfBaneOfAgony ? 28f : 24f, // recast period 0f, // damage per tick - set below 0f, // num ticks - set below COEFF, // tick coefficient 0f, // addedTickMultiplier true, //canTickCrit mommy.Talents.DoomAndGloom * .04f, // bonus crit chance 1f) // bonus crit multiplier { GCDBonus = mommy.Talents.Pandemic * .25f; // BoA consists of 4 weak ticks, 4 medium ticks, 4 strong ticks, and if glyphed, 2 very strong ticks. // Additional ticks from haste are weak ticks. TODO: this is wrong. float baseDamage = WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE * 12f; float baseNumTicks = mommy.Talents.GlyphOfBaneOfAgony ? 14f : 12f; NumTicks = (int)((baseNumTicks * mommy.AvgHaste) + 0.5f); BaseTickDamage = baseDamage * (1f + (NumTicks - baseNumTicks) * .042f + (mommy.Talents.GlyphOfBaneOfAgony ? .3325f : 0f)) / NumTicks; }
public Incinerate(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Fire, SpellTree.Destruction, .14f, // percentBaseMana, 2.5f - mommy.Talents.Emberstorm * .0125f, // baseCastTime, 0f, // cooldown, 0f, // recastPeriod, WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE, // avgDirectDamage, COEFF, // directCoefficient, (1f + (mommy.Talents.GlyphOfIncinerate ? .05f : 0f)) * (1f + mommy.Talents.ShadowAndFlame * .04f), // addedDirectMultiplier, 0f, // bonusCritChance, 1f) // bonus crit multiplier { }
public ImmolationAura(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Fire, SpellTree.Demonology, .64f, // percentBaseMana, 0f, // baseCastTime, 180f, // cooldown, 0f, // recastPeriod, 251f, // baseTickDamage, (int)((15f * mommy.AvgHaste) + 0.5f), // numTicks, COEFF, // tickCoefficient, 0f, // addedTickMultiplier, true, // canTickCrit, 0f, // bonusCritChance, 1f) // bonusCritMultiplier { }
public static float GetBaseCastTime(CharacterCalculationsWarlock mommy) { return 3f - talentValues[mommy.Talents.Bane]; }
public SearingPain(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Shadow, SpellTree.Demonology, .12f, // percentBaseMana, 1.5f, // baseCastTime, 0f, // cooldown, 0f, // recastPeriod, WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE, // avgDirectDamage COEFF, // directCoefficient 0f, // addedDirectMultiplier, 0f, // bonusCritChance, 1f) // bonus crit multiplier { // UNMODELED: bonus crit chance = 20% * #ImprovedSearingPain if target < 50% health }
public LifeTap(CharacterCalculationsWarlock mommy) : base( mommy, 0, // magic school SpellTree.Affliction, // spell tree 0f, // percent base mana (overwritten below) 0f, // cast time 0f, // cooldown 0f, // recast period false) // can miss { ManaCost = (mommy.CalcHealth() * .15f) * (1.2f + mommy.Talents.ImprovedLifeTap * .1f); GCDBonus = mommy.Talents.GlyphOfLifeTap ? 0.5f : 0f; }
public Incinerate_UnderMoltenCore(CharacterCalculationsWarlock mommy) : base(mommy) { BaseCastTime /= 1f + Mommy.Talents.MoltenCore * .1f; float procChance = Mommy.Talents.MoltenCore * .02f; float tickPeriod = Immolate.GetTickPeriod(mommy); Cooldown = tickPeriod / procChance; }
public CurseOfWeakness(CharacterCalculationsWarlock calculations) : base("Curse of Weakness", MagicSchool.Shadow, SpellTree.Affliction, 0, 0, 0, 120, 1.5f, 265) { }
public Corruption(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Shadow, // magic school SpellTree.Affliction, // spell tree .06f, // percent base mana 0f, // cast time 0f, // cooldown 18f, // recast period WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE, // base damage per tick (int)((6f * mommy.AvgHaste) + 0.5f), // hasted num ticks COEFF, // tick coefficient 0f, // addedTickMultiplier true, // canTickCrit mommy.Talents.EverlastingAffliction * .05f, // bonus crit chance 1f) // bonus crit multiplier { SpellModifiers.AddAdditiveTickMultiplier(mommy.Talents.ImprovedCorruption * .04f); WarlockTalents talents = Mommy.Talents; // Malficus solved the average duration of a rolling Corruption, see // http://rawr.codeplex.com/Thread/View.aspx?ThreadId=203628 // // D = the non-rolling duration // T = the time between reset triggers // P = the chance a trigger will actually reset the duration // TC = the time between corruption ticks float d = RecastPeriod; float t = GuessRollingTriggerFrequency(); float[] points = { 0f, .33f, .66f, 1f }; float p = Mommy.HitChance * points[talents.EverlastingAffliction]; float tc = d / NumTicks; if (p == 1 && t <= d) { RecastPeriod = Mommy.BossOpts.BerserkTimer; } else if (p > 0 && t > 0) { float fightLen = Mommy.BossOpts.BerserkTimer; int maxTriggers = (int)(fightLen * t); int maxTicks = (int)(fightLen / tc); RecastPeriod = tc * maleficusDuration(new float[maxTicks + 1, maxTriggers + 1], tc, p, 1 / t, (int)(fightLen / tc), 6, 0); } NumTicks = RecastPeriod / tc; }
public UnstableAffliction(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Shadow, SpellTree.Affliction, .15f, // percent base mana mommy.Talents.GlyphOfUnstableAffliction ? 1.3f : 1.5f, // cast time 0f, // cooldown 15f, // recast period WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE, // tick damage (int)((5f * mommy.AvgHaste) + 0.5f), // num ticks COEFF, // tick coefficient 0f, // addedTickMultiplier true, // canTickCrit mommy.Talents.EverlastingAffliction * .05f, // bonus crit chance 1f) // bonus crit multiplier { if (mommy.Talents.GlyphOfUnstableAffliction) { GCDBonus = .2f; } }
public BaneOfDoom(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Shadow, // magic school SpellTree.Affliction, // spell tree .15f, // percent base mana 0f, // baseCastTime, 0f, // cooldown, 60f, // recastPeriod, WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE, // baseTickDamage, 4f, // numTicks, COEFF, // tickCoefficient, 0f, // addedTickMultiplier, true, // canTickCrit, mommy.Talents.DoomAndGloom * .04f, // bonus crit chance 1f) // bonusCritMultiplier { GCDBonus = mommy.Talents.Pandemic * .25f; //UNMODELED: 20% chance to summon Ebon Imp with each tick (+ Impending Doom * 10%) //Ebon Imp does avg X damage over Y seconds; Z cooldown }
//DoT Constructor public Spell( CharacterCalculationsWarlock mommy, MagicSchool magicSchool, SpellTree spellTree, float percentBaseMana, float baseCastTime, float cooldown, float recastPeriod, float baseTickDamage, float numTicks, float tickCoefficient, float addedTickMultiplier, bool canTickCrit, float bonusCritChance, float bonusCritMultiplier) : this( mommy, magicSchool, spellTree, percentBaseMana, baseCastTime, cooldown, recastPeriod, true, 0f, // direct avg damage 0f, // direct coefficient 0f, // addedDirectMultiplier baseTickDamage, numTicks, tickCoefficient, addedTickMultiplier, canTickCrit, bonusCritChance, bonusCritMultiplier) { }
public DemonSoul(CharacterCalculationsWarlock mommy) : base( mommy, 0, SpellTree.Demonology, .15f, 0f, 120f, 0f, false) { /* Imp - Critical Strike chance on cast time Destruction spells increased by 30% for 20 sec. Succubus - Shadow Bolt damage increased by 10% for 20 sec. Felhunter - Periodic shadow damage increased by 20% for 20 sec. Felguard - Spell haste increased by 15% and fire and shadow damage done increased by 10% for 20 sec. */ }
// Kitchen Sink Constructor public Spell( CharacterCalculationsWarlock mommy, MagicSchool magicSchool, SpellTree spellTree, float percentBaseMana, float baseCastTime, float cooldown, float recastPeriod, bool canMiss, float avgDirectDamage, float directCoefficient, float addedDirectMultiplier, float baseTickDamage, float numTicks, float tickCoefficient, float addedTickMultiplier, bool canTickCrit, float bonusCritChance, float bonusCritMultiplier) { Mommy = mommy; MagicSchool = magicSchool; MySpellTree = spellTree; ManaCost = mommy.BaseMana * percentBaseMana; BaseCastTime = baseCastTime; BaseDamage = avgDirectDamage; Cooldown = cooldown; RecastPeriod = recastPeriod; CanMiss = canMiss; DirectCoefficient = directCoefficient; BaseTickDamage = baseTickDamage; NumTicks = numTicks; TickCoefficient = tickCoefficient; CanTickCrit = canTickCrit; SimulatedStats = new Dictionary<string, SimulatedStat>(); WarlockTalents talents = mommy.Talents; SpellModifiers = new SpellModifiers(); SpellModifiers.AddMultiplicativeDirectMultiplier(addedDirectMultiplier); SpellModifiers.AddMultiplicativeTickMultiplier(addedTickMultiplier); SpellModifiers.AddCritChance(bonusCritChance); SpellModifiers.AddCritBonusMultiplier(bonusCritMultiplier); }
public FelFlame(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Shadow, SpellTree.Destruction, .06f, // percentBaseMana, 0f, // baseCastTime, 0f, // cooldown, 0f, // recastPeriod, WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE, // avgDirectDamage COEFF, // directCoefficient 0f, // addedDirectMultiplier, 0f, // bonusCritChance, 1f) // bonus crit multiplier { // UNMODELED: extends Immolate or Unstable Affliction duration by 6 sec }
// TODO: is this order right? or is the Bane reduction applied after the 10% discount? public ChaosBolt(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Fire, SpellTree.Destruction, .07f, // percentBaseMana, (2.5f - talentValues[mommy.Talents.Bane]) * (mommy.Warlock_T11_2P ? 0.9f : 1f), // baseCastTime, mommy.Talents.GlyphOfChaosBolt ? 10f : 12f, // cooldown, 0f, // recastPeriod, WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE, // avgDirectDamage COEFF, // directCoefficient 0f, // addedDirectMultiplier, 0f, // bonusCritChance, 1f) // bonus crit multiplier { ApplySoulLeech(); }
public WarlockSpellRotation(CharacterCalculationsWarlock ccw) { calculations = ccw; spellList = new List <Spell>(); if (calculations.CalculationOptions.CastImmolate) { spellList.Add(new Immolate(calculations)); } switch (calculations.CalculationOptions.CastedCurse) { case CastedCurse.CurseOfAgony: spellList.Add(new CurseOfAgony(calculations)); break; case CastedCurse.CurseOfDoom: spellList.Add(new CurseOfDoom(calculations)); break; case CastedCurse.CurseOfRecklessness: spellList.Add(new CurseOfRecklessness(calculations)); break; case CastedCurse.CurseOfShadow: spellList.Add(new CurseOfShadow(calculations)); break; case CastedCurse.CurseOfTheElements: spellList.Add(new CurseOfTheElements(calculations)); break; case CastedCurse.CurseOfTongues: spellList.Add(new CurseOfTongues(calculations)); break; case CastedCurse.CurseOfWeakness: spellList.Add(new CurseOfWeakness(calculations)); break; } if (calculations.CalculationOptions.CastCorruption) { spellList.Add(new Corruption(calculations)); } if (calculations.CalculationOptions.CastSiphonLife) { spellList.Add(new SiphonLife(calculations)); } if (calculations.CalculationOptions.CastUnstableAffliction) { spellList.Add(new UnstableAffliction(calculations)); } switch (calculations.CalculationOptions.FillerSpell) { case FillerSpell.Shadowbolt: fillerSpell = new ShadowBolt(calculations); break; case FillerSpell.Incinerate: fillerSpell = new Incinerate(calculations); break; } ShadowSpellsPerSecond = 0; FireSpellsPerSecond = 0; SpellsPerSecond = 0; AfflictionSpellsPerSecond = 0; NonAfflictionSpellsPerSecond = 0; ShadowBoltsPerSecond = 0; IncineratesPerSecond = 0; }
public static bool WillBeCast(CharacterCalculationsWarlock mommy) { return mommy.CalcOpts.GetActiveRotation().Contains("Conflagrate") && mommy.Destruction; }
public abstract void Calculate(CharacterCalculationsWarlock calculations);
public Conflagrate(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Fire, SpellTree.Destruction, .16f, // percentBaseMana, 0f, // baseCastTime, COOLDOWN - (mommy.Talents.GlyphOfConflagrate ? 2f : 0f), // cooldown, 0f, // recastPeriod, 0f, // avgDirectDamage, will be set in SetDamageStats 0f, // directCoefficient, already accounted for by Immolate AvgTickDamage 0f, // addedDirectMultiplier, already accounted for by Immolate AvgTickDamage mommy.Talents.FireAndBrimstone * .05f, // bonusCritChance, 1f) // bonusCritMultiplier) { RecordMissesSeparately = true; }
public UnstableAffliction(CharacterCalculationsWarlock calculations) : base("Unstable Affliction", MagicSchool.Shadow, SpellTree.Affliction, 0, 0, 1050, 18, 1.5f, 400) { }
public static float GetTickPeriod(CharacterCalculationsWarlock mommy) { float period = 3.1f; // total guess period /= mommy.AvgHaste; return period; }
public ShadowBolt_Instant(CharacterCalculationsWarlock mommy) : base(mommy) { BaseCastTime = 0f; // Currently modeled as a spell on a cooldown equal to the // average time between procs. This lengthens the time between // casts according to the rules for cooldown collision, which is not // completely accurate, but close enough. To be accurate it // should instead factor in the probability that it will proc twice // (or more) while casting higher priority spells. float procChance = Mommy.Talents.Nightfall * .02f; if (Mommy.Talents.GlyphOfCorruption) { procChance += .04f; } float tickPeriod = Corruption.GetTickPeriod(mommy); Cooldown = tickPeriod / procChance; }
public Incinerate_UnderBackdraft(CharacterCalculationsWarlock mommy) : base(mommy) { }
public Shadowburn(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Shadow, SpellTree.Destruction, .15f, // percentBaseMana, 0f, // baseCastTime, 15f, // cooldown, 0f, // recastPeriod, WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE, // avgDirectDamage COEFF, // directCoefficient 0f, // addedDirectMultiplier, 0f, // bonusCritChance, 1f) // bonus crit multiplier { // UNMODELED: if glyphed and doesn't kill a target, cooldown is reset; cooldown 6 sec for this effect }
public SoulFire(CharacterCalculationsWarlock mommy) : base( mommy, MagicSchool.Fire, // magicSchool, SpellTree.Destruction, // spellTree, .09f, // percentBaseMana, 4f - mommy.Talents.Emberstorm * 0.5f, // baseCastTime, 0f, // cooldown, 0f, // recastPeriod, true, WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE, // avgDirectDamage, COEFF, // directCoefficient, 0f, // addedDirectMultiplier, WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE * mommy.Talents.BurningEmbers * .15f / 7f, // baseTickDamage, 7f, // numTicks, COEFF, // tickCoefficient, 0f, // addedTickMultiplier, true, // canTickCrit, 0f, // bonusCritChance, 1f) // bonusCritMultiplier { //UNMODELED: when target below 35% health, cast time reduced by #Decimation * 20% for 10 sec }
public ShadowBolt(CharacterCalculationsWarlock mommy) : base( mommy, // options MagicSchool.Shadow, // magic school SpellTree.Destruction, // spell tree .1f * (mommy.Talents.GlyphOfShadowBolt ? 0.85f : 1f), // percent base mana GetBaseCastTime(mommy), // cast time 0f, // cooldown 0f, // recast period WARLOCKSPELLBASEVALUES[mommy.CalcOpts.PlayerLevel - 80] * SCALE, // avg base COEFF, // direct coefficient mommy.Talents.ShadowAndFlame * .04f, // addedDirectMultiplier 0f, // bonus crit chance 1f) // bonus crit multiplier { }
public CurseOfTongues(CharacterCalculationsWarlock calculations) : base("Curse of Tongues", MagicSchool.Shadow, SpellTree.Affliction, 0, 0, 0, 30, 1.5f, 110) { }