Ejemplo n.º 1
0
        public void calculateFrequencySums()
        {
            specialShotsPerSecond     = 0f;
            critSpecialShotsPerSecond = 0f;
            critsRatioSum             = 0f;

            // 31-10-2009 Drizz: Updated to follow 92b
            // I still don't understand the method of how critSpecialShotsPerSecond is calculated.

            for (int i = 0; i < priorities.Length; i++)
            {
                if (priorities[i] == null)
                {
                    continue;
                }
                ShotData s = priorities[i];

                if (s.final_freq > 0)
                {
                    specialShotsPerSecond += 1f / s.final_freq;

                    if (s.Type == Shots.SerpentSting)
                    {
                        critSpecialShotsPerSecond += 1f / (s.final_freq / s.rotation_cooldown * 3f);
                    }
                    else
                    {
                        critSpecialShotsPerSecond += 1f / (s.final_freq);
                    }
                }
                critsRatioSum += s.CritsRatio;
            }
        }
Ejemplo n.º 2
0
 public RotationShotInfo(ShotData shot)
 {
     this.type      = shot.Type;
     this.cooldown  = shot.Cd;
     this.castTime  = shot.Cd;
     this.check_gcd = shot.TriggersGCD;
     this.no_gcd    = !shot.TriggersGCD && shot.Type != Shots.Readiness;
     this.damage    = shot.Damage;
     if (shot.Type == Shots.SerpentSting)
     {
         this.cooldown = shot.Duration;
     }
 }
Ejemplo n.º 3
0
        public void calculateRotationMPS()
        {
            MPS = 0;
            for (int i = 0; i < priorities.Length; i++)
            {
                if (priorities[i] != null)
                {
                    ShotData s = priorities[i];

                    s.calculateMPS(this);

                    MPS += s.MPS;
                }
            }
        }
Ejemplo n.º 4
0
        public void calculateCrits()
        {
            // called after we find out shot crit rates.
            // we calculated frequencies and ratios in earlier calls.

            critsCompositeSum = 0f;

            for (int i = 0; i < priorities.Length; i++)
            {
                if (priorities[i] == null)
                {
                    continue;
                }
                ShotData s = priorities[i];

                s.calculateComposites(this);
                critsCompositeSum += s.CritsComposite;
            }
        }
Ejemplo n.º 5
0
        public void calculateFrequencies()
        {
            // This function calculates the frequencies for each shot.
            // We have already calculated all shot cooldowns and validated the rotation by this point.

            // THIS FUNCTION IS CALLED THREE TIMES - TRY TO REMEMBER THIS!
            // 1) When we have mana and basic timings
            // 2) When we have LAL proc info
            // 3) When we have steady shot speed

            ShotData PrevShot = null;

            for (int i = 0; i < priorities.Length; i++)
            {
                if (priorities[i] == null)
                {
                    continue;
                }
                ShotData s = priorities[i];
                s.calculateTimings(this, PrevShot);

                PrevShot = s;
            }
        }
Ejemplo n.º 6
0
        public void calculateRotationDPS()
        {
            bool debug_shot_rotation = false;

            DPS = 0;

            for (int i = 0; i < priorities.Length; i++)
            {
                if (priorities[i] != null)
                {
                    ShotData s = priorities[i];

                    s.calculateDPS(this);

                    #region Spreadsheet Calculations

                    // the hidden shot calculations!
                    // G  (RotationCooldown)
                    // H  (Mana)
                    // I  (Damage)
                    // J  (TimeUsed)
                    // K  (Ratio) =IF(OR(AND(ChimeraRefreshesViper,E30="Viper Sting"),AND(ChimeraRefreshesSerpent,E30="Serpent Sting")),"Refreshed",AB30)
                    // N  (MPS) =IF(AND(NOT(UseRotationTest),OR(E30="Explosive Shot",E30="Arcane Shot)),V30,IF(L30="Refreshed","Refreshed",AD30))
                    // O  (StartFreq) =IF(AJ30=TRUE,0,IF(G30>J30,ROUNDUP((G30-J30)/(GCD+CastLag),0)*(GCD+CastLag)+J30,GCD+CastLag))*IF(VLOOKUP(E30,ShotsTable,8,FALSE)<>FALSE,1,0)
                    // P  (GCDLeft)
                    // Q  (GCDNeeded) =IF(AND(NOT(UseKillShot,E30="Kill Shot"),0,IF(OR(AND(ChimeraRefreshesViper,E30="Viper Sting"),AND(ChimeraRefreshesSerpent,E30="Serpent Sting")),0,IF(O30>0,IF(J30>O30,1,J30/O30),0)))
                    // R  (GCDUsed)
                    // S  (InBetFreq) =IF(AND(O30>0,R30>0),J30/R30,0)
                    // T  (InBetStings)
                    // W  (LALFreq) =IF(OR(O30=0,T30=2),0,IF(E30="Explosive Shot",IF(LALExplosiveFrequency>0,LALExplosiveFrequency,S30),IF(E30="Arcane Shot",IF(LALArcaneFrequency>0,LALArcaneFrequency,S30),S30)))
                    // X  (LALGCDLeft)
                    // Y  (LALGCDNeeded) =IF(AND(NOT(UseKillShot),E30="Kill Shot"),0,IF(AND(ChimeraRefreshesSerpent,E30="Serpent Sting"),0,IF(W30>0,IF(J30>W30,1,J30/W30),0)))
                    // Z  (LALGCDUsed)
                    // AA (ActualFreq) =IF(UseRotationTest,'Rotation Test'!D11,IF(AND(W30>0,Z30>0),J3/Z30,0))
                    // AB (ActualRatio) =IF(AND(NOT(UseKillShot),E30="Kill Shot"),0,IF(AND(ChimeraRefereshesSerpent,E30="Serpent Sting"),0,IF(AA30>0,IF(J30>AA30,1,J30/AA30),0)))
                    // AC (ActualDPS) =IF(OR(AND(ChimeraRefreshesViper,E30="Viper Sting"),AND(ChimeraRefreshesSerpent,E30="Serpent Sting")),I30/G30,IF(AA30>0,I30/AA30,0))
                    // AD (ActualMPS) =IF(OR(AND(ChimeraRefreshesViper,E30="Viper Sting"),AND(ChimeraRefreshesSerpent,E30="Serpent Sting")),0,IF(AA30>0,H30/AA30,0))
                    // AJ (InvalidShotPriority) =IF(VLOOKUP(E30,ShotPriorityList,2,FALSE)<>F30,TRUE,OR(IF(AND(E30="Arcane Shot",ExplosiveInRotation),IF(VLOOKUP("Explosive Shot",ShotPriorityList,2,FALSE)<F30,TRUE,FALSE),FALSE,IF(AND(

                    #endregion

                    DPS += s.DPS;

                    if (debug_shot_rotation)
                    {
                        string col1 = String.Format("{0,6:0.00}", s.rotation_cooldown);
                        string col2 = String.Format("{0,3:0}", s.ManaCost);
                        string col3 = String.Format("{0,4:0}", s.Damage);
                        string col4 = String.Format("{0:0.00}", s.time_used);
                        string col5 = String.Format("{0,6:0.00}%", 100 * s.ratio);
                        string col6 = String.Format("{0,6:0.00}", s.Freq);
                        string col7 = String.Format("{0,6:0.00}", s.DPS);
                        string col8 = String.Format("{0,6:0.00}", s.MPS);

                        Debug.WriteLine("Shot: |" + col1 + "|" + col2 + "|" + col3 + "|" + col4 + "|" + col5 + "|" + col6 + "|" + col7 + "|" + col8 + "|");
                    }
                }
                else
                {
                    if (debug_shot_rotation)
                    {
                        Debug.WriteLine("None: |------|---|----|----|-------|------|  0.00|  0.00|");
                    }
                }
            }

            if (debug_shot_rotation)
            {
                string debug_dps = String.Format("{0,6:0.00}", DPS);
                string debug_mps = String.Format("{0,6:0.00}", MPS);

                Debug.WriteLine("TOTAL:                                    |" + debug_dps + "|" + debug_mps + "|");
            }
        }
