Example #1
0
        private static Tuple <float, float> EvaluateRotation(AbilityCounts counts, BearAbilityBuilder abilities)
        {
            float damage = 0f;
            float threat = 0f;

            damage += abilities.MeleeStats.DPSTotalAverage * RotationDuration;
            threat += abilities.MeleeStats.TPSTotalAverage * RotationDuration;

            damage += abilities.MaulStats.DamageAverage * RotationDuration / 3f;             //TODO: Limit this by rage; just assume you maul on cooldown for now
            threat += abilities.MaulStats.ThreatAverage * RotationDuration / 3f;

            damage += abilities.FaerieFireStats.DamageAverage * counts.FFF;
            threat += abilities.FaerieFireStats.ThreatAverage * counts.FFF;

            damage += abilities.LacerateStats.DamageAverage * counts.Lacerate;
            threat += abilities.LacerateStats.ThreatAverage * counts.Lacerate;
            damage += abilities.LacerateStats.DamageTick1Raw * counts.LacerateTick;
            threat += abilities.LacerateStats.ThreatTick1Raw * counts.LacerateTick;

            damage += abilities.MangleStats.DamageAverage * counts.Mangle;
            threat += abilities.MangleStats.ThreatAverage * counts.Mangle;

            damage += abilities.PulverizeStats.Damage3Average * counts.Pulverize;
            threat += abilities.PulverizeStats.Threat3Average * counts.FFF;

            damage += abilities.SwipeStats.DamageAverage * counts.Swipe;
            threat += abilities.SwipeStats.ThreatAverage * counts.Swipe;

            damage += abilities.ThrashStats.DamageAverage * counts.Thrash;
            threat += abilities.ThrashStats.ThreatAverage * counts.Thrash;

            return(Tuple.Create(damage / RotationDuration, threat / RotationDuration));
        }
		public static Tuple<BearRotationCalculation, BearRotationCalculation> GetOptimalRotations(BearAbilityBuilder abilities)
		{
			int highestDPSRotation = -1;
			float highestDPSRotationDPS = 0;
			float highestDPSRotationTPS = 0;
			int highestTPSRotation = -1;
			float highestTPSRotationDPS = 0;
			float highestTPSRotationTPS = 0;

			for (int i = 0; i < Rotations.Length; i++)
			{
				var rotation = Rotations[i];
				var dpsTps = EvaluateRotation(rotation.Item2, abilities);

				if (dpsTps.Item1 > highestDPSRotationDPS)
				{
					highestDPSRotation = i;
					highestDPSRotationDPS = dpsTps.Item1;
					highestDPSRotationTPS = dpsTps.Item2;
				}
				if (dpsTps.Item2 > highestTPSRotationTPS)
				{
					highestTPSRotation = i;
					highestTPSRotationDPS = dpsTps.Item1;
					highestTPSRotationTPS = dpsTps.Item2;
				}
			}

			return Tuple.Create(
				highestDPSRotation >= 0 ? new BearRotationCalculation()
				{
					Name = BuildRotationName(Rotations[highestDPSRotation].Item1, highestDPSRotationDPS, highestDPSRotationTPS),
					DPS = highestDPSRotationDPS,
					TPS = highestDPSRotationTPS
				} : new BearRotationCalculation() { Name = "None" },
				highestTPSRotation >= 0 ? new BearRotationCalculation()
				{
					Name = BuildRotationName(Rotations[highestTPSRotation].Item1, highestTPSRotationDPS, highestTPSRotationTPS),
					DPS = highestTPSRotationDPS,
					TPS = highestTPSRotationTPS
				} : new BearRotationCalculation() { Name = "None" }
			);
		}
