private void calculationOptionControl_Changed(object sender, EventArgs e) { if (!_loadingCalculationOptions) { CalculationOptionsRogue calcOpts = Character.CalculationOptions as CalculationOptionsRogue; calcOpts.TargetLevel = int.Parse(comboBoxTargetLevel.SelectedItem.ToString()); calcOpts.TargetArmor = (int)numericUpDownTargetArmor.Value; calcOpts.TargetPoisonable = checkBoxPoisonable.Checked; calcOpts.BleedIsUp = checkBoxBleed.Checked; calcOpts.Duration = (int)numericUpDownDuration.Value; calcOpts.LagVariance = (int)numericUpDownLagVariance.Value; calcOpts.ForceCustom = checkBoxCustom.Checked; calcOpts.CustomUseRupt = checkBoxRupt.Checked; calcOpts.CustomUseExpose = checkBoxExpose.Checked; calcOpts.CustomUseTotT = checkBoxTotT.Checked; calcOpts.CustomCPG = comboBoxCPG.SelectedIndex; calcOpts.CustomCPSnD = int.Parse(comboBoxSnD.SelectedItem.ToString()); calcOpts.CustomFinisher = comboBoxFinisher.SelectedIndex; calcOpts.CustomCPFinisher = int.Parse(comboBoxCPFinisher.SelectedItem.ToString()); calcOpts.CustomMHPoison = comboBoxMHPoison.SelectedIndex; calcOpts.CustomOHPoison = comboBoxOHPoison.SelectedIndex; calcOpts.TrinketOffset = (float)trackBarTrinketOffset.Value / 2f; calcOpts.PTRMode = checkBoxPTR.Checked; labelTrinketOffset.Text = string.Format(labelTrinketOffset.Tag.ToString(), calcOpts.TrinketOffset); Character.OnCalculationsInvalidated(); } }
public RogueRotationCalculatorCombat(Character character, Stats stats, BossOptions bossOpts, CalculationOptionsRogue calcOpts, float hasteBonus, float mainHandSpeed, float offHandSpeed, float mainHandSpeedNorm, float offHandSpeedNorm, float avoidedWhiteMHAttacks, float avoidedWhiteOHAttacks, float avoidedMHAttacks, float avoidedOHAttacks, float avoidedFinisherAttacks, float avoidedPoisonAttacks, float chanceExtraCPPerHit, RogueAbilityStats mainHandStats, RogueAbilityStats offHandStats, RogueAbilityStats mainGaucheStats, RogueAbilityStats sStrikeStats, RogueAbilityStats rStrikeStats, RogueAbilityStats ruptStats, RogueAbilityStats evisStats, RogueAbilityStats snDStats, RogueAbilityStats exposeStats, RogueAbilityStats iPStats, RogueAbilityStats dPStats, RogueAbilityStats wPStats) : base(character, stats, bossOpts, calcOpts, hasteBonus, mainHandSpeed, offHandSpeed, mainHandSpeedNorm, offHandSpeedNorm, avoidedWhiteMHAttacks, avoidedWhiteOHAttacks, avoidedMHAttacks, avoidedOHAttacks, avoidedFinisherAttacks, avoidedPoisonAttacks, chanceExtraCPPerHit, mainHandStats, offHandStats, ruptStats, snDStats, exposeStats, iPStats, dPStats, wPStats) { SStrikeStats = sStrikeStats; RStrikeStats = rStrikeStats; EvisStats = evisStats; MainGaucheStats = mainGaucheStats; ChanceOnMGAttackOnMHAttack = RV.Mastery.MainGauche + RV.Mastery.MainGauchePerMast * StatConversion.GetMasteryFromRating(stats.MasteryRating); EnergyRegenMultiplier = (1f + RV.Mastery.VitalityRegenMult) * (1f + (RV.AR.Duration + (Talents.GlyphOfAdrenalineRush ? RV.Glyph.ARDurationBonus : 0f)) / RV.AR.CD * Talents.AdrenalineRush) * (1f + HasteBonus) - 1f; #region Probability tables float c = ChanceExtraCPPerHit, h = (1f - c), f = CPOnFinisher, nf = (1f - f); _averageNormalCP[1] = 1 * (f + nf * h) + 2 * (nf * c); _averageNormalCP[2] = 2 * (f * h + nf * c + nf * h * h) + 3 * (f * c); _averageNormalCP[3] = 3 * (f * c + f * h * h + 2 * nf * c * h + nf * h * h * h) + 4 * (f * h * c + nf * c * c + nf * h * h * c); _averageNormalCP[4] = 4 * (2 * f * c * h + f * h * h * h + nf * c * c + 3 * nf * c * h * h + nf * h * h * h * h) + 5 * (f * c * c + f * h * h * c + 2 * nf * c * h * c + nf * h * h * h * c); _averageNormalCP[5] = 5 * (f * c * c + 3 * f * c * h * h + f * h * h * h * h + 3 * nf * c * c * h + 4 * nf * c * h * h * h + nf * h * h * h * h * h) + 6 * (2 * f * c * h * c + f * h * h * h * c + nf * c * c * c + 3 * nf * c * h * h * c + nf * h * h * h * h * c); c = ChanceExtraCPPerHit + ChanceOnCPOnSSCrit * SStrikeStats.CritChance; h = (1f - c); _averageSStrikeCP[1] = 1 * (f + nf * h) + 2 * (nf * c); _averageSStrikeCP[2] = 2 * (f * h + nf * c + nf * h * h) + 3 * (f * c + nf * h * c); _averageSStrikeCP[3] = 3 * (f * c + f * h * h + 2 * nf * c * h + nf * h * h * h) + 4 * (f * h * c + nf * c * c + nf * h * h * c); _averageSStrikeCP[4] = 4 * (2 * f * c * h + f * h * h * h + nf * c * c + 3 * nf * c * h * h + nf * h * h * h * h) + 5 * (f * c * c + f * h * h * c + 2 * nf * c * h * c + nf * h * h * h * c); _averageSStrikeCP[5] = 5 * (f * c * c + 3 * f * c * h * h + f * h * h * h * h + 3 * nf * c * c * h + 4 * nf * c * h * h * h + nf * h * h * h * h * h) + 6 * (2 * f * c * h * c + f * h * h * h * c + nf * c * c * c + 3 * nf * c * h * h * c + nf * h * h * h * h * c); #endregion }
public RogueTestCharacter(RogueTalents talents) { Class = CharacterClass.Rogue; RogueTalents = talents; CurrentModel = "Rogue"; CalculationOptions = new CalculationOptionsRogue(); }
public void LoadCalculationOptions() { CalculationOptionsRogue options = Character.CalculationOptions as CalculationOptionsRogue; calculationSuspended = true; string talent; foreach (Control c in Controls) { if (c is GroupBox) { foreach (Control cc in c.Controls) { if (cc is ComboBox) { ComboBox cb = (ComboBox)cc; talent = cb.Name.Substring(8); cb.SelectedItem = options.GetTalentByName(talent).ToString(); } } } } calculationSuspended = false; }
protected override void LoadCalculationOptions() { _loadingCalculationOptions = true; if (Character.CalculationOptions == null) { Character.CalculationOptions = new CalculationOptionsRogue(); } CalculationOptionsRogue calcOpts = Character.CalculationOptions as CalculationOptionsRogue; comboBoxTargetLevel.SelectedItem = calcOpts.TargetLevel.ToString(); numericUpDownTargetArmor.Value = calcOpts.TargetArmor; checkBoxPoisonable.Checked = calcOpts.TargetPoisonable; checkBoxBleed.Checked = calcOpts.BleedIsUp; numericUpDownDuration.Value = calcOpts.Duration; numericUpDownLagVariance.Value = calcOpts.LagVariance; checkBoxRupt.Checked = calcOpts.CustomUseRupt; checkBoxExpose.Checked = calcOpts.CustomUseExpose; checkBoxTotT.Checked = calcOpts.CustomUseTotT; comboBoxCPG.SelectedIndex = calcOpts.CustomCPG; comboBoxSnD.SelectedItem = calcOpts.CustomCPSnD.ToString(); comboBoxFinisher.SelectedIndex = calcOpts.CustomFinisher; comboBoxCPFinisher.SelectedItem = calcOpts.CustomCPFinisher.ToString(); comboBoxMHPoison.SelectedIndex = calcOpts.CustomMHPoison; comboBoxOHPoison.SelectedIndex = calcOpts.CustomOHPoison; trackBarTrinketOffset.Value = (int)(calcOpts.TrinketOffset * 2); labelTrinketOffset.Text = string.Format(labelTrinketOffset.Tag.ToString(), calcOpts.TrinketOffset); _loadingCalculationOptions = false; }
private float CalcBaseDamage(float avgDamage, CalculationOptionsRogue calcOpts, Stats stats) { float baseDamage = avgDamage; baseDamage *= (1f + stats.BonusPhysicalDamageMultiplier) * (1f + stats.BonusDamageMultiplier); baseDamage *= (1f + Talents.HungerForBlood.Damage.Bonus) * (1f + Talents.Murder.Bonus); return baseDamage; }
private void OnMHPoisonChanged(object sender, EventArgs e) { if (Character != null && Character.CalculationOptions != null) { CalculationOptionsRogue calcOpts = Character.CalculationOptions as CalculationOptionsRogue; calcOpts.TempMainHandEnchant = ((ComboBox)sender).SelectedItem.ToString(); } }
public override ICalculationOptionBase DeserializeDataObject(string xml) { System.Xml.Serialization.XmlSerializer s = new System.Xml.Serialization.XmlSerializer(typeof(CalculationOptionsRogue)); System.IO.StringReader sr = new System.IO.StringReader(xml); CalculationOptionsRogue calcOpts = s.Deserialize(sr) as CalculationOptionsRogue; return(calcOpts); }
private float CalcBaseDamage(float avgDamage, CalculationOptionsRogue calcOpts, Stats stats) { float baseDamage = avgDamage; baseDamage *= (1f + stats.BonusPhysicalDamageMultiplier) * (1f + stats.BonusDamageMultiplier); baseDamage *= (1f + Talents.HungerForBlood.Damage.Bonus) * (1f + Talents.Murder.Bonus); return(baseDamage); }
public void LoadCalculationOptions() { _loadingCalculationOptions = true; if (Character.CalculationOptions == null) Character.CalculationOptions = new CalculationOptionsRogue(); calcOpts = Character.CalculationOptions as CalculationOptionsRogue; // Model Specific Code // _loadingCalculationOptions = false; }
private void OnSelectedIndexChanged(object sender, EventArgs e) { CalculationOptionsRogue options = Character.CalculationOptions as CalculationOptionsRogue; ComboBox cb = (ComboBox)sender; string talent = cb.Name.Substring(8); options.SetTalentByName(talent, int.Parse(cb.SelectedItem.ToString())); if (!calculationSuspended) { Character.OnItemsChanged(); } }
public void LoadCalculationOptions() { _loadingCalculationOptions = true; if (Character.CalculationOptions == null) { Character.CalculationOptions = new CalculationOptionsRogue(); } calcOpts = Character.CalculationOptions as CalculationOptionsRogue; // Model Specific Code // _loadingCalculationOptions = false; }
public RogueRotationCalculator(Character character, Stats stats, BossOptions bossOpts, CalculationOptionsRogue calcOpts, float hasteBonus, float mainHandSpeed, float offHandSpeed, float mainHandSpeedNorm, float offHandSpeedNorm, float avoidedWhiteMHAttacks, float avoidedWhiteOHAttacks, float avoidedMHAttacks, float avoidedOHAttacks, float avoidedFinisherAttacks, float avoidedPoisonAttacks, float chanceExtraCPPerHit, RogueAbilityStats mainHandStats, RogueAbilityStats offHandStats, RogueAbilityStats ruptStats, RogueAbilityStats snDStats, RogueAbilityStats exposeStats, RogueAbilityStats iPStats, RogueAbilityStats dPStats, RogueAbilityStats wPStats) { Char = character; Talents = character.RogueTalents; Stats = stats; CalcOpts = calcOpts; BossOpts = bossOpts; HasteBonus = hasteBonus; MainHandSpeed = mainHandSpeed; OffHandSpeed = offHandSpeed; MainHandSpeedNorm = mainHandSpeedNorm; OffHandSpeedNorm = offHandSpeedNorm; AvoidedWhiteMHAttacks = avoidedWhiteMHAttacks; AvoidedWhiteOHAttacks = avoidedWhiteOHAttacks; AvoidedMHAttacks = avoidedMHAttacks; AvoidedOHAttacks = avoidedOHAttacks; AvoidedFinisherAttacks = avoidedFinisherAttacks; AvoidedPoisonAttacks = avoidedPoisonAttacks; ChanceExtraCPPerHit = chanceExtraCPPerHit; T411 = stats.Rogue_T11_4P; MainHandStats = mainHandStats; OffHandStats = offHandStats; RuptStats = ruptStats; SnDStats = snDStats; ExposeStats = exposeStats; IPStats = iPStats; DPStats = dPStats; WPStats = wPStats; #region Talent/Mastery bonuses StepVanishResetCD = RV.Talents.PreparationCD * Talents.Preparation; ChanceOnEnergyOnGarrRuptTick = RV.Talents.VenomousWoundsProcChance * Talents.VenomousWounds; ChanceOnNoDPConsumeOnEnvenom = RV.Talents.MasterPoisonerNoDPConsumeChance * Talents.MasterPoisoner; ChanceOnSnDResetOnEvisEnv = RV.Talents.CutToTheChaseMult[Talents.CutToTheChase]; ChanceOnRuptResetonEvisCP = RV.Talents.SerratedBladesChance * Talents.SerratedBlades; ExposeCPCostMult = RV.Talents.ImpExposeArmorCPMult * Talents.ImprovedExposeArmor; EnergyOnBelow35BS = RV.Talents.MurderousIntentEnergyRefund * Talents.MurderousIntent; EnergyRegenTimeOnDamagingCP = (RV.AR.Duration + (Talents.GlyphOfAdrenalineRush ? RV.Glyph.ARDurationBonus : 0f)) / RV.AR.CD * Talents.AdrenalineRush * RV.Talents.RestlessBladesPerCPCDReduc * Talents.RestlessBlades; EnergyOnOHAttack = RV.Talents.CombatPotencyProcChance * RV.Talents.CombatPotencyEnergyBonus * Talents.CombatPotency; EnergyOnRecupTick = RV.Talents.EnergeticRecoveryEnergyBonus * Talents.EnergeticRecovery; ChanceOnEnergyPerCPFinisher = RV.Talents.RelentlessStrikesPerCPChance[Talents.RelentlessStrikes]; CPOnFinisher = RV.Talents.RuthlessnessChance * Talents.Ruthlessness; RSBonus = (RV.RS.FinishMult + (Talents.GlyphOfRevealingStrike ? RV.Glyph.RSFinishMultBonus : 0f)) * Talents.RevealingStrike; ToTTCostReduction = (Talents.GlyphOfTricksOfTheTrade ? RV.Glyph.TotTCostReduc : 0f); VanishCDReduction = RV.Talents.ElusivenessVanishCDReduc * Talents.Elusiveness; #endregion }
public RogueRotationCalculator(Character character, Stats stats, BossOptions bossOpts, CalculationOptionsRogue calcOpts, float hasteBonus, float mainHandSpeed, float offHandSpeed, float mainHandSpeedNorm, float offHandSpeedNorm, float avoidedWhiteMHAttacks, float avoidedWhiteOHAttacks, float avoidedMHAttacks, float avoidedOHAttacks, float avoidedFinisherAttacks, float avoidedPoisonAttacks, float chanceExtraCPPerHit, RogueAbilityStats mainHandStats, RogueAbilityStats offHandStats, RogueAbilityStats ruptStats, RogueAbilityStats snDStats, RogueAbilityStats exposeStats, RogueAbilityStats iPStats, RogueAbilityStats dPStats, RogueAbilityStats wPStats) { Char = character; Talents = character.RogueTalents; Stats = stats; CalcOpts = calcOpts; BossOpts = bossOpts; HasteBonus = hasteBonus; MainHandSpeed = mainHandSpeed; OffHandSpeed = offHandSpeed; MainHandSpeedNorm = mainHandSpeedNorm; OffHandSpeedNorm = offHandSpeedNorm; AvoidedWhiteMHAttacks = avoidedWhiteMHAttacks; AvoidedWhiteOHAttacks = avoidedWhiteOHAttacks; AvoidedMHAttacks = avoidedMHAttacks; AvoidedOHAttacks = avoidedOHAttacks; AvoidedFinisherAttacks = avoidedFinisherAttacks; AvoidedPoisonAttacks = avoidedPoisonAttacks; ChanceExtraCPPerHit = chanceExtraCPPerHit; T411 = stats.Rogue_T11_4P; MainHandStats = mainHandStats; OffHandStats = offHandStats; RuptStats = ruptStats; SnDStats = snDStats; ExposeStats = exposeStats; IPStats = iPStats; DPStats = dPStats; WPStats = wPStats; #region Talent/Mastery bonuses StepVanishResetCD = RV.Talents.PreparationCD * Talents.Preparation; ChanceOnEnergyOnGarrRuptTick = RV.Talents.VenomousWoundsProcChance * Talents.VenomousWounds; ChanceOnNoDPConsumeOnEnvenom = RV.Talents.MasterPoisonerNoDPConsumeChance * Talents.MasterPoisoner; ChanceOnSnDResetOnEvisEnv = RV.Talents.CutToTheChaseMult[Talents.CutToTheChase]; ChanceOnRuptResetonEvisCP = RV.Talents.SerratedBladesChance * Talents.SerratedBlades; ExposeCPCostMult = RV.Talents.ImpExposeArmorCPMult * Talents.ImprovedExposeArmor; EnergyOnBelow35BS = RV.Talents.MurderousIntentEnergyRefund * Talents.MurderousIntent; EnergyRegenTimeOnDamagingCP = (RV.AR.Duration + (Talents.GlyphOfAdrenalineRush ? RV.Glyph.ARDurationBonus : 0f)) / RV.AR.CD * Talents.AdrenalineRush * RV.Talents.RestlessBladesPerCPCDReduc * Talents.RestlessBlades; EnergyOnOHAttack = RV.Talents.CombatPotencyProcChance * RV.Talents.CombatPotencyEnergyBonus * Talents.CombatPotency; EnergyOnRecupTick = RV.Talents.EnergeticRecoveryEnergyBonus * Talents.EnergeticRecovery; ChanceOnEnergyPerCPFinisher = RV.Talents.RelentlessStrikesPerCPChance[Talents.RelentlessStrikes]; CPOnFinisher = RV.Talents.RuthlessnessChance * Talents.Ruthlessness; RSBonus = (RV.RS.FinishMult + (Talents.GlyphOfRevealingStrike ? RV.Glyph.RSFinishMultBonus : 0f)) * Talents.RevealingStrike; ToTTCostReduction = (Talents.GlyphOfTricksOfTheTrade ? RV.Glyph.TotTCostReduc : 0f); VanishCDReduction = RV.Talents.ElusivenessVanishCDReduc * Talents.Elusiveness; #endregion }
private void trackBarTargetArmor_ValueChanged(object sender, EventArgs e) { if (!_loadingCalculationOptions) { CalculationOptionsRogue calcOpts = Character.CalculationOptions as CalculationOptionsRogue; trackBarTargetArmor.Value = 100 * (trackBarTargetArmor.Value / 100); labelTargetArmorDescription.Text = trackBarTargetArmor.Value.ToString() + (armorBosses.ContainsKey(trackBarTargetArmor.Value) ? armorBosses[trackBarTargetArmor.Value] : ""); calcOpts.TargetLevel = int.Parse(comboBoxTargetLevel.SelectedItem.ToString()); calcOpts.TargetArmor = trackBarTargetArmor.Value; Character.OnItemsChanged(); } }
protected override void LoadCalculationOptions() { _loadingCalculationOptions = true; if (Character.CalculationOptions == null) { Character.CalculationOptions = new CalculationOptionsRogue(Character); } CalculationOptionsRogue calcOpts = Character.CalculationOptions as CalculationOptionsRogue; comboBoxTargetLevel.SelectedItem = calcOpts.TargetLevel.ToString(); if (talents != null) { talents.LoadCalculationOptions(); } _loadingCalculationOptions = false; }
public RogueRotationCalculatorAss(Character character, Stats stats, BossOptions bossOpts, CalculationOptionsRogue calcOpts, float hasteBonus, float mainHandSpeed, float offHandSpeed, float mainHandSpeedNorm, float offHandSpeedNorm, float avoidedWhiteMHAttacks, float avoidedWhiteOHAttacks, float avoidedMHAttacks, float avoidedOHAttacks, float avoidedFinisherAttacks, float avoidedPoisonAttacks, float chanceExtraCPPerHit, float chanceExtraCPPerMutiHit, RogueAbilityStats mainHandStats, RogueAbilityStats offHandStats, RogueAbilityStats backstabStats, RogueAbilityStats mutiStats, RogueAbilityStats ruptStats, RogueAbilityStats envenomStats, RogueAbilityStats snDStats, RogueAbilityStats exposeStats, RogueAbilityStats iPStats, RogueAbilityStats dPStats, RogueAbilityStats wPStats, RogueAbilityStats venomousWoundsStats) : base (character, stats, bossOpts, calcOpts, hasteBonus, mainHandSpeed, offHandSpeed, mainHandSpeedNorm, offHandSpeedNorm, avoidedWhiteMHAttacks, avoidedWhiteOHAttacks, avoidedMHAttacks, avoidedOHAttacks, avoidedFinisherAttacks, avoidedPoisonAttacks, chanceExtraCPPerHit, mainHandStats, offHandStats, ruptStats, snDStats, exposeStats, iPStats, dPStats, wPStats) { BackstabStats = backstabStats; MutiStats = mutiStats; EnvenomStats = envenomStats; VenomousWoundsStats = venomousWoundsStats; ChanceExtraCPPerMutiHit = chanceExtraCPPerMutiHit; BonusMaxEnergy = (Char.MainHand == null || Char.OffHand == null ? false : Char.MainHand.Type == ItemType.Dagger && Char.MainHand.Type == ItemType.Dagger) ? RV.Mastery.AssassinsResolveEnergyBonus : 0f; BonusStealthEnergyRegen = RV.Talents.OverkillRegenMult * Talents.Overkill; DPFrequencyBonus = RV.Mastery.ImprovedPoisonsDPBonus; IPFrequencyMultiplier = RV.Mastery.ImprovedPoisonsIPFreqMult; #region Probability tables float c = ChanceExtraCPPerHit, h = (1f - c), f = CPOnFinisher, nf = (1f - f); _averageNormalCP[1] = 1 * (f + nf * h) + 2 * (nf * c); _averageNormalCP[2] = 2 * (f * h + nf * c + nf * h * h) + 3 * (f * c); _averageNormalCP[3] = 3 * (f * c + f * h * h + 2 * nf * c * h + nf * h * h * h) + 4 * (f * h * c + nf * c * c + nf * h * h * c); _averageNormalCP[4] = 4 * (2 * f * c * h + f * h * h * h + nf * c * c + 3 * nf * c * h * h + nf * h * h * h * h) + 5 * (f * c * c + f * h * h * c + 2 * nf * c * h * c + nf * h * h * h * c); _averageNormalCP[5] = 5 * (f * c * c + 3 * f * c * h * h + f * h * h * h * h + 3 * nf * c * c * h + 4 * nf * c * h * h * h + nf * h * h * h * h * h) + 6 * (2 * f * c * h * c + f * h * h * h * c + nf * c * c * c + 3 * nf * c * h * h * c + nf * h * h * h * h * c); c = ChanceExtraCPPerMutiHit; h = (1f - c); _averageMutiCP[1] = 1 * (f) + 2 * (nf * h) + 3 * (nf * c); _averageMutiCP[2] = 2 * (nf * h) + 3 * (f * h + nf * c) + 4 * (f * c); _averageMutiCP[3] = 3 * (f * h + nf * c) + 4 * (f * c + nf * h * h) + 5 * (nf * h * c); _averageMutiCP[4] = 4 * (f * c + nf * h * h) + 5 * (f * h * h + 2 * nf * h * c) + 5 * (f * h * c + nf * c * c); _averageMutiCP[5] = 5 * (f * h * h + 2 * nf * h * c) + 6 * (2 * f * h * c + nf * h * h * h + nf * c * c) + 7 * (f * c * c + nf * h * h * c); _avgMutiNeeded[1] = 1 * (nf); _avgMutiNeeded[2] = 1 * (f * h + f * c + nf * h + nf * c); _avgMutiNeeded[3] = 1 * (f * h + f * c + nf * c) + 2 * (nf * h); _avgMutiNeeded[4] = 1 * (f * c) + 2 * (f * h * h + f * h * c + nf * h * h + nf * h * c + nf * c); _avgMutiNeeded[5] = 2 * (f + nf * h * c + nf * c) + 3 * (nf * h * h); #endregion }
public RogueRotationCalculatorSubt(Character character, Stats stats, BossOptions bossOpts, CalculationOptionsRogue calcOpts, float hasteBonus, float mainHandSpeed, float offHandSpeed, float mainHandSpeedNorm, float offHandSpeedNorm, float avoidedWhiteMHAttacks, float avoidedWhiteOHAttacks, float avoidedMHAttacks, float avoidedOHAttacks, float avoidedFinisherAttacks, float avoidedPoisonAttacks, float chanceExtraCPPerHit, RogueAbilityStats mainHandStats, RogueAbilityStats offHandStats, RogueAbilityStats backstabStats, RogueAbilityStats hemoStats, RogueAbilityStats ruptStats, RogueAbilityStats evisStats, RogueAbilityStats snDStats, RogueAbilityStats recupStats, RogueAbilityStats exposeStats, RogueAbilityStats iPStats, RogueAbilityStats dPStats, RogueAbilityStats wPStats) : base(character, stats, bossOpts, calcOpts, hasteBonus, mainHandSpeed, offHandSpeed, mainHandSpeedNorm, offHandSpeedNorm, avoidedWhiteMHAttacks, avoidedWhiteOHAttacks, avoidedMHAttacks, avoidedOHAttacks, avoidedFinisherAttacks, avoidedPoisonAttacks, chanceExtraCPPerHit, mainHandStats, offHandStats, ruptStats, snDStats, exposeStats, iPStats, dPStats, wPStats) { BackstabStats = backstabStats; HemoStats = hemoStats; EvisStats = evisStats; RecupStats = recupStats; #region Probability tables float c = ChanceExtraCPPerHit, h = (1f - c), f = CPOnFinisher, nf = (1f - f); _averageNormalCP[1] = 1 * (f + nf * h) + 2 * (nf * c); _averageNormalCP[2] = 2 * (f * h + nf * c + nf * h * h) + 3 * (f * c); _averageNormalCP[3] = 3 * (f * c + f * h * h + 2 * nf * c * h + nf * h * h * h) + 4 * (f * h * c + nf * c * c + nf * h * h * c); _averageNormalCP[4] = 4 * (2 * f * c * h + f * h * h * h + nf * c * c + 3 * nf * c * h * h + nf * h * h * h * h) + 5 * (f * c * c + f * h * h * c + 2 * nf * c * h * c + nf * h * h * h * c); _averageNormalCP[5] = 5 * (f * c * c + 3 * f * c * h * h + f * h * h * h * h + 3 * nf * c * c * h + 4 * nf * c * h * h * h + nf * h * h * h * h * h) + 6 * (2 * f * c * h * c + f * h * h * h * c + nf * c * c * c + 3 * nf * c * h * h * c + nf * h * h * h * h * c); #endregion }
/// <summary> /// Calculate damage output /// </summary> /// <param name="character"></param> /// <param name="additionalItem"></param> /// <returns></returns> /// Much of this code is based on Aldriana's RogueCalc /// public override CharacterCalculationsBase GetCharacterCalculations(Character character, Item additionalItem) { float energyCPG, numCPG, sndLength, finisherCost, sndEnergy, sndHaste, cycleTime, energyRegen, ruthlessnessCP; float totalHaste; string cpg; float missChance, mhDodgeChance, ohDodgeChance, glanceChance, mhExpertise, ohExpertise, mhCrit, ohCrit, probMHHit, probOHHit; float mhHastedSpeed, ohHastedSpeed, avgMHDmg, avgOHDmg, totalArmor; float mhAttacks, ohAttacks, ohHits, ssHits, wfHits, avgWFDmg; float whiteDPS, finisherDPS, wfDPS, ssDPS, poisonDPS, cpgDPS; float mhWhite, ohWhite, damageReduction, bonusWhiteCritDmg; float avgCPGDmg, bonusCPGCrit, bonusCPGDmgMult, bonusCPGCritDmgMult, cpgCrit; float finisherDmg, evisMod, evisMin, evisMax; float probPoison; bool calcDeadly; CalculationOptionsRogue calcOpts = character.CalculationOptions as CalculationOptionsRogue; Stats stats = GetCharacterStats(character, additionalItem); CharacterCalculationsRogue calculatedStats = new CharacterCalculationsRogue(); calculatedStats.BasicStats = stats; whiteDPS = finisherDPS = wfDPS = ssDPS = poisonDPS = cpgDPS = 0f; missChance = 28f; missChance -= calcOpts.Precision + stats.Hit + stats.HitRating * RogueConversions.HitRatingToHit; if (missChance < 0f) { missChance = 0f; } mhExpertise = ohExpertise = calcOpts.WeaponExpertise * 5f + stats.Expertise + stats.ExpertiseRating * RogueConversions.ExpertiseRatingToExpertise; if (character.Race == Character.CharacterRace.Human) { if (character.MainHand != null && (character.MainHand.Type == Item.ItemType.OneHandSword || character.MainHand.Type == Item.ItemType.OneHandMace)) { mhExpertise += 5f; } if (character.OffHand != null && (character.OffHand.Type == Item.ItemType.OneHandSword || character.OffHand.Type == Item.ItemType.OneHandMace)) { ohExpertise += 5f; } } mhDodgeChance = 6.5f; mhDodgeChance -= .25f * mhExpertise; ohDodgeChance = 6.5f; ohDodgeChance -= .25f * ohExpertise; if (mhDodgeChance < 0f) { mhDodgeChance = 0f; } if (ohDodgeChance < 0f) { ohDodgeChance = 0f; } probMHHit = 1f - missChance / 100f - mhDodgeChance / 100f; probOHHit = 1f - missChance / 100f - ohDodgeChance / 100f; glanceChance = .25f; mhCrit = ohCrit = stats.Crit + stats.CritRating * RogueConversions.CritRatingToCrit; if (character.MainHand != null && character.MainHand.Type == Item.ItemType.Dagger) { mhCrit += calcOpts.DaggerSpecialization; } if (character.OffHand != null && character.OffHand.Type == Item.ItemType.Dagger) { ohCrit += calcOpts.DaggerSpecialization; } if (character.MainHand != null && character.MainHand.Type == Item.ItemType.FistWeapon) { mhCrit += calcOpts.FistSpecialization; } if (character.OffHand != null && character.OffHand.Type == Item.ItemType.FistWeapon) { ohCrit += calcOpts.FistSpecialization; } // if we have mutilate and we're using two daggers, assume we use it to generate CPs if (calcOpts.Mutilate > 0 && character.MainHand != null && character.MainHand.Type == Item.ItemType.Dagger && character.OffHand != null && character.OffHand.Type == Item.ItemType.Dagger) { cpg = "mutilate"; energyCPG = 60f; } // if we're main handing a dagger, assume we're using backstab it to generate CPs else if (character.MainHand != null && character.MainHand.Type == Item.ItemType.Dagger) { cpg = "backstab"; energyCPG = 60f; } // if we have hemo, assume we use it to generate CPs else if (calcOpts.Hemorrhage > 0) { cpg = "hemo"; energyCPG = 35f; } // otherwise use sinister strike else { cpg = "ss"; switch (calcOpts.ImprovedSinisterStrike) { case 2: energyCPG = 40f; break; case 1: energyCPG = 42f; break; default: energyCPG = 45f; break; } } // cycle stuff sndLength = 6f + 3f * calcOpts.DPSCycle['s']; sndLength += stats.BonusSnDDuration; sndLength *= 1f + 0.15f * calcOpts.ImprovedSliceandDice; ruthlessnessCP = .2f * calcOpts.Ruthlessness; numCPG = calcOpts.DPSCycle.TotalComboPoints - 2f * ruthlessnessCP; if (calcOpts.DPSCycle['r'] > 0) { finisherCost = 25f; } else if (calcOpts.DPSCycle['e'] > 0) { finisherCost = 35f; } else { finisherCost = 0f; } energyRegen = 10f; if (calcOpts.AdrenalineRush > 0) { energyRegen += .5f; } sndEnergy = (calcOpts.DPSCycle['s'] - ruthlessnessCP) * energyCPG + 25f; sndHaste = .3f; sndHaste *= (1f + stats.BonusSnDHaste); totalArmor = calcOpts.TargetArmor - stats.ArmorPenetration; damageReduction = 1f - (totalArmor / (totalArmor + 10557.5f)); #region White Damage whiteDPS = mhWhite = ohWhite = 0f; totalHaste = 1f; totalHaste *= (1f + sndHaste) * (1f + (stats.HasteRating * RogueConversions.HasteRatingToHaste) / 100); totalHaste *= (1f + .2f * 15f / 120f * calcOpts.BladeFlurry); bonusWhiteCritDmg = 1f + stats.BonusCritMultiplier; // MH mhAttacks = 0f; avgMHDmg = 0f; ohHits = 0f; if (character.MainHand != null) { avgMHDmg = (character.MainHand.MinDamage + character.MainHand.MaxDamage + stats.WeaponDamage * 2) / 2.0f; avgMHDmg += (stats.AttackPower / 14.0f) * character.MainHand.Speed; //mhHastedSpeed = character.MainHand.Speed / totalHaste; mhAttacks = totalHaste / character.MainHand.Speed; mhWhite = avgMHDmg * mhAttacks * probMHHit; mhWhite = (1f - mhCrit / 100f) * mhWhite + (mhCrit / 100f) * (mhWhite * (2f * bonusWhiteCritDmg)); mhWhite *= damageReduction; } // OH ohAttacks = 0f; if (character.OffHand != null) { avgOHDmg = (character.OffHand.MinDamage + character.OffHand.MaxDamage + stats.WeaponDamage * 2) / 2.0f; avgOHDmg += (stats.AttackPower / 14.0f) * character.OffHand.Speed; avgOHDmg *= (0.25f + calcOpts.DualWieldSpecialization * 0.1f); ohAttacks = totalHaste / character.OffHand.Speed; ohHits = ohAttacks * probOHHit; energyRegen += (.2f * 3f * calcOpts.CombatPotency) * ohHits; ohWhite = avgOHDmg * ohHits; ohWhite = (1f - ohCrit / 100f) * ohWhite + (ohCrit / 100f) * (ohWhite * (2f * bonusWhiteCritDmg)); ohWhite *= damageReduction; } cycleTime = (numCPG * energyCPG + 25f + finisherCost) / energyRegen; #region CPG Damage cpgDPS = 0f; if (character.MainHand != null) { avgCPGDmg = 0f; cpgCrit = 0f; bonusCPGCrit = 0f; bonusCPGDmgMult = 1f; bonusCPGCritDmgMult = 2f; if (cpg == "mutilate" && character.OffHand != null) { bonusCPGCrit += 5f * calcOpts.PuncturingWounds; bonusCPGCritDmgMult *= (1f + .06f * calcOpts.Lethality); bonusCPGDmgMult *= (1f + 0.04f * calcOpts.Opportunity); avgCPGDmg = (character.MainHand.MinDamage + character.MainHand.MaxDamage) / 2f + 121.5f; avgCPGDmg += stats.AttackPower / 14f * 1.7f; avgCPGDmg += (character.OffHand.MinDamage + character.OffHand.MaxDamage) / 2f + 121.5f; avgCPGDmg += stats.AttackPower / 14f * 1.7f; avgCPGDmg *= 1.5f; } else if (cpg == "backstab") { bonusCPGDmgMult *= (1f + .02f * calcOpts.Aggression); bonusCPGDmgMult *= (1f + .1f * calcOpts.SurpriseAttacks); bonusCPGDmgMult *= (1f + 0.04f * calcOpts.Opportunity); bonusCPGCrit += 10f * calcOpts.PuncturingWounds; bonusCPGCritDmgMult *= (1f + .06f * calcOpts.Lethality); avgCPGDmg = (character.MainHand.MinDamage + character.MainHand.MaxDamage + stats.WeaponDamage) / 2f; avgCPGDmg += stats.AttackPower / 14f * 1.7f; avgCPGDmg *= 1.5f; avgCPGDmg += 255f; } else if (cpg == "hemo") { bonusCPGDmgMult *= (1f + .1f * calcOpts.SurpriseAttacks); bonusCPGDmgMult *= (1f + stats.BonusCPGDamage); bonusCPGCritDmgMult *= (1f + .06f * calcOpts.Lethality); avgCPGDmg = (character.MainHand.MinDamage + character.MainHand.MaxDamage + stats.WeaponDamage) / 2f; avgCPGDmg += stats.AttackPower / 14f * 2.4f; avgCPGDmg *= 1.1f; } else { // sinister strike avgCPGDmg = (character.MainHand.MinDamage + character.MainHand.MaxDamage + stats.WeaponDamage) / 2f; avgCPGDmg += stats.AttackPower / 14f * 2.4f; avgCPGDmg += 98f; // TBC max rank bonusCPGDmgMult *= (1f + .02f * calcOpts.Aggression); bonusCPGDmgMult *= (1f + .1f * calcOpts.SurpriseAttacks); bonusCPGDmgMult *= (1f + stats.BonusCPGDamage); bonusCPGCritDmgMult *= (1f + .06f * calcOpts.Lethality); } avgCPGDmg *= bonusCPGDmgMult; cpgCrit = mhCrit + bonusCPGCrit; avgCPGDmg = (1f - cpgCrit / 100f) * avgCPGDmg + (cpgCrit / 100f) * (avgCPGDmg * bonusCPGCritDmgMult); cpgDPS = avgCPGDmg * numCPG / cycleTime; cpgDPS *= damageReduction; } #endregion #region Finisher Damage finisherDPS = 0f; if (character.MainHand != null) { if (calcOpts.DPSCycle['r'] > 0) { switch (calcOpts.DPSCycle['r']) { case 5: finisherDmg = 4f * (stats.AttackPower * .01f + 81f); break; case 4: finisherDmg = 5f * (stats.AttackPower * 0.02f + 92f); break; case 3: finisherDmg = 6f * (stats.AttackPower * 0.03f + 103f); break; case 2: finisherDmg = 7f * (stats.AttackPower * 0.03f + 114f); break; default: finisherDmg = 8f * (stats.AttackPower * 0.03f + 125f); break; } finisherDmg *= (1f + .1f * calcOpts.SerratedBlades) * (1f + stats.BonusBleedDamageMultiplier); finisherDmg *= (1f - missChance / 100f); if (calcOpts.SurpriseAttacks < 1) { finisherDmg *= (1f - mhDodgeChance / 100f); } finisherDPS = finisherDmg / cycleTime; } else if (calcOpts.DPSCycle['e'] > 0) { evisMod = stats.AttackPower * calcOpts.DPSCycle['e'] * .03f; evisMin = 245f + (calcOpts.DPSCycle['e'] - 1f) * 185f + evisMod; evisMax = 365f + (calcOpts.DPSCycle['e'] - 1f) * 185f + evisMod; finisherDmg = (evisMin + evisMax) / 2f; finisherDmg *= (1f + 0.05f * calcOpts.ImprovedEviscerate); finisherDmg *= (1f + 0.02f * calcOpts.Aggression); finisherDmg = finisherDmg * (1f - (mhCrit / 100f)) + (finisherDmg * 2f) * (mhCrit / 100f); finisherDmg *= (1f - (missChance / 100f)); if (calcOpts.SurpriseAttacks < 1) { finisherDmg *= (1f - (mhDodgeChance / 100f)); } finisherDmg *= damageReduction; finisherDPS = finisherDmg / cycleTime; } else { } } #endregion #region Sword Spec Damage ssDPS = 0f; ssHits = 0f; // main hand if (character.MainHand != null && character.MainHand.Type == Item.ItemType.OneHandSword) { ssHits += mhAttacks * 0.01f * calcOpts.SwordSpecialization * probMHHit; // CPG ssHits += (numCPG / cycleTime) * 0.01f * calcOpts.SwordSpecialization * probMHHit; // finishers ssHits += 1f / cycleTime * 0.01f * calcOpts.SwordSpecialization * probMHHit; } // offhand if (character.OffHand != null && character.OffHand.Type == Item.ItemType.OneHandSword) { ssHits += ohAttacks * 0.01f * calcOpts.SwordSpecialization * probOHHit; } ssDPS = (ssHits * avgMHDmg) * (1 - mhCrit / 100f) + (ssHits * avgMHDmg * 2f * bonusWhiteCritDmg) * (mhCrit / 100f); ssDPS *= damageReduction; #endregion #region WF Damage wfDPS = 0f; if (character.MainHand != null && stats.WindfuryAPBonus > 0) { wfHits = mhAttacks * probMHHit * .2f * probMHHit; wfHits += ssHits * .2f * probMHHit; avgWFDmg = (character.MainHand.MinDamage + character.MainHand.MaxDamage + stats.WeaponDamage * 2) / 2.0f; avgWFDmg += (stats.AttackPower + stats.WindfuryAPBonus) / 14f * character.MainHand.Speed; avgWFDmg = avgWFDmg * (1f - mhCrit / 100f) + avgMHDmg * 2f * (mhCrit / 100f); wfDPS = avgWFDmg * wfHits; wfDPS *= damageReduction; } #endregion whiteDPS = mhWhite + ohWhite; #endregion #region Poison DPS poisonDPS = 0f; probPoison = (.83f + .05f * calcOpts.MasterPoisoner) * (.2f + .02f * calcOpts.ImprovedPoisons); calcDeadly = true; if (character.MainHand != null && stats.WindfuryAPBonus == 0f) { // no WF, consider the main hand poison if (calcOpts.TempMainHandEnchant == "Deadly Poison" && calcDeadly) { poisonDPS += 180f * calcOpts.VilePoisons * .04f / 12f; calcDeadly = false; } else if (calcOpts.TempMainHandEnchant == "Instant Poison") { poisonDPS += ohHits * probPoison * 170f * (1f + calcOpts.VilePoisons * 0.04f); } } if (character.OffHand != null) { if (calcOpts.TempOffHandEnchant == "Deadly Poison" && calcDeadly) { poisonDPS += 180f * (1f + calcOpts.VilePoisons * .04f) / 12f; calcDeadly = false; } else if (calcOpts.TempOffHandEnchant == "Instant Poison") { poisonDPS += ohHits * probPoison * 170f * (1f + calcOpts.VilePoisons * 0.04f); } } #endregion calculatedStats.WhiteDPS = whiteDPS + ssDPS; calculatedStats.CPGDPS = cpgDPS; calculatedStats.FinisherDPS = finisherDPS; calculatedStats.WindfuryDPS = wfDPS; calculatedStats.SwordSpecDPS = ssDPS; calculatedStats.PoisonDPS = poisonDPS; calculatedStats.DPSPoints = whiteDPS + cpgDPS + finisherDPS + wfDPS + ssDPS + poisonDPS; calculatedStats.OverallPoints = calculatedStats.DPSPoints; return(calculatedStats); }
public RogueRotationCalculatorSubt(Character character, Stats stats, BossOptions bossOpts, CalculationOptionsRogue calcOpts, float hasteBonus, float mainHandSpeed, float offHandSpeed, float mainHandSpeedNorm, float offHandSpeedNorm, float avoidedWhiteMHAttacks, float avoidedWhiteOHAttacks, float avoidedMHAttacks, float avoidedOHAttacks, float avoidedFinisherAttacks, float avoidedPoisonAttacks, float chanceExtraCPPerHit, RogueAbilityStats mainHandStats, RogueAbilityStats offHandStats, RogueAbilityStats backstabStats, RogueAbilityStats hemoStats, RogueAbilityStats ruptStats, RogueAbilityStats evisStats, RogueAbilityStats snDStats, RogueAbilityStats recupStats, RogueAbilityStats exposeStats, RogueAbilityStats iPStats, RogueAbilityStats dPStats, RogueAbilityStats wPStats) : base(character, stats, bossOpts, calcOpts, hasteBonus, mainHandSpeed, offHandSpeed, mainHandSpeedNorm, offHandSpeedNorm, avoidedWhiteMHAttacks, avoidedWhiteOHAttacks, avoidedMHAttacks, avoidedOHAttacks, avoidedFinisherAttacks, avoidedPoisonAttacks, chanceExtraCPPerHit, mainHandStats, offHandStats, ruptStats, snDStats, exposeStats, iPStats, dPStats, wPStats) { BackstabStats = backstabStats; HemoStats = hemoStats; EvisStats = evisStats; RecupStats = recupStats; #region Probability tables float c = ChanceExtraCPPerHit, h = (1f - c), f = CPOnFinisher, nf = (1f - f); _averageNormalCP[1] = 1 * (f + nf * h) + 2 * (nf * c); _averageNormalCP[2] = 2 * (f * h + nf * c + nf * h * h) + 3 * (f * c); _averageNormalCP[3] = 3 * (f * c + f * h * h + 2 * nf * c * h + nf * h * h * h) + 4 * (f * h * c + nf * c * c + nf * h * h * c); _averageNormalCP[4] = 4 * (2 * f * c * h + f * h * h * h + nf * c * c + 3 * nf * c * h * h + nf * h * h * h * h) + 5 * (f * c * c + f * h * h * c + 2 * nf * c * h * c + nf * h * h * h * c); _averageNormalCP[5] = 5 * (f * c * c + 3 * f * c * h * h + f * h * h * h * h + 3 * nf * c * c * h + 4 * nf * c * h * h * h + nf * h * h * h * h * h) + 6 * (2 * f * c * h * c + f * h * h * h * c + nf * c * c * c + 3 * nf * c * h * h * c + nf * h * h * h * h * c); #endregion }
public RogueRotationCalculatorAss(Character character, Stats stats, BossOptions bossOpts, CalculationOptionsRogue calcOpts, float hasteBonus, float mainHandSpeed, float offHandSpeed, float mainHandSpeedNorm, float offHandSpeedNorm, float avoidedWhiteMHAttacks, float avoidedWhiteOHAttacks, float avoidedMHAttacks, float avoidedOHAttacks, float avoidedFinisherAttacks, float avoidedPoisonAttacks, float chanceExtraCPPerHit, float chanceExtraCPPerMutiHit, RogueAbilityStats mainHandStats, RogueAbilityStats offHandStats, RogueAbilityStats backstabStats, RogueAbilityStats mutiStats, RogueAbilityStats ruptStats, RogueAbilityStats envenomStats, RogueAbilityStats snDStats, RogueAbilityStats exposeStats, RogueAbilityStats iPStats, RogueAbilityStats dPStats, RogueAbilityStats wPStats, RogueAbilityStats venomousWoundsStats) : base(character, stats, bossOpts, calcOpts, hasteBonus, mainHandSpeed, offHandSpeed, mainHandSpeedNorm, offHandSpeedNorm, avoidedWhiteMHAttacks, avoidedWhiteOHAttacks, avoidedMHAttacks, avoidedOHAttacks, avoidedFinisherAttacks, avoidedPoisonAttacks, chanceExtraCPPerHit, mainHandStats, offHandStats, ruptStats, snDStats, exposeStats, iPStats, dPStats, wPStats) { BackstabStats = backstabStats; MutiStats = mutiStats; EnvenomStats = envenomStats; VenomousWoundsStats = venomousWoundsStats; ChanceExtraCPPerMutiHit = chanceExtraCPPerMutiHit; BonusMaxEnergy = (Char.MainHand == null || Char.OffHand == null ? false : Char.MainHand.Type == ItemType.Dagger && Char.MainHand.Type == ItemType.Dagger) ? RV.Mastery.AssassinsResolveEnergyBonus : 0f; BonusStealthEnergyRegen = RV.Talents.OverkillRegenMult * Talents.Overkill; DPFrequencyBonus = RV.Mastery.ImprovedPoisonsDPBonus; IPFrequencyMultiplier = RV.Mastery.ImprovedPoisonsIPFreqMult; #region Probability tables float c = ChanceExtraCPPerHit, h = (1f - c), f = CPOnFinisher, nf = (1f - f); _averageNormalCP[1] = 1 * (f + nf * h) + 2 * (nf * c); _averageNormalCP[2] = 2 * (f * h + nf * c + nf * h * h) + 3 * (f * c); _averageNormalCP[3] = 3 * (f * c + f * h * h + 2 * nf * c * h + nf * h * h * h) + 4 * (f * h * c + nf * c * c + nf * h * h * c); _averageNormalCP[4] = 4 * (2 * f * c * h + f * h * h * h + nf * c * c + 3 * nf * c * h * h + nf * h * h * h * h) + 5 * (f * c * c + f * h * h * c + 2 * nf * c * h * c + nf * h * h * h * c); _averageNormalCP[5] = 5 * (f * c * c + 3 * f * c * h * h + f * h * h * h * h + 3 * nf * c * c * h + 4 * nf * c * h * h * h + nf * h * h * h * h * h) + 6 * (2 * f * c * h * c + f * h * h * h * c + nf * c * c * c + 3 * nf * c * h * h * c + nf * h * h * h * h * c); c = ChanceExtraCPPerMutiHit; h = (1f - c); _averageMutiCP[1] = 1 * (f) + 2 * (nf * h) + 3 * (nf * c); _averageMutiCP[2] = 2 * (nf * h) + 3 * (f * h + nf * c) + 4 * (f * c); _averageMutiCP[3] = 3 * (f * h + nf * c) + 4 * (f * c + nf * h * h) + 5 * (nf * h * c); _averageMutiCP[4] = 4 * (f * c + nf * h * h) + 5 * (f * h * h + 2 * nf * h * c) + 5 * (f * h * c + nf * c * c); _averageMutiCP[5] = 5 * (f * h * h + 2 * nf * h * c) + 6 * (2 * f * h * c + nf * h * h * h + nf * c * c) + 7 * (f * c * c + nf * h * h * c); _avgMutiNeeded[1] = 1 * (nf); _avgMutiNeeded[2] = 1 * (f * h + f * c + nf * h + nf * c); _avgMutiNeeded[3] = 1 * (f * h + f * c + nf * c) + 2 * (nf * h); _avgMutiNeeded[4] = 1 * (f * c) + 2 * (f * h * h + f * h * c + nf * h * h + nf * h * c + nf * c); _avgMutiNeeded[5] = 2 * (f + nf * h * c + nf * c) + 3 * (nf * h * h); #endregion }
public static void LoadTalentCode(Character c, string talentCode) { if (talentCode == null || talentCode.Length != 67) { return; } CalculationOptionsRogue calcOpts = c.CalculationOptions as CalculationOptionsRogue; calcOpts.ImprovedEviscerate = int.Parse(talentCode.Substring(0, 1)); calcOpts.RemorselessAttacks = int.Parse(talentCode.Substring(1, 1)); calcOpts.Malice = int.Parse(talentCode.Substring(2, 1)); calcOpts.Ruthlessness = int.Parse(talentCode.Substring(3, 1)); calcOpts.Murder = int.Parse(talentCode.Substring(4, 1)); calcOpts.PuncturingWounds = int.Parse(talentCode.Substring(5, 1)); calcOpts.RelentlessStrikes = int.Parse(talentCode.Substring(6, 1)); calcOpts.ImprovedExposeArmor = int.Parse(talentCode.Substring(7, 1)); calcOpts.Lethality = int.Parse(talentCode.Substring(8, 1)); calcOpts.VilePoisons = int.Parse(talentCode.Substring(9, 1)); calcOpts.ImprovedPoisons = int.Parse(talentCode.Substring(10, 1)); calcOpts.FleetFooted = int.Parse(talentCode.Substring(11, 1)); calcOpts.ColdBlood = int.Parse(talentCode.Substring(12, 1)); calcOpts.ImprovedKidneyShot = int.Parse(talentCode.Substring(13, 1)); calcOpts.QuickRecovery = int.Parse(talentCode.Substring(14, 1)); calcOpts.SealFate = int.Parse(talentCode.Substring(15, 1)); calcOpts.MasterPoisoner = int.Parse(talentCode.Substring(16, 1)); calcOpts.Vigor = int.Parse(talentCode.Substring(17, 1)); calcOpts.DeadenedNerves = int.Parse(talentCode.Substring(18, 1)); calcOpts.FindWeakness = int.Parse(talentCode.Substring(19, 1)); calcOpts.Mutilate = int.Parse(talentCode.Substring(20, 1)); calcOpts.ImprovedGouge = int.Parse(talentCode.Substring(21, 1)); calcOpts.ImprovedSinisterStrike = int.Parse(talentCode.Substring(22, 1)); calcOpts.LightningReflexes = int.Parse(talentCode.Substring(23, 1)); calcOpts.ImprovedSliceandDice = int.Parse(talentCode.Substring(24, 1)); calcOpts.Deflection = int.Parse(talentCode.Substring(25, 1)); calcOpts.Precision = int.Parse(talentCode.Substring(26, 1)); calcOpts.Endurance = int.Parse(talentCode.Substring(27, 1)); calcOpts.Riposte = int.Parse(talentCode.Substring(28, 1)); calcOpts.ImprovedSprint = int.Parse(talentCode.Substring(29, 1)); calcOpts.ImprovedKick = int.Parse(talentCode.Substring(30, 1)); calcOpts.DaggerSpecialization = int.Parse(talentCode.Substring(31, 1)); calcOpts.DualWieldSpecialization = int.Parse(talentCode.Substring(32, 1)); calcOpts.MaceSpecialization = int.Parse(talentCode.Substring(33, 1)); calcOpts.BladeFlurry = int.Parse(talentCode.Substring(34, 1)); calcOpts.SwordSpecialization = int.Parse(talentCode.Substring(35, 1)); calcOpts.FistSpecialization = int.Parse(talentCode.Substring(36, 1)); calcOpts.BladeTwisting = int.Parse(talentCode.Substring(37, 1)); calcOpts.WeaponExpertise = int.Parse(talentCode.Substring(38, 1)); calcOpts.Aggression = int.Parse(talentCode.Substring(39, 1)); calcOpts.Vitality = int.Parse(talentCode.Substring(40, 1)); calcOpts.AdrenalineRush = int.Parse(talentCode.Substring(41, 1)); calcOpts.NervesOfSteel = int.Parse(talentCode.Substring(42, 1)); calcOpts.CombatPotency = int.Parse(talentCode.Substring(43, 1)); calcOpts.SurpriseAttacks = int.Parse(talentCode.Substring(44, 1)); calcOpts.MasterOfDeception = int.Parse(talentCode.Substring(45, 1)); calcOpts.Opportunity = int.Parse(talentCode.Substring(46, 1)); calcOpts.SleightOfHand = int.Parse(talentCode.Substring(47, 1)); calcOpts.DirtyTricks = int.Parse(talentCode.Substring(48, 1)); calcOpts.Camouflage = int.Parse(talentCode.Substring(49, 1)); calcOpts.Initiative = int.Parse(talentCode.Substring(50, 1)); calcOpts.GhostlyStrike = int.Parse(talentCode.Substring(51, 1)); calcOpts.ImprovedAmbush = int.Parse(talentCode.Substring(52, 1)); calcOpts.Setup = int.Parse(talentCode.Substring(53, 1)); calcOpts.Elusiveness = int.Parse(talentCode.Substring(54, 1)); calcOpts.SerratedBlades = int.Parse(talentCode.Substring(55, 1)); calcOpts.HeightenedSenses = int.Parse(talentCode.Substring(56, 1)); calcOpts.Preparation = int.Parse(talentCode.Substring(57, 1)); calcOpts.DirtyDeeds = int.Parse(talentCode.Substring(58, 1)); calcOpts.Hemorrhage = int.Parse(talentCode.Substring(59, 1)); calcOpts.MasterOfSubtlety = int.Parse(talentCode.Substring(60, 1)); calcOpts.Deadliness = int.Parse(talentCode.Substring(61, 1)); calcOpts.EnvelopingShadows = int.Parse(talentCode.Substring(62, 1)); calcOpts.Premeditation = int.Parse(talentCode.Substring(63, 1)); calcOpts.CheatDeath = int.Parse(talentCode.Substring(64, 1)); calcOpts.SinisterCalling = int.Parse(talentCode.Substring(65, 1)); calcOpts.Shadowstep = int.Parse(talentCode.Substring(66, 1)); }
public Stats GetBuffsStats(Character character, CalculationOptionsRogue calcOpts) { List<Buff> removedBuffs = new List<Buff>(); List<Buff> addedBuffs = new List<Buff>(); 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 RogueRotationCalculatorCombat(Character character, Stats stats, BossOptions bossOpts, CalculationOptionsRogue calcOpts, float hasteBonus, float mainHandSpeed, float offHandSpeed, float mainHandSpeedNorm, float offHandSpeedNorm, float avoidedWhiteMHAttacks, float avoidedWhiteOHAttacks, float avoidedMHAttacks, float avoidedOHAttacks, float avoidedFinisherAttacks, float avoidedPoisonAttacks, float chanceExtraCPPerHit, RogueAbilityStats mainHandStats, RogueAbilityStats offHandStats, RogueAbilityStats mainGaucheStats, RogueAbilityStats sStrikeStats, RogueAbilityStats rStrikeStats, RogueAbilityStats ruptStats, RogueAbilityStats evisStats, RogueAbilityStats snDStats, RogueAbilityStats exposeStats, RogueAbilityStats iPStats, RogueAbilityStats dPStats, RogueAbilityStats wPStats) : base(character, stats, bossOpts, calcOpts, hasteBonus, mainHandSpeed, offHandSpeed, mainHandSpeedNorm, offHandSpeedNorm, avoidedWhiteMHAttacks, avoidedWhiteOHAttacks, avoidedMHAttacks, avoidedOHAttacks, avoidedFinisherAttacks, avoidedPoisonAttacks, chanceExtraCPPerHit, mainHandStats, offHandStats, ruptStats, snDStats, exposeStats, iPStats, dPStats, wPStats) { SStrikeStats = sStrikeStats; RStrikeStats = rStrikeStats; EvisStats = evisStats; MainGaucheStats = mainGaucheStats; ChanceOnMGAttackOnMHAttack = RV.Mastery.MainGauche + RV.Mastery.MainGauchePerMast * StatConversion.GetMasteryFromRating(stats.MasteryRating); EnergyRegenMultiplier = (1f + RV.Mastery.VitalityRegenMult) * (1f + (RV.AR.Duration + (Talents.GlyphOfAdrenalineRush ? RV.Glyph.ARDurationBonus : 0f)) / RV.AR.CD * Talents.AdrenalineRush) * (1f + HasteBonus) - 1f; #region Probability tables float c = ChanceExtraCPPerHit, h = (1f - c), f = CPOnFinisher, nf = (1f - f); _averageNormalCP[1] = 1 * (f + nf * h) + 2 * (nf * c); _averageNormalCP[2] = 2 * (f * h + nf * c + nf * h * h) + 3 * (f * c); _averageNormalCP[3] = 3 * (f * c + f * h * h + 2 * nf * c * h + nf * h * h * h) + 4 * (f * h * c + nf * c * c + nf * h * h * c); _averageNormalCP[4] = 4 * (2 * f * c * h + f * h * h * h + nf * c * c + 3 * nf * c * h * h + nf * h * h * h * h) + 5 * (f * c * c + f * h * h * c + 2 * nf * c * h * c + nf * h * h * h * c); _averageNormalCP[5] = 5 * (f * c * c + 3 * f * c * h * h + f * h * h * h * h + 3 * nf * c * c * h + 4 * nf * c * h * h * h + nf * h * h * h * h * h) + 6 * (2 * f * c * h * c + f * h * h * h * c + nf * c * c * c + 3 * nf * c * h * h * c + nf * h * h * h * h * c); c = ChanceExtraCPPerHit + ChanceOnCPOnSSCrit * SStrikeStats.CritChance; h = (1f - c); _averageSStrikeCP[1] = 1 * (f + nf * h) + 2 * (nf * c); _averageSStrikeCP[2] = 2 * (f * h + nf * c + nf * h * h) + 3 * (f * c + nf * h * c); _averageSStrikeCP[3] = 3 * (f * c + f * h * h + 2 * nf * c * h + nf * h * h * h) + 4 * (f * h * c + nf * c * c + nf * h * h * c); _averageSStrikeCP[4] = 4 * (2 * f * c * h + f * h * h * h + nf * c * c + 3 * nf * c * h * h + nf * h * h * h * h) + 5 * (f * c * c + f * h * h * c + 2 * nf * c * h * c + nf * h * h * h * c); _averageSStrikeCP[5] = 5 * (f * c * c + 3 * f * c * h * h + f * h * h * h * h + 3 * nf * c * c * h + 4 * nf * c * h * h * h + nf * h * h * h * h * h) + 6 * (2 * f * c * h * c + f * h * h * h * c + nf * c * c * c + 3 * nf * c * h * h * c + nf * h * h * h * h * c); #endregion }
public RogueRotationCalculator(Character character, Stats stats, CalculationOptionsRogue calcOpts, bool maintainBleed, float mainHandSpeed, float offHandSpeed, float mainHandSpeedNorm, float offHandSpeedNorm, float avoidedWhiteMHAttacks, float avoidedWhiteOHAttacks, float avoidedMHAttacks, float avoidedOHAttacks, float avoidedFinisherAttacks, float avoidedPoisonAttacks, float chanceExtraCPPerHit, float chanceExtraCPPerMutiHit, RogueAbilityStats mainHandStats, RogueAbilityStats offHandStats, RogueAbilityStats backstabStats, RogueAbilityStats hemoStats, RogueAbilityStats sStrikeStats, RogueAbilityStats mutiStats, RogueAbilityStats ruptStats, RogueAbilityStats evisStats, RogueAbilityStats envenomStats, RogueAbilityStats snDStats, RogueAbilityStats iPStats, RogueAbilityStats dPStats, RogueAbilityStats wPStats, RogueAbilityStats aPStats) { Char = character; Stats = stats; CalcOpts = calcOpts; Duration = CalcOpts.Duration; MaintainBleed = maintainBleed; MainHandSpeed = mainHandSpeed; OffHandSpeed = offHandSpeed; MainHandSpeedNorm = mainHandSpeedNorm; OffHandSpeedNorm = offHandSpeedNorm; AvoidedWhiteMHAttacks = avoidedWhiteMHAttacks; AvoidedWhiteOHAttacks = avoidedWhiteOHAttacks; AvoidedMHAttacks = avoidedMHAttacks; AvoidedOHAttacks = avoidedOHAttacks; AvoidedFinisherAttacks = avoidedFinisherAttacks; AvoidedPoisonAttacks = avoidedPoisonAttacks; ChanceExtraCPPerHit = chanceExtraCPPerHit; ChanceExtraCPPerMutiHit = chanceExtraCPPerMutiHit; MainHandStats = mainHandStats; OffHandStats = offHandStats; BackstabStats = backstabStats; HemoStats = hemoStats; MutiStats = mutiStats; SStrikeStats = sStrikeStats; RuptStats = ruptStats; EnvenomStats = envenomStats; EvisStats = evisStats; SnDStats = snDStats; IPStats = iPStats; DPStats = dPStats; WPStats = wPStats; APStats = aPStats; #region Talent bonuses BonusFlurryHaste = 0.2f * Char.RogueTalents.BladeFlurry; BonusEnergyRegen = (15 + (Char.RogueTalents.GlyphOfAdrenalineRush ? 5f : 0f)) * Char.RogueTalents.AdrenalineRush; BonusEnergyRegenMultiplier = 0.08f * Char.RogueTalents.Vitality; BonusHemoDamageMultiplier = 0.1f * Char.RogueTalents.SurpriseAttacks + 0.02f * Char.RogueTalents.SinisterCalling; BonusIPFrequencyMultiplier = 0.1f * Char.RogueTalents.ImprovedPoisons; BonusMaxEnergy = (10 + (Char.RogueTalents.GlyphOfVigor ? 10 : 0)) * Char.RogueTalents.Vigor; BonusStealthEnergyRegen = 0.3f * Char.RogueTalents.Overkill; ChanceOnCPOnSSCrit = Char.RogueTalents.GlyphOfSinisterStrike ? 0.5f : 0f; ChanceOnEnergyOnCrit = 2f * (Char.RogueTalents.FocusedAttacks > 2 ? 1f : (0.33f * Char.RogueTalents.FocusedAttacks)); ChanceOnEnergyOnOHAttack = 3 * 0.2f * Char.RogueTalents.CombatPotency; ChanceOnEnergyPerCPFinisher = 0.04f * Char.RogueTalents.RelentlessStrikes; ChanceOnMHAttackOnSwordAxeHit = 0.01f * Char.RogueTalents.HackAndSlash; ChanceOnNoDPConsumeOnEnvenom = Char.RogueTalents.MasterPoisoner == 3 ? 1f : (0.33f * Char.RogueTalents.MasterPoisoner); ChanceOnSnDResetOnEnvenom = 0.2f * Char.RogueTalents.CutToTheChase; CPOnFinisher = 0.2f * Char.RogueTalents.Ruthlessness + 3f * Stats.ChanceOn3CPOnFinisher; FlurryCostReduction = Char.RogueTalents.GlyphOfBladeFlurry ? 25 : 0; ToTTCDReduction = 5 * Char.RogueTalents.FilthyTricks; ToTTCostReduction = 5 * Char.RogueTalents.FilthyTricks; VanishCDReduction = 30 * Char.RogueTalents.Elusiveness; #endregion #region Probability tables float c = ChanceExtraCPPerHit, h = (1f - c), f = CPOnFinisher, nf = (1f - f); _averageNormalCP[1] = 1 * (f + nf * h) + 2 * (nf * c); _averageNormalCP[2] = 2 * (f * h + nf * c + nf * h * h) + 3 * (f * c); _averageNormalCP[3] = 3 * (f * c + f * h * h + 2 * nf * c * h + nf * h * h * h) + 4 * (f * h * c + nf * c * c + nf * h * h * c); _averageNormalCP[4] = 4 * (2 * f * c * h + f * h * h * h + nf * c * c + 3 * nf * c * h * h + nf * h * h * h * h) + 5 * (f * c * c + f * h * h * c + 2 * nf * c * h * c + nf * h * h * h * c); _averageNormalCP[5] = 5 * (f * c * c + 3 * f * c * h * h + f * h * h * h * h + 3 * nf * c * c * h + 4 * nf * c * h * h * h + nf * h * h * h * h * h) + 6 * (2 * f * c * h * c + f * h * h * h * c + nf * c * c * c + 3 * nf * c * h * h * c + nf * h * h * h * h * c); c = ChanceExtraCPPerHit + ChanceOnCPOnSSCrit * SStrikeStats.CritChance; h = (1f - c); _averageSStrikeCP[1] = 1 * (f + nf * h) + 2 * (nf * c); _averageSStrikeCP[2] = 2 * (f * h + nf * c + nf * h * h) + 3 * (f * c + nf * h * c); _averageSStrikeCP[3] = 3 * (f * c + f * h * h + 2 * nf * c * h + nf * h * h * h) + 4 * (f * h * c + nf * c * c + nf * h * h * c); _averageSStrikeCP[4] = 4 * (2 * f * c * h + f * h * h * h + nf * c * c + 3 * nf * c * h * h + nf * h * h * h * h) + 5 * (f * c * c + f * h * h * c + 2 * nf * c * h * c + nf * h * h * h * c); _averageSStrikeCP[5] = 5 * (f * c * c + 3 * f * c * h * h + f * h * h * h * h + 3 * nf * c * c * h + 4 * nf * c * h * h * h + nf * h * h * h * h * h) + 6 * (2 * f * c * h * c + f * h * h * h * c + nf * c * c * c + 3 * nf * c * h * h * c + nf * h * h * h * h * c); c = ChanceExtraCPPerMutiHit; h = (1f - c); _averageMutiCP[1] = 1 * (f) + 2 * (nf * h) + 3 * (nf * c); _averageMutiCP[2] = 2 * (nf * h) + 3 * (f * h + nf * c) + 4 * (f * c); _averageMutiCP[3] = 3 * (f * h + nf * c) + 4 * (f * c + nf * h * h) + 5 * (nf * h * c); _averageMutiCP[4] = 4 * (f * c + nf * h * h) + 5 * (f * h * h + 2 * nf * h * c) + 5 * (f * h * c + nf * c * c); _averageMutiCP[5] = 5 * (f * h * h + 2 * nf * h * c) + 6 * (2 * f * h * c + nf * h * h * h + nf * c * c) + 7 * (f * c * c + nf * h * h * c); _avgMutiNeeded[1] = 1 * (nf); _avgMutiNeeded[2] = 1 * (f * h + f * c + nf * h + nf * c); _avgMutiNeeded[3] = 1 * (f * h + f * c + nf * c) + 2 * (nf * h); _avgMutiNeeded[4] = 1 * (f * c) + 2 * (f * h * h + f * h * c + nf * h * h + nf * h * c + nf * c); _avgMutiNeeded[5] = 2 * (f + nf * h * c + nf * c) + 3 * (nf * h * h); #endregion }
public override Stats GetCharacterStats(Character character, Item additionalItem) { CalculationOptionsRogue calcOpts = character.CalculationOptions as CalculationOptionsRogue; Stats statsRace; if (character.Race == Character.CharacterRace.Human) { statsRace = GetRaceStats(character.Race); } else { statsRace = GetRaceStats(character.Race); } Stats statsBaseGear = GetItemStats(character, additionalItem); Stats statsEnchants = GetEnchantsStats(character); Stats statsBuffs = GetBuffsStats(character.ActiveBuffs); // buffs from DPSWarr //Add Expose Weakness since it's not listed as an AP buff if (statsBuffs.ExposeWeakness > 0) { statsBuffs.AttackPower += 200f; } //Mongoose if (character.MainHand != null && character.MainHandEnchant != null && character.MainHandEnchant.Id == 2673) { statsBuffs.Agility += 120f * ((40f * (1f / (60f / character.MainHand.Speed)) / 6f)); statsBuffs.HasteRating += (15.76f * 2f) * ((40f * (1f / (60f / character.MainHand.Speed)) / 6f)); } if (character.OffHand != null && character.OffHandEnchant != null && character.OffHandEnchant.Id == 2673) { statsBuffs.Agility += 120f * ((40f * (1f / (60f / character.OffHand.Speed)) / 6f)); statsBuffs.HasteRating += (15.76f * 2f) * ((40f * (1f / (60f / character.OffHand.Speed)) / 6f)); } //Executioner if (character.MainHand != null && character.MainHandEnchant != null && character.MainHandEnchant.Id == 3225) { statsBuffs.ArmorPenetration += 840f * ((40f * (1f / (60f / character.MainHand.Speed)) / 6f)); } Stats statsGearEnchantsBuffs = statsBaseGear + statsEnchants + statsBuffs; TalentTree tree = character.Talents; float agiBase = (float)Math.Floor(statsRace.Agility * (1 + statsRace.BonusAgilityMultiplier)); float agiBonus = (float)Math.Floor(statsGearEnchantsBuffs.Agility * (1 + statsRace.BonusAgilityMultiplier)); float strBase = (float)Math.Floor(statsRace.Strength * (1 + statsRace.BonusStrengthMultiplier)); float strBonus = (float)Math.Floor(statsGearEnchantsBuffs.Strength * (1 + statsRace.BonusStrengthMultiplier)); float staBase = (float)Math.Floor(statsRace.Stamina * (1 + statsRace.BonusStaminaMultiplier)); float staBonus = (float)Math.Floor(statsGearEnchantsBuffs.Stamina * (1 + statsRace.BonusStaminaMultiplier)); Stats statsTotal = new Stats(); statsTotal.BonusAttackPowerMultiplier = ((1 + statsRace.BonusAttackPowerMultiplier) * (1 + statsGearEnchantsBuffs.BonusAttackPowerMultiplier) * (1 + calcOpts.Deadliness * 0.02f)) - 1; statsTotal.BonusAgilityMultiplier = ((1 + statsRace.BonusAgilityMultiplier) * (1 + statsGearEnchantsBuffs.BonusAgilityMultiplier) * (1 + calcOpts.Vitality * 0.01f) * (1 + calcOpts.SinisterCalling * 0.03f)) - 1; statsTotal.BonusStrengthMultiplier = ((1 + statsRace.BonusStrengthMultiplier) * (1 + statsGearEnchantsBuffs.BonusStrengthMultiplier)) - 1; statsTotal.BonusStaminaMultiplier = ((1 + statsRace.BonusStaminaMultiplier) * (1 + statsGearEnchantsBuffs.BonusStaminaMultiplier) * (1 + calcOpts.Vitality * 0.02f)) - 1; statsTotal.Agility = (float)Math.Floor(agiBase * (1f + statsTotal.BonusAgilityMultiplier)) + (float)Math.Floor(agiBonus * (1 + statsTotal.BonusAgilityMultiplier)); statsTotal.Strength = (float)Math.Floor(strBase * (1f + statsTotal.BonusStrengthMultiplier)) + (float)Math.Floor(strBonus * (1 + statsTotal.BonusStrengthMultiplier)); statsTotal.Stamina = (float)Math.Floor(staBase * (1f + statsTotal.BonusStaminaMultiplier)) + (float)Math.Floor(staBonus * (1 + statsTotal.BonusStaminaMultiplier)); statsTotal.Health = (float)Math.Round(((statsRace.Health + statsGearEnchantsBuffs.Health + ((statsTotal.Stamina - staBase) * 10f)))); statsTotal.AttackPower = (statsTotal.Agility + statsTotal.Strength + statsRace.AttackPower) + statsGearEnchantsBuffs.AttackPower; //statsTotal.AttackPower = statsRace.AttackPower + ((statsTotal.Agility - agiBase) + (statsTotal.Strength - strBase) + statsGearEnchantsBuffs.AttackPower) * (1f + statsTotal.BonusAttackPowerMultiplier); //statsTotal.AttackPower = (float)Math.Floor((statsRace.AttackPower + statsGearEnchantsBuffs.AttackPower + ((statsTotal.Strength - strBase) * 1) + ((statsTotal.Agility - agiBase) * 1)) * (1f + statsTotal.BonusAttackPowerMultiplier)); statsTotal.Hit = calcOpts.Precision; statsTotal.HitRating = statsGearEnchantsBuffs.HitRating; statsTotal.Expertise += calcOpts.WeaponExpertise * 5.0f; statsTotal.ExpertiseRating = statsGearEnchantsBuffs.ExpertiseRating; statsTotal.HasteRating = statsGearEnchantsBuffs.HasteRating; statsTotal.ArmorPenetration = statsGearEnchantsBuffs.ArmorPenetration; switch (calcOpts.SerratedBlades) { case 3: statsTotal.ArmorPenetration += 560; break; case 2: statsTotal.ArmorPenetration += 373; break; case 1: statsTotal.ArmorPenetration += 186; break; } statsTotal.CritRating = statsRace.CritRating + statsGearEnchantsBuffs.CritRating; statsTotal.Crit = statsRace.Crit; statsTotal.Crit += (statsTotal.Agility - (statsRace.Agility * (1f + statsTotal.BonusAgilityMultiplier))) * RogueConversions.AgilityToCrit; statsTotal.Crit += calcOpts.Malice * 1f; //statsTotal.CritRating += statsBuffs.LotPCritRating; statsTotal.Dodge += statsTotal.Agility * RogueConversions.AgilityToDodge; statsTotal.Dodge += calcOpts.LightningReflexes; statsTotal.Parry += calcOpts.Deflection; statsTotal.WeaponDamage = statsGearEnchantsBuffs.WeaponDamage; statsTotal.BonusBleedDamageMultiplier = statsGearEnchantsBuffs.BonusBleedDamageMultiplier; statsTotal.WindfuryAPBonus = statsGearEnchantsBuffs.WindfuryAPBonus; // T4 bonuses statsTotal.BonusSnDDuration = statsGearEnchantsBuffs.BonusSnDDuration; statsTotal.CPOnFinisher = statsGearEnchantsBuffs.CPOnFinisher; // T5 bonuses statsTotal.BonusEvisEnvenomDamage = statsGearEnchantsBuffs.BonusEvisEnvenomDamage; statsTotal.BonusFreeFinisher = statsGearEnchantsBuffs.BonusFreeFinisher; // T6 bonuses statsTotal.BonusCPGDamage = statsGearEnchantsBuffs.BonusCPGDamage; statsTotal.BonusSnDHaste = statsGearEnchantsBuffs.BonusSnDHaste; return(statsTotal); }