Ejemplo n.º 7
0
        public void calculateLALProcs(Character character)
        {
            float lal_trigger_freq     = 0f;
            float lal_trigger_duration = 0f;

            ShotData proc_shot = null;

            if (proc_shot == null)
            {
                proc_shot = getShotInRotation(Shots.BlackArrow);
            }
            if (proc_shot == null)
            {
                proc_shot = getShotInRotation(Shots.ImmolationTrap);
            }
            if (proc_shot == null)
            {
                proc_shot = getShotInRotation(Shots.ExplosiveTrap);
            }
            if (proc_shot == null)
            {
                proc_shot = getShotInRotation(Shots.FreezingTrap);
            }
            if (proc_shot == null)
            {
                proc_shot = getShotInRotation(Shots.FrostTrap);
            }
            if (proc_shot == null)
            {
                proc_shot = getShotInRotation(Shots.Volley);
            }

            if (proc_shot != null)
            {
                lal_trigger_freq     = proc_shot.lal_freq;
                lal_trigger_duration = proc_shot.Duration;
            }

            float lal_proc_chance = 0.02f * character.HunterTalents.LockAndLoad;
            //lal_proc_chance = 0.06; //isolation testing for LAL
            float lal_proc_freq = 0f;

            if (CalcOpts.UseRotationTest)
            {
                // the spreadsheet gets the LAL proc frequency from the rotation test,
                // but it doesn't really matter because it's only used to calculate some
                // stats we'll throw away (final_freq via lal_freq).
            }
            else
            {
                if (lal_trigger_freq > 0 && lal_proc_chance > 0)
                {
                    lal_proc_freq = (lal_trigger_duration > lal_trigger_freq ? 1f : lal_trigger_freq / lal_trigger_duration) * 3f / lal_proc_chance;
                }
            }

            ShotData lalExplosive = getShotInRotation(Shots.ExplosiveShot);
            ShotData lalArcane    = getShotInRotation(Shots.ArcaneShot);

            float pre_lal_explosive_freq = (lalExplosive != null && CalcOpts.LALShotToUse == Shots.ExplosiveShot) ? lalExplosive.inbet_freq : 0;
            float pre_lal_arcane_freq    = (lalArcane != null && CalcOpts.LALShotToUse == Shots.ArcaneShot) ? lalArcane.inbet_freq : 0;

            LALExplosiveFrequency = 0;
            if (lal_proc_freq > 0 && pre_lal_explosive_freq > 0)
            {
                LALExplosiveFrequency = 1f / (1f / (lal_proc_freq / (pre_lal_explosive_freq / (pre_lal_arcane_freq + pre_lal_explosive_freq) * CalcOpts.LALShotsReplaced)) + 1f / pre_lal_explosive_freq);
            }

            LALArcaneFrequency = 0;
            if (lal_proc_freq > 0 && pre_lal_arcane_freq > 0)
            {
                LALArcaneFrequency = 1f / (1f / (lal_proc_freq / (pre_lal_arcane_freq / (pre_lal_explosive_freq + pre_lal_arcane_freq) * CalcOpts.LALShotsReplaced)) + 1f / pre_lal_arcane_freq);
            }
        }
Ejemplo n.º 8
0
        public void calculateTimings(ShotPriority Priority, ShotData PrevShot)
        {
            float CastLag = Priority.CalcOpts.Latency;

            #region Starting Calculations

            start_freq = (rotation_cooldown > time_used) ? (float)Math.Ceiling((rotation_cooldown - time_used) / (GCD + CastLag)) * (GCD + CastLag) + time_used : GCD + CastLag;

            start_gcd_needed = (start_freq > 0) ? (time_used > start_freq ? 1f : time_used / start_freq) : 0f;

            if (Priority.chimeraRefreshesSerpent && Type == Shots.SerpentSting)
            {
                start_gcd_needed = 0f;
            }
            if (!Priority.useKillShot && Type == Shots.KillShot)
            {
                start_gcd_needed = 0f;
            }

            start_gcd_left = 1f;
            if (PrevShot != null)
            {
                start_gcd_left = PrevShot.start_gcd_left - PrevShot.start_gcd_used;
            }

            start_gcd_used = 1f - (start_gcd_left - start_gcd_needed);
            if (PrevShot != null)
            {
                start_gcd_used = start_gcd_left > start_gcd_needed ? start_gcd_needed : start_gcd_left;
            }

            //Debug.WriteLine("Start Freq is " + start_freq);
            //Debug.WriteLine("GCD Left is " + start_gcd_left);
            //Debug.WriteLine("GCD Needed is " + start_gcd_needed);
            //Debug.WriteLine("GCD Used is " + start_gcd_used);

            #endregion
            #region In-Between Calculations

            inbet_freq = (start_freq > 0 && start_gcd_used > 0) ? time_used / start_gcd_used : 0;

            if (PrevShot != null)
            {
                if (Type == Shots.SerpentSting)
                {
                    sting_count = PrevShot.sting_count < 2 ? PrevShot.sting_count + 1 : PrevShot.sting_count;
                }
                else
                {
                    sting_count = PrevShot.sting_count == 2 ? 3 : PrevShot.sting_count;
                }
            }
            else
            {
                sting_count = (Type == Shots.SerpentSting) ? 1 : 0;
            }

            //Debug.WriteLine("Pre-LAL freq = "+inbet_freq);
            //Debug.WriteLine("Pre-LAL sting count = " + sting_count);

            #endregion
            #region Lock-and-Load Calculations

            lal_freq = inbet_freq;
            if (Type == Shots.ExplosiveShot && Priority.LALExplosiveFrequency > 0f)
            {
                lal_freq = Priority.LALExplosiveFrequency;
            }
            if (Type == Shots.ArcaneShot && Priority.LALArcaneFrequency > 0f)
            {
                lal_freq = Priority.LALArcaneFrequency;
            }
            if (start_freq == 0f || sting_count == 2f)
            {
                lal_freq = 0f;
            }

            lal_gcd_left = 1;
            if (PrevShot != null)
            {
                lal_gcd_left = PrevShot.lal_gcd_left - PrevShot.lal_gcd_used;
            }

            lal_gcd_needed = lal_freq > 0f ? (time_used > lal_freq ? 1f : time_used / lal_freq) : 0f;
            if (!Priority.useKillShot && Type == Shots.KillShot)
            {
                lal_gcd_needed = 0f;
            }
            if (Priority.chimeraRefreshesSerpent && Type == Shots.SerpentSting)
            {
                lal_gcd_needed = 0f;
            }

            lal_gcd_used = 1f - (lal_gcd_left - lal_gcd_needed);
            if (PrevShot != null)
            {
                lal_gcd_used = lal_gcd_left > lal_gcd_needed ? lal_gcd_needed : lal_gcd_left;
            }

            #endregion

            // RotationTest may come in later and override this value,
            // hence the split-function that we call here
            final_freq = (lal_freq > 0 && lal_gcd_used > 0) ? time_used / lal_gcd_used : 0;

            finishCalculateTimings(Priority);
        }
