public override CharacterCalculationsBase GetCharacterCalculations(Character character, Item additionalItem, bool referenceCalculation, bool significantChange, bool needsDisplayCalculations) { // First things first, we need to ensure that we aren't using bad data CharacterCalculationsEnhance calc = new CharacterCalculationsEnhance(); if (character == null) { return calc; } CalculationOptionsEnhance calcOpts = character.CalculationOptions as CalculationOptionsEnhance; if (calcOpts == null) { return calc; } BossOptions bossOpts = character.BossOptions; if (bossOpts == null) { bossOpts = new BossOptions(); } #region Applied Stats Stats stats = GetCharacterStats(character, additionalItem); //StatsEnhance stats = GetCharacterStats(character, additionalItem) as StatsEnhance; calc.BasicStats = stats; calc.BuffStats = GetBuffsStats(character.ActiveBuffs, character.SetBonusCount); Item noBuffs = RemoveAddedBuffs(calc.BuffStats); calc.EnhSimStats = GetCharacterStats(character, noBuffs); calc.TargetLevel = bossOpts.Level; calc.ActiveBuffs = new List<Buff>(character.ActiveBuffs); float initialAP = stats.AttackPower; // deal with Special Effects - for now add into stats regardless of effect later need to be more precise StatsSpecialEffects se = new StatsSpecialEffects(character, stats, calcOpts, bossOpts); stats.Accumulate(se.getSpecialEffects()); //Set up some talent variables float concussionMultiplier = 1f + .02f * character.ShamanTalents.Concussion; // float shieldBonus = 1f + .05f * character.ShamanTalents.ImprovedShields; // float callofFlameBonus = 1f + .1f * character.ShamanTalents.CallOfFlame; // float mentalQuickness = .5f; //AP -> SP conversion float windfuryWeaponBonus = 4430f; //WFAP (Check) float windfuryDamageBonus = 1f; // switch (character.ShamanTalents.ElementalWeapons) { case 1: windfuryDamageBonus = 1.20f; break; case 2: windfuryDamageBonus = 1.40f; break; } float focusedStrikes = 1f; // switch (character.ShamanTalents.FocusedStrikes) { case 1: focusedStrikes = 1.15f; break; case 2: focusedStrikes = 1.30f; break; case 3: focusedStrikes = 1.45f; break; } float unleashedRage = 0f; switch (character.ShamanTalents.UnleashedRage) { case 1: unleashedRage = .05f; break; case 2: unleashedRage = .10f; break; } // Tier Bonuses int setCount; float enhance2T11 = 0f; character.SetBonusCount.TryGetValue("Battlegear of the Raging Elements", out setCount); if (setCount >= 2) { enhance2T11 = 0.1f; } float enhance2T12 = 0f; float enhance4T12 = 0f; character.SetBonusCount.TryGetValue("Volcanic Battlegear", out setCount); if (setCount >= 2) { enhance2T12 = 0.05f; } if (setCount >= 4) { if (calcOpts.PriorityInUse(EnhanceAbility.StormStrike)) { enhance4T12 = 0.06f; //enhance4T12 = 0.16f; } } // float FTspellpower = (float)Math.Floor((float)(748f * (1 + character.ShamanTalents.ElementalWeapons * .2f))); if (calcOpts.MainhandImbue == "Flametongue") stats.SpellPower += FTspellpower; if (calcOpts.OffhandImbue == "Flametongue") stats.SpellPower += FTspellpower; float addedAttackPower = stats.AttackPower - initialAP; float MQSpellPower = mentalQuickness * addedAttackPower * (1 + stats.BonusAttackPowerMultiplier); // make sure to add in the spellpower from MQ gained from all the bonus AP added in this section stats.SpellPower += MQSpellPower * (1 + stats.BonusSpellPowerMultiplier); // also add in bonus attack power stats.AttackPower += addedAttackPower * stats.BonusAttackPowerMultiplier; // #endregion #region Damage Model //////////////////////////// // Main calculation Block // //////////////////////////// CombatStats cs = new CombatStats(character, stats, calcOpts, bossOpts); // calculate the combat stats using modified stats // only apply unleashed rage talent if not already applied Unleashed Rage buff. if (!character.ActiveBuffsContains("Unleashed Rage") && !character.ActiveBuffsContains("Trueshot Aura") && !character.ActiveBuffsContains("Abomination's Might")) { float URattackPower = (calc.BuffStats.BonusAttackPowerMultiplier == .1f) ? 0f : (stats.AttackPower * unleashedRage); stats.AttackPower += URattackPower; // no need to multiply by bonus attack power as the whole point is its zero if we need to add Unleashed rage stats.SpellPower += mentalQuickness * URattackPower * (1f + stats.BonusSpellPowerMultiplier); } // assign basic variables for calcs float attackPower = stats.AttackPower; float spellPower = stats.SpellPower; float mastery = 1f + ((8f + StatConversion.GetMasteryFromRating(stats.MasteryRating)) * 0.025f); float wdpsMH = character.MainHand == null ? 46.3f : (stats.WeaponDamage + (character.MainHand.MinDamage + character.MainHand.MaxDamage) / 2f) / character.MainHand.Speed; float wdpsOH = character.OffHand == null ? 46.3f : (stats.WeaponDamage + (character.OffHand.MinDamage + character.OffHand.MaxDamage) / 2f) / character.OffHand.Speed; float dualWieldSpecialization = .06f; //Hit portion of Dual Wield float bonusPhysicalDamage = (1f + stats.BonusDamageMultiplier) * (1f + stats.BonusPhysicalDamageMultiplier); //float bonusFrostDamage = (1f + stats.BonusDamageMultiplier) * (1f + stats.BonusFrostDamageMultiplier) * (1f + character.ShamanTalents.ElementalPrecision * 0.01f); // float bonusFireDamage = (1f + stats.BonusDamageMultiplier) * (1f + stats.BonusFireDamageMultiplier ) * (1f + character.ShamanTalents.ElementalPrecision * 0.01f); // float bonusNatureDamage = (1f + stats.BonusDamageMultiplier) * (1f + stats.BonusNatureDamageMultiplier) * (1f + character.ShamanTalents.ElementalPrecision * 0.01f); // #endregion #region Individual DPS #region Melee DPS float APDPS = (attackPower / 14f); float adjustedMHDPS = (wdpsMH + APDPS); float adjustedOHDPS = 0f; float dpsOHMeleeTotal = 0f; float dpsMoteOfAnger = 0f; float dpsMHMeleeNormal = adjustedMHDPS * cs.NormalHitModifierMH; float dpsMHMeleeCrits = adjustedMHDPS * cs.CritHitModifierMH; float dpsMHMeleeGlances = adjustedMHDPS * cs.GlancingHitModifier; float meleeMultipliers = cs.DamageReduction * bonusPhysicalDamage * (1f + stats.BonusWhiteDamageMultiplier); float dpsMHMeleeTotal = ((dpsMHMeleeNormal + dpsMHMeleeCrits + dpsMHMeleeGlances) * cs.UnhastedMHSpeed / cs.HastedMHSpeed) * meleeMultipliers; if (cs.HastedOHSpeed != 0) { adjustedOHDPS = (wdpsOH + APDPS) * .5f; float dpsOHMeleeNormal = adjustedOHDPS * cs.NormalHitModifierOH; float dpsOHMeleeCrits = adjustedOHDPS * cs.CritHitModifierOH; float dpsOHMeleeGlances = adjustedOHDPS * cs.GlancingHitModifier; dpsOHMeleeTotal = ((dpsOHMeleeNormal + dpsOHMeleeCrits + dpsOHMeleeGlances) * cs.UnhastedOHSpeed / cs.HastedOHSpeed) * meleeMultipliers; } // Generic MH & OH damage values used for SS, LL & WF float damageMHSwing = adjustedMHDPS * cs.UnhastedMHSpeed; float damageOHSwing = adjustedOHDPS * cs.UnhastedOHSpeed; if (cs.HastedOHSpeed != 0) dpsMoteOfAnger = (damageMHSwing + damageOHSwing) / 2 * stats.MoteOfAnger; else dpsMoteOfAnger = damageMHSwing * stats.MoteOfAnger; float dpsMelee = dpsMHMeleeTotal + dpsOHMeleeTotal + dpsMoteOfAnger; #endregion #region Stormstrike DPS float dpsSS = 0f; if (character.ShamanTalents.Stormstrike == 1 && calcOpts.PriorityInUse(EnhanceAbility.StormStrike) && character.MainHand != null) { float swingDPSMH = damageMHSwing * 2.25f * cs.HitsPerSMHSS; float swingDPSOH = damageOHSwing * 2.25f * cs.HitsPerSOHSS; float SSnormal = (swingDPSMH * cs.YellowHitModifierMH) + (swingDPSOH * cs.YellowHitModifierOH); float SScrit = ((swingDPSMH * cs.YellowCritModifierMH) + (swingDPSOH * cs.YellowCritModifierOH)) * cs.CritMultiplierMelee; dpsSS = (SSnormal + SScrit) * cs.DamageReduction * /*(1f + stats.BonusStormstrikeDamageMultiplier)*/focusedStrikes * (1f + enhance2T11); } #endregion #region Lavalash DPS /* Taken from EnhSim (thank you ziff) Damage = bwd * llb * (1.0 + sfs * (sfb + t12-2p) + ftb) * (1.0 + llt + llg + t11-2p) * fdm bwd - Base weapon damage against a target with no armor llb - Lava Lash Bonus, this is the default lava lash damage bonus of 2.0 sfs - # of current stacks of Searing Flames sfb - the searing flames bonus from Improved Lava Lash. Maxed out it is .20 t12-2p - the 2 piece bonus from T12, which is currently an extra 0.05 per searing flame stack ftb - the bonus if Flametongue weapon is on your off-hand, which is 0.40 llt - the Lava lash damage bonus from Improved Lava Lash. Maxed out, it is 0.30 llg - the bonus from Lava Lash glyph, which is 0.20 t11-2p - the 2 piece bonus from T11, which is 0.10 fdm - the fire damage multiplier, which includes the mastery bonus, elemental precision, buffs, debuff, etc. These multipliers are always multiplied to each other, and not done additively. */ float dpsLL = 0f; if (calcOpts.PriorityInUse(EnhanceAbility.LavaLash) && character.OffHand != null) { float impLL = character.ShamanTalents.ImprovedLavaLash * 0.15f; float searingFlames = 0f; float flametongue = 0f; float glyphLL = 0f; if (calcOpts.PriorityInUse(EnhanceAbility.SearingTotem) && character.ShamanTalents.SearingFlames != 0) { searingFlames = (character.ShamanTalents.ImprovedLavaLash * 0.1f + enhance2T12) * 5f; //5f = number of stacks of searing flames (takes app. 8.25s to hit 5 stacks, LL CD is 10s). } if (calcOpts.OffhandImbue == "Flametongue") { flametongue = .4f; } if (character.ShamanTalents.GlyphofLavaLash) { glyphLL = .2f; } float lavalashDPS = damageOHSwing * 2f * cs.HitsPerSLL; float LLnormal = lavalashDPS * cs.YellowHitModifierOH; float LLcrit = lavalashDPS * cs.YellowCritModifierOH * cs.CritMultiplierMelee; dpsLL = (LLnormal + LLcrit) * (1f + searingFlames + flametongue) * (1f + impLL + glyphLL + enhance2T11) * (1 + enhance4T12) * mastery * bonusFireDamage; } #endregion #region Earth Shock DPS float dpsES = 0f; if (calcOpts.PriorityInUse(EnhanceAbility.EarthShock)) { float damageESBase = 931f; float coefES = .386f; float damageES = concussionMultiplier/*(1f + stats.ConcussionMultiplier)*/ * (damageESBase + coefES * spellPower); float shockdps = damageES / cs.AbilityCooldown(EnhanceAbility.EarthShock); float shockNormal = shockdps * cs.NatureSpellHitModifier; float shockCrit = shockdps * cs.NatureSpellCritModifier * cs.CritMultiplierSpell; dpsES = (shockNormal + shockCrit) * mastery * bonusNatureDamage; } #endregion #region Flame Shock DPS float dpsFS = 0f; if (calcOpts.PriorityInUse(EnhanceAbility.FlameShock)) { float FSBaseNumTick = 18f / 3f; float damageFSBase = 531f; float damageFSDoTTickBase = 852f / FSBaseNumTick; float FSNumTick = cs.AverageFSDotTime / cs.AverageFSTickTime; float coefFS = 1.5f / 3.5f / 2f; float coefFSDoT = .6f; float damageFS = (damageFSBase + coefFS * spellPower) * /*(1f + stats.ConcussionMultiplier)*/concussionMultiplier; float damageFTDoT = ((damageFSDoTTickBase * FSNumTick) + coefFSDoT * spellPower) * /*(1f + stats.ConcussionMultiplier)*/concussionMultiplier; float usesCooldown = cs.AbilityCooldown(EnhanceAbility.FlameShock); float flameShockdps = damageFS / usesCooldown; float flameShockDoTdps = damageFTDoT / usesCooldown; float flameShockNormal = (flameShockdps + flameShockDoTdps) * cs.SpellHitModifier; float flameShockCrit = (flameShockdps + flameShockDoTdps) * cs.SpellCritModifier * cs.CritMultiplierSpell; dpsFS = (flameShockNormal + flameShockCrit) * (1 + enhance4T12) * mastery * bonusFireDamage; } #endregion #region Lightning Bolt DPS float dpsLB = 0f; if (calcOpts.PriorityInUse(EnhanceAbility.LightningBolt)) { float damageLBBase = 770f; float coefLB = .714f; float damageLB = concussionMultiplier/*(1f + stats.ConcussionMultiplier)*/ * (damageLBBase + coefLB * spellPower); float lbdps = damageLB / cs.AbilityCooldown(EnhanceAbility.LightningBolt); float lbNormal = lbdps * cs.NatureSpellHitModifier; float lbCrit = lbdps * cs.NatureSpellCritModifier * cs.CritMultiplierSpell; dpsLB = (lbNormal + lbCrit) * mastery * bonusNatureDamage; if (character.ShamanTalents.GlyphofLightningBolt) dpsLB *= 1.04f; // 4% bonus dmg if Lightning Bolt Glyph } #endregion #region Chain Lightning DPS float dpsCL = 0f; float coefCL = 0f; if (calcOpts.PriorityInUse(EnhanceAbility.ChainLightning)) { if (character.ShamanTalents.GlyphofChainLightning) { coefCL = 0.5714f * 0.9f; } else { coefCL = 0.5714f; } float damageCLBase = 1092f; float damageCL = concussionMultiplier/*(1f + stats.ConcussionMultiplier)*/ * (damageCLBase + coefCL * spellPower); float cldps = (damageCL) / cs.AbilityCooldown(EnhanceAbility.ChainLightning); float clNormal = cldps * cs.NatureSpellHitModifier; float clCrit = cldps * cs.NatureSpellCritModifier * cs.CritMultiplierSpell; dpsCL = (clNormal + clCrit) * mastery * bonusNatureDamage; } #endregion #region Windfury DPS float dpsWF = 0f; if (calcOpts.MainhandImbue == "Windfury" && character.MainHand != null) { float damageWFHit = damageMHSwing + (windfuryWeaponBonus / 14 * cs.UnhastedMHSpeed); float WFdps = damageWFHit * cs.HitsPerSWF; float WFnormal = WFdps * cs.YellowHitModifierMH; float WFcrit = WFdps * cs.YellowCritModifierMH * cs.CritMultiplierMelee; dpsWF = (WFnormal + WFcrit) * cs.DamageReduction * bonusPhysicalDamage * /*(1f + stats.BonusWindfuryDamageMultiplier)*/windfuryDamageBonus; } #endregion #region Lightning Shield DPS float dpsLS = 0f; if (calcOpts.PriorityInUse(EnhanceAbility.LightningShield)) { float damageLSBase = 391f; float damageLSCoef = 0.267f; // co-efficient from EnhSim float damageLS = shieldBonus/*stats.ShieldBonus*/ * (damageLSBase + damageLSCoef * spellPower); float lsdps = damageLS * cs.StaticShockProcsPerS; float lsNormal = lsdps * cs.NatureSpellHitModifier; float lsCrit = lsdps * cs.NatureSpellCritModifier * cs.CritMultiplierSpell; dpsLS = (lsNormal + lsCrit) * mastery * bonusNatureDamage; } #endregion #region Fire Totem DPS float dpsFireTotem = 0f; if (calcOpts.PriorityInUse(EnhanceAbility.MagmaTotem)) { float damageFireTotem = (268f + .067f * spellPower) * /*stats.CallofFlameBonus*/callofFlameBonus; float FireTotemdps = damageFireTotem / 2f * cs.FireTotemUptime; float FireTotemNormal = FireTotemdps * cs.SpellHitModifier; float FireTotemCrit = FireTotemdps * cs.SpellCritModifier * cs.CritMultiplierSpell; dpsFireTotem = (FireTotemNormal + FireTotemCrit) * mastery * bonusFireDamage * cs.MultiTargetMultiplier; } else if (calcOpts.PriorityInUse(EnhanceAbility.SearingTotem)) { float damageFireTotem = (96f + .1669f * spellPower) * /*stats.CallofFlameBonus*/callofFlameBonus; float FireTotemdps = damageFireTotem / 1.65f * cs.FireTotemUptime; float FireTotemNormal = FireTotemdps * cs.SpellHitModifier; float FireTotemCrit = FireTotemdps * cs.SpellCritModifier * cs.CritMultiplierSpell; dpsFireTotem = (FireTotemNormal + FireTotemCrit) * mastery * bonusFireDamage; } dpsFireTotem *= (1f - cs.FireElementalUptime); #endregion #region Fire Nova DPS float dpsFireNova = 0f; if (calcOpts.PriorityInUse(EnhanceAbility.FireNova) && calcOpts.PriorityInUse(EnhanceAbility.FlameShock)) { float damageFireNova = (686.0f + 0.143f * spellPower) * /*stats.CallofFlameBonus*/callofFlameBonus; float FireNovadps = (damageFireNova / cs.AbilityCooldown(EnhanceAbility.FireNova)); float FireNovaNormal = FireNovadps * cs.SpellHitModifier; float FireNovaCrit = FireNovadps * cs.SpellCritModifier * cs.CritMultiplierSpell; dpsFireNova = (FireNovaNormal + FireNovaCrit) * (1 + enhance4T12) * mastery * bonusFireDamage * cs.MultiTargetMultiplier; } #endregion #region Flametongue Weapon DPS float dpsFT = 0f; /*if (calcOpts.MainhandImbue == "Flametongue") { //float damageFTBase = 306f * cs.UnhastedOHSpeed / 4.0f; //float damageFTCoef = 0.15396f * cs.UnhastedOHSpeed; //float damageFT = damageFTBase + damageFTCoef * attackPower; float damageFTBase = 306f; float damageFTCoef = 0.1253f; float damageFT = (damageFTBase + (damageFTCoef * attackPower)) * cs.UnhastedOHSpeed / 4.0f; float FTdps = damageFT * (cs.HitsPerSOH - cs.HitsPerSLL); float FTNormal = FTdps * cs.SpellHitModifier; float FTCrit = FTdps * cs.SpellCritModifier * cs.CritMultiplierSpell; dpsFT += (FTNormal + FTCrit) * (1 + enhance4T12) * mastery * bonusFireDamage * bossFireResistance; }*/ if (calcOpts.OffhandImbue == "Flametongue" && character.OffHand != null) { //float damageFTBase = 306f * cs.UnhastedOHSpeed / 4.0f; //float damageFTCoef = 0.1253f * cs.UnhastedOHSpeed; //float damageFT = damageFTBase + damageFTCoef * attackPower; float damageFTBase = 306f; float damageFTCoef = 0.1253f; float damageFT = (damageFTBase + (damageFTCoef * attackPower)) * cs.UnhastedOHSpeed / 4.0f; float FTdps = damageFT * (cs.HitsPerSOH - cs.HitsPerSLL); float FTNormal = FTdps * cs.SpellHitModifier; float FTCrit = FTdps * cs.SpellCritModifier * cs.CritMultiplierSpell; dpsFT += (FTNormal + FTCrit) * (1 + enhance4T12) * mastery * bonusFireDamage; } #endregion #region Unleash Elements DPS #region Unleash Windfury float dpsUW = 0f; if (calcOpts.PriorityInUse(EnhanceAbility.UnleashElements) && calcOpts.MainhandImbue == "Windfury" && character.MainHand != null) { float damageUWHit = damageMHSwing * 1.75f; float UWdps = damageUWHit / cs.AbilityCooldown(EnhanceAbility.UnleashElements); float UWnormal = UWdps * cs.YellowCritModifierMH; float UWcrit = UWdps * cs.YellowCritModifierMH * cs.CritMultiplierMelee; dpsUW = (UWnormal + UWcrit) * cs.DamageReduction * bonusPhysicalDamage; } #endregion #region Unleash Flametongue float dpsUF = 0f; if (calcOpts.PriorityInUse(EnhanceAbility.UnleashElements) && calcOpts.OffhandImbue == "Flametongue" && character.OffHand != null) { float damageUFBase = 1070f; float damageUFCoef = 0.43f; float damageUF = damageUFBase + damageUFCoef * spellPower; float UFdps = damageUF / cs.AbilityCooldown(EnhanceAbility.UnleashElements); float UFnormal = UFdps * cs.SpellHitModifier; float UFcrit = UFdps * cs.SpellCritModifier * cs.CritMultiplierSpell; dpsUF = (UFnormal + UFcrit) * (1 + enhance4T12) * mastery * bonusFireDamage; } #endregion #endregion #region Other (Damage Procs) #endregion #region Pet calculations // needed for pets - spirit wolves and Fire Elemental bool critDebuff = character.ActiveBuffsContains("Heart of the Crusader") || character.ActiveBuffsContains("Master Poisioner") || character.ActiveBuffsContains("Totem of Wrath"); bool critBuff = character.ActiveBuffsContains("Leader of the Pack") || character.ActiveBuffsContains("Rampage"); float critbuffs = (critDebuff ? 0.03f : 0f) + (critBuff ? 0.05f : 0f); float meleeHitBonus = stats.PhysicalHit + StatConversion.GetHitFromRating(stats.HitRating) + dualWieldSpecialization; float petMeleeMissRate = Math.Max(0f, StatConversion.WHITE_MISS_CHANCE_CAP[bossOpts.Level - character.Level] - meleeHitBonus) + cs.AverageDodge; float petMeleeMultipliers = cs.DamageReduction * bonusPhysicalDamage; #endregion #region Doggies! // TTT article suggests 300-450 dps while the dogs are up plus 30% of AP // my analysis reveals they get 31% of shaman AP + 2 * their STR and base 206.17 dps. float dpsDogs = 0f; if (character.ShamanTalents.FeralSpirit == 1 && calcOpts.PriorityInUse(EnhanceAbility.FeralSpirits)) { float FSglyphAP = character.ShamanTalents.GlyphofFeralSpirit ? attackPower * .3f : 0f; float soeBuff = (character.ActiveBuffsContains("Strength of Earth Totem") || character.ActiveBuffsContains("Horn of Winter") || character.ActiveBuffsContains("Roar of Courage") || character.ActiveBuffsContains("Battle Shout")) ? 594f : 0f; float dogsStr = 331f + soeBuff; float dogsAgi = 113f + soeBuff; float dogsAP = ((dogsStr * 2f - 20f) + .31f * attackPower + FSglyphAP) * (1f + unleashedRage); float dogsCrit = (StatConversion.GetCritFromAgility(dogsAgi, CharacterClass.Shaman) + critbuffs) * (1 + stats.BonusCritDamageMultiplier); float dogsBaseSpeed = 1.5f; float dogsHitsPerS = 1f / (dogsBaseSpeed / (1f + stats.PhysicalHaste)); float dogsBaseDamage = (490.06f + dogsAP / 14f) * dogsBaseSpeed; float dogsMeleeNormal = dogsBaseDamage * (1 - petMeleeMissRate - dogsCrit - cs.GlancingRate); float dogsMeleeCrits = dogsBaseDamage * dogsCrit * cs.CritMultiplierMelee; float dogsMeleeGlances = dogsBaseDamage * cs.GlancingHitModifier; float dogsTotalDamage = dogsMeleeNormal + dogsMeleeCrits + dogsMeleeGlances; dpsDogs = 2 * (30f / 120f) * dogsTotalDamage * dogsHitsPerS * petMeleeMultipliers; calc.SpiritWolf = new DPSAnalysis(dpsDogs, petMeleeMissRate, cs.AverageDodge, cs.GlancingRate, dogsCrit, 60f / cs.AbilityCooldown(EnhanceAbility.FeralSpirits)); } else { calc.SpiritWolf = new DPSAnalysis(0, 0, 0, 0, 0, 0); } #endregion #region Fire Elemental if (calcOpts.PriorityInUse(EnhanceAbility.FireElemental)) { float spellHitBonus = stats.SpellHit + StatConversion.GetHitFromRating(stats.HitRating); float petSpellMissRate = Math.Max(0f, StatConversion.WHITE_MISS_CHANCE_CAP[bossOpts.Level - character.Level] - spellHitBonus); float petSpellMultipliers = bonusFireDamage * /*stats.CallofFlameBonus*/callofFlameBonus; float petCritRate = critbuffs * (1 + stats.BonusCritDamageMultiplier); calc.FireElemental = new FireElemental(attackPower, spellPower, stats.Intellect, cs, petCritRate, petMeleeMissRate, petMeleeMultipliers, petSpellMissRate, petSpellMultipliers); } else calc.FireElemental = new FireElemental(0, 0, 0, cs, 0, 0, 0, 0, 0); float dpsFireElemental = calc.FireElemental.getDPS(); #endregion #endregion #region Set CalculatedStats calc.DPS = dpsMelee + dpsSS + dpsLL + dpsES + dpsFS + dpsLB + dpsCL + dpsWF + dpsLS + dpsFireTotem + dpsFireNova + dpsFT + dpsDogs + dpsFireElemental; calc.Survivability = stats.Health * 0.02f; calc.OverallPoints = calc.DPS + calc.Survivability; calc.DodgedAttacks = cs.AverageDodge * 100f; calc.ParriedAttacks = cs.AverageParry * 100f; calc.MissedAttacks = (1 - cs.AverageWhiteHitChance) * 100f; calc.AvoidedAttacks = calc.MissedAttacks + calc.DodgedAttacks + calc.ParriedAttacks; calc.YellowHit = (float)Math.Floor((float)(cs.AverageYellowHitChance * 10000f)) / 100f; calc.SpellHit = (float)Math.Floor((float)(cs.ChanceSpellHit * 10000f)) / 100f; calc.ElemPrecMod = cs.ElemPrecMod; calc.DraeneiHitBonus = character.Race == CharacterRace.Draenei ? 0.01f : 0.00f; calc.OverSpellHitCap = (float)Math.Floor((float)(cs.OverSpellHitCap * 10000f)) / 100f; calc.OverMeleeCritCap = (float)Math.Floor((float)(cs.OverMeleeCritCap * 10000f)) / 100f; calc.WhiteHit = (float)Math.Floor((float)(cs.AverageWhiteHitChance * 10000f)) / 100f; calc.MeleeCrit = (float)Math.Floor((float)((cs.DisplayMeleeCrit)) * 10000f) / 100f; calc.YellowCrit = (float)Math.Floor((float)((cs.DisplayYellowCrit)) * 10000f) / 100f; calc.SpellCrit = (float)Math.Floor((float)(cs.ChanceSpellCrit * 10000f)) / 100f; calc.GlancingBlows = cs.GlancingRate * 100f; calc.ArmorMitigation = (1f - cs.DamageReduction) * 100f; calc.MasteryRating = stats.MasteryRating; //CATA FIXME!! calc.AttackPower = attackPower; calc.SpellPower = spellPower; calc.AvMHSpeed = cs.HastedMHSpeed; calc.AvOHSpeed = cs.HastedOHSpeed; calc.EDBonusCrit = cs.EDBonusCrit * 100f; calc.EDUptime = cs.EDUptime * 100f; calc.FlurryUptime = cs.FlurryUptime * 100f; calc.SecondsTo5Stack = cs.SecondsToFiveStack; calc.MHEnchantUptime = se.GetMHUptime() * 100f; calc.OHEnchantUptime = se.GetOHUptime() * 100f; calc.Trinket1Uptime = se.GetUptime(character.Trinket1) * 100f; calc.Trinket2Uptime = se.GetUptime(character.Trinket2) * 100f; calc.FireTotemUptime = cs.FireTotemUptime * 100f; calc.BaseRegen = cs.BaseRegen; calc.ManaRegen = cs.ManaRegen; calc.TotalExpertiseMH = (float) Math.Floor(cs.ExpertiseBonusMH * 400f); calc.TotalExpertiseOH = (float) Math.Floor(cs.ExpertiseBonusOH * 400f); calc.SwingDamage = new DPSAnalysis(dpsMelee, 1 - cs.AverageWhiteHitChance, cs.AverageDodge, cs.GlancingRate, cs.AverageWhiteCritChance, cs.MeleePPM); calc.Stormstrike = new DPSAnalysis(dpsSS, 1 - cs.AverageYellowHitChance, cs.AverageDodge, -1, cs.AverageYellowCritChance, 60f / cs.AbilityCooldown(EnhanceAbility.StormStrike)); calc.LavaLash = new DPSAnalysis(dpsLL, 1 - cs.ChanceYellowHitOH, cs.ChanceDodgeOH, -1, cs.ChanceYellowCritOH, 60f / cs.AbilityCooldown(EnhanceAbility.LavaLash)); calc.EarthShock = new DPSAnalysis(dpsES, 1 - cs.ChanceSpellHit, -1, -1, cs.ChanceNatureSpellCrit, 60f / cs.AbilityCooldown(EnhanceAbility.EarthShock)); calc.FlameShock = new DPSAnalysis(dpsFS, 1 - cs.ChanceSpellHit, -1, -1, cs.ChanceSpellCrit, 60f / cs.AbilityCooldown(EnhanceAbility.FlameShock)); calc.LightningBolt = new DPSAnalysis(dpsLB, 1 - cs.ChanceSpellHit, -1, -1, cs.ChanceLBSpellCrit/*cs.ChanceNatureSpellCrit*/, 60f / cs.AbilityCooldown(EnhanceAbility.LightningBolt)); calc.WindfuryAttack = new DPSAnalysis(dpsWF, 1 - cs.ChanceYellowHitMH, cs.ChanceDodgeMH, -1, cs.ChanceYellowCritMH, cs.WFPPM); calc.LightningShield = new DPSAnalysis(dpsLS, 1 - cs.ChanceSpellHit, -1, -1, cs.ChanceNatureSpellCrit, 60f / cs.AbilityCooldown(EnhanceAbility.LightningShield)); calc.ChainLightning = new DPSAnalysis(dpsCL, 1 - cs.ChanceSpellHit, -1, -1, cs.ChanceNatureSpellCrit, 60f / cs.AbilityCooldown(EnhanceAbility.ChainLightning)); calc.SearingMagma = new DPSAnalysis(dpsFireTotem, 1 - cs.ChanceSpellHit, -1, -1, cs.ChanceSpellCrit, calcOpts.Magma ? 60f / cs.AbilityCooldown(EnhanceAbility.MagmaTotem) : 60f / cs.AbilityCooldown(EnhanceAbility.SearingTotem)); calc.FlameTongueAttack = new DPSAnalysis(dpsFT, 1 - cs.ChanceSpellHit, -1, -1, cs.ChanceSpellCrit, cs.FTPPM); calc.FireNova = new DPSAnalysis(dpsFireNova, 1 - cs.ChanceSpellHit, -1, -1, cs.ChanceSpellCrit, 60f / cs.AbilityCooldown(EnhanceAbility.FireNova)); calc.UnleashWind = new DPSAnalysis(dpsUW, 1 - cs.ChanceYellowHitMH, cs.ChanceDodgeMH, -1, cs.ChanceYellowCritMH, 60f / cs.AbilityCooldown(EnhanceAbility.UnleashElements)); calc.UnleashFlame = new DPSAnalysis(dpsUF, 1 - cs.ChanceSpellHit, -1, -1, cs.ChanceSpellCrit, 60f / cs.AbilityCooldown(EnhanceAbility.UnleashElements)); calc.Other = new DPSAnalysis(0f, 1 - cs.ChanceSpellHit, -1, -1, cs.ChanceSpellCrit, 0f); #endregion return calc; }
public EnhSim(Character character, CalculationOptionsEnhance calcOpts, BossOptions bossOpts) { _character = character; _calcOpts = calcOpts; _bossOpts = bossOpts; CalculationsEnhance ce = new CalculationsEnhance(); CharacterCalculationsEnhance calcs = ce.GetCharacterCalculations(character, null) as CharacterCalculationsEnhance; Stats stats = calcs.EnhSimStats; CombatStats cs = new CombatStats(character, stats, _calcOpts, bossOpts); getSpecialsNames(character, stats); StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.AppendLine("##########################################"); sb.AppendLine("### Rawr.Enhance Data Export to EnhSim ###"); sb.AppendLine("##########################################"); sb.AppendLine(); sb.AppendLine("config_source rawr"); sb.AppendLine(); float MHSpeed = character.MainHand == null ? 3.0f : character.MainHand.Item.Speed; float wdpsMH = character.MainHand == null ? 46.3f : character.MainHand.Item.DPS; float OHSpeed = character.OffHand == null ? 3.0f : character.OffHand.Item.Speed; float wdpsOH = character.OffHand == null ? 46.3f : character.OffHand.Item.DPS; sb.AppendLine("race " + character.Race.ToString().ToLower()); sb.AppendLine("mh_speed " + MHSpeed.ToString("F1", CultureInfo.InvariantCulture)); sb.AppendLine("oh_speed " + OHSpeed.ToString("F1", CultureInfo.InvariantCulture)); sb.AppendLine("mh_dps " + wdpsMH.ToString("F1", CultureInfo.InvariantCulture)); sb.AppendLine("oh_dps " + wdpsOH.ToString("F1", CultureInfo.InvariantCulture)); sb.AppendLine("str " + stats.Strength.ToString("F0", CultureInfo.InvariantCulture)); sb.AppendLine("agi " + stats.Agility.ToString("F0", CultureInfo.InvariantCulture)); sb.AppendLine("int " + stats.Intellect.ToString("F0", CultureInfo.InvariantCulture)); sb.AppendLine("spi " + stats.Spirit.ToString("F0", CultureInfo.InvariantCulture)); sb.AppendLine("mastery_rating " + stats.MasteryRating.ToString("F0", CultureInfo.InvariantCulture)); float chanceCrit = cs.ExportMeleeCritMH * 100f; sb.AppendLine("mh_crit " + chanceCrit.ToString("F2", CultureInfo.InvariantCulture)); chanceCrit = cs.ExportMeleeCritOH * 100f; sb.AppendLine("oh_crit " + chanceCrit.ToString("F2", CultureInfo.InvariantCulture)); float hitBonus = StatConversion.GetHitFromRating(stats.HitRating) * 100f + 6f; if (character.Race == CharacterRace.Draenei) { hitBonus += 1f; } sb.AppendLine("mh_hit " + hitBonus.ToString("F2", CultureInfo.InvariantCulture)); sb.AppendLine("oh_hit " + hitBonus.ToString("F2", CultureInfo.InvariantCulture)); sb.AppendLine("mh_expertise_rating " + stats.ExpertiseRating.ToString("F0", CultureInfo.InvariantCulture)); sb.AppendLine("oh_expertise_rating " + stats.ExpertiseRating.ToString("F0", CultureInfo.InvariantCulture)); float unleashedRage = 0f; switch (character.ShamanTalents.UnleashedRage) { case 1: unleashedRage = .05f; break; case 2: unleashedRage = .10f; break; } sb.AppendLine("ap " + (stats.AttackPower * (1f + unleashedRage)).ToString("F0", CultureInfo.InvariantCulture)); float hasteBonus = StatConversion.GetHasteFromRating(stats.HasteRating, CharacterClass.Shaman) * 100f; sb.AppendLine("melee_haste " + hasteBonus.ToString("F2", CultureInfo.InvariantCulture)); float MQUnleashedRageSpellpower = stats.AttackPower * unleashedRage * 0.50f; sb.AppendLine("spellpower " + (stats.SpellPower + MQUnleashedRageSpellpower).ToString("F0", CultureInfo.InvariantCulture)); float chanceSpellCrit = cs.DisplaySpellCrit * 100f; sb.AppendLine("spell_crit " + chanceSpellCrit.ToString("F2", CultureInfo.InvariantCulture)); float elemPrec = character.ShamanTalents.ElementalPrecision > 0 ? (stats.Spirit - BaseStats.GetBaseStats(character).Spirit) * (character.ShamanTalents.ElementalPrecision / 3f) : 0f; hitBonus = StatConversion.GetSpellHitFromRating(stats.HitRating + elemPrec) * 100f; if (character.Race == CharacterRace.Draenei) { hitBonus += 1f; } sb.AppendLine("spell_hit " + hitBonus.ToString("F2", CultureInfo.InvariantCulture)); hasteBonus = StatConversion.GetSpellHasteFromRating(stats.HasteRating) * 100f; sb.AppendLine("spell_haste " + hasteBonus.ToString("F2", CultureInfo.InvariantCulture)); sb.AppendLine("max_mana " + stats.Mana.ToString()); sb.AppendLine("mp5 " + stats.Mp5.ToString()); sb.AppendLine(); sb.AppendLine("mh_imbue " + _calcOpts.MainhandImbue.ToString().ToLower()); sb.AppendLine("oh_imbue " + _calcOpts.OffhandImbue.ToString().ToLower()); sb.AppendLine(); sb.AppendLine("mh_enchant " + _mhEnchant); sb.AppendLine("oh_enchant " + _ohEnchant); String weaponType = "-"; if (character.MainHand != null) { if (character.MainHand.Type == ItemType.OneHandAxe || character.MainHand.Type == ItemType.TwoHandAxe) { weaponType = "axe"; } if (character.MainHand.Type == ItemType.FistWeapon) { weaponType = "fist"; } if (character.MainHand.Type == ItemType.OneHandMace || character.MainHand.Type == ItemType.TwoHandMace) { weaponType = "mace"; } } sb.AppendLine("mh_weapon " + weaponType); weaponType = "-"; if (character.OffHand != null) { if (character.OffHand.Type == ItemType.OneHandAxe) { weaponType = "axe"; } if (character.OffHand.Type == ItemType.FistWeapon) { weaponType = "fist"; } if (character.OffHand.Type == ItemType.OneHandMace) { weaponType = "mace"; } } sb.AppendLine("oh_weapon " + weaponType); sb.AppendLine(); sb.AppendLine("trinket1 " + _trinket1name); sb.AppendLine("trinket2 " + _trinket2name); sb.AppendLine(); sb.AppendLine(getSetBonuses(character)); sb.AppendLine("metagem " + _metagem); sb.AppendLine(); string glovesEnchant = character.HandsTinkering == null ? string.Empty : character.HandsTinkering.Name; if (glovesEnchant == "Synapse Springs") { sb.AppendLine("gloves_enchant synapse_springs"); } else if (glovesEnchant == "Tazik Shocker") { sb.AppendLine("gloves_enchant tazik_shocker"); } else { sb.AppendLine("gloves_enchant -"); } string cloakEnchant = character.BackEnchant == null ? string.Empty : character.BackEnchant.Name; if (cloakEnchant == "Lightweave Embroidery") { sb.AppendLine("cloak_enchant lightweave_embroidery"); } else if (cloakEnchant == "Swordguard Embroidery") { sb.AppendLine("cloak_enchant swordguard_embroidery"); } else { sb.AppendLine("cloak_enchant -"); } string weaponSetProc = "-"; if (character.MainHand != null && character.OffHand != null) { if (character.MainHand.Id == 63537 && character.OffHand.Id == 63538) { weaponSetProc = "agony_and_torment"; } } sb.AppendLine("weapon_set_proc " + weaponSetProc); /*addGlyphs(character, sb); * sb.AppendLine(); * sb.AppendLine("#############"); * sb.AppendLine("## Talents ##"); * sb.AppendLine("#############"); * sb.AppendLine("primary_talent enhancement"); * sb.AppendLine(); * sb.AppendLine("elemental_weapons " + character.ShamanTalents.ElementalWeapons + "/2"); * sb.AppendLine("focused_strikes " + character.ShamanTalents.FocusedStrikes + "/3"); * sb.AppendLine("improved_shields " + character.ShamanTalents.ImprovedShields + "/3"); * sb.AppendLine("elemental_devastation " + character.ShamanTalents.ElementalDevastation + "/3"); * sb.AppendLine("flurry " + character.ShamanTalents.Flurry + "/3"); * sb.AppendLine("static_shock " + character.ShamanTalents.StaticShock + "/3"); * sb.AppendLine("improved_fire_nova " + character.ShamanTalents.ImprovedFireNova + "/2"); * sb.AppendLine("searing_flames " + character.ShamanTalents.SearingFlames + "/3"); * sb.AppendLine("frozen_power " + character.ShamanTalents.FrozenPower + "/2"); * sb.AppendLine("shamanistic_rage " + character.ShamanTalents.ShamanisticRage + "/1"); * sb.AppendLine("unleashed_rage " + character.ShamanTalents.UnleashedRage + "/2"); * sb.AppendLine("maelstrom_weapon " + character.ShamanTalents.MaelstromWeapon + "/3"); * sb.AppendLine("improved_lava_lash " + character.ShamanTalents.ImprovedLavaLash + "/2"); * sb.AppendLine(); * //elemental talents in EnhSim have not been updated, so keep exporting old talent choices where appropriate. * sb.AppendLine("convection " + character.ShamanTalents.Convection + "/2"); * sb.AppendLine("concussion " + character.ShamanTalents.Concussion + "/3"); * sb.AppendLine("call_of_flame " + character.ShamanTalents.CallOfFlame + "/2"); * sb.AppendLine("reverberation " + character.ShamanTalents.Reverberation + "/2"); * sb.AppendLine("elemental_precision " + character.ShamanTalents.ElementalPrecision + "/3"); * sb.AppendLine("elemental_focus " + character.ShamanTalents.ElementalFocus + "/1"); * sb.AppendLine("elemental_oath " + character.ShamanTalents.ElementalOath + "/2"); * sb.AppendLine("lava_flows " + character.ShamanTalents.LavaFlows + "/3"); * sb.AppendLine("storm_earth_and_fire " + "0" + "/3"); * sb.AppendLine("elemental_mastery " + character.ShamanTalents.ElementalMastery + "/1"); * sb.AppendLine("feedback " + character.ShamanTalents.Feedback + "/3"); * sb.AppendLine("lava_surge " + character.ShamanTalents.LavaSurge + "/2"); * sb.AppendLine(); * * addBuffs(character, sb); * // add extras * sb.AppendLine(); * sb.AppendLine("combat_length " + (_bossOpts.BerserkTimer/60f).ToString("F2", CultureInfo.InvariantCulture));*/ _configText = sb.ToString(); }
public EnhSim(Character character, CalculationOptionsEnhance calcOpts) { _character = character; _calcOpts = calcOpts; CalculationsEnhance ce = new CalculationsEnhance(); CharacterCalculationsEnhance calcs = ce.GetCharacterCalculations(character, null) as CharacterCalculationsEnhance; Stats stats = calcs.EnhSimStats; if (_character.ActiveBuffsContains("Master of Anatomy")) { stats.CritRating += 40; } CombatStats cs = new CombatStats(character, stats, _calcOpts); getSpecialsNames(character, stats); StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.AppendLine("##########################################"); sb.AppendLine("### Rawr.Enhance Data Export to EnhSim ###"); sb.AppendLine("##########################################"); sb.AppendLine(); sb.AppendLine("config_source rawr"); sb.AppendLine(); float MHSpeed = character.MainHand == null ? 3.0f : character.MainHand.Item.Speed; float wdpsMH = character.MainHand == null ? 46.3f : character.MainHand.Item.DPS; float OHSpeed = character.OffHand == null ? 3.0f : character.OffHand.Item.Speed; float wdpsOH = character.OffHand == null ? 46.3f : character.OffHand.Item.DPS; sb.AppendLine("race " + character.Race.ToString().ToLower()); sb.AppendLine("mh_speed " + MHSpeed.ToString("F1", CultureInfo.InvariantCulture)); sb.AppendLine("oh_speed " + OHSpeed.ToString("F1", CultureInfo.InvariantCulture)); sb.AppendLine("mh_dps " + wdpsMH.ToString("F1", CultureInfo.InvariantCulture)); sb.AppendLine("oh_dps " + wdpsOH.ToString("F1", CultureInfo.InvariantCulture)); float chanceCrit = cs.ExportMeleeCritMH * 100f; sb.AppendLine("mh_crit " + chanceCrit.ToString("F2", CultureInfo.InvariantCulture)); chanceCrit = cs.ExportMeleeCritOH * 100f; sb.AppendLine("oh_crit " + chanceCrit.ToString("F2", CultureInfo.InvariantCulture)); float hitBonus = StatConversion.GetHitFromRating(stats.HitRating) * 100f; sb.AppendLine("mh_hit " + hitBonus.ToString("F2", CultureInfo.InvariantCulture)); sb.AppendLine("oh_hit " + hitBonus.ToString("F2", CultureInfo.InvariantCulture)); sb.AppendLine("mh_expertise_rating " + stats.ExpertiseRating.ToString("F0", CultureInfo.InvariantCulture)); sb.AppendLine("oh_expertise_rating " + stats.ExpertiseRating.ToString("F0", CultureInfo.InvariantCulture)); sb.AppendLine("ap " + stats.AttackPower.ToString("F0", CultureInfo.InvariantCulture)); float hasteBonus = StatConversion.GetHasteFromRating(stats.HasteRating, CharacterClass.Shaman) * 100f; sb.AppendLine("melee_haste " + hasteBonus.ToString("F2", CultureInfo.InvariantCulture)); float armourPenBonus = StatConversion.GetArmorPenetrationFromRating(stats.ArmorPenetrationRating) * 100f; sb.AppendLine("armor_penetration " + armourPenBonus.ToString("F2", CultureInfo.InvariantCulture)); sb.AppendLine("str " + stats.Strength.ToString("F0", CultureInfo.InvariantCulture)); sb.AppendLine("agi " + stats.Agility.ToString("F0", CultureInfo.InvariantCulture)); sb.AppendLine("int " + stats.Intellect.ToString("F0", CultureInfo.InvariantCulture)); sb.AppendLine("spi " + stats.Spirit.ToString("F0", CultureInfo.InvariantCulture)); sb.AppendLine("spellpower " + stats.SpellPower.ToString("F0", CultureInfo.InvariantCulture)); float chanceSpellCrit = cs.DisplaySpellCrit * 100f; sb.AppendLine("spell_crit " + chanceSpellCrit.ToString("F2", CultureInfo.InvariantCulture)); hitBonus = StatConversion.GetSpellHitFromRating(stats.HitRating) * 100f; sb.AppendLine("spell_hit " + hitBonus.ToString("F2", CultureInfo.InvariantCulture)); hasteBonus = StatConversion.GetSpellHasteFromRating(stats.HasteRating) * 100f; sb.AppendLine("spell_haste " + hasteBonus.ToString("F2", CultureInfo.InvariantCulture)); sb.AppendLine("max_mana " + stats.Mana.ToString()); sb.AppendLine("mp5 " + stats.Mp5.ToString()); sb.AppendLine(); sb.AppendLine("mh_imbue " + _calcOpts.MainhandImbue.ToString().ToLower()); sb.AppendLine("oh_imbue " + _calcOpts.OffhandImbue.ToString().ToLower()); sb.AppendLine(); sb.AppendLine("mh_enchant " + _mhEnchant); String weaponType = "-"; if (character.MainHand != null) { if (character.MainHand.Type == ItemType.OneHandAxe || character.MainHand.Type == ItemType.TwoHandAxe) { weaponType = "axe"; } if (character.MainHand.Type == ItemType.FistWeapon) { weaponType = "fist"; } } sb.AppendLine("mh_weapon " + weaponType); sb.AppendLine("oh_enchant " + _ohEnchant); weaponType = "-"; if (character.OffHand != null) { if (character.OffHand.Type == ItemType.OneHandAxe) { weaponType = "axe"; } if (character.OffHand.Type == ItemType.FistWeapon) { weaponType = "fist"; } } sb.AppendLine("oh_weapon " + weaponType); sb.AppendLine(); sb.AppendLine("trinket1 " + _trinket1name); sb.AppendLine("trinket2 " + _trinket2name); sb.AppendLine(); sb.AppendLine("totem " + _totemname); sb.AppendLine(getSetBonuses(character)); sb.AppendLine("metagem " + _metagem); sb.AppendLine(); string handEnchant = character.HandsEnchant == null ? string.Empty : character.HandsEnchant.Name; if (handEnchant == "Hyperspeed Accelerators") { sb.AppendLine("gloves_enchant hyperspeed_accelerators"); } else if (handEnchant == "Hand-Mounted Pyro Rocket") { sb.AppendLine("gloves_enchant hand_mounted_pyro_rocket"); } else { sb.AppendLine("gloves_enchant -"); } string backEnchant = character.BackEnchant == null ? string.Empty : character.BackEnchant.Name; if (backEnchant == "Lightweave Embroidery") { sb.AppendLine("cloak_enchant lightweave_embroidery"); } else if (backEnchant == "Swordguard Embroidery") { sb.AppendLine("cloak_enchant swordguard_embroidery"); } else { sb.AppendLine("cloak_enchant -"); } if (character.Finger1.Id == 50401 || character.Finger2.Id == 50401 || character.Finger1.Id == 50402 || character.Finger2.Id == 50402) { sb.AppendLine("ring_proc ashen_verdict"); } else { sb.AppendLine("ring_proc -"); } addGlyphs(character, sb); sb.AppendLine(); sb.AppendLine("glyph_minor1 -"); sb.AppendLine("glyph_minor2 -"); sb.AppendLine("glyph_minor3 -"); sb.AppendLine(); sb.AppendLine("necrotic_touch " + (character.MainHand.Id == 50035 ? "1" : "0")); sb.AppendLine("necrotic_touch_heroic " + (character.MainHand.Id == 50692 ? "1" : "0")); sb.AppendLine("mixology " + (character.PrimaryProfession == Profession.Alchemy || character.SecondaryProfession == Profession.Alchemy ? "1" : "0")); // addPriorities(_calcOpts, sb); addManaConfigs(character, sb); sb.AppendLine(); sb.AppendLine("#############"); sb.AppendLine("## Talents ##"); sb.AppendLine("#############"); sb.AppendLine(); sb.AppendLine("ancestral_knowledge " + character.ShamanTalents.AncestralKnowledge + "/5"); sb.AppendLine("improved_shields " + character.ShamanTalents.ImprovedShields + "/3"); sb.AppendLine("mental_dexterity " + character.ShamanTalents.MentalDexterity + "/3"); sb.AppendLine("shamanistic_focus " + character.ShamanTalents.ShamanisticFocus + "/1"); sb.AppendLine("flurry " + character.ShamanTalents.Flurry + "/5"); sb.AppendLine("elemental_weapons " + character.ShamanTalents.ElementalWeapons + "/3"); sb.AppendLine("unleashed_rage " + character.ShamanTalents.UnleashedRage + "/3"); sb.AppendLine("weapon_mastery " + character.ShamanTalents.WeaponMastery + "/3"); sb.AppendLine("dual_wield_specialization " + character.ShamanTalents.DualWieldSpecialization + "/3"); sb.AppendLine("mental_quickness " + character.ShamanTalents.MentalQuickness + "/3"); sb.AppendLine("improved_stormstrike " + character.ShamanTalents.ImprovedStormstrike + "/2"); sb.AppendLine("static_shock " + character.ShamanTalents.StaticShock + "/3"); sb.AppendLine("maelstrom_weapon " + character.ShamanTalents.MaelstromWeapon + "/5"); sb.AppendLine("convection " + character.ShamanTalents.Convection + "/5"); sb.AppendLine("concussion " + character.ShamanTalents.Concussion + "/5"); sb.AppendLine("call_of_flame " + character.ShamanTalents.CallOfFlame + "/3"); sb.AppendLine("elemental_devastation " + character.ShamanTalents.ElementalDevastation + "/3"); sb.AppendLine("reverberation " + character.ShamanTalents.Reverberation + "/5"); sb.AppendLine("elemental_focus " + character.ShamanTalents.ElementalFocus + "/1"); sb.AppendLine("elemental_fury " + character.ShamanTalents.ElementalFury + "/5"); sb.AppendLine("improved_fire_nova " + character.ShamanTalents.ImprovedFireNova + "/2"); sb.AppendLine("call_of_thunder " + character.ShamanTalents.CallOfThunder + "/1"); sb.AppendLine("unrelenting_storm " + character.ShamanTalents.UnrelentingStorm + "/3"); sb.AppendLine("elemental_precision " + character.ShamanTalents.ElementalPrecision + "/3"); sb.AppendLine("lightning_mastery " + character.ShamanTalents.LightningMastery + "/5"); sb.AppendLine("elemental_oath " + character.ShamanTalents.ElementalOath + "/2"); sb.AppendLine("lightning_overload " + character.ShamanTalents.LightningOverload + "/5"); sb.AppendLine("lava_flows " + character.ShamanTalents.LavaFlows + "/3"); sb.AppendLine("storm_earth_and_fire " + character.ShamanTalents.StormEarthAndFire + "/3"); sb.AppendLine("shamanism " + character.ShamanTalents.Shamanism + "/5"); sb.AppendLine(); addBuffs(character, sb); // add extras sb.AppendLine(); sb.AppendLine("combat_length " + _calcOpts.FightLength.ToString("F2", CultureInfo.InvariantCulture)); _configText = sb.ToString(); }