Example #3
0
        /// <summary>
        /// Calculates the threat properties of the Character
        /// </summary>
        /// <param name="stats">The total Stats of the character</param>
        /// <param name="targetLevel">The level of the target</param>
        /// <param name="calculatedStats">The CharacterCalculationsBear object to fill with results</param>
        /// <param name="character">The Character to calculate the threat properties of</param>
        private void CalculateThreat(StatsBear stats, int targetLevel, CharacterCalculationsBear calculatedStats, Character character)
        {
            CalculationOptionsBear calcOpts = character.CalculationOptions as CalculationOptionsBear ?? new CalculationOptionsBear();
            BossOptions bossOpts = character.BossOptions;
            if (bossOpts.Attacks.Count < 1) { bossOpts.Attacks.Add(BossHandler.ADefaultMeleeAttack); bossOpts.Attacks[0].IsTheDefaultMelee = true; bossOpts.DamagingTargs = true; }
            if (bossOpts.DefaultMeleeAttack == null) { bossOpts.Attacks.Add(BossHandler.ADefaultMeleeAttack); bossOpts.Attacks[bossOpts.Attacks.Count - 1].IsTheDefaultMelee = true; bossOpts.DamagingTargs = true; }
            Attack bossAttack = bossOpts.DefaultMeleeAttack;
            DruidTalents talents = character.DruidTalents;

            // Establish base multipliers and chances
            float modArmor = 1f - StatConversion.GetArmorDamageReduction(character.Level, bossOpts.Armor,
                stats.TargetArmorReduction, stats.ArmorPenetration);

            float critMultiplier = 2f * (1 + stats.BonusCritDamageMultiplier);
            float spellCritMultiplier = 2f * (1 + stats.BonusCritDamageMultiplier);

            float hasteBonus = StatConversion.GetPhysicalHasteFromRating(stats.HasteRating, CharacterClass.Druid);
            float attackSpeed = (2.5f) / (1f + hasteBonus);
            attackSpeed = attackSpeed / (1f + stats.PhysicalHaste);

            float hitBonus = StatConversion.GetPhysicalHitFromRating(stats.HitRating, CharacterClass.Druid) + stats.PhysicalHit;
            float expertiseBonus = StatConversion.GetDodgeParryReducFromExpertise(StatConversion.GetExpertiseFromRating(stats.ExpertiseRating, CharacterClass.Druid) + stats.Expertise, CharacterClass.Druid);
            float spellHitBonus = StatConversion.GetSpellHitFromRating(stats.HitRating, CharacterClass.Druid) + stats.SpellHit;
            
            int levelDifference = (targetLevel - character.Level);
            float chanceDodge = Math.Max(0f, StatConversion.WHITE_DODGE_CHANCE_CAP[levelDifference] - expertiseBonus);
            float chanceParry = Math.Max(0f, StatConversion.WHITE_PARRY_CHANCE_CAP[levelDifference] - expertiseBonus);
            float chanceMiss = Math.Max(0f, StatConversion.WHITE_MISS_CHANCE_CAP[levelDifference] - hitBonus);
            float chanceResist = Math.Max(0f, StatConversion.GetSpellMiss(-levelDifference, false) - spellHitBonus);
            
            float chanceGlance = StatConversion.WHITE_GLANCE_CHANCE_CAP[levelDifference]; //0.2335774f;
            //float glanceMultiplier = 0.7f;
            float chanceAvoided = chanceMiss + chanceDodge + chanceParry;
            
            float rawChanceCrit = StatConversion.GetPhysicalCritFromRating(stats.CritRating, CharacterClass.Druid)
                                + StatConversion.GetPhysicalCritFromAgility(stats.Agility, CharacterClass.Druid)
                                + stats.PhysicalCrit
                                + StatConversion.NPC_LEVEL_CRIT_MOD[levelDifference];
            float chanceCrit = rawChanceCrit * (1f - chanceAvoided);
            
            float rawChanceCritSpell = StatConversion.GetSpellCritFromRating(stats.CritRating, CharacterClass.Druid)
                                + StatConversion.GetSpellCritFromIntellect(stats.Intellect, CharacterClass.Druid)
                                + stats.SpellCrit + stats.SpellCritOnTarget
                                + StatConversion.NPC_LEVEL_CRIT_MOD[levelDifference];
            float chanceCritSpell = rawChanceCritSpell * (1f - chanceResist);

            calculatedStats.DodgedAttacks = chanceDodge;
            calculatedStats.ParriedAttacks = chanceParry;
            calculatedStats.MissedAttacks = chanceMiss;

            float movementdowntime = 3f / 5.5f / (1 + stats.MovementSpeed); // Movement Duration / Movement Frequency / (1 + Movement Speed)
            
            BearAbilityBuilder abilities = new BearAbilityBuilder(stats,
                character.MainHand == null ? 0.75f : ((character.MainHand.MinDamage + character.MainHand.MaxDamage) / 2f) / character.MainHand.Speed,
                attackSpeed, modArmor, chanceAvoided, chanceResist, chanceCrit, chanceCritSpell, chanceGlance, critMultiplier, spellCritMultiplier);
            var optimalRotations = BearRotationCalculator.GetOptimalRotations(abilities);
            calculatedStats.Abilities = abilities;
            calculatedStats.HighestDPSRotation = optimalRotations.Item1;
            float bonusdamage = stats.ArcaneDamage + stats.FireDamage + stats.FrostDamage + stats.NatureDamage + stats.ShadowDamage + stats.HolyDamage + stats.PhysicalDamage;
            calculatedStats.HighestDPSRotation.DPS += bonusdamage;
            calculatedStats.HighestDPSRotation.DPS *= 1 - movementdowntime;
            calculatedStats.HighestTPSRotation = optimalRotations.Item2;
            calculatedStats.HighestTPSRotation.TPS += bonusdamage * 5f;
            calculatedStats.HighestTPSRotation.TPS *= 1 - movementdowntime;
            calculatedStats.ThreatPoints = calculatedStats.HighestTPSRotation.TPS * calcOpts.ThreatScale / 10f;
        }
