public static float CalcMana(Stats stats) { return((1 + stats.BonusManaMultiplier) * (stats.Mana + StatConversion.GetManaFromIntellect( CalcIntellect(stats)))); }
public override Stats GetCharacterStats(Character character, Item additionalItem) { CalculationOptionsHealPriest calcOpts = character.CalculationOptions as CalculationOptionsHealPriest; StatsPriest statsTotal = new StatsPriest() { SpellHaste = PriestInformation.GetDarkness(character.PriestTalents.Darkness), InnerFire = true, BonusIntellectMultiplier = 0.05f, // Cloth bonus. PriestSpec = PriestSpec.GetPriestSpec(character.PriestTalents), }; if (statsTotal.PriestSpec == ePriestSpec.Spec_Disc) { statsTotal.SpellCombatManaRegeneration = 0.5f; statsTotal.BonusIntellectMultiplier = 0.15f; } else if (statsTotal.PriestSpec == ePriestSpec.Spec_Holy) { statsTotal.SpellCombatManaRegeneration = 0.5f + PriestInformation.GetHolyConcentration(character.PriestTalents.HolyConcentration); statsTotal.BonusHealingDoneMultiplier = 0.15f; } else if (statsTotal.PriestSpec == ePriestSpec.Spec_ERROR) { throw new Exception("Unpossible Talent Spec!"); } statsTotal.Accumulate(BaseStats.GetBaseStats(character)); statsTotal.Accumulate(GetItemStats(character, additionalItem)); statsTotal.Accumulate(GetBuffsStats(character, calcOpts)); statsTotal.Stamina = (float)Math.Floor((statsTotal.Stamina) * (1 + statsTotal.BonusStaminaMultiplier)); statsTotal.Intellect = (float)Math.Floor((statsTotal.Intellect) * (1 + statsTotal.BonusIntellectMultiplier)); statsTotal.Spirit = (float)Math.Floor((statsTotal.Spirit) * (1 + statsTotal.BonusSpiritMultiplier)); statsTotal.SpellPower += (statsTotal.InnerFire ? PriestInformation.GetInnerFireSpellPowerBonus(character) : 0) + (statsTotal.Intellect - 10); statsTotal.SpellPower *= (1f + statsTotal.BonusSpellPowerMultiplier); statsTotal.Mana += StatConversion.GetManaFromIntellect(statsTotal.Intellect); statsTotal.Mana *= (1f + statsTotal.BonusManaMultiplier); statsTotal.Health += StatConversion.GetHealthFromStamina(statsTotal.Stamina); statsTotal.Health = (float)Math.Floor(statsTotal.Health * (1f + statsTotal.BonusHealthMultiplier)); statsTotal.SpellCrit += StatConversion.GetSpellCritFromIntellect(statsTotal.Intellect) + StatConversion.GetSpellCritFromRating(statsTotal.CritRating); statsTotal.SpellHaste = (1f + statsTotal.SpellHaste) * (1f + StatConversion.GetSpellHasteFromRating(statsTotal.HasteRating)) - 1f; statsTotal.Armor *= (1 + (statsTotal.InnerFire ? PriestInformation.GetInnerFireArmorBonus(character) : 0)); if (statsTotal.PriestSpec == ePriestSpec.Spec_Disc) { statsTotal.ShieldDiscipline = (PriestInformation.DisciplineMasteryBase + StatConversion.GetMasteryFromRating(statsTotal.MasteryRating)) * PriestInformation.DisciplineMasteryEffect; } else if (statsTotal.PriestSpec == ePriestSpec.Spec_Holy) { statsTotal.EchoofLight = (PriestInformation.HolyMasteryBase + StatConversion.GetMasteryFromRating(statsTotal.MasteryRating)) * PriestInformation.HolyMasteryEffect; } return(statsTotal); }
private void ConvertRatings(Stats stats, PaladinTalents talents, CalculationOptionsHealadin calcOpts) { stats.Stamina *= 1f + stats.BonusStaminaMultiplier; // Intellect is used to calculate initial mana pool. // To avoid temporary intellect from highest stat procs changing initial mana pool // we track temporary intellect separatly in HighestStat property and combine it with intellect // when needed. // TODO: However this doesn't help to deal with pure temporary intellect procs (if there are any). // NOTE: If we add highest stat to intellect after we calculate mana, the only visible change // will be the displayed intellect for the character. stats.Intellect *= (1f + stats.BonusIntellectMultiplier); stats.HighestStat *= (1f + stats.BonusIntellectMultiplier); stats.SpellCrit = stats.SpellCrit + StatConversion.GetSpellCritFromIntellect( stats.Intellect + stats.HighestStat, CharacterClass.Paladin) + StatConversion.GetSpellCritFromRating(stats.CritRating, CharacterClass.Paladin); // I want to track haste before talent seperately, going to use RangedHaste for that. // I plan to use this on the "Stats" page so I can report sources of haste seperatly stats.RangedHaste = (1f + stats.SpellHaste) * (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin)) - 1f; // calculating physical haste for use in melee attacks, which will generate mana // can also divide spellhaste / physicalhaste to get orignal value of spellhaste, which is from buffs as far as I can tell stats.PhysicalHaste = (1f + talents.JudgementsOfThePure * 0.03f) * (1f + talents.SpeedOfLight * 0.01f) * (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin)) - 1f; stats.SpellHaste = (1f + talents.JudgementsOfThePure * 0.03f) * (1f + talents.SpeedOfLight * 0.01f) * (1f + stats.SpellHaste) * (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin)) - 1f; // GetManaFromIntellect/GetHealthFromStamina account for the fact // that the first 20 Int/Sta only give 1 Mana/Health each. stats.Mana += StatConversion.GetManaFromIntellect(stats.Intellect, CharacterClass.Paladin) * (1f + stats.BonusManaMultiplier); stats.Health += StatConversion.GetHealthFromStamina(stats.Stamina, CharacterClass.Paladin); stats.PhysicalHit += StatConversion.GetPhysicalHitFromRating( stats.HitRating, CharacterClass.Paladin); }
private void ConvertRatings(Stats stats, PaladinTalents talents, CalculationOptionsHealadin calcOpts) { stats.Stamina *= 1f + stats.BonusStaminaMultiplier; // Intellect is used to calculate initial mana pool. // To avoid temporary intellect from highest stat procs changing initial mana pool // we track temporary intellect separatly in HighestStat property and combine it with intellect // when needed. // TODO: However this doesn't help to deal with pure temporary intellect procs (if there are any). // NOTE: If we add highest stat to intellect after we calculate mana, the only visible change // will be the displayed intellect for the character. stats.Intellect *= (1f + stats.BonusIntellectMultiplier) * (1f + talents.DivineIntellect * .02f); stats.HighestStat *= (1f + stats.BonusIntellectMultiplier) * (1f + talents.DivineIntellect * .02f); stats.SpellPower += 0.04f * (stats.Intellect + stats.HighestStat) * talents.HolyGuidance; stats.SpellCrit = stats.SpellCrit + StatConversion.GetSpellCritFromIntellect( stats.Intellect + stats.HighestStat, CharacterClass.Paladin) + StatConversion.GetSpellCritFromRating(stats.CritRating, CharacterClass.Paladin) + talents.SanctityOfBattle * .01f + talents.Conviction * .01f; stats.SpellHaste = (1f + talents.JudgementsOfThePure * (calcOpts.JotP ? .03f : 0f)) * (1f + stats.SpellHaste) * (1f + StatConversion.GetSpellHasteFromRating(stats.HasteRating, CharacterClass.Paladin)) - 1f; // GetManaFromIntellect/GetHealthFromStamina account for the fact // that the first 20 Int/Sta only give 1 Mana/Health each. stats.Mana += StatConversion.GetManaFromIntellect(stats.Intellect, CharacterClass.Paladin) * (1f + stats.BonusManaMultiplier); stats.Health += StatConversion.GetHealthFromStamina(stats.Stamina, CharacterClass.Paladin); stats.PhysicalHit += StatConversion.GetPhysicalHitFromRating( stats.HitRating, CharacterClass.Paladin); }
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 static float CalcMana(Stats stats, float baseIntellect, int playerLevel) { return((float)Math.Round((stats.Mana + StatConversion.GetManaFromIntellect(CalcIntellect(stats, baseIntellect, playerLevel))) * (1 + stats.BonusManaMultiplier) - 0.00001f)); }
public override Stats GetCharacterStats(Character character, Item additionalItem) { CalculationOptionsElemental calcOpts = character.CalculationOptions as CalculationOptionsElemental; Stats statsRace = BaseStats.GetBaseStats(character); Stats statsItems = GetItemStats(character, additionalItem); Stats statsBuffs = GetBuffsStats(character, calcOpts); Stats statsTotal = statsRace + statsItems + statsBuffs; if (statsTotal.HighestStat > 0) { if (statsTotal.Spirit > statsTotal.Intellect) { statsTotal.Spirit += (statsTotal.HighestStat * 15f / 50f); } else { statsTotal.Intellect += (statsTotal.HighestStat * 15f / 50f); } } statsTotal.Strength *= 1 + statsTotal.BonusStrengthMultiplier; statsTotal.Agility *= 1 + statsTotal.BonusAgilityMultiplier; statsTotal.Stamina *= 1 + statsTotal.BonusStaminaMultiplier; statsTotal.Intellect *= 1 + statsTotal.BonusIntellectMultiplier; statsTotal.Spirit *= 1 + statsTotal.BonusSpiritMultiplier; statsTotal.Strength = (float)Math.Floor(statsTotal.Strength); statsTotal.Agility = (float)Math.Floor(statsTotal.Agility); statsTotal.Stamina = (float)Math.Floor(statsTotal.Stamina); statsTotal.Intellect = (float)Math.Floor(statsTotal.Intellect); statsTotal.Spirit = (float)Math.Floor(statsTotal.Spirit); if (Character.ValidateArmorSpecialization(character, ItemType.Mail)) { statsTotal.Intellect *= 1.05f; } statsTotal.AttackPower += statsTotal.Strength + statsTotal.Agility; statsTotal.Mana += StatConversion.GetManaFromIntellect(statsTotal.Intellect); statsTotal.Mana *= (float)Math.Round(1f + statsTotal.BonusManaMultiplier); statsTotal.Health += StatConversion.GetHealthFromStamina(statsTotal.Stamina); statsTotal.Health *= (float)Math.Round(1f + statsTotal.BonusHealthMultiplier); statsTotal.SpellCrit += StatConversion.GetSpellCritFromRating(statsTotal.CritRating); statsTotal.SpellCrit += StatConversion.GetSpellCritFromIntellect(statsTotal.Intellect); statsTotal.SpellCrit += statsTotal.SpellCritOnTarget; statsTotal.SpellHit += StatConversion.GetSpellHitFromRating(statsTotal.HitRating + ((.33f * character.ShamanTalents.ElementalPrecision) * statsTotal.Spirit)); // Flametongue weapon assumed statsTotal.SpellPower += (float)Math.Floor(747.78 * (1f + character.ShamanTalents.ElementalWeapons * .2f)); if (character.ShamanTalents.GlyphofFlametongueWeapon) { statsTotal.SpellCrit += .02f; } // Water shield assumed statsTotal.Mp5 += 100; if (character.ShamanTalents.GlyphofWaterShield) { statsTotal.Mp5 += 30; } return(statsTotal); }
public override Stats GetCharacterStats(Character character, Item additionalItem) { PriestTalents talents = character.PriestTalents; Stats statsTotal = new Stats(); Stats baseStats = BaseStats.GetBaseStats(character.Level, character.Class, character.Race); Stats itemStats = GetItemStats(character, additionalItem); Stats buffStats = GetBuffsStats(character, _calculationOptions); // Get the gear/enchants/buffs stats loaded in statsTotal.Accumulate(baseStats); statsTotal.Accumulate(itemStats); statsTotal.Accumulate(buffStats); Stats statsTalents = new Stats() { // we can only wear items that are cloth so we always have our specialization, even naked. BonusIntellectMultiplier = 0.05f, BonusShadowDamageMultiplier = (1 + 0.02f * talents.TwinDisciplines) * (1 + 0.02f * talents.TwistedFaith) * (1 + 0.15f * talents.Shadowform) - 1, BonusHolyDamageMultiplier = (1 + 0.02f * talents.TwinDisciplines) - 1, // this is the shadow priest model so they must have 'Shadow Power' BonusSpellPowerMultiplier = .15f, }; statsTotal.Accumulate(statsTalents); statsTotal.Stamina = (float)Math.Floor(statsTotal.Stamina * (1 + statsTotal.BonusStaminaMultiplier)); statsTotal.Intellect += (float)Math.Floor(itemStats.Intellect * statsTotal.BonusIntellectMultiplier); statsTotal.Spirit = (float)Math.Round(statsTotal.Spirit * (1 + statsTotal.BonusSpiritMultiplier)); statsTotal.Health += (float)Math.Floor(StatConversion.GetHealthFromStamina(statsTotal.Stamina) * (1f + statsTotal.BonusHealthMultiplier)); statsTotal.Mana = (float)Math.Round(statsTotal.Mana + StatConversion.GetManaFromIntellect(statsTotal.Intellect)); statsTotal.Mana = (float)Math.Round(statsTotal.Mana * (1f + statsTotal.BonusManaMultiplier)); statsTotal.SpellPower += statsTotal.Intellect - 10; float hasteFromRating = StatConversion.GetSpellHasteFromRating(statsTotal.HasteRating); float talentedHaste = (1 + hasteFromRating) * (1 + talents.Darkness * .01f) - 1; statsTotal.SpellHaste += character.Race == CharacterRace.Goblin ? talentedHaste * 1.01f : talentedHaste; float baseBonus = (float)Math.Floor(baseStats.Spirit * statsTotal.BonusSpiritMultiplier); float itemBonus = (float)Math.Floor(itemStats.Spirit * statsTotal.BonusSpiritMultiplier); float spiritFromItemsAndEffects = baseBonus + itemBonus + itemStats.Spirit; float hitRatingFromSpirit = (0.5f * talents.TwistedFaith) * Math.Max(0f, spiritFromItemsAndEffects); statsTotal.HitRating += hitRatingFromSpirit; statsTotal.SpellHit += StatConversion.GetSpellHitFromRating(statsTotal.HitRating); // ignoring the base crit percentage here as the in-game tooltip says that the int -> crit conversion contains the base. float critFromInt = StatConversion.GetSpellCritFromIntellect(statsTotal.Intellect) + 0.012375f; float critFromRating = StatConversion.GetSpellCritFromRating(statsTotal.CritRating); statsTotal.SpellCrit = character.Race == CharacterRace.Worgen ? (critFromInt + critFromRating) + .01f : (critFromInt + critFromRating); // Armor statsTotal.Armor = statsTotal.Armor * (1f + statsTotal.BaseArmorMultiplier); statsTotal.BonusArmor = statsTotal.BonusArmor * (1f + statsTotal.BonusArmorMultiplier); statsTotal.Armor += statsTotal.BonusArmor; statsTotal.Armor = (float)Math.Round(statsTotal.Armor); return(statsTotal); }
protected float CalcManaReg(float castsPerSecond, float critsPerSecond) { // Other things bool bBloodElf = character.Race == CharacterRace.BloodElf; // Spirit based float tmpReg, manaReg = 0; float spiritBaseRegen; if (verbose) { ManaSources.Clear(); } tmpReg = CalcSpiritRegen(stats.Spirit, stats.Intellect, stats.SpellCombatManaRegeneration); spiritBaseRegen = tmpReg; if (verbose) { ManaSources.Add(new ManaSource("Spirit Regen", "This is your mana regeneration while in combat", tmpReg)); } manaReg += tmpReg; tmpReg = stats.Mp5 / 5; if (verbose) { ManaSources.Add(new ManaSource("MP5", "This mana regeneration is constant, in combat or not.\n5% is from your base mana, rest from enchants and buffs", tmpReg)); } manaReg += tmpReg; tmpReg = CalcShadowfiend(stats.Mana); if (verbose) { ManaSources.Add(new ManaSource("Shadowfiend", "Assuming you cast Shadowfiend after 30 seconds and then on cooldown rest of fight", tmpReg)); } manaReg += tmpReg; if (character.PriestTalents.Rapture > 0) { tmpReg = CalcRapture(stats.Mana); if (verbose) { ManaSources.Add(new ManaSource("Rapture", String.Format("Assuming you gain the Rapture proc every {0} seconds", calcOpts.Rapture.ToString("0")), tmpReg)); } manaReg += tmpReg; } if (stats.ManaRestoreFromMaxManaPerSecond > 0) { tmpReg = stats.Mana * stats.ManaRestoreFromMaxManaPerSecond * (calcOpts.Replenishment / 100f); if (verbose) { ManaSources.Add(new ManaSource("Replenishment", String.Format("Assuming an uptime of {0}%.", calcOpts.Replenishment.ToString("0.00")), tmpReg)); } manaReg += tmpReg; } if (bBloodElf) { tmpReg = stats.Mana * 0.06f / 120; if (verbose) { ManaSources.Add(new ManaSource("Blood Elf", "Assuming you use it on cooldown", tmpReg)); } manaReg += tmpReg; } if (calcOpts.ModelProcs) { foreach (SpecialEffect se in stats.SpecialEffects()) { float uptime = 0; if (se.Trigger == Trigger.Use) { uptime = se.GetAverageUptime(se.Cooldown, 1f); } else if (se.Trigger == Trigger.HealingSpellCast || se.Trigger == Trigger.HealingSpellCrit || se.Trigger == Trigger.SpellCast || se.Trigger == Trigger.SpellCrit || se.Trigger == Trigger.DamageOrHealingDone) { uptime = se.GetAverageUptime(castsPerSecond, (se.Trigger == Trigger.HealingSpellCrit || se.Trigger == Trigger.SpellCrit) ? critsPerSecond : 1f); } if (se.Stats.Spirit > 0) { // Bonus Spirit float bonusSpirit = se.Stats.Spirit * (1f + stats.BonusSpiritMultiplier); tmpReg = CalcSpiritRegen(bonusSpirit, stats.Intellect, stats.SpellCombatManaRegeneration) * uptime; if (verbose) { ManaSources.Add(new ManaSource(se.ToString(), String.Format("{0}% expected uptime", (uptime * 100f).ToString("0.00")), tmpReg)); } manaReg += tmpReg; } if (se.Stats.Intellect > 0) { // Bonus Intellect float bonusInt = se.Stats.Intellect * (1f + stats.BonusIntellectMultiplier); float bonusMana = StatConversion.GetManaFromIntellect(bonusInt) * (1f + stats.BonusManaMultiplier); float spiritReg = CalcSpiritRegen(stats.Spirit, stats.Intellect + bonusInt, stats.SpellCombatManaRegeneration) - spiritBaseRegen; float raptureReg = CalcRapture(bonusMana); float replenishmentReg = bonusMana * stats.ManaRestoreFromMaxManaPerSecond * (calcOpts.Replenishment / 100f); float shadowfiendReg = CalcShadowfiend(bonusMana); float bloodelfReg = bBloodElf ? bonusMana * 0.06f / 120 : 0; tmpReg = (spiritReg + replenishmentReg + raptureReg + shadowfiendReg + bloodelfReg) * uptime; if (verbose) { ManaSources.Add(new ManaSource(se.ToString(), String.Format("{0}% expected uptime", (uptime * 100f).ToString("0.00")), tmpReg)); } manaReg += tmpReg; } if (se.Stats.BonusSpiritMultiplier > 0) { // Mana Tide // Do some assumptions about the shamans gearing. Lets assume that he stacked spirit in the same way we stacked our best secondary stat. // This may cause some issues which further buff our primary secondary stat, but oh well float maxSecondary = Math.Max(Math.Max(stats.CritRating, stats.HasteRating), Math.Max(stats.Spirit, stats.MasteryRating)); float bonusSpirit = maxSecondary * (1f + se.Stats.BonusSpiritMultiplier); tmpReg = CalcSpiritRegen(bonusSpirit, stats.Intellect, stats.SpellCombatManaRegeneration) * uptime; if (verbose) { ManaSources.Add(new ManaSource(se.ToString(), String.Format("{0}% expected uptime\n{1} Spirit bonus for duration", (uptime * 100f).ToString("0.00"), bonusSpirit.ToString("0")), tmpReg)); } manaReg += tmpReg; } } } return(manaReg); }