Ejemplo n.º 9
0
        public void calculateTimings(ShotPriority Priority, ShotData PrevShot)
        {
            float CastLag = Priority.CalcOpts.Latency;

            #region Starting Calculations

            start_freq = (rotation_cooldown > time_used) ? (float)Math.Ceiling((rotation_cooldown - time_used) / (GCD + CastLag)) * (GCD + CastLag) + time_used : GCD + CastLag;

            start_gcd_needed = (start_freq > 0) ? (time_used > start_freq ? 1f : time_used / start_freq) : 0f;

            if (Priority.chimeraRefreshesSerpent && Type == Shots.SerpentSting) start_gcd_needed = 0f;
            if (!Priority.useKillShot && Type == Shots.KillShot) start_gcd_needed = 0f;

            start_gcd_left = 1f;
            if (PrevShot != null) {
                start_gcd_left = PrevShot.start_gcd_left - PrevShot.start_gcd_used;
            }

            start_gcd_used = 1f - (start_gcd_left - start_gcd_needed);
            if (PrevShot != null) {
                start_gcd_used = start_gcd_left > start_gcd_needed ? start_gcd_needed : start_gcd_left;
            }

            //Debug.WriteLine("Start Freq is " + start_freq);
            //Debug.WriteLine("GCD Left is " + start_gcd_left);
            //Debug.WriteLine("GCD Needed is " + start_gcd_needed);
            //Debug.WriteLine("GCD Used is " + start_gcd_used);

            #endregion
            #region In-Between Calculations

            inbet_freq = (start_freq > 0 && start_gcd_used > 0) ? time_used / start_gcd_used : 0;

            if (PrevShot != null) {
                if (Type == Shots.SerpentSting) {
                    sting_count = PrevShot.sting_count < 2 ? PrevShot.sting_count + 1 : PrevShot.sting_count;
                } else {
                    sting_count = PrevShot.sting_count == 2 ? 3 : PrevShot.sting_count;
                }
            } else {
                sting_count = (Type == Shots.SerpentSting) ? 1 : 0;
            }

            //Debug.WriteLine("Pre-LAL freq = "+inbet_freq);
            //Debug.WriteLine("Pre-LAL sting count = " + sting_count);

            #endregion
            #region Lock-and-Load Calculations

            lal_freq = inbet_freq;
            if (Type == Shots.ExplosiveShot && Priority.LALExplosiveFrequency > 0f) lal_freq = Priority.LALExplosiveFrequency;
            if (Type == Shots.ArcaneShot && Priority.LALArcaneFrequency > 0f) lal_freq = Priority.LALArcaneFrequency;
            if (start_freq == 0f || sting_count == 2f) lal_freq = 0f;

            lal_gcd_left = 1;
            if (PrevShot != null) {
                lal_gcd_left = PrevShot.lal_gcd_left - PrevShot.lal_gcd_used;
            }

            lal_gcd_needed = lal_freq > 0f ? (time_used > lal_freq ? 1f : time_used / lal_freq) : 0f;
            if (!Priority.useKillShot && Type == Shots.KillShot) lal_gcd_needed = 0f;
            if (Priority.chimeraRefreshesSerpent && Type == Shots.SerpentSting) lal_gcd_needed = 0f;

            lal_gcd_used = 1f - (lal_gcd_left - lal_gcd_needed);
            if (PrevShot != null) {
                lal_gcd_used = lal_gcd_left > lal_gcd_needed ? lal_gcd_needed : lal_gcd_left;
            }

            #endregion

            // RotationTest may come in later and override this value,
            // hence the split-function that we call here
            final_freq = (lal_freq > 0 && lal_gcd_used > 0) ? time_used / lal_gcd_used : 0;

            finishCalculateTimings(Priority);
        }
