Пример #1
0
 public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
 {
     if (CalculationOptions.DisplaySegmentCooldowns != CalculationOptions.ComparisonSegmentCooldowns || CalculationOptions.DisplayIntegralMana != CalculationOptions.ComparisonIntegralMana)
     {
         bool savedIncrementalOptimizations = CalculationOptions.IncrementalOptimizations;
         CalculationOptions.IncrementalOptimizations = false;
         CharacterCalculationsMage   smp = Solver.GetCharacterCalculations(Character, null, CalculationOptions, Calculations, MageArmor, CalculationOptions.DisplaySegmentCooldowns, CalculationOptions.DisplayIntegralMana);
         Dictionary <string, string> ret = smp.GetCharacterDisplayCalculationValuesInternal();
         ret["Dps"] = String.Format("{0:F}*{1:F}% Error margin", smp.DpsRating, Math.Abs(DpsRating - smp.DpsRating) / DpsRating * 100);
         CalculationOptions.IncrementalOptimizations = savedIncrementalOptimizations;
         return(ret);
     }
     else
     {
         return(GetCharacterDisplayCalculationValuesInternal());
     }
 }
Пример #2
0
        public SolverLP(int baseRows, int maximumColumns, CharacterCalculationsMage calculations, int segments)
        {
            if (baseRows > maxRows || maximumColumns > maxCols)
            {
                maxRows = Math.Max(baseRows, maxRows);
                maxCols = Math.Max(maximumColumns, maxCols);
                RecreateArrays();
            }

            this.calculations = calculations;
            this.segments     = segments;
            cRows             = baseRows;
            cCols             = 0;

            for (int i = 0; i <= cRows; i++)
            {
                rowScale[i] = 1.0;
            }

            lp = new LP(cRows, maximumColumns);
        }
Пример #3
0
 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
     CharacterCalculationsMage calcs = new CharacterCalculationsMage();
     if (character == null) { return calcs; }
     CalculationOptionsMage calcOpts = character.CalculationOptions as CalculationOptionsMage;
     if (calcOpts == null) { return calcs; }
     //
     bool computeIncrementalSet = referenceCalculation && calcOpts.IncrementalOptimizations;
     bool useGlobalOptimizations = calcOpts.SmartOptimization && !significantChange;
     bool useIncrementalOptimizations = calcOpts.IncrementalOptimizations && (!significantChange || calcOpts.ForceIncrementalOptimizations);
     bool solveCycles = referenceCalculation || significantChange;
     if (useIncrementalOptimizations && calcOpts.IncrementalSetStateIndexes == null) computeIncrementalSet = true;
     if (computeIncrementalSet)
     {
         useIncrementalOptimizations = false;
         needsDisplayCalculations = true;
     }
     if (useIncrementalOptimizations && !character.DisableBuffAutoActivation)
     {
         return GetCharacterCalculations(character, additionalItem, calcOpts, calcOpts.IncrementalSetArmor, useIncrementalOptimizations, useGlobalOptimizations, needsDisplayCalculations, computeIncrementalSet, solveCycles);
     }
     else if (calcOpts.AutomaticArmor && !calcOpts.ArmorSwapping && !character.DisableBuffAutoActivation)
     {
         CharacterCalculationsMage mage = GetCharacterCalculations(character, additionalItem, calcOpts, "Mage Armor", useIncrementalOptimizations, useGlobalOptimizations, needsDisplayCalculations, computeIncrementalSet, solveCycles);
         CharacterCalculationsMage molten = GetCharacterCalculations(character, additionalItem, calcOpts, "Molten Armor", useIncrementalOptimizations, useGlobalOptimizations, needsDisplayCalculations, computeIncrementalSet, solveCycles);
         CharacterCalculationsMage calc = (mage.OverallPoints > molten.OverallPoints) ? mage : molten;
         if (calcOpts.MeleeDps + calcOpts.MeleeDot + calcOpts.PhysicalDps + calcOpts.PhysicalDot > 0)
         {
             CharacterCalculationsMage ice = GetCharacterCalculations(character, additionalItem, calcOpts, "Ice Armor", useIncrementalOptimizations, useGlobalOptimizations, needsDisplayCalculations, computeIncrementalSet, solveCycles);
             if (ice.OverallPoints > calc.OverallPoints) calc = ice;
         }
         if (computeIncrementalSet) StoreIncrementalSet(character, calc.DisplayCalculations);
         if (referenceCalculation) StoreCycleSolutions(character, calc.DisplayCalculations);
         return calc;
     }
     else
     {
         CharacterCalculationsMage calc = GetCharacterCalculations(character, additionalItem, calcOpts, null, useIncrementalOptimizations, useGlobalOptimizations, needsDisplayCalculations, computeIncrementalSet, solveCycles);
         if (computeIncrementalSet) StoreIncrementalSet(character, calc.DisplayCalculations);
         if (referenceCalculation) StoreCycleSolutions(character, calc.DisplayCalculations);
         return calc;
     }
 }
