public float ManaPool(CharacterCalculationsHealadin calc) { DivinePleas = (float)Math.Ceiling((FightLength - 120f) / (120f * CalcOpts.DivinePlea)); calc.ManaBase = Stats.Mana; calc.ManaLayOnHands = Stats.Mana * ((Talents.GlyphOfDivinity ? 0.1f : 0) * loh.Casts()); calc.ManaArcaneTorrent = (Character.Race == CharacterRace.BloodElf ? Stats.Mana * .06f * (float)Math.Ceiling(FightLength / 120f - .25f) : 0); calc.ManaDivinePlea = Stats.Mana * (Talents.GlyphOfDivinePlea ? 0.18f : 0.12f) * DivinePleas; calc.ManaMp5 = FightLength * Stats.Mp5 / 5f; // this Stats.ManaRestoreFromMaxManaPerSecond is 0 is is messing up the replenishment calculation! //calc.ManaReplenishment = Stats.ManaRestoreFromMaxManaPerSecond * Stats.Mana * FightLength * CalcOpts.Replenishment; calc.ManaReplenishment = 0.001f * Stats.Mana * FightLength * CalcOpts.Replenishment; calc.ManaOther += Stats.ManaRestore; // add calc.ManaJudgements calc.ManaJudgements = HealadinConstants.basemana * 0.15f * jotp.Casts(); if (Stats.HighestStat > 0) { float greatnessMana = Stats.HighestStat * StatConversion.RATING_PER_MANA; calc.ManaReplenishment += Stats.ManaRestoreFromMaxManaPerSecond * FightLength * greatnessMana * CalcOpts.Replenishment; // Replenishment calc.ManaDivinePlea += DivinePleas * greatnessMana * .1f; // Divine Plea } // check if this is correct regen per 5 seconds.. // combat regen = 50% of spirit regen (from Meditation), plus MP5 from gear, plus 5% base mana per 5 secs. Base mana = 23422 at 85 float effective_spirit = Stats.Spirit + Stats.BonusCritChanceFrostStrike * 540 * 6 / CalcOpts.HolyShock; // add in bonus spirit from 4T11 procs float spirit_regen = StatConversion.GetSpiritRegenSec(effective_spirit, Stats.Intellect) * 5f; calc.CombatRegenRate = spirit_regen * 0.5f + Stats.Mp5 + HealadinConstants.basemana * 0.05f; calc.ManaRegenRate = spirit_regen + Stats.Mp5 + HealadinConstants.basemana * 0.05f; calc.CombatRegenTotal = calc.CombatRegenRate * FightLength / 5f; return(calc.ManaBase + calc.ManaDivinePlea + calc.CombatRegenTotal + calc.ManaOther + calc.ManaReplenishment + calc.ManaLayOnHands + calc.ManaJudgements); }
public void SetManaRegen() { baseMana = BaseStats.GetBaseStats(_character).Mana; float spiRegen = StatConversion.GetSpiritRegenSec(_stats.Spirit, _stats.Intellect); float replenishRegen = _stats.Mana * _stats.ManaRestoreFromMaxManaPerSecond; float judgementRegen = _stats.ManaRestoreFromBaseManaPPM / 60f * baseMana; manaRegen = _stats.Mp5 / 5 + spiRegen + replenishRegen + judgementRegen; }
public override float GetOptimizableCalculationValue(string calculation) { switch (calculation) { case "Health": return(BasicStats.Health); case "Resilience": return(BasicStats.Resilience); case "Mana": return(BasicStats.Mana); case "Mana Regen": return(BasicStats.Mp5 + StatConversion.GetSpiritRegenSec(BasicStats.Spirit, BasicStats.Intellect) * 5f); case "Combat Regen": return(BasicStats.Mp5 + StatConversion.GetSpiritRegenSec(BasicStats.Spirit, BasicStats.Intellect) * 5f * BasicStats.SpellCombatManaRegeneration); case "Haste Rating": return(BasicStats.HasteRating); case "Mastery Rating": return(BasicStats.MasteryRating); case "Haste %": return(BasicStats.SpellHaste * 100f); case "Renew Ticks": return(new SpellRenew(Character, BasicStats).OverTimeTicks); case "Crit Rating": return(BasicStats.CritRating); // case "Healing Crit %": return (basicStats.SpellCrit * 100f) + character.PriestTalents.HolySpecialization * 1f + character.PriestTalents.RenewedHope * 2f; // case "PW:Shield": return new PowerWordShield(basicStats, character).AvgHeal; // case "GHeal Avg": return new Heal(basicStats, character).AvgHeal; // case "FHeal Avg": return new FlashHeal(basicStats, character).AvgHeal; // case "CoH Avg": return new CircleOfHealing(basicStats, character).AvgHeal; case "Armor": return(BasicStats.Armor + BasicStats.BonusArmor); case "Arcane Resistance": return(BasicStats.ArcaneResistance + BasicStats.ArcaneResistanceBuff); case "Fire Resistance": return(BasicStats.FireResistance + BasicStats.FireResistanceBuff); case "Frost Resistance": return(BasicStats.FrostResistance + BasicStats.FrostResistance); case "Nature Resistance": return(BasicStats.NatureResistance + BasicStats.NatureResistanceBuff); case "Shadow Resistance": return(BasicStats.ShadowResistance + BasicStats.ShadowResistanceBuff); } return(0f); }
public override Dictionary <string, string> GetCharacterDisplayCalculationValues() { Dictionary <string, string> dictValues = new Dictionary <string, string>(); dictValues.Add("DPS Points", DPS.ToString("F2", CultureInfo.InvariantCulture)); dictValues.Add("Survivability Points", Survivability.ToString("F2", CultureInfo.InvariantCulture)); dictValues.Add("Overall Points", OverallPoints.ToString("F2", CultureInfo.InvariantCulture)); dictValues.Add("Health", BasicStats.Health.ToString("F0", CultureInfo.InvariantCulture)); dictValues.Add("Mana", BasicStats.Mana.ToString("F0", CultureInfo.InvariantCulture)); dictValues.Add("Strength", String.Format("{0}*Increases Attack Power by {1}", BasicStats.Strength.ToString("F0", CultureInfo.InvariantCulture), (BasicStats.Strength - 10f).ToString("F0", CultureInfo.InvariantCulture))); dictValues.Add("Agility", String.Format("{0}*Increases Attack Power by {1}\r\nIncreases Critical Hit chance by {2}%", BasicStats.Agility.ToString("F0", CultureInfo.InvariantCulture), ((BasicStats.Agility * 2f) - 20f).ToString("F0", CultureInfo.InvariantCulture), (StatConversion.GetCritFromAgility(BasicStats.Agility, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture))); dictValues.Add("Stamina", String.Format("{0}*Increase Health by {1}", BasicStats.Stamina.ToString("F0", CultureInfo.InvariantCulture), (StatConversion.GetHealthFromStamina(BasicStats.Stamina)).ToString("F0", CultureInfo.InvariantCulture))); dictValues.Add("Intellect", String.Format("{0}*Increases Mana by {1}\r\nIncreases Spell Power by {2}\r\nIncreases Spell Critical Hit chance by {3}%", BasicStats.Intellect.ToString("F0", CultureInfo.InvariantCulture), (StatConversion.GetManaFromIntellect(BasicStats.Intellect)).ToString("F0", CultureInfo.InvariantCulture), (BasicStats.Intellect - 10f).ToString("F0", CultureInfo.InvariantCulture), (StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture))); dictValues.Add("Spirit", String.Format("{0}*Increases mana regeneration by {1} every 5 seconds while not casting", BasicStats.Spirit.ToString("F0", CultureInfo.InvariantCulture), (StatConversion.GetSpiritRegenSec(BasicStats.Spirit, BasicStats.Intellect) * 5f).ToString("F0", CultureInfo.InvariantCulture))); dictValues.Add("Mastery", String.Format("{0}*Mastery rating of {1} adds {2} Mastery\r\nIncreases all Fire, Frost, and Nature Damage by {3}%.", (8f + StatConversion.GetMasteryFromRating(BasicStats.MasteryRating)).ToString("F2", CultureInfo.InvariantCulture), BasicStats.MasteryRating.ToString("F0", CultureInfo.InvariantCulture), (StatConversion.GetMasteryFromRating(BasicStats.MasteryRating)).ToString("F2", CultureInfo.InvariantCulture), ((8f + StatConversion.GetMasteryFromRating(BasicStats.MasteryRating)) * 2.5f).ToString("F2", CultureInfo.InvariantCulture))); //dictValues.Add("Damage" //dictValues.Add("DPS" dictValues.Add("Attack Power", BasicStats.AttackPower.ToString("F0", CultureInfo.InvariantCulture)); //dictValues.Add("Speed" dictValues.Add("Melee Haste", String.Format("{0}%*Haste Rating of {1} adds {2}% Haste", (StatConversion.GetHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture), BasicStats.HasteRating.ToString("F0", CultureInfo.InvariantCulture), (StatConversion.GetHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture))); dictValues.Add("Melee Hit", String.Format("{0}%*Hit Rating of {1} adds {2}% Hit chance\r\n{3}% Draenei Hit Bonus", (StatConversion.GetHitFromRating(BasicStats.HitRating) * 100f + DraeneiHitBonus * 100f).ToString("F2", CultureInfo.InvariantCulture), BasicStats.HitRating.ToString("F0", CultureInfo.InvariantCulture), (StatConversion.GetHitFromRating(BasicStats.HitRating) * 100f).ToString("F2", CultureInfo.InvariantCulture), DraeneiHitBonus * 100f)); dictValues.Add("Melee Crit", String.Format("{0}%*Crit Rating of {1} adds {2}% Crit chance", ((StatConversion.GetCritFromRating(BasicStats.CritRating, CharacterClass.Shaman) * 100f) + (StatConversion.GetCritFromAgility(BasicStats.Agility, CharacterClass.Shaman) * 100f)).ToString("F2", CultureInfo.InvariantCulture), BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture), (StatConversion.GetCritFromRating(BasicStats.CritRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture))); dictValues.Add("Expertise", getExpertiseString());// String.Format("{0} / {1}*Reduces chance to be dodged or parried by {2}% / {3}%\r\nExpertise Rating of {4} adds {5} Expertise", dictValues.Add("Spell Power", BasicStats.SpellPower.ToString("F0", CultureInfo.InvariantCulture)); dictValues.Add("Spell Haste", String.Format("{0}%*Haste Rating of {1} adds {2}% Haste", (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture), BasicStats.HasteRating.ToString("F0", CultureInfo.InvariantCulture), (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture))); dictValues.Add("Spell Hit", String.Format("{0}%*Hit Rating of {1} adds {2}% Hit chance\r\n{3}% Draenei Hit Bonus", (StatConversion.GetSpellHitFromRating(BasicStats.HitRating + ElemPrecMod) * 100f + DraeneiHitBonus * 100f).ToString("F2", CultureInfo.InvariantCulture), (BasicStats.HitRating + ElemPrecMod).ToString("F0", CultureInfo.InvariantCulture), (StatConversion.GetSpellHitFromRating(BasicStats.HitRating + ElemPrecMod) * 100f).ToString("F2", CultureInfo.InvariantCulture), DraeneiHitBonus * 100f)); dictValues.Add("Spell Crit", String.Format("{0}%*Crit Rating of {1} adds {2}% Crit chance", ((StatConversion.GetSpellCritFromRating(BasicStats.CritRating, CharacterClass.Shaman) * 100f) + (StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect, CharacterClass.Shaman) * 100f)).ToString("F2", CultureInfo.InvariantCulture), BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture), (StatConversion.GetSpellCritFromRating(BasicStats.CritRating, CharacterClass.Shaman) * 100f).ToString("F2", CultureInfo.InvariantCulture))); dictValues.Add("Combat Regen", String.Format("{0}*{0} mana regenerated every 5 seconds while in combat", BaseRegen.ToString("F0", CultureInfo.InvariantCulture))); //dictValues.Add("Avg Agility", _attackPower.ToString("F0", CultureInfo.InvariantCulture)); //dictValues.Add("Avg Intellect" //dictValues.Add("Avg Mastery" //dictValues.Add("Avg Attack Power" dictValues.Add("Avg Speed", String.Format("{0} / {1}", AvMHSpeed.ToString("F2", CultureInfo.InvariantCulture), AvOHSpeed.ToString("F2", CultureInfo.InvariantCulture))); //dictValues.Add("Avg Melee Haste" //dictValues.Add("Avg Melee Hit" //dictValues.Add("Avg Melee Crit" //dictValues.Add("Avg Expertise" //dictValues.Add("Avg Spell Power" //dictValues.Add("Avg Spell Haste" //dictValues.Add("Avg Spell Hit" //dictValues.Add("Avg Spell Crit" dictValues.Add("Avg Combat Regen", ManaRegen.ToString("F0", CultureInfo.InvariantCulture)); /*dictValues.Add("White Hit", WhiteHit.ToString("F2", CultureInfo.InvariantCulture) + "%"); * if (YellowHit < 100f && TotalExpertiseMH < 26) * { * float ratingRequired = (float)Math.Ceiling(4f * StatConversion.GetRatingFromExpertise(100f - YellowHit)); * dictValues.Add("Yellow Hit", String.Format("{0}% (Under Cap)*You need {1} more expertise to cap specials (WF,SS)", * YellowHit.ToString("F2", CultureInfo.InvariantCulture), * ratingRequired.ToString("F0", CultureInfo.InvariantCulture))); * } * else * { * if (ParriedAttacks > 0) * { * float ratingRequired = (float)Math.Ceiling(4f * StatConversion.GetRatingFromExpertise(100f - YellowHit)); * dictValues.Add("Yellow Hit", String.Format("{0}%*Being in front of boss allows your attacks to be parried\r\nYou would need {1} more expertise to cap specials (WF,SS)", * YellowHit.ToString("F2", CultureInfo.InvariantCulture), * ratingRequired.ToString("F0", CultureInfo.InvariantCulture))); * } * else * dictValues.Add("Yellow Hit", YellowHit.ToString("F2", CultureInfo.InvariantCulture) + "%"); * } * if (OverSpellHitCap > 0.38f) // only warn if more than .38% over cap (equivalent to 10 hit rating) * dictValues.Add("Spell Hit", String.Format("{0}% (Over Cap)*Over Spell Hit Cap by {1}%", * SpellHit.ToString("F2", CultureInfo.InvariantCulture), * OverSpellHitCap.ToString("F2", CultureInfo.InvariantCulture))); * else * { * if (SpellHit < 100f) * { * float ratingRequired = (float)Math.Ceiling(StatConversion.GetRatingFromSpellHit(1f - SpellHit/100f)); * dictValues.Add("Spell Hit", String.Format("{0}% (Under Cap)*You need {1} more hit rating to cap spells (ES, LB etc)", * SpellHit.ToString("F2", CultureInfo.InvariantCulture), * ratingRequired.ToString("F0", CultureInfo.InvariantCulture))); * } * else * dictValues.Add("Spell Hit", SpellHit.ToString("F2", CultureInfo.InvariantCulture) + "%"); * }*/ /*if (OverMeleeCritCap > 0.21f) // only warn if more than .21% over cap (equivalent to 10 crit rating) * dictValues.Add("Melee Crit", String.Format("{0} (Over Cap)*Crit Rating {1} (+{2}% crit chance)\r\nOver Soft Cap by {3}%", * MeleeCrit.ToString("F2", CultureInfo.InvariantCulture) + "%", * BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture), * (StatConversion.GetCritFromRating(BasicStats.CritRating) * 100f).ToString("F2", CultureInfo.InvariantCulture), * OverMeleeCritCap.ToString("F2", CultureInfo.InvariantCulture))); * else * dictValues.Add("Melee Crit", String.Format("{0}*Crit Rating {1} (+{2}% crit chance)", * MeleeCrit.ToString("F2", CultureInfo.InvariantCulture) + "%", * BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture), * (StatConversion.GetCritFromRating(BasicStats.CritRating) * 100f).ToString("F2", CultureInfo.InvariantCulture))); * * dictValues.Add("Spell Crit", String.Format("{0}*Crit Rating {1} (+{2}% crit chance)", * SpellCrit.ToString("F2", CultureInfo.InvariantCulture) + "%", * BasicStats.CritRating.ToString("F0", CultureInfo.InvariantCulture), * (StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f).ToString("F2", CultureInfo.InvariantCulture)));*/ float spellMiss = 100 - SpellHit; dictValues.Add("Avoided Attacks", String.Format("{0}%*{1}% Boss Dodged\r\n{2}% Boss Parried\r\n{3}% Spell Misses\r\n{4}% White Misses", AvoidedAttacks.ToString("F2", CultureInfo.InvariantCulture), DodgedAttacks.ToString("F2", CultureInfo.InvariantCulture), ParriedAttacks.ToString("F2", CultureInfo.InvariantCulture), spellMiss.ToString("F2", CultureInfo.InvariantCulture), MissedAttacks.ToString("F2", CultureInfo.InvariantCulture))); dictValues.Add("Armor Mitigation", ArmorMitigation.ToString("F2", CultureInfo.InvariantCulture) + "%*Amount of physical damage lost due to boss armor"); dictValues.Add("ED Uptime", String.Format("{0}%*{1}% ED Bonus Crit", EDUptime.ToString("F2", CultureInfo.InvariantCulture), EDBonusCrit.ToString("F2", CultureInfo.InvariantCulture))); dictValues.Add("Flurry Uptime", FlurryUptime.ToString("F2", CultureInfo.InvariantCulture) + "%"); dictValues.Add("Avg Time to 5 Stack", String.Format("{0} sec*{1} PPM", SecondsTo5Stack.ToString("F2", CultureInfo.InvariantCulture), _MWPPM.ToString("F2", CultureInfo.InvariantCulture))); dictValues.Add("MH Enchant Uptime", MHEnchantUptime.ToString("F2", CultureInfo.InvariantCulture) + "%"); dictValues.Add("OH Enchant Uptime", OHEnchantUptime.ToString("F2", CultureInfo.InvariantCulture) + "%"); dictValues.Add("Trinket 1 Uptime", Trinket1Uptime.ToString("F2", CultureInfo.InvariantCulture) + "%"); dictValues.Add("Trinket 2 Uptime", Trinket2Uptime.ToString("F2", CultureInfo.InvariantCulture) + "%"); dictValues.Add("Fire Totem Uptime", FireTotemUptime.ToString("F2", CultureInfo.InvariantCulture) + "%"); dictValues.Add("White Damage", dpsOutputFormat(SwingDamage, DPS, true)); dictValues.Add("Windfury Attack", dpsOutputFormat(WindfuryAttack, DPS, true)); dictValues.Add("Flametongue Attack", dpsOutputFormat(FlameTongueAttack, DPS, true)); dictValues.Add("Stormstrike", dpsOutputFormat(Stormstrike, DPS, true)); dictValues.Add("Lava Lash", dpsOutputFormat(LavaLash, DPS, true)); dictValues.Add("Searing/Magma Totem", dpsOutputFormat(SearingMagma, DPS, false)); dictValues.Add("Earth Shock", dpsOutputFormat(EarthShock, DPS, false)); dictValues.Add("Flame Shock", dpsOutputFormat(FlameShock, DPS, false)); dictValues.Add("Lightning Bolt", dpsOutputFormat(LightningBolt, DPS, false)); dictValues.Add("Unleash Wind", dpsOutputFormat(UnleashWind, DPS, true)); dictValues.Add("Unleash Flame", dpsOutputFormat(UnleashFlame, DPS, false)); dictValues.Add("Lightning Shield", dpsOutputFormat(LightningShield, DPS, false)); dictValues.Add("Chain Lightning", dpsOutputFormat(ChainLightning, DPS, false)); dictValues.Add("Fire Nova", dpsOutputFormat(FireNova, DPS, false)); dictValues.Add("Fire Elemental", FireElemental.getDPSOutput()); dictValues.Add("Spirit Wolf", dpsOutputFormat(SpiritWolf, DPS, true)); dictValues.Add("Other", dpsOutputFormat(Other, DPS, false)); dictValues.Add("Total DPS", DPS.ToString("F2", CultureInfo.InvariantCulture)); /*dictValues.Add("Status", String.Format("Enhance Model : DPS Points {0}, Survivability Points {1}, Overall Points {2}", * DPS.ToString("F2", CultureInfo.InvariantCulture), * Survivability.ToString("F2", CultureInfo.InvariantCulture), * OverallPoints.ToString("F2", CultureInfo.InvariantCulture)));*/ return(dictValues); }
public override Dictionary <string, string> GetCharacterDisplayCalculationValues() { Dictionary <string, string> dictValues = new Dictionary <string, string>(); Buff activeBuff; string s; Stats baseStats = BaseStats.GetBaseStats(Character); #region General dictValues["Health"] = BasicStats.Health.ToString("0"); dictValues["Mana"] = BasicStats.Mana.ToString("0"); dictValues["Item Level"] = String.Format("{0}*Lowest: {1}\nHighest: {2}", Character.AvgWornItemLevel.ToString("0"), Character.MinWornItemLevel.ToString("0"), Character.MaxWornItemLevel.ToString("0")); dictValues["Speed"] = String.Format("{0}%*{0}% Run speed", ((1f + BasicStats.MovementSpeed) * 100f).ToString("0")); #endregion #region Attributes dictValues["Strength"] = BasicStats.Strength.ToString(); dictValues["Agility"] = BasicStats.Agility.ToString(); dictValues["Stamina"] = BasicStats.Stamina.ToString(); dictValues["Intellect"] = BasicStats.Intellect.ToString(); dictValues["Spirit"] = BasicStats.Spirit.ToString(); #endregion #region Spell #region Spell Power s = String.Empty; float intPower = BasicStats.Intellect - 10; if (BasicStats.InnerFire) { s += String.Format("\n{0} from Inner Fire", PriestInformation.GetInnerFireSpellPowerBonus(Character)); } activeBuff = GetActiveBuffsByGroup("Spell Power"); if (activeBuff != null) { s += makeActiveBuffTextPercent(activeBuff, activeBuff.Stats.BonusSpellPowerMultiplier); } dictValues["Spell Power"] = String.Format("{0}*{1} from {2} Intellect{3}", BasicStats.SpellPower.ToString("0"), intPower.ToString("0"), BasicStats.Intellect.ToString("0"), s ); #endregion #region Haste s = String.Empty; if (Character.PriestTalents.Darkness > 0) { s += String.Format("\n{0}% from {1} points in Darkness", Character.PriestTalents.Darkness, Character.PriestTalents.Darkness); } activeBuff = GetActiveBuffsByGroup("Spell Haste"); if (activeBuff != null) { s += makeActiveBuffTextPercent(activeBuff, activeBuff.Stats.SpellHaste); } activeBuff = GetActiveBuffsByGroup("Dark Intent"); if (activeBuff != null) { s += makeActiveBuffTextPercent(activeBuff, activeBuff.Stats.SpellHaste); } dictValues["Haste"] = String.Format("{0}%*{1}% from {2} Haste Rating{3}", (BasicStats.SpellHaste * 100f).ToString("0.00"), (StatConversion.GetSpellHasteFromRating(BasicStats.HasteRating) * 100f).ToString("0.00"), BasicStats.HasteRating.ToString("0"), s ); #endregion dictValues["Hit"] = (BasicStats.SpellHit * 100f).ToString("0.00"); dictValues["Penetration"] = BasicStats.SpellPenetration.ToString("0"); #region Mana Regen float manaRegen = StatConversion.GetSpiritRegenSec(BasicStats.Spirit, BasicStats.Intellect) * 5f; s = String.Format("\n{0} Mana per 5 sec from Base Mana Regeneration", (baseStats.Mana * 0.05f).ToString("0")); activeBuff = GetActiveBuffsByGroup("Mana Regeneration"); if (activeBuff != null) { s += makeActiveBuffText(activeBuff, activeBuff.Stats.Mp5); } dictValues["Mana Regen"] = String.Format("{0}*{1} from Spirit based regen{2}", (manaRegen + BasicStats.Mp5).ToString("0"), manaRegen.ToString("0"), s ); dictValues["Combat Regen"] = String.Format("{0}*{1} from Spirit based regen{2}", (manaRegen * BasicStats.SpellCombatManaRegeneration + BasicStats.Mp5).ToString("0"), (manaRegen * BasicStats.SpellCombatManaRegeneration).ToString("0"), s ); #endregion #region Crit s = String.Empty; activeBuff = GetActiveBuffsByGroup("Critical Strike Chance"); if (activeBuff != null) { s += makeActiveBuffTextPercent(activeBuff, activeBuff.Stats.SpellCrit); } activeBuff = GetActiveBuffsByGroup("Focus Magic, Spell Critical Strike Chance"); if (activeBuff != null) { s += makeActiveBuffTextPercent(activeBuff, activeBuff.Stats.SpellCrit); } dictValues["Crit Chance"] = String.Format("{0}%*{1}% from {2} Crit Rating\n{3}% from {4} Intellect\n{5}% from Priest base{6}", (BasicStats.SpellCrit * 100f).ToString("0.00"), (StatConversion.GetSpellCritFromRating(BasicStats.CritRating) * 100f).ToString("0.00"), BasicStats.CritRating.ToString("0"), (StatConversion.GetSpellCritFromIntellect(BasicStats.Intellect) * 100f).ToString("0.00"), BasicStats.Intellect.ToString("0"), (baseStats.SpellCrit * 100f).ToString("0.00"), s ); #endregion #region Mastery s = string.Empty; float masteryBase = 0, masteryBonus = 0; if (BasicStats.PriestSpec == ePriestSpec.Spec_Disc) { masteryBase = PriestInformation.DisciplineMasteryBase; masteryBonus = PriestInformation.DisciplineMasteryEffect * 100f; s += String.Format("\n\nEach point of mastery increases the potency of Absorbs by an additional {0}%.", masteryBonus.ToString("0.00")); } else if (BasicStats.PriestSpec == ePriestSpec.Spec_Holy) { masteryBase = PriestInformation.HolyMasteryBase; masteryBonus = PriestInformation.HolyMasteryEffect * 100f; s += String.Format("\n\nEach point of mastery provides an additional {0}% healing over 6 sec.", masteryBonus.ToString("0.00")); } dictValues["Mastery"] = String.Format("{0}%*{1}% from {2} Mastery Rating\n{3}% from {4} Base Mastery{5}", ((StatConversion.GetMasteryFromRating(BasicStats.MasteryRating) + masteryBase) * masteryBonus).ToString("0.00"), (StatConversion.GetMasteryFromRating(BasicStats.MasteryRating) * masteryBonus).ToString("0.00"), BasicStats.MasteryRating.ToString("0"), (masteryBase * masteryBonus).ToString("0.00"), masteryBase.ToString("0"), s ); #endregion #endregion #region Defense dictValues["Armor"] = String.Format("{0}*{1}% physical damage reduction from same level target", BasicStats.Armor.ToString("0"), (StatConversion.GetDamageReductionFromArmor(Character.Level, BasicStats.Armor) * 100f).ToString("0.00")); dictValues["Dodge"] = String.Format("{0}%", (BasicStats.Dodge * 100f).ToString("0.00")); dictValues["Resilience"] = String.Format("{0}*{1}% damage reduction on attacks from other players\n{2}% damage reduction from spells", BasicStats.Resilience.ToString("0"), (StatConversion.GetDamageReductionFromResilience(BasicStats.Resilience) * 100f).ToString("0.00"), (Character.PriestTalents.InnerSanctum * 2f).ToString("0")); #endregion #region Resistance string resistTxt = "{0}*PvP\n{1}\n\nBoss\n{2}"; string[] resistList = { "Arcane", "Fire", "Frost", "Nature", "Shadow" }; float[] resistances = { BasicStats.ArcaneResistance + BasicStats.ArcaneResistanceBuff, BasicStats.FireResistance + BasicStats.FireResistanceBuff, BasicStats.FrostResistance + BasicStats.FrostResistanceBuff, BasicStats.NatureResistance + BasicStats.NatureResistanceBuff, BasicStats.ShadowResistance + BasicStats.ShadowResistanceBuff }; for (int x = 0; x < resistList.Length; x++) { dictValues[resistList[x]] = String.Format(resistTxt, resistances[x].ToString("0"), StatConversion.GetResistanceTableString(Character.Level, Character.Level, resistances[x], 0f), StatConversion.GetResistanceTableString(Character.Level + 3, Character.Level, resistances[x], 0f) ); } #endregion #region Model CalculationOptionsHealPriest calcOpts = Character.CalculationOptions as CalculationOptionsHealPriest; if (calcOpts != null) { PriestSolver solver = PriestModels.GetModel(this, calcOpts, true); solver.Solve(); List <string> reqs = solver.MeetsRequirements(); string disp; if (reqs.Count > 0) { disp = String.Format("{0}\n\n{1}", solver.Name, String.Join("\n", reqs)); } else { disp = solver.Name; } dictValues["Role"] = disp; dictValues["Burst Goal"] = this.BurstGoal.ToString("0"); dictValues["Sust. Goal"] = this.SustainGoal.ToString("0"); dictValues["Mana Goal"] = this.ManaGoal.ToString("0"); dictValues["Burst"] = this.BurstPoints.ToString("0"); dictValues["Sustained"] = this.SustainPoints.ToString("0"); dictValues["Mana "] = this.ManaPoints.ToString("0"); } #endregion #region Holy Spells SpellHeal spellHeal = new SpellHeal(Character, BasicStats); dictValues["Heal"] = String.Format("{0}*{1}", spellHeal.HPS().ToString("0"), spellHeal.ToString()); SpellGreaterHeal spellGreaterHeal = new SpellGreaterHeal(Character, BasicStats); dictValues["Greater Heal"] = String.Format("{0}*{1}", spellGreaterHeal.HPS().ToString("0"), spellGreaterHeal.ToString()); SpellFlashHeal spellFlashHeal = new SpellFlashHeal(Character, BasicStats); dictValues["Flash Heal"] = String.Format("{0}*{1}", spellFlashHeal.HPS().ToString("0"), spellFlashHeal.ToString()); SpellBindingHeal spellBindingHeal = new SpellBindingHeal(Character, BasicStats); dictValues["Binding Heal"] = String.Format("{0}*{1}", spellBindingHeal.HPS().ToString("0"), spellBindingHeal.ToString()); SpellRenew spellRenew = new SpellRenew(Character, BasicStats); dictValues["Renew"] = String.Format("{0}*{1}", spellRenew.HPS().ToString("0"), spellRenew.ToString()); if (Character.PriestTalents.Lightwell > 0) { SpellLightwell spellLW = new SpellLightwell(Character, BasicStats); dictValues["Lightwell"] = String.Format("{0}*{1}", spellLW.HPS().ToString("0"), spellLW.ToString()); } else { dictValues["Lightwell"] = "N/A*You do not have the talent required."; } SpellPrayerOfHealing spellProH = new SpellPrayerOfHealing(Character, BasicStats); dictValues["ProH"] = String.Format("{0}*{1}", spellProH.HPS().ToString("0"), spellProH.ToString()); SpellHolyNova spellHolyNova = new SpellHolyNova(Character, BasicStats); dictValues["Holy Nova"] = String.Format("NYI*{1}", spellHolyNova.HPS().ToString("0"), spellHolyNova.ToString()); if (Character.PriestTalents.CircleOfHealing > 0) { SpellCircleOfHealing spellCoH = new SpellCircleOfHealing(Character, BasicStats); dictValues["CoH"] = String.Format("{0}*{1}", spellCoH.HPS().ToString("0"), spellCoH.ToString()); } else { dictValues["CoH"] = "N/A*You do not have the talent required."; } if (BasicStats.PriestSpec == ePriestSpec.Spec_Disc) { SpellPenance spellPenance = new SpellPenance(Character, BasicStats); dictValues["Penance"] = String.Format("{0}*{1}", spellPenance.HPS().ToString("0"), spellPenance.ToString()); } else { dictValues["Penance"] = "N/A*You do not have the correct Talent specialization."; } if (Character.PriestTalents.Revelations > 0) { SpellSerenity spellSerenity = new SpellSerenity(Character, BasicStats); dictValues["HW Serenity"] = String.Format("{0}*{1}", spellSerenity.HPS().ToString("0"), spellSerenity.ToString()); SpellSanctuary spellSanctuary = new SpellSanctuary(Character, BasicStats); dictValues["HW Sanctuary"] = String.Format("{0}*{1}", spellSanctuary.HPS().ToString("0"), spellSanctuary.ToString()); } else { dictValues["HW Serenity"] = "N/A*You do not have the talent required."; dictValues["HW Sanctuary"] = "N/A*You do not have the talent required."; } SpellPrayerOfMending spellProM = new SpellPrayerOfMending(Character, BasicStats, 1); dictValues["ProM"] = String.Format("{0}*{1}", spellProM.HPS().ToString("0"), spellProM.ToString()); spellProM = new SpellPrayerOfMending(Character, BasicStats); dictValues["ProM 5 Hits"] = String.Format("{0}*{1}", spellProM.HPS().ToString("0"), spellProM.ToString()); SpellPowerWordShield spellPWS = new SpellPowerWordShield(Character, BasicStats); dictValues["PWS"] = String.Format("{0}*{1}", spellPWS.HPS().ToString("0"), spellPWS.ToString()); SpellDivineHymn spellDivineHymn = new SpellDivineHymn(Character, BasicStats); dictValues["Divine Hymn"] = String.Format("{0}*{1}", spellDivineHymn.HPS().ToString("0"), spellDivineHymn.ToString()); if (Character.Race == CharacterRace.Draenei) { SpellGiftOfTheNaaru spellGoat = new SpellGiftOfTheNaaru(Character, BasicStats); dictValues["Gift of the Naaru"] = String.Format("{0}*{1}", spellGoat.HPS().ToString("0"), spellGoat.ToString()); } else { dictValues["Gift of the Naaru"] = "N/A*You are not a spacegoat!"; } SpellResurrection spellResurrection = new SpellResurrection(Character, BasicStats); dictValues["Resurrection"] = String.Format("{0}*{1}", spellResurrection.CastTime.ToString("0.00"), spellResurrection.ToString()); #endregion #region Shadow Spells #endregion return(dictValues); }
private float CalcSpiritRegen(float Spirit, float Intellect, float combatRegen) { return(StatConversion.GetSpiritRegenSec(Spirit, Intellect) * combatRegen); }
public static void solve(CharacterCalculationsElemental calculatedStats, CalculationOptionsElemental calcOpts, BossOptions bossOpts) { Stats stats = calculatedStats.BasicStats; Character character = calculatedStats.LocalCharacter; ShamanTalents talents = character.ShamanTalents; /* Effects: * Clearcasting (-40% mana cost next 2 spells) * Glyph of flame shock or not * Clearcasting (5/10% more total damage) * Elemental Mastery (+15% haste chance, 15 sec/3 min cd) * Trinkets * * Assume LvB used on CD and FS either after LvB, on dot drop or before LvB * Filler: LB * NYI Optional: use of CL */ Estimation e; Rotation rot; float damage; Stats procStats; #if RAWR3 || SILVERLIGHT float FightDuration = bossOpts.BerserkTimer; #else float FightDuration = calcOpts.FightDuration; #endif // WITHOUT PROCS e = new Estimation(stats, new Stats { }, talents, calcOpts); rot = e.getPriorityRotation(calcOpts.RotationType); // WITH PROCS int nPasses = 2, k; for (k = 0; k < nPasses; k++) { procStats = DoSpecialEffects(character, stats, rot, FightDuration); //procStats = getTrinketStats(character, stats, calcOpts.FightDuration, rot); e.Update(stats, procStats, talents, calcOpts); rot = e.getPriorityRotation(calcOpts.RotationType); } // Thunderstorm usage float thunderstormRegen = 0f; #region Thunderstorm if (calcOpts.UseThunderstorm) { float procsPerSecond = Thunderstorm.getProcsPerSecond(talents.GlyphofThunder, (int)FightDuration); thunderstormRegen += (talents.GlyphofThunderstorm ? .1f : .08f) * stats.Mana * procsPerSecond * 5; } #endregion /* Regen variables: (divide by 5 for regen per second) * While casting: ManaRegInFSR * During regen: ManaRegOutFSR */ #region Calculate Regen float spiRegen = 5 * StatConversion.GetSpiritRegenSec(stats.Spirit, stats.Intellect); float replenishRegen = 5 * stats.Mana * stats.ManaRestoreFromMaxManaPerSecond; float judgementRegen = 5 * rot.GetBaseCastTime() / rot.Duration * stats.ManaRestoreFromBaseManaPPM / 60f * BaseStats.GetBaseStats(character).Mana; float ManaRegInFSR = spiRegen * stats.SpellCombatManaRegeneration + stats.Mp5 + replenishRegen + judgementRegen + thunderstormRegen; float ManaRegOutFSR = spiRegen + stats.Mp5 + replenishRegen + thunderstormRegen; float ManaRegen = ManaRegInFSR; #endregion // TotalDamage, CastFraction, TimeUntilOOM #region Calculate total damage in the fight float TimeUntilOOM = 0; float effectiveMPS = rot.MPS - ManaRegen / 5f; if (effectiveMPS <= 0) { TimeUntilOOM = FightDuration; } else { TimeUntilOOM = (calculatedStats.BasicStats.Mana) / effectiveMPS; } if (TimeUntilOOM > FightDuration) { TimeUntilOOM = FightDuration; } #region SpecialEffects from procs etc. procStats = DoSpecialEffects(character, stats, rot, FightDuration); //procStats = getTrinketStats(character, stats, calcOpts.FightDuration, rot); //damage procs (Thunder Capacitor etc.) are effected by spellcrit and damage debuffs damage = procStats.ArcaneDamage * (1 + stats.BonusArcaneDamageMultiplier) + procStats.NatureDamage * (1 + stats.BonusNatureDamageMultiplier) + procStats.FireDamage * (1 + stats.BonusFireDamageMultiplier) + procStats.ShadowDamage * (1 + stats.BonusShadowDamageMultiplier); if (damage > 0) { damage *= (1 + stats.SpellCrit * .5f); // but only with the normal 50% dmg bonus rot.DPS += damage; } #endregion float TotalDamage = TimeUntilOOM * rot.DPS; float TimeToRegenFull = 5f * calculatedStats.BasicStats.Mana / ManaRegOutFSR; float TimeToBurnAll = calculatedStats.BasicStats.Mana / effectiveMPS; float CastFraction = 1f; if (ManaRegOutFSR > 0 && FightDuration > TimeUntilOOM) { float timeLeft = FightDuration - TimeUntilOOM; if (TimeToRegenFull + TimeToBurnAll == 0) { CastFraction = 0; } else { CastFraction = TimeToBurnAll / (TimeToRegenFull + TimeToBurnAll); } TotalDamage += timeLeft * rot.DPS * CastFraction; } #endregion float bsRatio = ((float)calcOpts.BSRatio) * 0.01f; calculatedStats.BurstPoints = (1f - bsRatio) * 2f * rot.DPS; calculatedStats.SustainedPoints = bsRatio * 2f * TotalDamage / FightDuration; calculatedStats.OverallPoints = calculatedStats.BurstPoints + calculatedStats.SustainedPoints; calculatedStats.CombatStats = stats.Clone(); calculatedStats.CombatStats.Accumulate(procStats); calculatedStats.ManaRegenInFSR = ManaRegInFSR; calculatedStats.ManaRegenOutFSR = ManaRegOutFSR; calculatedStats.ReplenishMP5 = replenishRegen; calculatedStats.LightningBolt = rot.LB; calculatedStats.ChainLightning = rot.CL; calculatedStats.FlameShock = rot.FS; calculatedStats.LavaBurst = rot.LvB; calculatedStats.EarthShock = rot.ES; calculatedStats.FrostShock = rot.FrS; calculatedStats.FireNova = rot.FN; calculatedStats.SearingTotem = rot.ST; calculatedStats.MagmaTotem = rot.MT; calculatedStats.TimeToOOM = TimeUntilOOM; calculatedStats.CastRegenFraction = CastFraction; calculatedStats.CastsPerSecond = rot.getCastsPerSecond(); calculatedStats.CritsPerSecond = rot.getWeightedCritchance() * rot.getCastsPerSecond(); calculatedStats.MissesPerSecond = rot.getCastsPerSecond() * (1f - rot.getWeightedHitchance()); calculatedStats.LvBPerSecond = rot.getCastsPerSecond(typeof(LavaBurst)); calculatedStats.LBPerSecond = rot.getCastsPerSecond(typeof(LightningBolt)); calculatedStats.FSPerSecond = rot.getCastsPerSecond(typeof(FlameShock)); calculatedStats.LatencyPerSecond = rot.LatencyPerSecond; calculatedStats.RotationDPS = rot.DPS; calculatedStats.RotationMPS = rot.MPS; calculatedStats.TotalDPS = TotalDamage / FightDuration; rot.ClearCasting.TryGetValue(typeof(FlameShock), out calculatedStats.ClearCast_FlameShock); rot.ClearCasting.TryGetValue(typeof(LavaBurst), out calculatedStats.ClearCast_LavaBurst); rot.ClearCasting.TryGetValue(typeof(LightningBolt), out calculatedStats.ClearCast_LightningBolt); calculatedStats.Rotation = rot.ToString(); calculatedStats.RotationDetails = rot.ToDetailedString(); }
private double GetManaRegenFromSpiritAndIntellect() { return(Math.Floor(5f * StatConversion.GetSpiritRegenSec(TotalStats.Spirit, TotalStats.Intellect))); }