protected void Initialize(Character character, StatsHunter stats, CombatFactors cf, CalculationOptionsHunter co, Skills.Ability ability, bool useSpellHit, bool alwaysHit) { Char = character; StatS = stats; calcOpts = co; combatFactors = cf; Abil = ability; if (Abil == null) { isWhite = true; } else { Abil.combatFactors = combatFactors; } PetAbil = PetAttacks.None; this.useSpellHit = useSpellHit; /*// Defaults Miss Dodge Parry Block Glance Critical Hit*/ // Start a calc if (alwaysHit) CalculateAlwaysHit(); else Calculate(); }
protected void Initialize(Character character, StatsHunter stats, CombatFactors cf, CalculationOptionsHunter co, Skills.Ability ability, bool useSpellHit, bool alwaysHit) { Char = character; StatS = stats; calcOpts = co; combatFactors = cf; Abil = ability; if (Abil == null) { isWhite = true; } else { Abil.combatFactors = combatFactors; } PetAbil = PetAttacks.None; this.useSpellHit = useSpellHit; /*// Defaults * Miss * Dodge * Parry * Block * Glance * Critical * Hit*/ // Start a calc if (alwaysHit) { CalculateAlwaysHit(); } else { Calculate(); } }
public AttackTable(Character character, StatsHunter stats, CombatFactors cf, CalculationOptionsHunter co, Skills.Ability ability, bool useSpellHit, bool alwaysHit) { Initialize(character, stats, cf, co, ability, useSpellHit, alwaysHit); }
public AttackTable(Character character, Stats stats, CombatFactors cf, CalculationOptionsHunter co, bool useSpellHit, bool alwaysHit) { Initialize(character, stats, cf, co, null, useSpellHit, alwaysHit); }
/* private void GenPrioRotation(CharacterCalculationsHunter calculatedStats, CalculationOptionsHunter calcOpts, HunterTalents talents) { calculatedStats.priorityRotation = new ShotPriority(calcOpts); calculatedStats.priorityRotation.priorities[0] = getShotByIndex(calcOpts.PriorityIndex1, calculatedStats); calculatedStats.priorityRotation.priorities[1] = getShotByIndex(calcOpts.PriorityIndex2, calculatedStats); calculatedStats.priorityRotation.priorities[2] = getShotByIndex(calcOpts.PriorityIndex3, calculatedStats); calculatedStats.priorityRotation.priorities[3] = getShotByIndex(calcOpts.PriorityIndex4, calculatedStats); calculatedStats.priorityRotation.priorities[4] = getShotByIndex(calcOpts.PriorityIndex5, calculatedStats); calculatedStats.priorityRotation.priorities[5] = getShotByIndex(calcOpts.PriorityIndex6, calculatedStats); calculatedStats.priorityRotation.priorities[6] = getShotByIndex(calcOpts.PriorityIndex7, calculatedStats); calculatedStats.priorityRotation.priorities[7] = getShotByIndex(calcOpts.PriorityIndex8, calculatedStats); calculatedStats.priorityRotation.priorities[8] = getShotByIndex(calcOpts.PriorityIndex9, calculatedStats); calculatedStats.priorityRotation.priorities[9] = getShotByIndex(calcOpts.PriorityIndex10, calculatedStats); calculatedStats.priorityRotation.validateShots(talents); } private void GenAbilityCds(Character character, CharacterCalculationsHunter calculatedStats, CalculationOptionsHunter calcOpts, BossOptions bossOpts, HunterTalents talents) { calculatedStats.serpentSting.Cd = 1.5f; calculatedStats.serpentSting.Duration = talents.GlyphOfSerpentSting ? 21 : 15; calculatedStats.aimedShot.Cd = talents.GlyphOfAimedShot ? 8 : 10; calculatedStats.explosiveShot.Cd = 6; calculatedStats.chimeraShot.Cd = talents.GlyphOfChimeraShot ? 9 : 10; calculatedStats.arcaneShot.Cd = 6; calculatedStats.multiShot.Cd = /*talents.GlyphOfMultiShot ? 9 : 10; calculatedStats.blackArrow.Cd = 30 - (talents.Resourcefulness * 2); calculatedStats.blackArrow.Duration = 15; calculatedStats.killShot.Cd = talents.GlyphOfKillShot ? 9 : 15; calculatedStats.immolationTrap.Cd = 30 - talents.Resourcefulness * 2; calculatedStats.immolationTrap.Duration = talents.GlyphOfImmolationTrap ? 9 : 15; calculatedStats.explosiveTrap.Cd = 30 - talents.Resourcefulness * 2; calculatedStats.explosiveTrap.Duration = 20; calculatedStats.freezingTrap.Cd = 30 - talents.Resourcefulness * 2; calculatedStats.freezingTrap.Duration = 20; calculatedStats.frostTrap.Cd = 30 - talents.Resourcefulness * 2; calculatedStats.frostTrap.Duration = 30; // if (bossOpts.MultiTargs && bossOpts.MultiTargsTime > 0) { // // Good to go, now change the cooldown based on the multitargs uptime // calculatedStats.volley.Duration = 6f; // calculatedStats.volley.Cd = (1f / (bossOpts.MultiTargsTime / calculatedStats.volley.Duration)) * bossOpts.BerserkTimer; //#endif // } else { // // invalidate it // calculatedStats.volley.Cd = -1f; // //calculatedStats.volley.CastTime = -1f; // calculatedStats.volley.Duration = -1f; // } if (calculatedStats.priorityRotation.containsShot(Shots.Readiness)) { calculatedStats.rapidFire.Cd = 157.5f - (30f * talents.RapidKilling); } else { calculatedStats.rapidFire.Cd = (5 - talents.RapidKilling) * 60f; } calculatedStats.rapidFire.Duration = 15; // We will set the correct value for this later, after we've calculated haste calculatedStats.steadyShot.Cd = 2; // TODO Zhok: Same 4 cobra? calculatedStats.readiness.Cd = 180; calculatedStats.bestialWrath.Cd = (talents.GlyphOfBestialWrath ? 100f : 120f) * (1f - talents.Longevity * 0.10f); calculatedStats.bestialWrath.Duration = calcOpts.PetFamily == PETFAMILY.None ? 0 : 10; // We can calculate the rough frequencies now calculatedStats.priorityRotation.initializeTimings(); if (!calcOpts.UseRotationTest) { calculatedStats.priorityRotation.calculateFrequencies(); calculatedStats.priorityRotation.calculateLALProcs(character); calculatedStats.priorityRotation.calculateFrequencies(); calculatedStats.priorityRotation.calculateFrequencySums(); } } private static void GenRotation(Character character, Stats stats, CharacterCalculationsHunter calculatedStats, CalculationOptionsHunter calcOpts, BossOptions bossOpts, HunterTalents talents, out float rangedWeaponSpeed, out float rangedWeaponDamage, out float autoShotSpeed, out float autoShotsPerSecond, out float specialShotsPerSecond, out float totalShotsPerSecond, out float shotsPerSecondWithoutHawk, out RotationTest rotationTest) { #region Ranged Weapon Stats rangedWeaponDamage = 0; rangedWeaponSpeed = 0; if (character.Ranged != null) { rangedWeaponDamage = (character.Ranged.Item.MinDamage + character.Ranged.Item.MaxDamage) / 2f; rangedWeaponSpeed = character.Ranged.Item.Speed; } /* Projectiles/Ammo have been removed in Cata if (character.Projectile != null) { rangedAmmoDPS = (float)(character.Projectile.Item.MaxDamage + character.Projectile.Item.MinDamage) / 2f; } #endregion #region Static Haste Calcs // default quiver speed calculatedStats.hasteFromBase = 0.15f; // haste from haste rating calculatedStats.hasteFromRating = StatConversion.GetHasteFromRating(stats.HasteRating, character.Class); // haste buffs calculatedStats.hasteFromRangedBuffs = stats.RangedHaste; // total hastes calculatedStats.hasteStaticTotal = stats.PhysicalHaste; // Needed by the rotation test calculatedStats.autoShotStaticSpeed = rangedWeaponSpeed / (1f + calculatedStats.hasteStaticTotal); #endregion #region Rotation Test // Using the rotation test will get us better frequencies //RotationTest rotationTest = new RotationTest(character, calculatedStats, calcOpts, bossOpts); if (calcOpts.UseRotationTest) { // The following properties of CalculatedStats must be ready by this call: // * priorityRotation (shot order, durations, cooldowns) // * quickShotsEffect // * hasteStaticTotal // * autoShotStaticSpeed rotationTest.RunTest(); } #endregion #region Dynamic Haste Calcs /* http://elitistjerks.com/f74/t65904-hunter_dps_analyzer/p25/#post1887407 * 1) Base focus regen is 4.00. * 2) Pathing adds an additional 1% base focus regen per point (4.12 with 3/3 and no gear). * 3) WF/IT/HP and ISS don't modify base regen directly. * 4) Each 1% gear haste adds 2% base focus regen. * 5) Rapid Fire adds 40% base regen (4.00->5.60). * 6) Hero adds 30% base regen (4.00->5.20). * 7) Glyph of Rapid Fire adds 10% base regen (4.00->6.00). * 8) Focused Fire adds 15% base regen (4.00->4.60). // Now we have the haste, we can calculate steady shot cast time, // then rebuild other various stats. // (future enhancement: we only really need to rebuild steady shot) calculatedStats.steadyShot.Cd = 2f / (1f + calculatedStats.hasteStaticTotal); if (calcOpts.UseRotationTest) { calculatedStats.priorityRotation.initializeTimings(); calculatedStats.priorityRotation.recalculateRatios(); calculatedStats.priorityRotation.calculateFrequencySums(); } else { calculatedStats.priorityRotation.initializeTimings(); calculatedStats.priorityRotation.calculateFrequencies(); calculatedStats.priorityRotation.calculateFrequencySums(); } //float autoShotSpeed = rangedWeaponSpeed / (1f + calculatedStats.hasteStaticTotal); #endregion #region Shots Per Second float baseAutoShotsPerSecond = autoShotSpeed > 0 ? 1f / autoShotSpeed : 0; //float autoShotsPerSecond = baseAutoShotsPerSecond; //float specialShotsPerSecond = calculatedStats.priorityRotation.specialShotsPerSecond; //float totalShotsPerSecond = autoShotsPerSecond + specialShotsPerSecond; float crittingSpecialsPerSecond = calculatedStats.priorityRotation.critSpecialShotsPerSecond; float crittingShotsPerSecond = autoShotsPerSecond + crittingSpecialsPerSecond; //float shotsPerSecondWithoutHawk = specialShotsPerSecond + baseAutoShotsPerSecond; calculatedStats.BaseAttackSpeed = (float)autoShotSpeed; calculatedStats.shotsPerSecondCritting = crittingShotsPerSecond; #endregion } public float ConstrainCrit(float lvlDifMOD, float chance) { return Math.Min(1f + lvlDifMOD, Math.Max(0f, chance)); } */ 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 CharacterCalculationsHunter calc = new CharacterCalculationsHunter(); if (character == null) { return calc; } CalculationOptionsHunter calcOpts = character.CalculationOptions as CalculationOptionsHunter; if (calcOpts == null) { return calc; } // calc.character = character; calc.CalcOpts = calcOpts; BossOptions bossOpts = character.BossOptions; calc.BossOpts = bossOpts; HunterTalents talents = character.HunterTalents; Specialization hunterspec = GetSpecialization(talents); calc.Hunter = new HunterBase(character, this.GetCharacterStats(character, additionalItem, true), talents, hunterspec, bossOpts.Level); CombatFactors combatFactors = new CombatFactors(character, calc.Hunter.Stats, calcOpts, bossOpts); // WhiteAttacks whiteAttacks = new WhiteAttacks(character, calc.Hunter.Stats, combatFactors, calcOpts, bossOpts); Rotation Rot = new Rotation(combatFactors, talents); Rot.Initialize(calc); // Sets up the shots in the rotation and provides connection with the Calc object. calc.HunterDpsPoints = calc.CustomDPS; if (needsDisplayCalculations) { calc.HunterUnBuffed = new HunterBase(character, GetCharacterStats(character, additionalItem, false), talents, hunterspec, bossOpts.Level); } return calc; }