Ejemplo n.º 10
0
        public void RunTest()
        {
            float FightDuration = BossOpts.BerserkTimer;
            float Latency       = CalcOpts.Latency;
            float CDCutoff      = CalcOpts.CDCutoff;
            float Longevity     = character.HunterTalents.Longevity;
            float GCD           = 1.5f;
            float BA            = calculatedStats.blackArrow.Duration;
            float it            = calculatedStats.immolationTrap.Duration;
            float et            = calculatedStats.explosiveTrap.Duration;
            float ft            = calculatedStats.freezingTrap.Duration;
            float frt           = calculatedStats.frostTrap.Duration;
            //float vly = calculatedStats.volley.Duration;
            float LALChance     = character.HunterTalents.BlackArrow == 1 ? character.HunterTalents.LockAndLoad * CalcOpts.LALProcChance : -1;
            bool  RandomProcs   = CalcOpts.RandomizeProcs;
            int   ISSfix        = 0;
            int   IAotHfix      = 0;
            int   LALfix        = 0;
            float AutoShotSpeed = 2; // Speed at which we shoot auto-shots
            //float IAotHEffect = 1 + calculatedStats.quickShotsEffect; // haste increase during IAoTH
            float IAotHChance      = -1;
            float WaitForESCS      = CalcOpts.waitForCooldown;
            bool  InterleaveLAL    = CalcOpts.interleaveLAL;
            bool  ArcAimedPrio     = CalcOpts.prioritiseArcAimedOverSteady;
            float ISSTalent        = character.HunterTalents.ImprovedSteadyShot * 5;
            float ISSDuration      = -1;
            int   ISSprocsAimed    = 0;
            int   ISSProcsArcane   = 0;
            int   ISSProcsChimera  = 0;
            float BossHPPercentage = CalcOpts.BossHPPerc * 100;
            float Sub20Time        = (BossHPPercentage > 20) ? FightDuration - (float)BossOpts.Under20Perc * FightDuration : 0; // time *until* we hit sub-20
            bool  UseKillShot      = calculatedStats.priorityRotation.containsShot(Shots.KillShot);
            bool  BMSpec           = character.HunterTalents.BestialWrath + character.HunterTalents.TheBeastWithin > 0;

            if (CalcOpts.PetFamily == PETFAMILY.None)
            {
                BMSpec = false;
            }

            int   currentShot;
            float currentTime;
            //int selectedShot;
            float ElapsedTime;
            float BWTime;
            float RFTime;
            //float VolleyTime;
            float BWCD;
            float RFCD;
            //float VLYCD;
            float LALTimer;          // timer till current serpent sting expires
            float LALShots;          // amount of free shots left
            float LALDuration;       // time since last Explosive Shot while having L&L up
            float LastLALCheck;      // time since last check for proc
            float LastLALProc;       // time since last proc
            int   LALProcs;          // Amount of procs
            Shots LALType;           // Type of L&L proc, i.e. Immolation trap or Black Arrow
            float IAotHDuration;     // Time until buff expires
            float LastAutoShotCheck; // Last time we checked for IAotH procs
            int   IAotHProcs;
            bool  SerpentUsed;       // Have we used Serpent Sting yet?

            #region Initialize shotData & shotTable
            shotData  = new Dictionary <Shots, RotationShotInfo>(); // the shot info (focus, cooldown, etc)
            shotTable = new RotationShotInfo[10];                   // the rotation info

            for (int i = 0; i < calculatedStats.priorityRotation.priorities.Length; i++)
            {
                ShotData shot = calculatedStats.priorityRotation.priorities[i];
                if (shot != null && shot.Type != Shots.None)
                {
                    shotData[shot.Type] = new RotationShotInfo(shot);
                    shotTable[i]        = shotData[shot.Type];
                }
                else
                {
                    shotTable[i] = null;
                }
            }
            #endregion
            #region Shot Timing Adjustments

            // we need to adjust rapid fire cooldown, since we accounted for readiness initially
            if (shotData.ContainsKey(Shots.RapidFire))
            {
                shotData[Shots.RapidFire].cooldown = (5 - character.HunterTalents.RapidKilling) * 60f;
            }

            // set Steady Shot cast time so it's only static haste
            if (shotData.ContainsKey(Shots.SteadyShot))
            {
                //shotData[Shots.SteadyShot].castTime = 2f / (1f + calculatedStats.hasteStaticTotal);
            }

            // Set Auto Shot Speed to statically hasted value
            AutoShotSpeed = 0f;//calculatedStats.autoShotStaticSpeed;

            #endregion
            #region Variable setup

            // these are used by both the frequency rotation and here in the rotation test
            bool chimeraRefreshesSerpent = containsShot(Shots.ChimeraShot) && containsShot(Shots.SerpentSting);

            currentShot = 1;
            currentTime = 0;
            ElapsedTime = 0;

            //Lock And Load variables
            LALTimer     = -1;
            LALShots     = -1;
            LALDuration  = -1;
            LastLALCheck = -1;
            LastLALProc  = -50;
            LALType      = Shots.None;

            //IAotH variables
            // 021109 Drizz: Updating init variables to align with v92b spreadsheet
            LastAutoShotCheck = 0; // -50;
            IAotHDuration     = 0; // -1;
            IAotHProcs        = 0;

            SerpentUsed = false;

            // some things not initialized in the spreadsheet
            BWTime = 0;
            //VolleyTime = 0;
            RFTime = 0;
            BWCD   = 0;
            RFCD   = 0;
            //VLYCD = 0;
            currentTime = 0;
            LALProcs    = 0;
            float IAotHUptime = 0;

            #endregion
            #region The Main Loop
            do
            {
                bool  haveShot = false;
                Shots thisShot = Shots.None;

                #region Find shot - Non-GCD

                // Check shots that are off the GCD
                for (int i = 0; i < shotTable.Length && !haveShot; i++)
                {
                    RotationShotInfo s = shotTable[i];
                    if (s != null)
                    {
                        if (s.type == Shots.BestialWrath && BWTime > currentTime)
                        {
                            // do nothing if Rapid Fire is still active
                        }
                        else if (s.type == Shots.RapidFire && RFTime > currentTime)
                        {
                            // Check if TBW/BW CD is nearly up if we want to use Rapid Fire
                        }
                        else if (BMSpec && s.type == Shots.Readiness && BWCD < (currentTime + CDCutoff))
                        {
                            // Wait for Rapid Fire if it's close too
                        }
                        else if (s.type == Shots.Readiness && RFCD < (currentTime + CDCutoff))
                        {
                            // wait for Rapid Fire
                        }
                        else if (s.type == Shots.BestialWrath && !BMSpec)
                        {
                            // do nothing
                            //} else if (s.type == Shots.Volley && VLYCD < (currentTime + CDCutoff)) {
                            // do nothing, we're channelling
                        }
                        else
                        {
                            // check if the shot is off the GCD
                            if (s.no_gcd && s.time_until_off_cd <= currentTime)
                            {
                                thisShot = s.type;
                                haveShot = true;
                            }
                        }
                    }
                }

                #endregion
                #region Find Shot - Any

                // Check all shots whether they are off CD
                for (int i = 0; i < shotTable.Length && !haveShot; i++)
                {
                    RotationShotInfo s = shotTable[i]; // known as thisShot
                    if (s != null)
                    {
                        // During L&L proc Explosive Shot gets priority over everything else
                        // Do nothing if L&L just proc'ed and ES is still on CD
                        if (s.time_until_off_cd > currentTime && LALShots == 3 && s.type == Shots.ExplosiveShot)
                        {
                        }
                        //  First L&L proc shot
                        else if (s.time_until_off_cd < currentTime && LALShots == 3 && s.type == Shots.ExplosiveShot)
                        {
                            s.time_until_off_cd = 0;
                            LALShots--;
                            haveShot = true;
                            thisShot = s.type;
                            // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "L&L #1"
                        }
                        // If We're interleaving, make sure the last ES was at least 2 seconds before this
                        else if (InterleaveLAL && LALShots < 3 && LALShots > 0 && LALDuration - currentTime > -2 && LALDuration - currentTime <= 0 && s.type == Shots.ExplosiveShot)
                        {
                            currentTime        += 0.5f;
                            s.time_until_off_cd = 0;
                            haveShot            = true;
                            thisShot            = s.type;
                            if (LALShots == 2)
                            {
                                // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "L&L #2"
                            }
                            else if (LALShots == 1)
                            {
                                // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "L&L #3"
                            }
                            LALShots--;
                        }
                        // If we're not interleaving other shots with L&L procs reset ES cooldown and advance timer by 0.5 seconds (to miss the last tick)
                        else if (!InterleaveLAL && LALShots < 3 && LALShots > 0 && s.type == Shots.ExplosiveShot)
                        {
                            // ******************************************************************************
                            // 29-10-2009 - Drizz: Commenting out this line to align with Spreadsheet (v92b)
                            // currentTime += 0.5;
                            // ******************************************************************************
                            s.time_until_off_cd = 0;
                            haveShot            = true;
                            thisShot            = s.type;

                            if (LALShots == 2)
                            {
                                // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "L&L #2"
                            }
                            else if (LALShots == 1)
                            {
                                // Cells(row + 1, col + 5).value =  Cells(row + 1, col + 5).value + "L&L #3"
                            }
                            LALShots--;
                        }

                        float waitTime = (float)Math.Round(s.time_until_off_cd - currentTime, 2);

                        // Check if shots with CDs come off CD soon enough to wait for them, excluding stings
                        if (!haveShot && waitTime > 0 && s.time_until_off_cd > currentTime && s.time_until_off_cd <= currentTime + WaitForESCS &&
                            s.type != Shots.SerpentSting && s.type != Shots.BlackArrow)
                        {
                            if (!ArcAimedPrio && (thisShot == Shots.AimedShot || thisShot == Shots.ArcaneShot || thisShot == Shots.MultiShot))
                            {
                                // do nothing if we don't want to prioritise Aimed/Arcane or Multi-Shot
                            }
                            // ************************************************************************
                            //29-10-2009 Drizz : Added one else if check to align with Spreadsheet v92b
                            else if (s.type == Shots.Readiness && RFCD < (currentTime + CDCutoff + waitTime))
                            {
                                // Do nothing if we Rapid Fire isn't soon enough of CD
                            }
                            // ************************************************************************
                            else if (s.check_gcd)
                            {
                                bool result = true;

                                // Check if other shots that are about to come off CD do more damage than this one
                                for (int j = i; j < shotTable.Length && result; j++)
                                {
                                    RotationShotInfo thatShot = shotTable[j];
                                    if (thatShot != null)
                                    {
                                        // 021109 Drizz: Removed the last && on this line (align with Worksheet 92b.
                                        if (thatShot.time_until_off_cd > currentTime && thatShot.time_until_off_cd <= currentTime + WaitForESCS) // && checkGCD(thisShot))
                                        {
                                            if (compareDamage(thisShot, thatShot.type, waitTime) != thisShot)
                                            {
                                                result = false;
                                                // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "(Skipped " & thisShot & ") "
                                                //exit for loop
                                            }
                                        }
                                    }
                                }

                                if (result)
                                {
                                    currentTime = s.time_until_off_cd;
                                    thisShot    = s.type;
                                    haveShot    = true;
                                    // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "(Waited " & waitTime & "s) "
                                }
                            }
                        }

                        // this is a horrible round hack, i know. the issue probably comes
                        // somewhere from a float->float cast.
                        // the issue is that we have currentTime at (e.g.) 65.35 and steady shot CD is at 65.3500000001
                        // so we skip forward by 0.1 seconds when we didn;t really need to.
                        if (!haveShot && s.time_until_off_cd <= currentTime + 0.00001)
                        {
                            if (s.type == Shots.SerpentSting && chimeraRefreshesSerpent && SerpentUsed)
                            {
                                // do nothing for refreshed Serpent Sting except the first time
                            }
                            else if (s.type == Shots.KillShot && (!UseKillShot || currentTime < Sub20Time))
                            {
                                // Do not use Kill Shot if Boss HP is above 20%
                            }
                            else if (s.type == Shots.BestialWrath && BWTime > currentTime)
                            {
                                // do nothing if TBW or BW is still active
                            }
                            else if (s.type == Shots.RapidFire && RFTime > currentTime)
                            {
                                // do nothing if Rapid Fire is still active
                            }
                            else if (BMSpec && s.type == Shots.Readiness && BWCD < (currentTime + CDCutoff))
                            {
                                // Check if TBW/BW CD is nearly up if we want to use Rapid Fire
                            }
                            else if (s.type == Shots.Readiness && RFCD < (currentTime + CDCutoff))
                            {
                                // Wait for Rapid Fire if it's close too
                            }
                            else if (s.type == Shots.SerpentSting && FightDuration - currentTime < s.cooldown)
                            {
                                // do nothing if Rapid Fire is about to come off CD
                                // do nothing if we don't get all the ticks of Serpent Sting anyway
                            }
                            else if (s.type == Shots.BlackArrow && FightDuration - currentTime < BA)
                            {
                                // ditto for Black Arrow
                            }
                            else if (s.type == Shots.BestialWrath && !BMSpec)
                            {
                                // do nothing
                            }
                            else
                            {
                                thisShot = s.type;
                                haveShot = true;
                            }
                        }
                    }
                }

                #endregion
                #region Execute shot

                if (!haveShot)
                {
                    // If no shot, advance 100 ms
                    // This case should almost never happen unless Steady Shot isn't in the rotation
                    currentTime += 0.1f;
                    //Debug.WriteLine("no shot found - advancing time to "+currentTime);
                }
                else
                {
                    float currentAutoShotSpeed;

                    currentAutoShotSpeed = AutoShotSpeed;
                    RotationShotInfo thisShotInfo = shotData[thisShot];

                    if (thisShotInfo.type == Shots.SerpentSting && !SerpentUsed)
                    {
                        SerpentUsed = true;
                    }

                    // Adjust AutoShot Speed if Rapid Fire is active
                    if (RFTime > currentTime)
                    {
                        currentAutoShotSpeed *= 0.6f;
                    }

                    //  Adjust AutoShotSpeed if IAotH is active

                    /*if (IAotHDuration - currentTime > 0)
                     * {
                     *  currentAutoShotSpeed *= (1f / IAotHEffect);
                     * }*/

                    // Check if we had an auto shot since the last check
                    if (currentTime - LastAutoShotCheck > currentAutoShotSpeed)
                    {
                        // *******************************************************
                        // 021109 Drizz: Added if around LastAutoShotCheck, Updated from v92b (spreadsheet)
                        if (currentTime == 0)
                        {
                            LastAutoShotCheck = currentTime;
                        }
                        else
                        {
                            LastAutoShotCheck += currentAutoShotSpeed;
                        }
                        // *******************************************************

                        // 021109 Drizz: Updating to use "LastAutoShotCheck" instead of currentTime (Align with v92b)
                        if (RandomProcs)
                        {
                            // 10% proc chance
                            if (randomProc(IAotHChance))
                            {
                                if (IAotHDuration - LastAutoShotCheck < 0)
                                {
                                    // No IAotH proc active
                                    IAotHUptime = IAotHUptime + 12;
                                }
                                else
                                {
                                    IAotHUptime = IAotHUptime - (IAotHDuration - LastAutoShotCheck) + 12;
                                }
                                IAotHDuration = LastAutoShotCheck + 12;
                                IAotHProcs    = IAotHProcs + 1;
                            }
                        }
                        else if (IAotHChance > 0)
                        {
                            IAotHfix = IAotHfix + 1;
                            if (IAotHfix * IAotHChance > 100)
                            {
                                IAotHfix = 0; // reset counter
                                if (IAotHDuration - LastAutoShotCheck < 0)
                                {
                                    // No IAotH proc active
                                    IAotHUptime = IAotHUptime + 12;
                                }
                                else
                                {
                                    IAotHUptime = IAotHUptime - (IAotHDuration - LastAutoShotCheck) + 12;
                                }
                                IAotHDuration = LastAutoShotCheck + 12;
                                IAotHProcs    = IAotHProcs + 1;
                            }
                        }
                    }


                    // count shots
                    currentShot++;

                    // advance row on the test page
                    //row++

                    thisShotInfo.countUsed++;

                    // Determine Steady Shot haste
                    float SShaste = 1f;
                    if (RFTime > currentTime)
                    {
                        SShaste *= 1.4f;
                    }
                    //if (IAotHDuration > currentTime) SShaste *= IAotHEffect;


                    // Increment cooldown on the shot just fired
                    if (thisShot == Shots.SteadyShot && thisShotInfo.castTime * (1f / SShaste) < GCD + Latency)
                    {
                        thisShotInfo.time_until_off_cd = currentTime + GCD + Latency;
                    }
                    else if (thisShot == Shots.SteadyShot)
                    {
                        thisShotInfo.time_until_off_cd = currentTime + thisShotInfo.castTime * (1f / SShaste) + Latency;
                    }
                    else if (checkGCD(thisShot))
                    {
                        thisShotInfo.time_until_off_cd = currentTime + thisShotInfo.cooldown + Latency;
                    }
                    else
                    {
                        // Shots that are off the GCD do not incur latency
                        thisShotInfo.time_until_off_cd = currentTime + thisShotInfo.cooldown;
                    }


                    // Note down shot current time and shot used
                    // 091109 Drizz: If we now can get the debug info within Rawr, no need to go by debug option.

                    /*if (calculatedStats.collectSequence)
                     * {
                     *  float timeUsed = 0;
                     *  float castEnd = currentTime;
                     *  float onCDUntil = currentTime + thisShotInfo.cooldown;
                     *
                     *  // Note down cast time used, cast end time and time till CD
                     *  if (!checkGCD(thisShot))
                     *  {
                     *      // These do not cost time
                     *      // (we set these values just above)
                     *  }
                     *  else
                     *  {
                     *      // Steady Shot can fire faster than GCD so check
                     *      if (thisShot == Shots.SteadyShot)
                     *      {
                     *          timeUsed = thisShotInfo.castTime * (1 / SShaste) + Latency;
                     *          castEnd = currentTime + thisShotInfo.castTime * (1 / SShaste) + Latency;
                     *      }
                     *      //else if (thisShot == Shots.Volley)
                     *      //{
                     *      //    timeUsed = thisShotInfo.castTime + Latency;
                     *      //    castEnd = currentTime + thisShotInfo.castTime + Latency;
                     *      //}
                     *      else
                     *      {
                     *          // Other shots fire at GCD + Latency
                     *          timeUsed = GCD + Latency;
                     *          castEnd = currentTime + GCD + Latency;
                     *      }
                     *      onCDUntil = thisShotInfo.time_until_off_cd;
                     *  }
                     *  // 091109 Drizz: Removing the Debug.Writeline
                     *  //Debug.WriteLine(" "+ currentTime + ": " + thisShot + " (" +timeUsed+"/"+castEnd+"/"+onCDUntil + ")");
                     *  calculatedStats.sequence += String.Format("{0,6:0.00}:{1,-13}" + " : {2,7:0.000}:{3,7:0.000}:{4,7:0.000}", currentTime, thisShot, timeUsed, castEnd, onCDUntil) + Environment.NewLine;
                     #if !RAWR3 && !RAWR4 && !SILVERLIGHT
                     *  Debug.Flush();
                     #endif
                     * }
                     */

                    // Set L&L Timer after Black Arrow/Immolation Trap was used
                    if (thisShot == Shots.BlackArrow ||
                        thisShot == Shots.ImmolationTrap ||
                        thisShot == Shots.ExplosiveTrap ||
                        thisShot == Shots.FreezingTrap ||
                        thisShot == Shots.IceTrap)
                    {
                        switch (thisShot)
                        {
                        case Shots.BlackArrow: { LALTimer = currentTime + BA; break; }

                        case Shots.ImmolationTrap: { LALTimer = currentTime + it; break; }

                        case Shots.ExplosiveTrap: { LALTimer = currentTime + et; break; }

                        case Shots.FreezingTrap: { LALTimer = currentTime + ft; break; }

                        default: { LALTimer = currentTime + frt; break; }     // Shots.IceTrap
                        }
                        LALType      = thisShot;
                        LastLALCheck = currentTime - 3;
                    }


                    if (currentTime + thisShotInfo.cooldown > ElapsedTime)
                    {
                        if (thisShotInfo.cooldown < GCD + Latency)
                        {
                            ElapsedTime = currentTime + GCD + Latency;
                        }
                        else
                        {
                            ElapsedTime = currentTime + thisShotInfo.cooldown;
                        }
                    }

                    // If we have Improved Steady Shot and have just cast Steady Shot
                    if (ISSTalent > 0 && thisShot == Shots.SteadyShot)
                    {
                        if (RandomProcs)
                        {
                            if (randomProc(ISSTalent))
                            {
                                ISSDuration = currentTime + 12;
                            }
                        }
                        else if (ISSTalent > 0)
                        {
                            ISSfix++;
                            if (ISSfix * ISSTalent > 100)
                            {
                                ISSfix      = 0;
                                ISSDuration = currentTime + 12;
                            }
                        }
                    }

                    if (ISSDuration > currentTime)
                    {
                        if (thisShot == Shots.AimedShot)
                        {
                            ISSprocsAimed++;
                            ISSDuration = -1;
                            //Cells(row, col + 5).value = Cells(row, col + 5).value + "(ISS proc)"
                        }
                        else if (thisShot == Shots.ArcaneShot)
                        {
                            ISSProcsArcane++;
                            ISSDuration = -1;
                            //Cells(row, col + 5).value = Cells(row, col + 5).value + "(ISS proc)"
                        }
                        else if (thisShot == Shots.ChimeraShot)
                        {
                            ISSProcsChimera++;
                            ISSDuration = -1;
                            //Cells(row, col + 5).value = Cells(row, col + 5).value + "(ISS proc)"
                        }
                    }

                    // If we used Explosive Shot, set the duration of the debuff
                    if (thisShot == Shots.ExplosiveShot && LALShots > 0)
                    {
                        LALDuration = currentTime + 2;
                    }

                    // If we used Explosive Shot, set Arcane Shot on CD as well and likewise
                    if (thisShot == Shots.ArcaneShot && shotData.ContainsKey(Shots.ExplosiveShot))
                    {
                        shotData[Shots.ExplosiveShot].time_until_off_cd = currentTime + shotData[Shots.ExplosiveShot].cooldown + Latency;
                    }
                    if (thisShot == Shots.ExplosiveShot && shotData.ContainsKey(Shots.ArcaneShot))
                    {
                        shotData[Shots.ArcaneShot].time_until_off_cd = currentTime + shotData[Shots.ArcaneShot].cooldown + Latency;
                    }

                    // If we used Multi-Shot set Aimed Shot cooldown as well and vice-versa
                    if (thisShot == Shots.MultiShot && shotData.ContainsKey(Shots.AimedShot))
                    {
                        shotData[Shots.AimedShot].time_until_off_cd = currentTime + shotData[Shots.AimedShot].cooldown + Latency;
                    }
                    if (thisShot == Shots.AimedShot && shotData.ContainsKey(Shots.MultiShot))
                    {
                        shotData[Shots.MultiShot].time_until_off_cd = currentTime + shotData[Shots.MultiShot].cooldown + Latency;
                    }

                    // If Black Arrow is active (LALTimer) do check a proc every 3 seconds and if no LAL proc has occured within the last 22 seconds
                    if (LALTimer > currentTime && currentTime - LastLALCheck > 3 && LALDuration < currentTime && currentTime - LastLALProc > 22)
                    {
                        if (RandomProcs)
                        {
                            // And currentTime - LastLALProc > 30 Then --- currently no ICD
                            if (randomProc(LALChance))
                            {
                                //L&L procs
                                LALShots    = 3;
                                LastLALProc = currentTime;
                                LALProcs++;
                                //Cells(row, col + 5).value = Cells(row, col + 5).value + "(Proc L&L after this shot)"
                            }
                        }
                        else if (LALChance > 0)
                        {
                            LALfix++;
                            if (LALfix * LALChance > 100)
                            {
                                //L&L procs
                                LALShots    = 3;
                                LastLALProc = currentTime;
                                LALProcs++;
                                //Cells(row, col + 5).value = /Cells(row, col + 5).value + "(Proc L&L after this shot)"
                                LALfix = 0;
                            }
                        }
                        LastLALCheck = currentTime;
                    }

                    // If we used Beast Within, set duration to 18 seconds
                    if (thisShot == Shots.BestialWrath)
                    {
                        BWTime = currentTime + 10;
                        // also record the time when it comes off CD
                        BWCD = thisShotInfo.time_until_off_cd;
                    }

                    // If we used Volley, set duration to 6 seconds
                    //if (thisShot == Shots.Volley)
                    //{
                    //    VolleyTime = currentTime + thisShotInfo.castTime;
                    //    // also record the time when it comes off CD
                    //    VLYCD = thisShotInfo.time_until_off_cd;
                    //}

                    if (thisShot == Shots.RapidFire)
                    {
                        RFTime = currentTime + 15;
                        // also record the time when it comes off CD
                        RFCD = thisShotInfo.time_until_off_cd;
                    }

                    // If Readiness is used, reset CD on other shots
                    if (thisShot == Shots.Readiness)
                    {
                        // Reset everything but Readiness and Serpent Sting and TBW
                        for (int i = 0; i < shotTable.Length; i++)
                        {
                            RotationShotInfo s = shotTable[i];
                            if (s != null)
                            {
                                if (s.type != Shots.Readiness &&
                                    s.type != Shots.SerpentSting &&
                                    s.type != Shots.BestialWrath)
                                {
                                    s.time_until_off_cd = 0;
                                }
                            }
                        }
                    }

                    if (LALTimer > currentTime)
                    {
                        //Cells(row, col + 5).value = "(" & LALType & ") " + Cells(row, col + 5).value
                    }

                    // Advance time by 0 if the shot is off the GCD, otherwise by GCD+Latency
                    if (!checkGCD(thisShot))
                    {
                        // do nothing
                    }
                    else if (thisShot == Shots.SteadyShot && thisShotInfo.castTime * (1f / SShaste) < GCD + Latency)
                    {
                        currentTime += GCD + Latency;
                    }
                    else if (thisShot == Shots.SteadyShot)
                    {
                        currentTime += thisShotInfo.castTime * (1f / SShaste) + Latency;
                        //} else if (thisShot == Shots.Volley) {
                        //    currentTime += thisShotInfo.castTime + Latency;
                    }
                    else
                    {
                        currentTime += GCD + Latency;
                    }
                    // more here...
                }
                #endregion
            }while (currentTime < FightDuration - 1);

            #endregion
            #region Save Results

            foreach (var pair in shotData)
            {
                pair.Value.frequency = pair.Value.countUsed > 0 ? currentTime / pair.Value.countUsed : 0;
            }

            for (int i = 0; i < calculatedStats.priorityRotation.priorities.Length; i++)
            {
                ShotData s = calculatedStats.priorityRotation.priorities[i];
                if (s != null)
                {
                    s.setFrequency(calculatedStats.priorityRotation, shotData.ContainsKey(s.Type) ? shotData[s.Type].frequency : 0);
                }
            }

            this.TestTimeElapsed = currentTime;
            this.ISSProcsAimed   = ISSprocsAimed;
            this.ISSProcsArcane  = ISSProcsArcane;
            this.ISSProcsChimera = ISSProcsChimera;
            this.IAotHProcs      = IAotHProcs;
            this.IAotHTime       = IAotHUptime;
            this.LALProcCount    = LALProcs;

            this.IAotHUptime      = this.TestTimeElapsed > 0 ? 1.0f * this.IAotHTime / this.TestTimeElapsed : 0;
            this.ISSAimedUptime   = this.ISSProcsAimed > 0 ? 1.0f * this.ISSProcsAimed / shotData[Shots.AimedShot].countUsed : 0;
            this.ISSArcaneUptime  = this.ISSProcsArcane > 0 ? 1.0f * this.ISSProcsArcane / shotData[Shots.ArcaneShot].countUsed : 0;
            this.ISSChimeraUptime = this.ISSProcsChimera > 0 ? 1.0f * this.ISSProcsChimera / shotData[Shots.ChimeraShot].countUsed : 0;

            #endregion

            /*
             *  ActiveWorkbook.Names.Add name:="RotationTestResultNames", RefersToR1C1:= _
             *          "='Rotation Test'!R5C7:R" & row & "C7"
             *  ActiveWorkbook.Names.Add name:="RotationTestTable", RefersToR1C1:= _
             *          "='Rotation Test'!R5C6:R" & row & "C" & col + 5
             */
        }
