public WeightedStat[] GetUptimes(
            Stats stats,
            Dictionary <int, float> periods,
            Dictionary <int, float> chances,
            StatExtractor statExtractor,
            UptimeCombiner uptimeCombiner)
        {
            List <SpecialEffect> hasteEffects   = new List <SpecialEffect>();
            List <float>         hasteIntervals = new List <float>();
            List <float>         hasteChances   = new List <float>();
            List <float>         hasteOffsets   = new List <float>();
            List <float>         hasteScales    = new List <float>();
            List <float>         hasteValues    = new List <float>();

            foreach (SpecialEffect effect in stats.SpecialEffects())
            {
                if (!periods.ContainsKey((int)effect.Trigger))
                {
                    continue;
                }

                float value = statExtractor(effect.Stats);
                if (value > 0)
                {
                    hasteEffects.Add(effect);
                    hasteIntervals.Add(periods[(int)effect.Trigger]);
                    hasteChances.Add(chances[(int)effect.Trigger]);
                    hasteOffsets.Add(0f);
                    hasteScales.Add(1f);
                    hasteValues.Add(value);
                }
            }
            return(uptimeCombiner(
                       hasteEffects.ToArray(),
                       hasteIntervals.ToArray(),
                       hasteChances.ToArray(),
                       hasteOffsets.ToArray(),
                       hasteScales.ToArray(),
                       CalculationsWarlock.AVG_UNHASTED_CAST_TIME,
                       Options.Duration,
                       hasteValues.ToArray()));
        }
        public WeightedStat[] GetUptimes(Stats stats, Dictionary<int, float> periods, Dictionary<int, float> chances, StatExtractor statExtractor, UptimeCombiner uptimeCombiner)
        {
            List<SpecialEffect> hasteEffects = new List<SpecialEffect>();
            List<float> hasteIntervals = new List<float>();
            List<float> hasteChances = new List<float>();
            List<float> hasteOffsets = new List<float>();
            List<float> hasteScales = new List<float>();
            List<float> hasteValues = new List<float>();
            foreach (SpecialEffect effect in stats.SpecialEffects())
            {
                if (!periods.ContainsKey((int)effect.Trigger))
                {
                    continue;
                }

                float value = statExtractor(effect.Stats);
                if (value > 0)
                {
                    hasteEffects.Add(effect);
                    hasteIntervals.Add(periods[(int)effect.Trigger]);
                    hasteChances.Add(chances[(int)effect.Trigger]);
                    hasteOffsets.Add(0f);
                    hasteScales.Add(1f);
                    hasteValues.Add(value);
                }
            }
            return uptimeCombiner(
                    hasteEffects.ToArray(),
                    hasteIntervals.ToArray(),
                    hasteChances.ToArray(),
                    hasteOffsets.ToArray(),
                    hasteScales.ToArray(),
                    CalculationsWarlock.AVG_UNHASTED_CAST_TIME,
                    BossOpts.BerserkTimer,
                    hasteValues.ToArray());
        }