Exemplo n.º 1
0
        private float ApplySpecialEffect(SpecialEffect effect, DPSWarrCharacter charStruct, Dictionary<Trigger, float> triggerIntervals, Dictionary<Trigger, float> triggerChances, ref Base.StatsWarrior applyTo)
        {
#if DEBUG
            //ConstructionCounts["ApplySpecialEffect"]++;
#endif
            float fightDuration = charStruct.BossOpts.BerserkTimer;
            float fightDuration2Pass = charStruct.CalcOpts.SE_UseDur ? fightDuration : 0;

            Stats effectStats = effect.Stats;

            float upTime = 0f;
            //float avgStack = 1f;
            /*if (effect.Stats.TargetArmorReduction > 0f || effect.Stats.ArmorPenetrationRating > 0f) {
                //int j = 0;
            }*/
            if (effect.Trigger == Trigger.Use) {
                if (effect.Stats._rawSpecialEffectDataSize == 1) {
                    upTime = effect.GetAverageUptime(0f, 1f, charStruct.CombatFactors.CMHItemSpeed, fightDuration2Pass);
                    //float uptime =  (effect.Cooldown / fightDuration);
                    List<SpecialEffect> nestedEffect = new List<SpecialEffect>();
                    nestedEffect.Add(effect.Stats._rawSpecialEffectData[0]);
                    Base.StatsWarrior _stats2 = new Base.StatsWarrior();
                    ApplySpecialEffect(effect.Stats._rawSpecialEffectData[0], charStruct, triggerIntervals, triggerChances, ref _stats2);
                    effectStats = _stats2;
                } else {
                    upTime = effect.GetAverageStackSize(0f, 1f, charStruct.CombatFactors.CMHItemSpeed, fightDuration2Pass); 
                }
            } else if (effect.Duration == 0f && triggerIntervals.ContainsKey(effect.Trigger) && !float.IsInfinity(triggerIntervals[effect.Trigger])) {
                upTime = effect.GetAverageProcsPerSecond(triggerIntervals[effect.Trigger], 
                                                         triggerChances[effect.Trigger],
                                                         charStruct.CombatFactors.CMHItemSpeed,
                                                         fightDuration2Pass);
            } else if (effect.Trigger == Trigger.ExecuteHit) {
                upTime = effect.GetAverageStackSize(triggerIntervals[effect.Trigger], 
                                                         triggerChances[effect.Trigger],
                                                         charStruct.CombatFactors.CMHItemSpeed,
                                                         fightDuration2Pass * (float)charStruct.BossOpts.Under20Perc);
            } else if (triggerIntervals.ContainsKey(effect.Trigger) && !float.IsInfinity(triggerIntervals[effect.Trigger])) {
                upTime = effect.GetAverageStackSize(triggerIntervals[effect.Trigger], 
                                                         triggerChances[effect.Trigger],
                                                         charStruct.CombatFactors.CMHItemSpeed,
                                                         fightDuration2Pass);
            }

            if (upTime > 0f) {
                if (effect.Duration == 0f) {
                    applyTo.Accumulate(effectStats, upTime * fightDuration);
                } else if (upTime <= effect.MaxStack) {
                    applyTo.Accumulate(effectStats, upTime);
                }
                return upTime;
            }
            return 0f;
        }