Ejemplo n.º 11
0
        private ComparisonCalculationHunter comparisonFromShotDPF(ShotData shot)
        {
            ComparisonCalculationHunter comp = new ComparisonCalculationHunter();

            float dpm = shot.FocusCost > 0 ? (float)(shot.Damage / shot.FocusCost) : 0;

            comp.Name = Enum.GetName(typeof(Shots), shot.Type);
            comp.SubPoints = new float[] { dpm };
            comp.OverallPoints = dpm;
            return comp;
        }
Ejemplo n.º 12
0
 private ComparisonCalculationHunter comparisonFromShotRotationFocusPS(ShotData shot)
 {
     ComparisonCalculationHunter comp = new ComparisonCalculationHunter();
     comp.Name = Enum.GetName(typeof(Shots), shot.Type);
     comp.SubPoints = new float[] { (float)shot.FocusPS };
     comp.OverallPoints = (float)shot.FocusPS;
     return comp;
 }
Ejemplo n.º 13
0
        private ComparisonCalculationHunter comparisonFromShotSpammedMPS(ShotData shot)
        {
            ComparisonCalculationHunter comp = new ComparisonCalculationHunter();

            float shotWait = shot.Duration > shot.Cd ? shot.Duration : shot.Cd;
            float mps = shotWait > 0 ? (float)(shot.FocusCost / shotWait) : 0;

            comp.Name = Enum.GetName(typeof(Shots), shot.Type);
            comp.SubPoints = new float[] { mps };
            comp.OverallPoints = mps;
            return comp;
        }
