protected override void LoadCalculationOptions() { loading = true; if (Character.CalculationOptions == null) { Character.CalculationOptions = new CalculationOptionsHealadin(); } CalculationOptionsHealadin calcOpts = Character.CalculationOptions as CalculationOptionsHealadin; cmbLength.Value = (decimal)calcOpts.Length; nudDivinePlea.Value = (decimal)calcOpts.DivinePlea; nudGHL.Value = (decimal)calcOpts.GHL_Targets; trkActivity.Value = (int)(calcOpts.Activity * 100); lblActivity.Text = trkActivity.Value + "%"; chkSpiritIrrelevant.Checked = calcOpts.HitIrrelevant; chkHitIrrelevant.Checked = calcOpts.SpiritIrrelevant; if (CalculationsHealadin.IsHitIrrelevant != calcOpts.HitIrrelevant || CalculationsHealadin.IsSpiritIrrelevant != calcOpts.SpiritIrrelevant) { CalculationsHealadin.IsSpiritIrrelevant = calcOpts.SpiritIrrelevant; CalculationsHealadin.IsHitIrrelevant = calcOpts.HitIrrelevant; ItemCache.OnItemsChanged(); } chkJotP.Checked = calcOpts.JotP; chkJudgement.Checked = calcOpts.Judgement; chkLoHSelf.Checked = calcOpts.LoHSelf; trkReplenishment.Value = (int)Math.Round(calcOpts.Replenishment * 100); lblReplenishment.Text = trkReplenishment.Value + "%"; trkBoLUp.Value = (int)Math.Round(calcOpts.BoLUp * 100); lblBoLUp.Text = trkBoLUp.Value + "%"; trkBurstScale.Value = (int)Math.Round(calcOpts.BurstScale * 100); lblBurstScale.Text = trkBurstScale.Value + "%"; trkHS.Value = (int)Math.Round(calcOpts.HolyShock * 100); lblHS.Text = trkHS.Value + "%"; trkSacredShield.Value = (int)Math.Round(calcOpts.SSUptime * 100); lblSacredShield.Text = trkSacredShield.Value + "%"; trkFlashOfLightOnTank.Value = (int)Math.Round(calcOpts.FoLOnTank * 100); lblFlashOfLightOnTank.Text = trkFlashOfLightOnTank.Value + "%"; chkIoL.Checked = calcOpts.InfusionOfLight; trkIoLRatio.Value = (int)Math.Round(calcOpts.IoLHolyLight * 100f); lblIoLHL.Text = trkIoLRatio.Value + "% HL"; lblIoLFoL.Text = (100 - trkIoLRatio.Value) + "% FoL"; trkIoLRatio.Enabled = calcOpts.InfusionOfLight; lblIoLHL.Enabled = calcOpts.InfusionOfLight; lblIoLFoL.Enabled = calcOpts.InfusionOfLight; loading = false; }
private void nudGHL_ValueChanged(object sender, EventArgs e) { if (!loading) { CalculationOptionsHealadin calcOpts = Character.CalculationOptions as CalculationOptionsHealadin; calcOpts.GHL_Targets = (float)nudGHL.Value; Character.OnCalculationsInvalidated(); } }
public void LoadCalculationOptions() { _loadingCalculationOptions = true; if (Character.CalculationOptions == null) Character.CalculationOptions = new CalculationOptionsHealadin(); calcOpts = Character.CalculationOptions as CalculationOptionsHealadin; // Model Specific Code // _loadingCalculationOptions = false; }
public override ICalculationOptionBase DeserializeDataObject(string xml) { System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(CalculationOptionsHealadin)); System.IO.StringReader reader = new System.IO.StringReader(xml); CalculationOptionsHealadin calcOpts = serializer.Deserialize(reader) as CalculationOptionsHealadin; return(calcOpts); }
private void nudDivinePlea_ValueChanged(object sender, EventArgs e) { if (!loading) { CalculationOptionsHealadin calcOpts = Character.CalculationOptions as CalculationOptionsHealadin; calcOpts.DivinePlea = (float)nudDivinePlea.Value; Character.OnCalculationsInvalidated(); } }
private void chkJudgement_CheckedChanged(object sender, EventArgs e) { if (!loading) { CalculationOptionsHealadin calcOpts = Character.CalculationOptions as CalculationOptionsHealadin; calcOpts.Judgement = chkJudgement.Checked; Character.OnCalculationsInvalidated(); } }
private void trkFlashOfLightOnTank_Scroll(object sender, EventArgs e) { if (!loading) { CalculationOptionsHealadin calcOpts = Character.CalculationOptions as CalculationOptionsHealadin; calcOpts.FoLOnTank = trkFlashOfLightOnTank.Value / 100f; lblFlashOfLightOnTank.Text = trkFlashOfLightOnTank.Value + "%"; Character.OnCalculationsInvalidated(); } }
private void trkSacredShield_Scroll(object sender, EventArgs e) { if (!loading) { CalculationOptionsHealadin calcOpts = Character.CalculationOptions as CalculationOptionsHealadin; calcOpts.SSUptime = trkSacredShield.Value / 100f; lblSacredShield.Text = trkSacredShield.Value + "%"; Character.OnCalculationsInvalidated(); } }
private void trkHS_Scroll(object sender, EventArgs e) { if (!loading) { CalculationOptionsHealadin calcOpts = Character.CalculationOptions as CalculationOptionsHealadin; calcOpts.HolyShock = trkHS.Value / 100f; lblHS.Text = trkHS.Value + "%"; Character.OnCalculationsInvalidated(); } }
private void trkBurstScale_Scroll(object sender, EventArgs e) { if (!loading) { CalculationOptionsHealadin calcOpts = Character.CalculationOptions as CalculationOptionsHealadin; calcOpts.BurstScale = trkBurstScale.Value / 100f; lblBurstScale.Text = trkBurstScale.Value + "%"; Character.OnCalculationsInvalidated(); } }
private void trkIoLRatio_Scroll(object sender, EventArgs e) { if (!loading) { CalculationOptionsHealadin calcOpts = Character.CalculationOptions as CalculationOptionsHealadin; calcOpts.IoLHolyLight = trkIoLRatio.Value / 100f; lblIoLHL.Text = trkIoLRatio.Value + "% HL"; lblIoLFoL.Text = (100 - trkIoLRatio.Value) + "% FoL"; Character.OnCalculationsInvalidated(); } }
private void chkIoL_CheckedChanged(object sender, EventArgs e) { if (!loading) { CalculationOptionsHealadin calcOpts = Character.CalculationOptions as CalculationOptionsHealadin; calcOpts.InfusionOfLight = chkIoL.Checked; trkIoLRatio.Enabled = calcOpts.InfusionOfLight; lblIoLHL.Enabled = calcOpts.InfusionOfLight; lblIoLFoL.Enabled = calcOpts.InfusionOfLight; Character.OnCalculationsInvalidated(); } }
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 CharacterCalculationsHealadin calc = new CharacterCalculationsHealadin(); if (character == null) { return(calc); } CalculationOptionsHealadin calcOpts = character.CalculationOptions as CalculationOptionsHealadin; if (calcOpts == null) { return(calc); } // Stats stats; calc = null; PaladinTalents talents = character.PaladinTalents; for (int i = 0; i < 5; i++) { float oldBurst = 0; if (i > 0) { oldBurst = calc.BurstPoints; } stats = GetCharacterStats(character, additionalItem, true, calc); calc = new CharacterCalculationsHealadin(); Rotation rot = new Rotation(character, stats); if (i > 0) { calc.BurstPoints = oldBurst; } else { calc.BurstPoints = rot.CalculateBurstHealing(calc); } calc.FightPoints = rot.CalculateFightHealing(calc); calc.OverallPoints = calc.BurstPoints + calc.FightPoints; } calc.BasicStats = GetCharacterStats(character, additionalItem, false, null); return(calc); }
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); }
public Stats GetBuffsStats(Character character, CalculationOptionsHealadin calcOpts) { List <Buff> removedBuffs = new List <Buff>(); List <Buff> addedBuffs = new List <Buff>(); //float hasRelevantBuff; #region Passive Ability Auto-Fixing // Removes the Trueshot Aura Buff and it's equivalents Unleashed Rage and Abomination's Might if you are // maintaining it yourself. We are now calculating this internally for better accuracy and to provide // value to relevant talents /*{ * hasRelevantBuff = character.HunterTalents.TrueshotAura; * Buff a = Buff.GetBuffByName("Trueshot Aura"); * Buff b = Buff.GetBuffByName("Unleashed Rage"); * Buff c = Buff.GetBuffByName("Abomination's Might"); * if (hasRelevantBuff > 0) * { * if (character.ActiveBuffs.Contains(a)) { character.ActiveBuffs.Remove(a); removedBuffs.Add(a); } * if (character.ActiveBuffs.Contains(b)) { character.ActiveBuffs.Remove(b); removedBuffs.Add(b); } * if (character.ActiveBuffs.Contains(c)) { character.ActiveBuffs.Remove(c); removedBuffs.Add(c); } * } * }*/ #endregion Stats statsBuffs = GetBuffsStats(character.ActiveBuffs); foreach (Buff b in removedBuffs) { character.ActiveBuffsAdd(b); } foreach (Buff b in addedBuffs) { character.ActiveBuffs.Remove(b); } return(statsBuffs); }
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 Stats GetBuffsStats(Character character, CalculationOptionsHealadin calcOpts) { List<Buff> removedBuffs = new List<Buff>(); List<Buff> addedBuffs = new List<Buff>(); //float hasRelevantBuff; #region Passive Ability Auto-Fixing // Removes the Trueshot Aura Buff and it's equivalents Unleashed Rage and Abomination's Might if you are // maintaining it yourself. We are now calculating this internally for better accuracy and to provide // value to relevant talents /*{ hasRelevantBuff = character.HunterTalents.TrueshotAura; Buff a = Buff.GetBuffByName("Trueshot Aura"); Buff b = Buff.GetBuffByName("Unleashed Rage"); Buff c = Buff.GetBuffByName("Abomination's Might"); if (hasRelevantBuff > 0) { if (character.ActiveBuffs.Contains(a)) { character.ActiveBuffs.Remove(a); removedBuffs.Add(a); } if (character.ActiveBuffs.Contains(b)) { character.ActiveBuffs.Remove(b); removedBuffs.Add(b); } if (character.ActiveBuffs.Contains(c)) { character.ActiveBuffs.Remove(c); removedBuffs.Add(c); } } }*/ #endregion Stats statsBuffs = GetBuffsStats(character.ActiveBuffs, character.SetBonusCount); foreach (Buff b in removedBuffs) { character.ActiveBuffsAdd(b); } foreach (Buff b in addedBuffs) { character.ActiveBuffs.Remove(b); } return statsBuffs; }
public Stats GetCharacterStats(Character character, Item additionalItem, bool computeAverageStats, CharacterCalculationsHealadin calc) { PaladinTalents talents = character.PaladinTalents; CalculationOptionsHealadin calcOpts = character.CalculationOptions as CalculationOptionsHealadin; if (calcOpts == null) { calcOpts = new CalculationOptionsHealadin(); } #if (RAWR3) BossOptions bossOpts = character.BossOptions; if (bossOpts == null) { bossOpts = new BossOptions(); } #endif #if (RAWR3) float fightLength = bossOpts.BerserkTimer * 60f; #else float fightLength = calcOpts.Length * 60f; #endif Stats statsRace = BaseStats.GetBaseStats(character.Level, CharacterClass.Paladin, character.Race); Stats statsBaseGear = GetItemStats(character, additionalItem); Stats statsBuffs = GetBuffsStats(character, calcOpts); Stats stats = statsBaseGear + statsBuffs + statsRace; ConvertRatings(stats, talents, calcOpts); if (computeAverageStats) { Stats statsAverage = new Stats(); foreach (SpecialEffect effect in stats.SpecialEffects()) { float trigger = 0f; if (calc == null) { trigger = 1.5f / calcOpts.Activity / (1f + stats.SpellHaste); if (effect.Trigger == Trigger.HealingSpellCrit || effect.Trigger == Trigger.SpellCrit) { trigger *= stats.SpellCrit; } else if (effect.Trigger == Trigger.HolyShockCast) { trigger = 6f / calcOpts.HolyShock; } } else { if (effect.Trigger == Trigger.HealingSpellCast || effect.Trigger == Trigger.HealingSpellHit) { trigger = 1f / Rotation.GetHealingCastsPerSec(calc); } else if (effect.Trigger == Trigger.HealingSpellCrit || effect.Trigger == Trigger.SpellCrit) { trigger = 1f / Rotation.GetHealingCritsPerSec(calc); } else if (effect.Trigger == Trigger.SpellCast || effect.Trigger == Trigger.SpellHit) { trigger = 1f / Rotation.GetSpellCastsPerSec(calc); } else if (effect.Trigger == Trigger.DamageOrHealingDone) { trigger = 1f / Rotation.GetHealingCastsPerSec(calc); } else if (effect.Trigger == Trigger.HolyShockCast) { trigger = 6f / calcOpts.HolyShock; } else if (effect.Trigger == Trigger.Use) { trigger = 0f; foreach (SpecialEffect childEffect in effect.Stats.SpecialEffects()) { float childTrigger = 0f; if (effect.Trigger == Trigger.HealingSpellCast || effect.Trigger == Trigger.HealingSpellHit) { childTrigger = 1f / Rotation.GetHealingCastsPerSec(calc); } else if (effect.Trigger == Trigger.HealingSpellCrit || effect.Trigger == Trigger.SpellCrit) { childTrigger = 1f / Rotation.GetHealingCritsPerSec(calc); } else if (effect.Trigger == Trigger.SpellCast || effect.Trigger == Trigger.SpellHit) { childTrigger = 1f / Rotation.GetSpellCastsPerSec(calc); } statsAverage.Accumulate(childEffect.Stats, effect.GetAverageUptime(0.0f, 1.0f) * childEffect.GetAverageStackSize(childTrigger, 1f, 1.5f, effect.Duration)); } } else if (effect.Trigger == Trigger.HolyLightCast) { trigger = 1f / Rotation.GetHolyLightCastsPerSec(calc); } else { continue; } } statsAverage.Accumulate(effect.GetAverageStats(trigger, 1f, 1.5f, fightLength)); } statsAverage.ManaRestore *= fightLength; statsAverage.Healed *= fightLength; stats = statsBaseGear + statsBuffs + statsRace + statsAverage; ConvertRatings(stats, talents, calcOpts); } return(stats); }
public override ComparisonCalculationBase[] GetCustomChartData(Character character, string chartName) { CharacterCalculationsHealadin calc = GetCharacterCalculations(character) as CharacterCalculationsHealadin; if (calc == null) { calc = new CharacterCalculationsHealadin(); } ComparisonCalculationHealadin FoL = new ComparisonCalculationHealadin("Flash of Light"); ComparisonCalculationHealadin HL11 = new ComparisonCalculationHealadin("Holy Light 11"); ComparisonCalculationHealadin HL10 = new ComparisonCalculationHealadin("Holy Light 10"); ComparisonCalculationHealadin HL9 = new ComparisonCalculationHealadin("Holy Light 9"); ComparisonCalculationHealadin HL8 = new ComparisonCalculationHealadin("Holy Light 8"); ComparisonCalculationHealadin HL7 = new ComparisonCalculationHealadin("Holy Light 7"); ComparisonCalculationHealadin HL6 = new ComparisonCalculationHealadin("Holy Light 6"); ComparisonCalculationHealadin HL5 = new ComparisonCalculationHealadin("Holy Light 5"); ComparisonCalculationHealadin HL4 = new ComparisonCalculationHealadin("Holy Light 4"); CalculationOptionsHealadin calcOpts = character.CalculationOptions as CalculationOptionsHealadin; if (calcOpts == null) { calcOpts = new CalculationOptionsHealadin(); } calc[0] = new Spell("Flash of Light", 7, calcOpts.BoL); calc[1] = new Spell("Holy Light", 11, calcOpts.BoL); calc[2] = new Spell("Holy Light", 10, calcOpts.BoL); calc[3] = new Spell("Holy Light", 9, calcOpts.BoL); calc[4] = new Spell("Holy Light", 8, calcOpts.BoL); calc[5] = new Spell("Holy Light", 7, calcOpts.BoL); calc[6] = new Spell("Holy Light", 6, calcOpts.BoL); calc[7] = new Spell("Holy Light", 5, calcOpts.BoL); calc[8] = new Spell("Holy Light", 4, calcOpts.BoL); switch (chartName) { case "Healing per second": FoL.OverallPoints = FoL.ThroughputPoints = calc[0].Hps; HL11.OverallPoints = HL11.ThroughputPoints = calc[1].Hps; HL10.OverallPoints = HL10.ThroughputPoints = calc[2].Hps; HL9.OverallPoints = HL9.ThroughputPoints = calc[3].Hps; HL8.OverallPoints = HL8.ThroughputPoints = calc[4].Hps; HL7.OverallPoints = HL7.ThroughputPoints = calc[5].Hps; HL6.OverallPoints = HL6.ThroughputPoints = calc[6].Hps; HL5.OverallPoints = HL5.ThroughputPoints = calc[7].Hps; HL4.OverallPoints = HL4.ThroughputPoints = calc[8].Hps; break; case "Average heal": FoL.OverallPoints = FoL.ThroughputPoints = calc[0].AverageHeal; HL11.OverallPoints = HL11.ThroughputPoints = calc[1].AverageHeal; HL10.OverallPoints = HL10.ThroughputPoints = calc[2].AverageHeal; HL9.OverallPoints = HL9.ThroughputPoints = calc[3].AverageHeal; HL8.OverallPoints = HL8.ThroughputPoints = calc[4].AverageHeal; HL7.OverallPoints = HL7.ThroughputPoints = calc[5].AverageHeal; HL6.OverallPoints = HL6.ThroughputPoints = calc[6].AverageHeal; HL5.OverallPoints = HL5.ThroughputPoints = calc[7].AverageHeal; HL4.OverallPoints = HL4.ThroughputPoints = calc[8].AverageHeal; break; case "Healing per mana": FoL.OverallPoints = FoL.LongevityPoints = calc[0].Hpm; HL11.OverallPoints = HL11.LongevityPoints = calc[1].Hpm; HL10.OverallPoints = HL10.LongevityPoints = calc[2].Hpm; HL9.OverallPoints = HL9.LongevityPoints = calc[3].Hpm; HL8.OverallPoints = HL8.LongevityPoints = calc[4].Hpm; HL7.OverallPoints = HL7.LongevityPoints = calc[5].Hpm; HL6.OverallPoints = HL6.LongevityPoints = calc[6].Hpm; HL5.OverallPoints = HL5.LongevityPoints = calc[7].Hpm; HL4.OverallPoints = HL4.LongevityPoints = calc[8].Hpm; break; case "Mana per second": FoL.OverallPoints = FoL.LongevityPoints = calc[0].Mps; HL11.OverallPoints = HL11.LongevityPoints = calc[1].Mps; HL10.OverallPoints = HL10.LongevityPoints = calc[2].Mps; HL9.OverallPoints = HL9.LongevityPoints = calc[3].Mps; HL8.OverallPoints = HL8.LongevityPoints = calc[4].Mps; HL7.OverallPoints = HL7.LongevityPoints = calc[5].Mps; HL6.OverallPoints = HL6.LongevityPoints = calc[6].Mps; HL5.OverallPoints = HL5.LongevityPoints = calc[7].Mps; HL4.OverallPoints = HL4.LongevityPoints = calc[8].Mps; break; } return(new ComparisonCalculationBase[] { FoL, HL11, HL10, HL9, HL8, HL7, HL6, HL5, HL4 }); }
public override CharacterCalculationsBase GetCharacterCalculations(Character character, Item additionalItem) { //_cachedCharacter = character; Stats stats = GetCharacterStats(character, additionalItem); CharacterCalculationsHealadin calculatedStats = new CharacterCalculationsHealadin(); //CharacterCalculationsHealadin oldStats = _cachedCharacterStatsWithSlotEmpty as CharacterCalculationsHealadin; calculatedStats.BasicStats = stats; CalculationOptionsHealadin calcOpts = character.CalculationOptions as CalculationOptionsHealadin; if (calcOpts == null) { calcOpts = new CalculationOptionsHealadin(); } float activity = calcOpts.Activity / 100f; float time = calcOpts.Length * 60; float length = time * activity; float totalMana = stats.Mana + (time * stats.Mp5 / 5) + (calcOpts.Spriest * time / 5) + ((1 + stats.BonusManaPotion) * calcOpts.ManaAmt * (float)Math.Ceiling((time / 60 - 1) / calcOpts.ManaTime)) + calcOpts.Spiritual; if (stats.MementoProc > 0) { totalMana += (float)Math.Ceiling(time / 60 - .25) * stats.MementoProc * 3; } calculatedStats[0] = new Spell("Flash of Light", 7, calcOpts.BoL); calculatedStats[1] = new Spell("Holy Light", 11, calcOpts.BoL); calculatedStats[2] = new Spell("Holy Light", 10, calcOpts.BoL); calculatedStats[3] = new Spell("Holy Light", 9, calcOpts.BoL); calculatedStats[4] = new Spell("Holy Light", 8, calcOpts.BoL); calculatedStats[5] = new Spell("Holy Light", 7, calcOpts.BoL); calculatedStats[6] = new Spell("Holy Light", 6, calcOpts.BoL); calculatedStats[7] = new Spell("Holy Light", 5, calcOpts.BoL); calculatedStats[8] = new Spell("Holy Light", 4, calcOpts.BoL); #region Divine Illumination Spell hl1_di = new Spell("Holy Light", 11, calcOpts.BoL); hl1_di.Calculate(stats, true); Spell hl2_di = new Spell("Holy Light", 9, calcOpts.BoL); hl2_di.Calculate(stats, true); Spell fol_di = new Spell("Flash of Light", 7, calcOpts.BoL); fol_di.Calculate(stats, true); float hl1_dimana = calculatedStats[1].Mps - hl1_di.Mps; float hl2_dimana = calculatedStats[3].Mps - hl2_di.Mps; float fol_dimana = calculatedStats[0].Mps - fol_di.Mps; float di_mana = (hl1_dimana * 6 + hl2_dimana * 3 + fol_dimana * 6) * activity * (float)Math.Ceiling((time - 1) / 180); totalMana += di_mana; #endregion #region Divine Favor totalMana += (float)Math.Ceiling((time - 30) / 120f) * calculatedStats[1].DFMana(); calculatedStats.Healed = (float)Math.Ceiling((time - 30) / 120f) * calculatedStats[1].DFHeal(); #endregion Spell FoL = calculatedStats[0]; int rank1 = 12 - calcOpts.Rank1; int rank2 = 12 - calcOpts.Rank2; float HL_Mps = calculatedStats[rank1].Mps * (1f - calcOpts.Ratio) + calculatedStats[rank2].Mps * calcOpts.Ratio; float HL_Hps = calculatedStats[rank1].Hps * (1f - calcOpts.Ratio) + calculatedStats[rank2].Hps * calcOpts.Ratio; float time_hl = Math.Min(length, Math.Max(0, (totalMana - (length * FoL.Mps)) / (HL_Mps - FoL.Mps))); float time_fol = length - time_hl; if (time_hl == 0) { time_fol = Math.Min(length, totalMana / FoL.Mps); } calculatedStats.TimeHL = time_hl / length; float healing_fol = time_fol * FoL.Hps; float healing_hl = time_hl * HL_Hps; calculatedStats.Healed += healing_fol + healing_hl; calculatedStats.HLHPS = HL_Hps; calculatedStats.FoLHPS = FoL.Hps; calculatedStats.ThroughputPoints = calculatedStats.Healed / time;// FoL.Hps* activity; //calculatedStats.LongevityPoints = calculatedStats.Healed / time - FoL.Hps; /*if (oldStats == null) * { * calculatedStats.ThroughputPoints = FoL.Hps * length; * calculatedStats.LongevityPoints = calculatedStats.Healed - calculatedStats.ThroughputPoints; * } * else * { * float otime = Math.Max(oldStats.TimeHL * length, time_hl); * calculatedStats.LongevityPoints = (length-otime) * oldStats.FoLHPS + otime * oldStats.HLHPS; * calculatedStats.ThroughputPoints = calculatedStats.Healed - calculatedStats.LongevityPoints; * }*/ calculatedStats.OverallPoints = calculatedStats.ThroughputPoints;// +calculatedStats.LongevityPoints; calculatedStats.HealHL = healing_hl / calculatedStats.Healed; calculatedStats.AvgHPS = calculatedStats.Healed / length * activity; calculatedStats.AvgHPM = calculatedStats.Healed / totalMana; return(calculatedStats); }
public Stats GetCharacterStats(Character character, Item additionalItem, bool computeAverageStats, CharacterCalculationsHealadin calc) { CalculationOptionsHealadin calcOpts = character.CalculationOptions as CalculationOptionsHealadin; BossOptions bossOpts = character.BossOptions; PaladinTalents talents = character.PaladinTalents; float fightLength = bossOpts.BerserkTimer; Stats statsRace = BaseStats.GetBaseStats(character.Level, CharacterClass.Paladin, character.Race); Stats statsBaseGear = GetItemStats(character, additionalItem); Stats statsBuffs = GetBuffsStats(character, calcOpts); Stats stats = statsBaseGear + statsBuffs + statsRace; ConvertRatings(stats, talents, calcOpts); if (computeAverageStats) { Stats statsAverage = new Stats(); foreach (SpecialEffect effect in stats.SpecialEffects()) { float trigger = 0f; if (calc == null) { trigger = 1.5f / calcOpts.Activity / (1f + stats.SpellHaste); if (effect.Trigger == Trigger.HealingSpellCrit || effect.Trigger == Trigger.SpellCrit) { trigger *= stats.SpellCrit; } } else { if (effect.Trigger == Trigger.HealingSpellCast || effect.Trigger == Trigger.HealingSpellHit) { trigger = 1f / Rotation.GetHealingCastsPerSec(calc); } else if (effect.Trigger == Trigger.HealingSpellCrit || effect.Trigger == Trigger.SpellCrit) { trigger = 1f / Rotation.GetHealingCritsPerSec(calc); } else if (effect.Trigger == Trigger.SpellCast || effect.Trigger == Trigger.SpellHit) { trigger = 1f / Rotation.GetSpellCastsPerSec(calc); } else if (effect.Trigger == Trigger.DamageOrHealingDone) { trigger = 1f / Rotation.GetHealingCastsPerSec(calc); } else if (effect.Trigger == Trigger.Use) { trigger = 0f; foreach (SpecialEffect childEffect in effect.Stats.SpecialEffects()) { float childTrigger = 0f; if (effect.Trigger == Trigger.HealingSpellCast || effect.Trigger == Trigger.HealingSpellHit) { childTrigger = 1f / Rotation.GetHealingCastsPerSec(calc); } else if (effect.Trigger == Trigger.HealingSpellCrit || effect.Trigger == Trigger.SpellCrit) { childTrigger = 1f / Rotation.GetHealingCritsPerSec(calc); } else if (effect.Trigger == Trigger.SpellCast || effect.Trigger == Trigger.SpellHit) { childTrigger = 1f / Rotation.GetSpellCastsPerSec(calc); } statsAverage.Accumulate(childEffect.Stats, effect.GetAverageUptime(0.0f, 1.0f) * childEffect.GetAverageStackSize(childTrigger, 1f, 1.5f, effect.Duration)); } } else { continue; } } statsAverage.Accumulate(effect.GetAverageStats(trigger, 1f, 1.5f, fightLength)); } statsAverage.ManaRestore *= fightLength; statsAverage.Healed *= fightLength; statsAverage.HealedPerSP *= fightLength; stats = statsBaseGear + statsBuffs + statsRace + statsAverage; ConvertRatings(stats, talents, calcOpts); } #region Set Bonuses int T11Count; character.SetBonusCount.TryGetValue("Reinforced Sapphirium Regalia", out T11Count); stats.BonusCritChanceDeathCoil = 0; // using this for Holy Light crit bonus, for now stats.BonusCritChanceFrostStrike = 0; // yes, I'm pure evil, using this to track 4T11 if (T11Count >= 2) { // T11 Pally 2 piece bonus: add 5% crit to HL stats.BonusCritChanceDeathCoil = 0.05f; } if (T11Count >= 4) { // T11 Pally 4 piece bonus: 540 spirit buff for 6 secs after HS cast stats.BonusCritChanceFrostStrike = 1; } #endregion Set Bonuses return(stats); }