Пример #4
0
        public CastingState(CharacterCalculationsMage calculations, Stats characterStats, CalculationOptionsMage calculationOptions, string armor, Character character, bool arcanePower, bool moltenFury, bool icyVeins, bool heroism, bool destructionPotion, bool flameCap, bool trinket1, bool trinket2, bool combustion, bool drums, int incrementalSetIndex)
        {
            this.calculations   = calculations;
            IncrementalSetIndex = incrementalSetIndex;

            float levelScalingFactor;

            if (calculationOptions.WotLK)
            {
                levelScalingFactor = (float)((52f / 82f) * Math.Pow(63f / 131f, (calculationOptions.PlayerLevel - 70) / 10f));
            }
            else
            {
                levelScalingFactor = (1 - (70 - 60) / 82f * 3);
            }

            SpellDamageRating = characterStats.SpellDamageRating;
            SpellHasteRating  = characterStats.SpellHasteRating;

            if (destructionPotion)
            {
                SpellDamageRating += 120;
            }

            if (trinket1)
            {
                Stats t = character.Trinket1.Stats;
                SpellDamageRating += t.SpellDamageFor20SecOnUse2Min + t.SpellDamageFor15SecOnManaGem + t.SpellDamageFor15SecOnUse90Sec + t.SpellDamageFor15SecOnUse2Min;
                SpellHasteRating  += t.SpellHasteFor20SecOnUse2Min + t.SpellHasteFor20SecOnUse5Min;
                Mp5OnCastFor20Sec  = t.Mp5OnCastFor20SecOnUse2Min;
                if (t.SpellDamageFor15SecOnManaGem > 0.0)
                {
                    ManaGemActivation = true;
                }
            }
            if (trinket2)
            {
                Stats t = character.Trinket2.Stats;
                SpellDamageRating += t.SpellDamageFor20SecOnUse2Min + t.SpellDamageFor15SecOnManaGem + t.SpellDamageFor15SecOnUse90Sec + t.SpellDamageFor15SecOnUse2Min;
                SpellHasteRating  += t.SpellHasteFor20SecOnUse2Min + t.SpellHasteFor20SecOnUse5Min;
                Mp5OnCastFor20Sec  = t.Mp5OnCastFor20SecOnUse2Min;
                if (t.SpellDamageFor15SecOnManaGem > 0.0)
                {
                    ManaGemActivation = true;
                }
            }
            if (drums)
            {
                SpellHasteRating += 80;
            }

            CastingSpeed    = 1 + SpellHasteRating / 995f * levelScalingFactor;
            ArcaneDamage    = characterStats.SpellArcaneDamageRating + SpellDamageRating;
            FireDamage      = characterStats.SpellFireDamageRating + SpellDamageRating + (flameCap ? 80.0f : 0.0f);
            FrostDamage     = characterStats.SpellFrostDamageRating + SpellDamageRating;
            NatureDamage    = /* characterStats.SpellNatureDamageRating + */ SpellDamageRating;
            ShadowDamage    = characterStats.SpellShadowDamageRating + SpellDamageRating;
            FrostFireDamage = Math.Max(FireDamage, FrostDamage);

            float spellCritPerInt = 0f;
            float spellCritBase   = 0f;
            float baseRegen       = 0f;

            switch (calculationOptions.PlayerLevel)
            {
            case 70:
                spellCritPerInt = 0.0125f;
                spellCritBase   = 0.9075f;
                baseRegen       = 0.009327f;
                break;

            case 71:
                spellCritPerInt = 0.0116f;
                spellCritBase   = 0.9075f;
                baseRegen       = 0.009079f;
                break;

            case 72:
                spellCritPerInt = 0.0108f;
                spellCritBase   = 0.9075f;
                baseRegen       = 0.008838f;
                break;

            case 73:
                spellCritPerInt = 0.0101f;
                spellCritBase   = 0.9075f;
                baseRegen       = 0.008603f;
                break;

            case 74:
                spellCritPerInt = 0.0093f;
                spellCritBase   = 0.9075f;
                baseRegen       = 0.008375f;
                break;

            case 75:
                spellCritPerInt = 0.0087f;
                spellCritBase   = 0.9075f;
                baseRegen       = 0.008152f;
                break;

            case 76:
                spellCritPerInt = 0.0081f;
                spellCritBase   = 0.9075f;
                baseRegen       = 0.007936f;
                break;

            case 77:
                spellCritPerInt = 0.0075f;
                spellCritBase   = 0.9075f;
                baseRegen       = 0.007725f;
                break;

            case 78:
                spellCritPerInt = 0.007f;
                spellCritBase   = 0.9075f;
                baseRegen       = 0.00752f;
                break;

            case 79:
                spellCritPerInt = 0.0065f;
                spellCritBase   = 0.9075f;
                baseRegen       = 0.00732f;
                break;

            case 80:
                spellCritPerInt = 0.006f;
                spellCritBase   = 0.9075f;
                baseRegen       = 0.007125f;
                break;
            }
            SpellCrit = 0.01f * (characterStats.Intellect * spellCritPerInt + spellCritBase) + 0.01f * calculationOptions.ArcaneInstability + (calculationOptions.WotLK ? 0.015f : 0.01f) * calculationOptions.ArcanePotency + characterStats.SpellCritRating / 1400f * levelScalingFactor + characterStats.SpellCrit;
            if (destructionPotion)
            {
                SpellCrit += 0.02f;
            }
            SpellHit = characterStats.SpellHitRating * levelScalingFactor / 800f;

            int   targetLevel = calculationOptions.TargetLevel;
            int   playerLevel = calculationOptions.PlayerLevel;
            float maxHitRate  = (calculationOptions.WotLK) ? 1.00f : 0.99f;

            ArcaneHitRate    = Math.Min(maxHitRate, ((targetLevel <= playerLevel + 2) ? (0.96f - (targetLevel - playerLevel) * 0.01f) : (0.94f - (targetLevel - playerLevel - 2) * 0.11f)) + SpellHit + (calculationOptions.WotLK ? 0.01f : 0.02f) * calculationOptions.ArcaneFocus);
            FireHitRate      = Math.Min(maxHitRate, ((targetLevel <= playerLevel + 2) ? (0.96f - (targetLevel - playerLevel) * 0.01f) : (0.94f - (targetLevel - playerLevel - 2) * 0.11f)) + SpellHit + 0.01f * calculationOptions.ElementalPrecision);
            FrostHitRate     = Math.Min(maxHitRate, ((targetLevel <= playerLevel + 2) ? (0.96f - (targetLevel - playerLevel) * 0.01f) : (0.94f - (targetLevel - playerLevel - 2) * 0.11f)) + SpellHit + 0.01f * calculationOptions.ElementalPrecision);
            NatureHitRate    = Math.Min(maxHitRate, ((targetLevel <= playerLevel + 2) ? (0.96f - (targetLevel - playerLevel) * 0.01f) : (0.94f - (targetLevel - playerLevel - 2) * 0.11f)) + SpellHit);
            ShadowHitRate    = Math.Min(maxHitRate, ((targetLevel <= playerLevel + 2) ? (0.96f - (targetLevel - playerLevel) * 0.01f) : (0.94f - (targetLevel - playerLevel - 2) * 0.11f)) + SpellHit);
            FrostFireHitRate = Math.Min(maxHitRate, ((targetLevel <= playerLevel + 2) ? (0.96f - (targetLevel - playerLevel) * 0.01f) : (0.94f - (targetLevel - playerLevel - 2) * 0.11f)) + SpellHit + 0.01f * calculationOptions.ElementalPrecision);

            SpiritRegen       = 0.001f + characterStats.Spirit * baseRegen * (float)Math.Sqrt(characterStats.Intellect);
            ManaRegen         = SpiritRegen + characterStats.Mp5 / 5f + SpiritRegen * 4 * 20 * calculationOptions.Innervate / calculationOptions.FightDuration + calculationOptions.ManaTide * 0.24f * characterStats.Mana / calculationOptions.FightDuration;
            ManaRegen5SR      = SpiritRegen * characterStats.SpellCombatManaRegeneration + characterStats.Mp5 / 5f + SpiritRegen * (5 - characterStats.SpellCombatManaRegeneration) * 20 * calculationOptions.Innervate / calculationOptions.FightDuration + calculationOptions.ManaTide * 0.24f * characterStats.Mana / calculationOptions.FightDuration;
            ManaRegenDrinking = ManaRegen + 240f;
            HealthRegen       = 0.0312f * characterStats.Spirit + characterStats.Hp5 / 5f;
            HealthRegenCombat = characterStats.Hp5 / 5f;
            HealthRegenEating = ManaRegen + 250f;
            MeleeMitigation   = (1 - 1 / (1 + 0.1f * characterStats.Armor / (8.5f * (70 + 4.5f * (70 - 59)) + 40)));
            Defense           = 350 + characterStats.DefenseRating / 2.37f;
            int molten = (armor == "Molten Armor") ? 1 : 0;

            PhysicalCritReduction = (0.04f * (Defense - 5 * 70) / 100 + characterStats.Resilience / 2500f * levelScalingFactor + molten * 0.05f);
            SpellCritReduction    = (characterStats.Resilience / 2500f * levelScalingFactor + molten * 0.05f);
            CritDamageReduction   = (characterStats.Resilience / 2500f * 2f * levelScalingFactor);
            Dodge = ((0.0443f * characterStats.Agility + 3.28f + 0.04f * (Defense - 5 * 70)) / 100f + characterStats.DodgeRating / 1200 * levelScalingFactor);

            // spell calculations

            ArcanePower       = arcanePower;
            MoltenFury        = moltenFury;
            IcyVeins          = icyVeins;
            Heroism           = heroism;
            DestructionPotion = destructionPotion;
            FlameCap          = flameCap;
            Trinket1          = trinket1;
            Trinket2          = trinket2;
            Combustion        = combustion;
            DrumsOfBattle     = drums;

            if (icyVeins)
            {
                CastingSpeed *= 1.2f;
            }
            if (heroism)
            {
                CastingSpeed *= 1.3f;
            }
            if (calculationOptions.WotLK)
            {
                CastingSpeed *= (1f + 0.02f * calculationOptions.NetherwindPresence);
            }

            Latency            = calculationOptions.Latency;
            ClearcastingChance = 0.02f * calculationOptions.ArcaneConcentration;

            GlobalCooldownLimit = 1f;
            GlobalCooldown      = Math.Max(GlobalCooldownLimit, 1.5f / CastingSpeed);

            ArcaneSpellModifier = (1 + 0.01f * calculationOptions.ArcaneInstability) * (1 + 0.01f * calculationOptions.PlayingWithFire) * (1 + characterStats.BonusSpellPowerMultiplier) * (1 + 0.02f * calculationOptions.TormentTheWeak * calculationOptions.SlowedTime);
            if (arcanePower)
            {
                ArcaneSpellModifier *= 1.3f;
            }
            if (moltenFury)
            {
                ArcaneSpellModifier *= (1 + 0.1f * calculationOptions.MoltenFury);
            }
            FireSpellModifier      = ArcaneSpellModifier * (1 + 0.02f * calculationOptions.FirePower);
            FrostSpellModifier     = ArcaneSpellModifier * (1 + 0.02f * calculationOptions.PiercingIce) * (1 + 0.01f * calculationOptions.ArcticWinds);
            NatureSpellModifier    = ArcaneSpellModifier;
            ShadowSpellModifier    = ArcaneSpellModifier;
            FrostFireSpellModifier = ArcaneSpellModifier * (1 + 0.02f * calculationOptions.FirePower) * (1 + 0.02f * calculationOptions.PiercingIce) * (1 + 0.01f * calculationOptions.ArcticWinds) * Math.Max(1 + characterStats.BonusFireSpellPowerMultiplier, 1 + characterStats.BonusFrostSpellPowerMultiplier);
            ArcaneSpellModifier   *= (1 + characterStats.BonusArcaneSpellPowerMultiplier);
            FireSpellModifier     *= (1 + characterStats.BonusFireSpellPowerMultiplier);
            FrostSpellModifier    *= (1 + characterStats.BonusFrostSpellPowerMultiplier);
            NatureSpellModifier   *= (1 + characterStats.BonusNatureSpellPowerMultiplier);
            ShadowSpellModifier   *= (1 + characterStats.BonusShadowSpellPowerMultiplier);

            ResilienceCritDamageReduction = 1;
            ResilienceCritRateReduction   = 0;

            ArcaneCritBonus    = (1 + (1.5f * (1 + characterStats.BonusSpellCritMultiplier) - 1) * (1 + 0.25f * calculationOptions.SpellPower)) * ResilienceCritDamageReduction;
            FireCritBonus      = (1 + (1.5f * (1 + characterStats.BonusSpellCritMultiplier) - 1) * (1 + 0.25f * calculationOptions.SpellPower)) * (1 + 0.08f * calculationOptions.Ignite) * ResilienceCritDamageReduction;
            FrostCritBonus     = (1 + (1.5f * (1 + characterStats.BonusSpellCritMultiplier) - 1) * (1 + 0.2f * calculationOptions.IceShards + 0.25f * calculationOptions.SpellPower)) * ResilienceCritDamageReduction;
            FrostFireCritBonus = (1 + (1.5f * (1 + characterStats.BonusSpellCritMultiplier) - 1) * (1 + 0.2f * calculationOptions.IceShards + 0.25f * calculationOptions.SpellPower)) * (1 + 0.08f * calculationOptions.Ignite) * ResilienceCritDamageReduction;
            NatureCritBonus    = (1 + (1.5f * (1 + characterStats.BonusSpellCritMultiplier) - 1) * (1 + 0.25f * calculationOptions.SpellPower)) * ResilienceCritDamageReduction;
            ShadowCritBonus    = (1 + (1.5f * (1 + characterStats.BonusSpellCritMultiplier) - 1) * (1 + 0.25f * calculationOptions.SpellPower)) * ResilienceCritDamageReduction;

            ArcaneCritRate = SpellCrit;
            FireCritRate   = SpellCrit + 0.02f * calculationOptions.CriticalMass + 0.01f * calculationOptions.Pyromaniac;
            if (combustion)
            {
                CombustionDuration = ComputeCombustion(FireCritRate);
                FireCritRate       = 3 / CombustionDuration;
            }
            FrostFireCritRate = FireCritRate + characterStats.SpellFrostCritRating / 22.08f / 100f;
            FrostCritRate     = SpellCrit + characterStats.SpellFrostCritRating / 22.08f / 100f;
            NatureCritRate    = SpellCrit;
            ShadowCritRate    = SpellCrit;

            float threatFactor = (1 + characterStats.ThreatIncreaseMultiplier) * (1 - characterStats.ThreatReductionMultiplier);

            ArcaneThreatMultiplier    = threatFactor * (1 - calculationOptions.ArcaneSubtlety * 0.2f);
            FireThreatMultiplier      = threatFactor * (1 - calculationOptions.BurningSoul * 0.05f);
            FrostThreatMultiplier     = threatFactor * (1 - ((calculationOptions.FrostChanneling > 0) ? (0.01f + 0.03f * calculationOptions.FrostChanneling) : 0f));
            FrostFireThreatMultiplier = threatFactor * (1 - calculationOptions.BurningSoul * 0.05f) * (1 - ((calculationOptions.FrostChanneling > 0) ? (0.01f + 0.03f * calculationOptions.FrostChanneling) : 0f));
            NatureThreatMultiplier    = threatFactor;
            ShadowThreatMultiplier    = threatFactor;
        }