Exemplo n.º 2
0
        private void DoSpecialEffects(DPSWarrCharacter charStruct, List<SpecialEffect> bersMainHand, List<SpecialEffect> bersOffHand, Base.StatsWarrior statsTotal)
        {
#if DEBUG
            //ConstructionCounts["DoSpecialEffects"]++;
#endif
            #region Initialize Triggers
            Dictionary<Trigger, float> triggerIntervals = new Dictionary<Trigger, float>();
            Dictionary<Trigger, float> triggerChances = new Dictionary<Trigger, float>();

            CalculateTriggers(charStruct, triggerIntervals, triggerChances);
            #endregion

            #region ArPen Lists
            /*List<float> tempArPenRatings = new List<float>();
            List<float> tempArPenRatingsCapLimited = new List<float>();
            List<float> tempArPenRatingUptimes = new List<float>();
            List<SpecialEffect> tempArPenEffects = new List<SpecialEffect>();
            List<float> tempArPenEffectIntervals = new List<float>();
            List<float> tempArPenEffectChances = new List<float>();
            List<float> tempArPenEffectScales = new List<float>();*/
            #endregion

            // First Let's add InnerRage in, because that affects other calcs
            if (charStruct.CalcOpts.M_InnerRage) {
                AbilityWrapper ir = charStruct.Rot.GetWrapper<Skills.InnerRage>();
                statsTotal.Accumulate(((ir.Ability as Skills.InnerRage).Effect.Stats as Base.StatsWarrior), (ir.Ability as Skills.InnerRage).Effect.GetAverageUptime(0f, 1.00f));
            }

            List<SpecialEffect> critEffects = new List<SpecialEffect>();

            List<SpecialEffect> firstPass = new List<SpecialEffect>();
            List<SpecialEffect> secondPass = new List<SpecialEffect>();
            List<SpecialEffect> thirdPass = new List<SpecialEffect>();
            //bool doubleExecutioner = false;
            foreach (SpecialEffect effect in statsTotal.SpecialEffects())
            {
                effect.Stats.GenerateSparseData();

                if (!triggerIntervals.ContainsKey(effect.Trigger)) continue;
                else if (effect.Stats.CritRating > 0f)
                {
                    critEffects.Add(effect);
                }
                #region ArP Proc (which don't exist anymore)
                /*else if (effect.Stats.ArmorPenetrationRating > 0f)
                {
                    if (doubleExecutioner) continue;
                    Trigger realTrigger;
                    if (bersMainHand.Contains(effect))
                    {
                        bersMainHand.Remove(effect);
                        doubleExecutioner = true;
                        if (bersOffHand.Contains(effect))
                        {
                            bersOffHand.Remove(effect);
                            realTrigger = Trigger.MeleeHit;
                        }
                        else realTrigger = Trigger.MainHandHit;
                    }
                    else if (bersOffHand.Contains(effect))
                    {
                        bersOffHand.Remove(effect);
                        realTrigger = Trigger.OffHandHit;
                    }
                    else realTrigger = effect.Trigger;
                    tempArPenEffects.Add(effect);
                    tempArPenEffectIntervals.Add(triggerIntervals[realTrigger]);
                    tempArPenEffectChances.Add(triggerChances[realTrigger]);
                    tempArPenEffectScales.Add(1f);
                }*/
                #endregion
                else if (!bersMainHand.Contains(effect) && !bersOffHand.Contains(effect) &&
                   (effect.Stats.Agility > 0f ||
                    effect.Stats.HasteRating > 0f ||
                    effect.Stats.HitRating > 0f ||
                    effect.Stats.CritRating > 0f ||
                    effect.Stats.MasteryRating > 0f ||
                    effect.Stats.PhysicalHaste > 0f ||
                    effect.Stats.PhysicalCrit > 0f ||
                    effect.Stats.PhysicalHit > 0f))
                {
                    // These procs affect rotation
                    firstPass.Add(effect);
                }
                else if (!bersMainHand.Contains(effect) && !bersOffHand.Contains(effect) &&
                   (effect.Stats.FireDamage > 0 ||
                    effect.Stats.FireDamage > 0f ||
                    effect.Stats.NatureDamage > 0f ||
                    effect.Stats.ShadowDamage > 0f ||
                    effect.Stats.HolyDamage > 0f ||
                    effect.Stats.ArcaneDamage > 0f))
                {
                    // It's a Special Damage Proc
                    thirdPass.Add(effect);
                }
                else if (!bersMainHand.Contains(effect) && !bersOffHand.Contains(effect))
                {
                    // Any other stat proc
                    secondPass.Add(effect);
                }
            }

            #region ArP Proc Cap handling
            /*if (tempArPenEffects.Count == 0)
            {
                //tempArPenRatings.Add(0.0f);
                //tempArPenRatingUptimes.Add(1.0f);
            }
            else if (tempArPenEffects.Count == 1)
            { //Only one, add it to
                SpecialEffect effect = tempArPenEffects[0];
                float uptime = effect.GetAverageStackSize(tempArPenEffectIntervals[0], tempArPenEffectChances[0], charStruct.combatFactors.CmhItemSpeed,
                    (charStruct.calcOpts.SE_UseDur ? charStruct.bossOpts.BerserkTimer : 0f)) * tempArPenEffectScales[0];
                tempArPenRatings.Add(effect.Stats.ArmorPenetrationRating);
                tempArPenRatingUptimes.Add(uptime);
                tempArPenRatings.Add(0.0f);
                tempArPenRatingUptimes.Add(1.0f - uptime);
            }
            else if (tempArPenEffects.Count > 1)
            {
                //if (tempArPenEffects.Count >= 2)
                //{
                //    offset[0] = calcOpts.TrinketOffset;
                //}
                WeightedStat[] arPenWeights = SpecialEffect.GetAverageCombinedUptimeCombinations(tempArPenEffects.ToArray(), tempArPenEffectIntervals.ToArray(), tempArPenEffectChances.ToArray(), new float[tempArPenEffectChances.Count], tempArPenEffectScales.ToArray(), charStruct.combatFactors.CmhItemSpeed,
                    charStruct.bossOpts.BerserkTimer,
                    AdditiveStat.ArmorPenetrationRating);
                for (int i = 0; i < arPenWeights.Length; i++)
                {
                    tempArPenRatings.Add(arPenWeights[i].Value);
                    tempArPenRatingUptimes.Add(arPenWeights[i].Chance);
                }
            }*/
            // Get the average Armor Pen Rating across all procs
            /*if (tempArPenRatings.Count > 0f)
            {
                Stats originalStats = charStruct.combatFactors.StatS;
                int LevelDif = charStruct.bossOpts.Level- charStruct.Char.Level;

                float arpenBuffs = 0.0f;

                //float OriginalArmorReduction = StatConversion.GetArmorDamageReduction(charStruct.Char.Level, (int)StatConversion.NPC_ARMOR[LevelDif], originalStats.TargetArmorReduction, arpenBuffs, Math.Max(0f, originalStats.ArmorPenetrationRating));
                float AverageArmorPenRatingsFromProcs = 0f;
                float tempCap = StatConversion.RATING_PER_ARMORPENETRATION - StatConversion.GetRatingFromArmorPenetration(arpenBuffs);

                for (int i = 0; i < tempArPenRatings.Count; i++)
                {
                    tempArPenRatingsCapLimited.Add(Math.Max(0f, Math.Min(tempCap - originalStats.ArmorPenetrationRating, tempArPenRatings[i])));
                    //float bah = StatConversion.GetArmorDamageReduction(charStruct.Char.Level, (int)StatConversion.NPC_ARMOR[LevelDif], originalStats.TargetArmorReduction, arpenBuffs, Math.Max(0f, originalStats.ArmorPenetrationRating + tempArPenRatingsCapLimited[i]));
                    AverageArmorPenRatingsFromProcs += tempArPenRatingUptimes[i] * tempArPenRatingsCapLimited[i];
                }
                Stats dummyStats = new Stats();
                
                //float procArp = StatConversion.GetRatingFromArmorReduction(charStruct.Char.Level, (int)StatConversion.NPC_ARMOR[LevelDif], originalStats.TargetArmorReduction, arpenBuffs, ProccedArmorReduction);
                originalStats.ArmorPenetrationRating += AverageArmorPenRatingsFromProcs;//(procArp - originalStats.ArmorPenetrationRating);                
            }*/
            #endregion

            IterativeSpecialEffectsStats(charStruct, firstPass,  critEffects, triggerIntervals, triggerChances, 0f, true, new Base.StatsWarrior(), charStruct.CombatFactors.StatS);
            IterativeSpecialEffectsStats(charStruct, secondPass, critEffects, triggerIntervals, triggerChances, 0f, false, null, charStruct.CombatFactors.StatS);
            IterativeSpecialEffectsStats(charStruct, thirdPass,  critEffects, triggerIntervals, triggerChances, 0f, false, null, charStruct.CombatFactors.StatS);
        }