Example #4
0
        public static Tuple <BearRotationCalculation, BearRotationCalculation> GetOptimalRotations(BearAbilityBuilder abilities)
        {
            int   highestDPSRotation    = -1;
            float highestDPSRotationDPS = 0;
            float highestDPSRotationTPS = 0;
            int   highestTPSRotation    = -1;
            float highestTPSRotationDPS = 0;
            float highestTPSRotationTPS = 0;

            for (int i = 0; i < Rotations.Length; i++)
            {
                var rotation = Rotations[i];
                var dpsTps   = EvaluateRotation(rotation.Item2, abilities);

                if (dpsTps.Item1 > highestDPSRotationDPS)
                {
                    highestDPSRotation    = i;
                    highestDPSRotationDPS = dpsTps.Item1;
                    highestDPSRotationTPS = dpsTps.Item2;
                }
                if (dpsTps.Item2 > highestTPSRotationTPS)
                {
                    highestTPSRotation    = i;
                    highestTPSRotationDPS = dpsTps.Item1;
                    highestTPSRotationTPS = dpsTps.Item2;
                }
            }

            return(Tuple.Create(
                       highestDPSRotation >= 0 ? new BearRotationCalculation()
            {
                Name = BuildRotationName(Rotations[highestDPSRotation].Item1, highestDPSRotationDPS, highestDPSRotationTPS),
                DPS = highestDPSRotationDPS,
                TPS = highestDPSRotationTPS
            } : new BearRotationCalculation()
            {
                Name = "None"
            },
                       highestTPSRotation >= 0 ? new BearRotationCalculation()
            {
                Name = BuildRotationName(Rotations[highestTPSRotation].Item1, highestTPSRotationDPS, highestTPSRotationTPS),
                DPS = highestTPSRotationDPS,
                TPS = highestTPSRotationTPS
            } : new BearRotationCalculation()
            {
                Name = "None"
            }
                       ));
        }
		private static Tuple<float,float> EvaluateRotation(AbilityCounts counts, BearAbilityBuilder abilities)
		{
			float damage = 0f;
			float threat = 0f;

			damage += abilities.MeleeStats.DPSTotalAverage * RotationDuration;
			threat += abilities.MeleeStats.TPSTotalAverage * RotationDuration;
					  
			damage += abilities.MaulStats.DamageAverage * RotationDuration / 3f; //TODO: Limit this by rage; just assume you maul on cooldown for now
			threat += abilities.MaulStats.ThreatAverage * RotationDuration / 3f;
					  
			damage += abilities.FaerieFireStats.DamageAverage * counts.FFF;
			threat += abilities.FaerieFireStats.ThreatAverage * counts.FFF;
					  
			damage += abilities.LacerateStats.DamageAverage * counts.Lacerate;
			threat += abilities.LacerateStats.ThreatAverage * counts.Lacerate;
			damage += abilities.LacerateStats.DamageTick1Raw * counts.LacerateTick;
			threat += abilities.LacerateStats.ThreatTick1Raw * counts.LacerateTick;
					  
			damage += abilities.MangleStats.DamageAverage * counts.Mangle;
			threat += abilities.MangleStats.ThreatAverage * counts.Mangle;
					  
			damage += abilities.PulverizeStats.Damage3Average * counts.Pulverize;
			threat += abilities.PulverizeStats.Threat3Average * counts.FFF;
					  
			damage += abilities.SwipeStats.DamageAverage * counts.Swipe;
			threat += abilities.SwipeStats.ThreatAverage * counts.Swipe;
					  
			damage += abilities.ThrashStats.DamageAverage * counts.Thrash;
			threat += abilities.ThrashStats.ThreatAverage * counts.Thrash;

			return Tuple.Create(damage / RotationDuration, threat / RotationDuration);
		}