public new StatsPaladin Clone() { StatsPaladin clone = (StatsPaladin)this.MemberwiseClone(); StatsPaladin retVal = new StatsPaladin(); // retVal.Accumulate(base.Clone()); // retVal._rawAdditivePaladinData = (float[])clone._rawAdditivePaladinData.Clone(); retVal._rawMultiplicativePaladinData = (float[])clone._rawMultiplicativePaladinData.Clone(); retVal._rawInverseMultiplicativePaladinData = (float[])clone._rawInverseMultiplicativePaladinData.Clone(); retVal._rawNoStackPaladinData = (float[])clone._rawNoStackPaladinData.Clone(); // return(retVal); }
private void GetSpecialEffectsStats_Child(Dictionary<Trigger, float> triggerIntervals, Dictionary<Trigger, float> triggerChances, float weaponSpeed, CalculationOptionsProtPaladin calcOpts, BossOptions bossOpts, StatsPaladin stats, ref StatsPaladin statsSpecialEffects) { StatsPaladin effectsToAdd = new StatsPaladin(); float uptime = 0f; foreach (SpecialEffect effect in stats.SpecialEffects()) { switch (effect.Trigger) { case Trigger.Use: { if (calcOpts.TrinketOnUseHandling != "Ignore") { if (calcOpts.TrinketOnUseHandling == "Active") { statsSpecialEffects.Accumulate(effect.Stats); } else { effectsToAdd.Clear(); effectsToAdd.Accumulate(effect.GetAverageStats(0f, 1f, weaponSpeed, bossOpts.BerserkTimer)); // Health on Use Effects are never averaged. effectsToAdd.BattlemasterHealthProc = 0.0f; effectsToAdd.Health = 0.0f; statsSpecialEffects.Accumulate(effectsToAdd); } // Recursive Effects foreach (SpecialEffect childEffect in effect.Stats.SpecialEffects()) { effectsToAdd.Clear(); GetSpecialEffectsStats_Child(triggerIntervals, triggerChances, weaponSpeed, calcOpts, bossOpts, stats, ref effectsToAdd); statsSpecialEffects.Accumulate(effectsToAdd, effect.GetAverageUptime(0.0f, 1.0f)); } } break; } case Trigger.MeleeAttack: case Trigger.PhysicalAttack: case Trigger.MeleeHit: case Trigger.PhysicalHit: case Trigger.MeleeCrit: case Trigger.PhysicalCrit: case Trigger.DamageSpellCrit: case Trigger.DamageSpellHit: case Trigger.DoTTick: case Trigger.DamageOrHealingDone: // Need to add Self-Heals case Trigger.DamageDone: case Trigger.JudgementHit: case Trigger.SpellCast: case Trigger.DamageSpellCast: case Trigger.DamageTaken: case Trigger.DamageTakenPhysical: case Trigger.DamageTakenPutsMeBelow35PercHealth: case Trigger.DivineProtection: if (effect.MaxStack != 1) { uptime = effect.GetAverageStackSize(triggerIntervals[effect.Trigger], triggerChances[effect.Trigger], weaponSpeed, bossOpts.BerserkTimer); } else { uptime = effect.GetAverageUptime(triggerIntervals[effect.Trigger], triggerChances[effect.Trigger], weaponSpeed, bossOpts.BerserkTimer); } statsSpecialEffects.Accumulate(effect.Stats, uptime); break; } } }
private Stats GetSpecialEffectStats(Character character, StatsPaladin stats, CalculationOptionsProtPaladin calcOpts, BossOptions bossOpts) { StatsPaladin statsSpecialEffects = new StatsPaladin(); float weaponSpeed = 1.0f; if (character.MainHand != null) weaponSpeed = character.MainHand.Speed; AttackModel am = new AttackModel(character, stats, calcOpts, bossOpts); Dictionary<Trigger, float> triggerIntervals; Dictionary<Trigger, float> triggerChances; CreateTriggers(am, character, stats, calcOpts, bossOpts, out triggerIntervals, out triggerChances); GetSpecialEffectsStats_Child(triggerIntervals, triggerChances, weaponSpeed, calcOpts, bossOpts, stats, ref statsSpecialEffects); // Darkmoon card greatness & Paragon procs // These should always increase strength, which is going to be the Paladin's top stat outside of stamina statsSpecialEffects.Strength += statsSpecialEffects.HighestStat + statsSpecialEffects.Paragon; statsSpecialEffects.HighestStat = 0; statsSpecialEffects.Paragon = 0; if (statsSpecialEffects.HighestSecondaryStat > 0) { float paragon = statsSpecialEffects.HighestSecondaryStat; statsSpecialEffects.HighestSecondaryStat = 0; if ((statsSpecialEffects.CritRating > statsSpecialEffects.HasteRating) && (statsSpecialEffects.CritRating > statsSpecialEffects.MasteryRating)) statsSpecialEffects.CritRating += paragon; else if ((statsSpecialEffects.HasteRating > statsSpecialEffects.CritRating) && (statsSpecialEffects.HasteRating > statsSpecialEffects.MasteryRating)) statsSpecialEffects.HasteRating += paragon; else statsSpecialEffects.MasteryRating += paragon; } // Base Stats statsSpecialEffects.Stamina = (float)Math.Floor(statsSpecialEffects.Stamina * (1.0f + stats.BonusStaminaMultiplier)); statsSpecialEffects.Strength = (float)Math.Floor(statsSpecialEffects.Strength * (1.0f + stats.BonusStrengthMultiplier)); statsSpecialEffects.Agility = (float)Math.Floor(statsSpecialEffects.Agility * (1.0f + stats.BonusAgilityMultiplier)); statsSpecialEffects.Health += (float)Math.Floor(statsSpecialEffects.Stamina * 10.0f) + (float)Math.Floor(statsSpecialEffects.BattlemasterHealthProc); // Defensive Stats statsSpecialEffects.Armor = (float)Math.Floor(statsSpecialEffects.Armor * (1f + stats.BaseArmorMultiplier + statsSpecialEffects.BaseArmorMultiplier)); statsSpecialEffects.BonusArmor = (float)Math.Floor(statsSpecialEffects.BonusArmor * (1.0f + stats.BonusArmorMultiplier + statsSpecialEffects.BonusArmorMultiplier)); statsSpecialEffects.Armor += statsSpecialEffects.BonusArmor; // Offensive Stats statsSpecialEffects.AttackPower += statsSpecialEffects.Strength * 2.0f; statsSpecialEffects.AttackPower = (float)Math.Floor(statsSpecialEffects.AttackPower * (1.0f + stats.BonusAttackPowerMultiplier + statsSpecialEffects.BonusAttackPowerMultiplier)); return statsSpecialEffects; }
public StatsPaladin GetCharacterStats(Character character, Item additionalItem, CalculationOptionsProtPaladin calcOpts, BossOptions bossOpts) { PaladinTalents talents = character.PaladinTalents; Stats statsBase = BaseStats.GetBaseStats(character.Level, CharacterClass.Paladin, character.Race); statsBase.Expertise += BaseStats.GetRacialExpertise(character, ItemSlot.MainHand); Stats statsBuffs = GetBuffsStats(character, calcOpts); Stats statsItems = GetItemStats(character, additionalItem, calcOpts); Stats statsTalents = new Stats() { BaseArmorMultiplier = talents.Toughness * 0.1f / 3f, BonusStaminaMultiplier = 0.15f // Touched by the Light }; Stats statsGearEnchantsBuffs = new Stats(); statsGearEnchantsBuffs.Accumulate(statsItems); statsGearEnchantsBuffs.Accumulate(statsBuffs); StatsPaladin statsTotal = new StatsPaladin(); statsTotal.Accumulate(statsBase); statsTotal.Accumulate(statsItems); statsTotal.Accumulate(statsBuffs); statsTotal.Accumulate(statsTalents); int T11count; character.SetBonusCount.TryGetValue("Reinforced Sapphirium Battlearmor", out T11count); if (T11count >= 2) { statsTotal.BonusDamageMultiplierCrusaderStrike = 0.05f; } if (T11count >= 4) { statsTotal.BonusDurationMultiplierGuardianOfAncientKings = 0.50f; } int T12count; character.SetBonusCount.TryGetValue("Battlearmor of Immolation", out T12count); if (T12count >= 2) { statsTotal.BonusDamageShieldofRighteous = 0.20f; } if (T12count >= 4) { statsBuffs.AddSpecialEffect(new SpecialEffect(Trigger.DivineProtection, new Stats() { Parry = 0.12f, }, 10f, 60f)); } statsTotal.Intellect = (float)Math.Floor(statsBase.Intellect * (1.0f + statsTalents.BonusIntellectMultiplier)); statsTotal.Intellect += (float)Math.Floor((statsItems.Intellect + statsBuffs.Intellect) * (1.0f + statsTalents.BonusIntellectMultiplier)); statsTotal.BaseAgility = statsBase.Agility + statsTalents.Agility; statsTotal.Stamina = (float)Math.Floor(statsBase.Stamina + statsItems.Stamina + statsBuffs.Stamina); statsTotal.Stamina = (float)Math.Floor(statsTotal.Stamina * (1.0f + statsTotal.BonusStaminaMultiplier) * (Character.ValidateArmorSpecialization(character, ItemType.Plate) ? 1.05f : 1f)); // Plate specialization statsTotal.Strength = (float)Math.Floor((statsBase.Strength + statsTalents.Strength) * (1.0f + statsTotal.BonusStrengthMultiplier)); statsTotal.Strength += (float)Math.Floor((statsItems.Strength + statsBuffs.Strength) * (1.0f + statsTotal.BonusStrengthMultiplier)); statsTotal.ParryRating += (float)Math.Floor((statsTotal.Strength - statsBase.Strength) * 0.27f); statsTotal.SpellPower = statsTotal.Strength * 0.60f; // Touched by the Light statsTotal.SpellPower += statsTotal.Intellect - 10f; if (talents.GlyphOfSealOfTruth && calcOpts.SealChoice == "Seal of Truth") { statsTotal.Expertise += 10.0f; } statsTotal.Agility = (float)Math.Floor((statsBase.Agility + statsTalents.Agility) * (1.0f + statsTotal.BonusAgilityMultiplier)); statsTotal.Agility += (float)Math.Floor((statsItems.Agility + statsBuffs.Agility) * (1.0f + statsTotal.BonusAgilityMultiplier)); statsTotal.Health += StatConversion.GetHealthFromStamina(statsTotal.Stamina, CharacterClass.Paladin); statsTotal.Health *= 1f + statsTotal.BonusHealthMultiplier; statsTotal.Mana += StatConversion.GetManaFromIntellect(statsTotal.Intellect, CharacterClass.Paladin) * (1f + statsTotal.BonusManaMultiplier); // Armor statsTotal.Armor = (float)Math.Floor(statsTotal.Armor * (1f + statsTotal.BaseArmorMultiplier)); statsTotal.Armor += (float)Math.Floor(statsTotal.BonusArmor * (1f + statsTotal.BonusArmorMultiplier)); statsTotal.AttackPower += ((statsTotal.Strength - 10f) * 2f); statsTotal.AttackPower = (float)Math.Floor(statsTotal.AttackPower * (1f + statsTotal.BonusAttackPowerMultiplier)); statsTotal.NatureResistance += statsTotal.NatureResistanceBuff; statsTotal.FireResistance += statsTotal.FireResistanceBuff; statsTotal.FrostResistance += statsTotal.FrostResistanceBuff; statsTotal.ShadowResistance += statsTotal.ShadowResistanceBuff; statsTotal.ArcaneResistance += statsTotal.ArcaneResistanceBuff; //statsTotal.BonusCritDamageMultiplier = statsBase.BonusCritDamageMultiplier + statsGearEnchantsBuffs.BonusCritDamageMultiplier; statsTotal.CritRating = statsBase.CritRating + statsGearEnchantsBuffs.CritRating; statsTotal.ExpertiseRating = statsBase.ExpertiseRating + statsGearEnchantsBuffs.ExpertiseRating; statsTotal.HasteRating = statsBase.HasteRating + statsGearEnchantsBuffs.HasteRating; statsTotal.HitRating = statsBase.HitRating + statsGearEnchantsBuffs.HitRating; statsTotal.MasteryRating = statsBase.MasteryRating + statsGearEnchantsBuffs.MasteryRating; statsTotal.BlockRating = statsBase.BlockRating + statsGearEnchantsBuffs.BlockRating; statsTotal.WeaponDamage += Lookup.WeaponDamage(character, statsTotal.AttackPower, false); //statsTotal.ExposeWeakness = statsBase.ExposeWeakness + statsGearEnchantsBuffs.ExposeWeakness; // Nerfed in 3.1 // Calculate Procs and Special Effects statsTotal.Accumulate(GetSpecialEffectStats(character, statsTotal, calcOpts, bossOpts)); return statsTotal; }
public void Accumulate(StatsPaladin data, float weight) { #region Base if (data.sparseIndices != null) { int i = 0; for (int a = 0; a < data.sparseAdditiveCount; a++, i++) { int index = data.sparseIndices[i]; rawAdditiveData[index] += weight * data.rawAdditiveData[index]; } for (int a = 0; a < data.sparseMultiplicativeCount; a++, i++) { int index = data.sparseIndices[i]; rawMultiplicativeData[index] = (1 + rawMultiplicativeData[index]) * (1 + weight * data.rawMultiplicativeData[index]) - 1; } for (int a = 0; a < data.sparseInverseMultiplicativeCount; a++, i++) { int index = data.sparseIndices[i]; rawInverseMultiplicativeData[index] = 1 - (1 - rawInverseMultiplicativeData[index]) * (1 - weight * data.rawInverseMultiplicativeData[index]); } for (int a = 0; a < data.sparseNoStackCount; a++, i++) { int index = data.sparseIndices[i]; float value = weight * data.rawNoStackData[index]; if (value > rawNoStackData[index]) { rawNoStackData[index] = value; } } } else { float[] add = data.rawAdditiveData; for (int i = 0; i < rawAdditiveData.Length; i++) { rawAdditiveData[i] += weight * add[i]; } add = data.rawMultiplicativeData; for (int i = 0; i < rawMultiplicativeData.Length; i++) { rawMultiplicativeData[i] = (1 + rawMultiplicativeData[i]) * (1 + weight * add[i]) - 1; } add = data.rawInverseMultiplicativeData; for (int i = 0; i < rawInverseMultiplicativeData.Length; i++) { rawInverseMultiplicativeData[i] = 1 - (1 - rawInverseMultiplicativeData[i]) * (1 - weight * add[i]); } add = data.rawNoStackData; for (int i = 0; i < rawNoStackData.Length; i++) { if (weight * add[i] > rawNoStackData[i]) { rawNoStackData[i] = weight * add[i]; } } } #endregion #region Paladin if (data._sparseIndicesPaladin != null) { int i = 0; for (int a = 0; a < data._sparseAdditivePaladinCount; a++, i++) { int index = data._sparseIndicesPaladin[i]; _rawAdditivePaladinData[index] += weight * data._rawAdditivePaladinData[index]; } for (int a = 0; a < data._sparseMultiplicativePaladinCount; a++, i++) { int index = data._sparseIndicesPaladin[i]; _rawMultiplicativePaladinData[index] = (1 + _rawMultiplicativePaladinData[index]) * (1 + weight * data._rawMultiplicativePaladinData[index]) - 1; } for (int a = 0; a < data._sparseInverseMultiplicativePaladinCount; a++, i++) { int index = data._sparseIndicesPaladin[i]; _rawInverseMultiplicativePaladinData[index] = 1 - (1 - _rawInverseMultiplicativePaladinData[index]) * (1 - weight * data._rawInverseMultiplicativePaladinData[index]); } for (int a = 0; a < data._sparseNoStackPaladinCount; a++, i++) { int index = data._sparseIndicesPaladin[i]; float value = weight * data._rawNoStackPaladinData[index]; if (value > _rawNoStackPaladinData[index]) { _rawNoStackPaladinData[index] = value; } } } else { float[] add = data._rawAdditivePaladinData; for (int i = 0; i < _rawAdditivePaladinData.Length; i++) { _rawAdditivePaladinData[i] += weight * add[i]; } add = data._rawMultiplicativePaladinData; for (int i = 0; i < _rawMultiplicativePaladinData.Length; i++) { _rawMultiplicativePaladinData[i] = (1 + _rawMultiplicativePaladinData[i]) * (1 + weight * add[i]) - 1; } add = data._rawInverseMultiplicativePaladinData; for (int i = 0; i < _rawInverseMultiplicativePaladinData.Length; i++) { _rawInverseMultiplicativePaladinData[i] = 1 - (1 - _rawInverseMultiplicativePaladinData[i]) * (1 - weight * add[i]); } add = data._rawNoStackPaladinData; for (int i = 0; i < _rawNoStackPaladinData.Length; i++) { if (weight * add[i] > _rawNoStackPaladinData[i]) { _rawNoStackPaladinData[i] = weight * add[i]; } } } #endregion if (data._rawSpecialEffectDataSize > 0) { EnsureSpecialEffectCapacity(_rawSpecialEffectDataSize + data._rawSpecialEffectDataSize); Array.Copy(data._rawSpecialEffectData, 0, _rawSpecialEffectData, _rawSpecialEffectDataSize, data._rawSpecialEffectDataSize); _rawSpecialEffectDataSize += data._rawSpecialEffectDataSize; } }
public void Accumulate(StatsPaladin data, float weight) { #region Base if (data.sparseIndices != null) { int i = 0; for (int a = 0; a < data.sparseAdditiveCount; a++, i++) { int index = data.sparseIndices[i]; rawAdditiveData[index] += weight * data.rawAdditiveData[index]; } for (int a = 0; a < data.sparseMultiplicativeCount; a++, i++) { int index = data.sparseIndices[i]; rawMultiplicativeData[index] = (1 + rawMultiplicativeData[index]) * (1 + weight * data.rawMultiplicativeData[index]) - 1; } for (int a = 0; a < data.sparseInverseMultiplicativeCount; a++, i++) { int index = data.sparseIndices[i]; rawInverseMultiplicativeData[index] = 1 - (1 - rawInverseMultiplicativeData[index]) * (1 - weight * data.rawInverseMultiplicativeData[index]); } for (int a = 0; a < data.sparseNoStackCount; a++, i++) { int index = data.sparseIndices[i]; float value = weight * data.rawNoStackData[index]; if (value > rawNoStackData[index]) rawNoStackData[index] = value; } } else { float[] add = data.rawAdditiveData; for (int i = 0; i < rawAdditiveData.Length; i++) { rawAdditiveData[i] += weight * add[i]; } add = data.rawMultiplicativeData; for (int i = 0; i < rawMultiplicativeData.Length; i++) { rawMultiplicativeData[i] = (1 + rawMultiplicativeData[i]) * (1 + weight * add[i]) - 1; } add = data.rawInverseMultiplicativeData; for (int i = 0; i < rawInverseMultiplicativeData.Length; i++) { rawInverseMultiplicativeData[i] = 1 - (1 - rawInverseMultiplicativeData[i]) * (1 - weight * add[i]); } add = data.rawNoStackData; for (int i = 0; i < rawNoStackData.Length; i++) { if (weight * add[i] > rawNoStackData[i]) rawNoStackData[i] = weight * add[i]; } } #endregion #region Paladin if (data._sparseIndicesPaladin != null) { int i = 0; for (int a = 0; a < data._sparseAdditivePaladinCount; a++, i++) { int index = data._sparseIndicesPaladin[i]; _rawAdditivePaladinData[index] += weight * data._rawAdditivePaladinData[index]; } for (int a = 0; a < data._sparseMultiplicativePaladinCount; a++, i++) { int index = data._sparseIndicesPaladin[i]; _rawMultiplicativePaladinData[index] = (1 + _rawMultiplicativePaladinData[index]) * (1 + weight * data._rawMultiplicativePaladinData[index]) - 1; } for (int a = 0; a < data._sparseInverseMultiplicativePaladinCount; a++, i++) { int index = data._sparseIndicesPaladin[i]; _rawInverseMultiplicativePaladinData[index] = 1 - (1 - _rawInverseMultiplicativePaladinData[index]) * (1 - weight * data._rawInverseMultiplicativePaladinData[index]); } for (int a = 0; a < data._sparseNoStackPaladinCount; a++, i++) { int index = data._sparseIndicesPaladin[i]; float value = weight * data._rawNoStackPaladinData[index]; if (value > _rawNoStackPaladinData[index]) _rawNoStackPaladinData[index] = value; } } else { float[] add = data._rawAdditivePaladinData; for (int i = 0; i < _rawAdditivePaladinData.Length; i++) { _rawAdditivePaladinData[i] += weight * add[i]; } add = data._rawMultiplicativePaladinData; for (int i = 0; i < _rawMultiplicativePaladinData.Length; i++) { _rawMultiplicativePaladinData[i] = (1 + _rawMultiplicativePaladinData[i]) * (1 + weight * add[i]) - 1; } add = data._rawInverseMultiplicativePaladinData; for (int i = 0; i < _rawInverseMultiplicativePaladinData.Length; i++) { _rawInverseMultiplicativePaladinData[i] = 1 - (1 - _rawInverseMultiplicativePaladinData[i]) * (1 - weight * add[i]); } add = data._rawNoStackPaladinData; for (int i = 0; i < _rawNoStackPaladinData.Length; i++) { if (weight * add[i] > _rawNoStackPaladinData[i]) _rawNoStackPaladinData[i] = weight * add[i]; } } #endregion if (data._rawSpecialEffectDataSize > 0) { EnsureSpecialEffectCapacity(_rawSpecialEffectDataSize + data._rawSpecialEffectDataSize); Array.Copy(data._rawSpecialEffectData, 0, _rawSpecialEffectData, _rawSpecialEffectDataSize, data._rawSpecialEffectDataSize); _rawSpecialEffectDataSize += data._rawSpecialEffectDataSize; } }
public new StatsPaladin Clone() { StatsPaladin clone = (StatsPaladin)this.MemberwiseClone(); StatsPaladin retVal = new StatsPaladin(); // retVal.Accumulate(base.Clone()); // retVal._rawAdditivePaladinData = (float[])clone._rawAdditivePaladinData.Clone(); retVal._rawMultiplicativePaladinData = (float[])clone._rawMultiplicativePaladinData.Clone(); retVal._rawInverseMultiplicativePaladinData = (float[])clone._rawInverseMultiplicativePaladinData.Clone(); retVal._rawNoStackPaladinData = (float[])clone._rawNoStackPaladinData.Clone(); // return retVal; }