Ejemplo n.º 14
0
        /*private ComparisonCalculationHunter[] GetPetTalentSpecsChart(Character character, CharacterCalculationsHunter calcs)
        {
            List<ComparisonCalculationBase> talentCalculations = new List<ComparisonCalculationBase>();
            Character newChar = character.Clone();

            /*PetTalentsBase nothing = character.CurrentTalents.Clone();
            for (int i = 0; i < nothing.Data.Length; i++) nothing.Data[i] = 0;
            for (int i = 0; i < nothing.GlyphData.Length; i++) nothing.GlyphData[i] = false;
            newChar.CurrentTalents = nothing;

            CharacterCalculationsBase baseCalc = Calculations.GetCharacterCalculations(newChar, null, false, true, true);
            CharacterCalculationsBase newCalc;
            ComparisonCalculationBase compare;

            bool same, found = false;
            foreach (SavedTalentSpec sts in SavedTalentSpec.SpecsFor(character.Class))
            {
                same = false;
                if (sts.Equals(character.CurrentTalents)) same = true;
                newChar.CurrentTalents = sts.TalentSpec();
                newCalc = Calculations.GetCharacterCalculations(newChar, null, false, true, true);
                compare = Calculations.GetCharacterComparisonCalculations(baseCalc, newCalc, sts.Name, same);
                compare.Item = null;
                compare.Name = sts.ToString();
                compare.Description = sts.Spec;
                talentCalculations.Add(compare);
                found = found || same;
            }
            if (!found)
            {
                newCalc = Calculations.GetCharacterCalculations(character, null, false, true, true);
                compare = Calculations.GetCharacterComparisonCalculations(baseCalc, newCalc, "Custom", true);
                talentCalculations.Add(compare);
            }
            //CGL_Legend.LegendItems = Calculations.SubPointNameColors;
            //ComparisonGraph.LegendItems = Calculations.SubPointNameColors;
            //ComparisonGraph.Mode = ComparisonGraph.DisplayMode.Subpoints;
            //ComparisonGraph.DisplayCalcs(talentCalculations.ToArray());
            return talentCalculations.ToArray();

            /*List<ComparisonCalculationHunter> talentCalculations = new List<ComparisonCalculationHunter>();
            Character baseChar = character.Clone(); CalculationOptionsHunter baseCalcOpts = baseChar.CalculationOptions as CalculationOptionsHunter;
            Character newChar = character.Clone(); CalculationOptionsHunter newCalcOpts = newChar.CalculationOptions as CalculationOptionsHunter;
            CharacterCalculationsHunter currentCalc;
            CharacterCalculationsHunter newCalc;
            ComparisonCalculationHunter compare;
            currentCalc = (CharacterCalculationsHunter)Calculations.GetCharacterCalculations(baseChar, null, false, true, false);

            foreach (PropertyInfo pi in baseCalcOpts.PetTalents.GetType().GetProperties())
            {
                PetTalentDataAttribute[] petTalentDatas = pi.GetCustomAttributes(typeof(PetTalentDataAttribute), true) as PetTalentDataAttribute[];
                int orig;
                if (petTalentDatas.Length > 0) {
                    PetTalentDataAttribute petTalentData = petTalentDatas[0];
                    orig = baseCalcOpts.PetTalents.Data[petTalentData.Index];
                    if (petTalentData.MaxPoints == (int)pi.GetValue(baseCalcOpts.PetTalents, null)) {
                        newCalcOpts.PetTalents.Data[petTalentData.Index]--;
                        newCalc = (CharacterCalculationsHunter)GetCharacterCalculations(newChar, null, false, true, false);
                        compare = (ComparisonCalculationHunter)GetCharacterComparisonCalculations(newCalc, currentCalc, petTalentData.Name, petTalentData.MaxPoints == orig);
                    } else {
                        newCalcOpts.PetTalents.Data[petTalentData.Index]++;
                        newCalc = (CharacterCalculationsHunter)GetCharacterCalculations(newChar, null, false, true, false);
                        compare = (ComparisonCalculationHunter)GetCharacterComparisonCalculations(currentCalc, newCalc, petTalentData.Name, petTalentData.MaxPoints == orig);
                    }
                    string text = string.Format("Current Rank {0}/{1}\r\n\r\n", orig, petTalentData.MaxPoints);
                    if (orig == 0) {
                        // We originally didn't have it, so first rank is next rank
                        text += "Next Rank:\r\n";
                        text += petTalentData.Description[0];
                    } else if (orig >= petTalentData.MaxPoints) {
                        // We originally were at max, so there isn't a next rank, just show the capped one
                        text += petTalentData.Description[petTalentData.MaxPoints - 1];
                    } else {
                        // We aren't at 0 or MaxPoints originally, so it's just a point in between
                        text += petTalentData.Description[orig - 1];
                        text += "\r\n\r\nNext Rank:\r\n";
                        text += petTalentData.Description[orig];
                    }
                    compare.Description = text;
                    compare.Item = null;
                    talentCalculations.Add(compare);
                    newCalcOpts.PetTalents.Data[petTalentData.Index] = orig;
                }
            }
            return talentCalculations.ToArray();
        }*/
#if FALSE
        private ComparisonCalculationHunter comparisonFromShotSpammedDPS(ShotData shot)
        {
            ComparisonCalculationHunter comp =  new ComparisonCalculationHunter();

            float shotWait = shot.Duration > shot.Cd ? shot.Duration : shot.Cd;
            float dps = shotWait > 0 ? (float)(shot.Damage / shotWait) : 0;

            comp.Name = Enum.GetName(typeof(Shots), shot.Type);
            comp.HunterDPSPoints = dps;
            comp.OverallPoints = dps;
            return comp;
        }
Ejemplo n.º 15
0
 public RotationShotInfo(ShotData shot)
 {
     this.type = shot.Type;
     this.cooldown = shot.Cd;
     this.castTime = shot.Cd;
     this.check_gcd = shot.TriggersGCD;
     this.no_gcd = !shot.TriggersGCD && shot.Type != Shots.Readiness;
     this.damage = shot.Damage;
     if (shot.Type == Shots.SerpentSting) this.cooldown = shot.Duration;
 }