private ComparisonCalculationTree GetRelativeValue(Stats baseStats, int minMultiplier, int maxMultiplier, String label, Character character, CharacterCalculationsTree calcBaseValue) { ComparisonCalculationTree compCalc = null; Stats stats = new Stats(); for (int multiplier = minMultiplier; multiplier < maxMultiplier; multiplier++) { stats += baseStats; CharacterCalculationsTree calcValue = GetCharacterCalculations(character, new Item() { Stats = stats }) as CharacterCalculationsTree; if (compCalc == null || (compCalc.OverallPoints < (calcValue.OverallPoints - calcBaseValue.OverallPoints) / multiplier)) { compCalc = new ComparisonCalculationTree(label + "*" + multiplier) { OverallPoints = (calcValue.OverallPoints - calcBaseValue.OverallPoints) / multiplier, HpSPoints = (calcValue.HpSPoints - calcBaseValue.HpSPoints) / multiplier, Mp5Points = (calcValue.Mp5Points - calcBaseValue.Mp5Points) / multiplier, SurvivalPoints = (calcValue.SurvivalPoints - calcBaseValue.SurvivalPoints) / multiplier, ToLPoints = (calcValue.ToLPoints - calcBaseValue.ToLPoints) / multiplier, }; } } return(compCalc); }
public TreeSolver(Character character, CharacterCalculationsTree calc) { this.character = character; this.calc = calc; this.opts = (CalculationOptionsTree)character.CalculationOptions; if (opts == null) opts = new CalculationOptionsTree(); compute(); }
public Solver(CalculationOptionsTree calcOpts, CharacterCalculationsTree calculatedStats) { this.calcOpts = calcOpts; this.calculatedStats = calculatedStats; baseSpellCycles = CalculateBaseCycles(); if (baseSpellCycles.Count != 0) { baseRotations = CalculateBaseRotations(); bestRotation = GetBestRotation(); FightFraction = RotationMultiplier(bestRotation); InnervateMp5 = InnervateManaPerSecond(bestRotation) * 5f; MementoMp5 = MementoManaPerSecond(bestRotation) * 5f; ManaProcOnCastMp5 = ManaPerCastInManaPerSecond(bestRotation) * 5f; LessMana_15s_1m_Mp5 = LessManaPerCastInManaPerSecond(bestRotation) * 5f; BlueDragonMp5 = BlueDragonInManaPerSecond(bestRotation) * 5f; BangleMp5 = BangleInManaPerSecond(bestRotation) * 5f; HpS = bestRotation.healPerCycle / bestRotation.bestCycleDuration * FightFraction + // 1 proc / 50 sec (calculatedStats.BasicStats.ShatteredSunRestoProc > 0 && calcOpts.ShattrathFaction == "Scryer" ? (618 + 682) / 2f * (1 + calculatedStats.BasicStats.SpellCrit / 100f) / 50 : 0); } }
public override ComparisonCalculationBase[] GetCustomChartData(Character character, string chartName) { switch (chartName) { case "Relative Stat Values (Bigger Picture)": int multiplier = 5; CharacterCalculationsTree calcBaseValue = GetCharacterCalculations(character) as CharacterCalculationsTree; CharacterCalculationsTree calcMp5Value = GetCharacterCalculations(character, new Item() { Stats = new Stats() { Mp5 = 4 * multiplier } }) as CharacterCalculationsTree; CharacterCalculationsTree calcHasteValue = GetCharacterCalculations(character, new Item() { Stats = new Stats() { SpellHasteRating = 10 * multiplier } }) as CharacterCalculationsTree; CharacterCalculationsTree calcSpiritValue = GetCharacterCalculations(character, new Item() { Stats = new Stats() { Spirit = 10 * multiplier } }) as CharacterCalculationsTree; CharacterCalculationsTree calcIntValue = GetCharacterCalculations(character, new Item() { Stats = new Stats() { Intellect = 10 * multiplier } }) as CharacterCalculationsTree; return(new ComparisonCalculationBase[] { GetRelativeValue(new Stats() { Healing = 22 }, 5, 10, "22 Healing", character, calcBaseValue), GetRelativeValue(new Stats() { Mp5 = 4 }, 5, 10, "4 Mp5", character, calcBaseValue), GetRelativeValue(new Stats() { SpellHasteRating = 10 }, 1, 15, "10 Spell Haste", character, calcBaseValue), GetRelativeValue(new Stats() { Spirit = 10 }, 5, 10, "10 Spirit", character, calcBaseValue), GetRelativeValue(new Stats() { Intellect = 10 }, 5, 10, "10 Intellect", character, calcBaseValue), GetRelativeValue(new Stats() { Healing = 11, Spirit = 5 }, 5, 10, "11 Healing 5 Spirit", character, calcBaseValue), GetRelativeValue(new Stats() { Healing = 11, Intellect = 5 }, 5, 10, "11 Healing 5 Intellect", character, calcBaseValue), }); default: return(new ComparisonCalculationBase[0]); } }
public override CharacterCalculationsBase GetCharacterCalculations(Character character, Item additionalItem) { CalculationOptionsTree calcOpts = character.CalculationOptions as CalculationOptionsTree; CharacterCalculationsTree calculatedStats = new CharacterCalculationsTree(); calculatedStats.BasicStats = GetCharacterStats(character, additionalItem); calculatedStats.BasicStats.SpellCrit = (float)Math.Round((calculatedStats.BasicStats.Intellect / 80) + (calculatedStats.BasicStats.SpellCritRating / 22.08) + 1.85 + calcOpts.NaturalPerfection, 2); calculatedStats.BasicStats.SpellCombatManaRegeneration += 0.1f * calcOpts.Intensity; calculatedStats.BasicStats.TreeOfLifeAura += (calculatedStats.BasicStats.Spirit / 4f); calculatedStats.BasicStats.TreeOfLifeAura *= calcOpts.TreeOfLife; if (calculatedStats.BasicStats.ShatteredSunRestoProc > 0 && calcOpts.ShattrathFaction == "Aldor") { calculatedStats.BasicStats.AverageHeal += 44; // 1 proc/50 sec } calculatedStats.BasicStats.AverageHeal += calculatedStats.BasicStats.HealingDoneFor15SecOnUse2Min / 8; calculatedStats.BasicStats.AverageHeal += calculatedStats.BasicStats.HealingDoneFor15SecOnUse90Sec / 6; calculatedStats.BasicStats.AverageHeal += calculatedStats.BasicStats.HealingDoneFor20SecOnUse2Min / 6; float baseRegenConstant = 0.00932715221261f; float spiritRegen = 0.001f + baseRegenConstant * (float)Math.Sqrt(calculatedStats.BasicStats.Intellect) * calculatedStats.BasicStats.Spirit; calculatedStats.OS5SRRegenRaw = spiritRegen + calculatedStats.BasicStats.Mp5 / 5f; calculatedStats.IS5SRRegenRaw = spiritRegen * calculatedStats.BasicStats.SpellCombatManaRegeneration + calculatedStats.BasicStats.Mp5 / 5f; if (calculatedStats.BasicStats.SpiritFor20SecOnUse2Min > 0) { spiritRegen = 0.001f + baseRegenConstant * (float)Math.Sqrt(calculatedStats.BasicStats.Intellect) * (calculatedStats.BasicStats.Spirit + calculatedStats.BasicStats.SpiritFor20SecOnUse2Min); calculatedStats.OS5SRRegen = calculatedStats.OS5SRRegenRaw * 5f / 6f + (spiritRegen + calculatedStats.BasicStats.Mp5 / 5f) / 6f; calculatedStats.IS5SRRegen = calculatedStats.IS5SRRegenRaw * 5f / 6f + (spiritRegen * calculatedStats.BasicStats.SpellCombatManaRegeneration + calculatedStats.BasicStats.Mp5 / 5f) / 6f; } else { calculatedStats.OS5SRRegen = calculatedStats.OS5SRRegenRaw; calculatedStats.IS5SRRegen = calculatedStats.IS5SRRegenRaw; } Spell lbs = new LifebloomStack(character, calculatedStats.BasicStats, true); Spell lb = new Lifebloom(character, calculatedStats.BasicStats, true); Spell rj = new Rejuvenation(character, calculatedStats.BasicStats, true); Spell rg = new Regrowth(character, calculatedStats.BasicStats, true); Spell ht = new HealingTouch(character, calculatedStats.BasicStats); Spell lbsrh = new LifebloomStack(character, calculatedStats.BasicStats, false); Spell lbrh = new Lifebloom(character, calculatedStats.BasicStats, false); Spell rjrh = new Rejuvenation(character, calculatedStats.BasicStats, false); Spell rgrh = new Regrowth(character, calculatedStats.BasicStats, false); Spell nothing = new Nothing(character, calculatedStats.BasicStats); calculatedStats.Spells = new List <Spell>(); calculatedStats.Spells.Add(lbs); calculatedStats.Spells.Add(lb); calculatedStats.Spells.Add(rj); calculatedStats.Spells.Add(rg); calculatedStats.Spells.Add(ht); calculatedStats.Spells.Add(lbrh); calculatedStats.Spells.Add(rjrh); calculatedStats.Spells.Add(rgrh); calculatedStats.Spells.Add(lbsrh); calculatedStats.Spells.Add(nothing); calculatedStats.FightLength = calcOpts.FightLength; // Calculate scores in another function later to reduce clutter int health = (int)calculatedStats.BasicStats.Health; int healthBelow = (int)(health < calcOpts.TargetHealth ? health : calcOpts.TargetHealth); int healthAbove = health - healthBelow; calculatedStats.AddMp5Points(calculatedStats.IS5SRRegenRaw * 5f, "Regen"); calculatedStats.AddMp5Points((calculatedStats.IS5SRRegen - calculatedStats.IS5SRRegenRaw) * 5f, "Spirit on Use (20 sec/2min)"); calculatedStats.AddMp5Points(calcOpts.Spriest, "Shadow Priest"); calculatedStats.AddMp5Points((calcOpts.ManaPotAmt * (1 + calculatedStats.BasicStats.BonusManaPotion)) / (calcOpts.ManaPotDelay * 12), "Potion"); calculatedStats.solver = new Solver(calcOpts, calculatedStats); // getBestSpellRotation(calcOpts, calculatedStats); if (calculatedStats.solver.bestRotation != null) { calculatedStats.HpSPoints = calculatedStats.solver.HpS; calculatedStats.AddMp5Points(calculatedStats.solver.InnervateMp5, "Innervate"); calculatedStats.AddMp5Points(calculatedStats.solver.ManaProcOnCastMp5, "Mana per Cast (5%)"); calculatedStats.AddMp5Points(calculatedStats.solver.LessMana_15s_1m_Mp5, "Less Mana per Cast (15 sec/1min)"); calculatedStats.AddMp5Points(calculatedStats.solver.BlueDragonMp5, "Blue Dragon"); calculatedStats.AddMp5Points(calculatedStats.solver.BangleMp5, "Bangle"); calculatedStats.AddMp5Points(calculatedStats.solver.MementoMp5, "Memento of Tyrande"); calculatedStats.SurvivalPoints = healthBelow / calcOpts.SurvScalingBelow + healthAbove / calcOpts.SurvScalingAbove; calculatedStats.ToLPoints = calculatedStats.BasicStats.TreeOfLifeAura; } else { calculatedStats.HpSPoints = 0; calculatedStats.SurvivalPoints = 0; calculatedStats.ToLPoints = 0; } calculatedStats.OverallPoints = calculatedStats.HpSPoints + calculatedStats.Mp5Points + calculatedStats.SurvivalPoints + calculatedStats.ToLPoints; return(calculatedStats); }
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 CharacterCalculationsTree calc = new CharacterCalculationsTree(); if (character == null) return calc; calc.BasicStats = (Stats)GetCharacterStats(character, additionalItem); new TreeSolver(character, calc); return calc; }