本文整理汇总了C#中Stats.Accumulate方法的典型用法代码示例。如果您正苦于以下问题:C# Stats.Accumulate方法的具体用法?C# Stats.Accumulate怎么用?C# Stats.Accumulate使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Stats
的用法示例。
在下文中一共展示了Stats.Accumulate方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: getSpecialEffects
public Stats getSpecialEffects(SpecialEffect effect)
{
Stats statsAverage = new Stats();
if (effect == mainHandEnchant || effect == offHandEnchant)
{
if (mainHandEnchant != null && !mhProcessed)
{
statsAverage.Accumulate(mainHandEnchant.Stats, GetMHUptime());
mhProcessed = true;
}
else if (offHandEnchant != null && !ohProcessed)
{
statsAverage.Accumulate(offHandEnchant.Stats, GetOHUptime());
ohProcessed = true;
}
}
else if (effect.Trigger == Trigger.Use)
{
effect.AccumulateAverageStats(statsAverage);
foreach (SpecialEffect e in effect.Stats.SpecialEffects())
statsAverage.Accumulate(this.getSpecialEffects(e) * (effect.Duration / effect.Cooldown));
}
else
{
SetTriggerChanceAndSpeed(effect);
foreach (SpecialEffect e in effect.Stats.SpecialEffects()) // deal with secondary effects
{
statsAverage.Accumulate(this.getSpecialEffects(e));
}
if (effect.MaxStack > 1)
{
if (effect.Stats.MoteOfAnger > 0)
{
// When in effect stats, MoteOfAnger is % of melee hits
// When in character stats, MoteOfAnger is average procs per second
statsAverage.Accumulate(new Stats() { MoteOfAnger = effect.Stats.MoteOfAnger * effect.GetAverageProcsPerSecond(trigger, chance, unhastedAttackSpeed, 0f) / effect.MaxStack });
}
else
{
float timeToMax = (float)Math.Min(_cs.FightLength, effect.GetChance(unhastedAttackSpeed) * trigger * effect.MaxStack);
float buffDuration = _cs.FightLength;
if (effect.Stats.AttackPower == 250f || effect.Stats.AttackPower == 215f || effect.Stats.HasteRating == 57f || effect.Stats.HasteRating == 64f)
{
buffDuration = 20f;
}
if (timeToMax * .5f > buffDuration)
{
timeToMax = 2 * buffDuration;
}
statsAverage.Accumulate(effect.Stats * (effect.MaxStack * (((buffDuration) - .5f * timeToMax) / (buffDuration))));
}
}
else
{
effect.AccumulateAverageStats(statsAverage, trigger, chance, unhastedAttackSpeed);
}
}
return statsAverage;
}
示例2: RenderStatsGraph
public static void RenderStatsGraph(Graphics g, int graphWidth, int graphHeight, Character character, Stats[] statsList, Color[] colors, int scale, string explanatoryText, string calculation, Style style)
{
CharacterCalculationsBase baseCalc = Calculations.GetCharacterCalculations(character);
float baseFigure = GetCalculationValue(baseCalc, calculation);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
float graphOffset = graphWidth / 2.0f, graphStep = (graphWidth - 100) / 2.0f / scale;
if (statsList.Length == 0 || statsList.Length > colors.Length) return; // more than 12 elements for the array would run out of colours
float minDpsChange = 0f, maxDpsChange = 0f;
PointF[][] points = new PointF[statsList.Length][];
for (int index = 0; index < statsList.Length; index++)
{
Stats newStats = new Stats();
points[index] = new PointF[2 * scale + 1];
newStats.Accumulate(statsList[index], -scale - 1);
for (int count = -scale; count <= scale; count++)
{
newStats.Accumulate(statsList[index]);
CharacterCalculationsBase currentCalc = Calculations.GetCharacterCalculations(character, new Item() { Stats = newStats }, false, false, false);
float currentFigure = GetCalculationValue(currentCalc, calculation);
float dpsChange = currentFigure - baseFigure;
points[index][count + scale] = new PointF(graphOffset + count * graphStep, dpsChange);
if (dpsChange < minDpsChange)
minDpsChange = dpsChange;
if (dpsChange > maxDpsChange)
maxDpsChange = dpsChange;
}
}
float DpsVariance = maxDpsChange - minDpsChange;
if (DpsVariance == 0)
DpsVariance = 1;
for (int index = 0; index < statsList.Length; index++)
{
for (int count = -scale; count <= scale; count++)
{
points[index][count + scale].Y = (int)((maxDpsChange - points[index][count + scale].Y) * (graphHeight - 48) / DpsVariance) + 20;
}
Brush statBrush = new SolidBrush(colors[index]);
switch (style)
{
case Style.DpsWarr:
g.DrawLines(new Pen(statBrush, 3), points[index]);
break;
case Style.Mage:
g.DrawLines(new Pen(statBrush, 1), points[index]);
break;
}
}
RenderGrid(g, graphWidth, graphHeight, character, statsList, colors, scale, 1f, "F1", explanatoryText, calculation, style, minDpsChange, maxDpsChange, DpsVariance, true);
}
示例3: UpdateStatsGraph
/// <summary>
/// Generate a graph to compare stat progressions.
/// </summary>
/// <param name="character"></param>
/// <param name="statsList">Array of Stats objects that contain what stats to evalutate.</param>
/// <param name="colors">Color for each stat object. Should be same or > # of elements as statsList</param>
/// <param name="scale">How many increments of the stats values should be performed? Larger values mean much larger calculation times.</param>
/// <param name="explanatoryText"></param>
/// <param name="calculation">[In] Generally pass in null or "Overall Points" otherwise pass in the specific subpoint string you are concerned about.</param>
public void UpdateStatsGraph(Character character, Stats[] statsList, Color[] colors, int scale, string explanatoryText, string calculation)
{
CharacterCalculationsBase baseCalc = Calculations.GetCharacterCalculations(character);
float baseFigure = GetCalculationValue(baseCalc, calculation);
if (statsList.Length == 0 || statsList.Length > colors.Length) return; // more than 12 elements for the array would run out of colours
Point[][] points = new Point[statsList.Length][];
Chart.Series.Clear();
for (int index = 0; index < statsList.Length; index++)
{
Stats newStats = new Stats();
points[index] = new Point[2 * scale + 1];
newStats.Accumulate(statsList[index], -scale - 1);
for (int count = -scale; count <= scale; count++)
{
newStats.Accumulate(statsList[index]);
CharacterCalculationsBase currentCalc = Calculations.GetCharacterCalculations(character, new Item() { Stats = newStats }, false, false, false);
float currentFigure = GetCalculationValue(currentCalc, calculation);
float dpsChange = currentFigure - baseFigure;
points[index][count + scale] = new Point(count, dpsChange);
}
Style dataPointStyle = new Style(typeof(LineDataPoint));
dataPointStyle.Setters.Add(new Setter(DataPoint.TemplateProperty, Resources["InvisibleDataPointTemplate"]));
dataPointStyle.Setters.Add(new Setter(DataPoint.BackgroundProperty, new SolidColorBrush(colors[index])));
Chart.Series.Add(new LineSeries()
{
Title = statsList[index].ToString(),
ItemsSource = points[index],
IndependentValuePath = "X",
DependentValuePath = "Y",
DataPointStyle = dataPointStyle,
});
}
Chart.Axes.Clear();
Chart.Axes.Add(new LinearAxis()
{
Orientation = AxisOrientation.X,
Title = "Stat Change",
ShowGridLines = true,
});
Chart.Axes.Add(new LinearAxis()
{
Orientation = AxisOrientation.Y,
Title = calculation,
ShowGridLines = true,
});
orgDataDirty = true;
}
示例4: CalcCritProcs
private Stats CalcCritProcs()
{
if (CalcOpts.NoProcs)
{
return new Stats();
}
Dictionary<int, float> periods = new Dictionary<int, float>();
Dictionary<int, float> chances = new Dictionary<int, float>();
PopulateTriggers(periods, chances);
Stats procStats = new Stats();
foreach (SpecialEffect effect in Stats.SpecialEffects())
{
if (!periods.ContainsKey((int)effect.Trigger))
{
continue;
}
Stats proc = CalcNormalProc(effect, periods, chances);
procStats.Accumulate(proc);
if (effect.Trigger == Trigger.Use && !IsDoublePot(effect))
{
ExtraCritAtMax += StatUtils.CalcSpellCrit(effect.Stats, BaseIntellect, CalcOpts.PlayerLevel)
- StatUtils.CalcSpellCrit(proc, BaseIntellect, CalcOpts.PlayerLevel);
}
}
return procStats;
}
示例5: CalcHasteAndManaProcs
private void CalcHasteAndManaProcs()
{
float nonProcHaste = StatUtils.CalcSpellHaste(PreProcStats, CalcOpts.PlayerLevel);
if (CalcOpts.NoProcs)
{
WeightedStat staticHaste = new WeightedStat();
staticHaste.Chance = 1f;
staticHaste.Value = nonProcHaste;
Haste = new List<WeightedStat> { staticHaste };
AvgHaste = nonProcHaste;
return;
}
// the trigger rates are all guestimates at this point, since the
// real values depend on haste (which obviously has not been
// finalized yet)
Dictionary<int, float> periods = new Dictionary<int, float>();
Dictionary<int, float> chances = new Dictionary<int, float>();
float corruptionPeriod = 0f;
if (CalcOpts.GetActiveRotation().Contains("Corruption"))
{
corruptionPeriod = 3.1f / nonProcHaste;
}
PopulateTriggers(periods, chances, CalculationsWarlock.AVG_UNHASTED_CAST_TIME / nonProcHaste + CalcOpts.Latency, 1 / 1.5f, corruptionPeriod, 1f);
// calculate the haste procs
Haste = new List<WeightedStat>();
WeightedStat[] percentages = GetUptimes(Stats, periods, chances, s => s.SpellHaste,
(a, b, c, d, e, f, g, h) => SpecialEffect.GetAverageCombinedUptimeCombinationsMultiplicative(a, b, c, d, e, f, g, h));
WeightedStat[] ratings = GetUptimes(Stats, periods, chances, s => s.HasteRating,
(a, b, c, d, e, f, g, h) => SpecialEffect.GetAverageCombinedUptimeCombinations(a, b, c, d, e, f, g, h));
for (int p = percentages.Length, f = 0; --p >= 0; )
{
if (percentages[p].Chance == 0)
{
continue;
}
for (int r = ratings.Length; --r >= 0; ++f)
{
if (ratings[r].Chance == 0)
{
continue;
}
WeightedStat s = new WeightedStat();
s.Chance = percentages[p].Chance * ratings[r].Chance;
s.Value = (1 + percentages[p].Value)
* (1 + StatUtils.GetSpellHasteFromRating(ratings[r].Value + Stats.HasteRating, CalcOpts.PlayerLevel))
* (1 + Stats.SpellHaste);
Haste.Add(s);
AvgHaste += s.Chance * s.Value;
}
}
// calculate mana procs
Stats procStats = new Stats();
foreach (SpecialEffect effect in Stats.SpecialEffects())
{
if (!periods.ContainsKey((int)effect.Trigger))
{
continue;
}
Stats proc = effect.GetAverageStats(periods[(int)effect.Trigger], chances[(int)effect.Trigger], CalculationsWarlock.AVG_UNHASTED_CAST_TIME, BossOpts.BerserkTimer);
if (proc.ManaRestore > 0)
{
proc.ManaRestore *= BossOpts.BerserkTimer;
}
procStats.Accumulate(proc);
}
Stats.Mana += procStats.Mana;
Stats.ManaRestore += procStats.ManaRestore;
Stats.ManaRestoreFromMaxManaPerSecond += procStats.ManaRestoreFromMaxManaPerSecond;
Stats.Mp5 += procStats.Mp5;
}
示例6: fixed
// this is now included in accumulating item stats
/*public unsafe virtual void AccumulateEnchantsStats(Stats stats, Character character)
{
fixed (float* pRawAdditiveData = stats._rawAdditiveData, pRawMultiplicativeData = stats._rawMultiplicativeData, pRawNoStackData = stats._rawNoStackData)
{
stats.BeginUnsafe(pRawAdditiveData, pRawMultiplicativeData, pRawNoStackData);
stats.AccumulateUnsafe(character.BackEnchant.Stats, true);
stats.AccumulateUnsafe(character.ChestEnchant.Stats, true);
stats.AccumulateUnsafe(character.FeetEnchant.Stats, true);
stats.AccumulateUnsafe(character.Finger1Enchant.Stats, true);
stats.AccumulateUnsafe(character.Finger2Enchant.Stats, true);
stats.AccumulateUnsafe(character.HandsEnchant.Stats, true);
stats.AccumulateUnsafe(character.HeadEnchant.Stats, true);
stats.AccumulateUnsafe(character.LegsEnchant.Stats, true);
stats.AccumulateUnsafe(character.ShouldersEnchant.Stats, true);
if (character.MainHand != null &&
(character.MainHandEnchant.Slot == ItemSlot.OneHand ||
(character.MainHandEnchant.Slot == ItemSlot.TwoHand &&
character.MainHand.Slot == ItemSlot.TwoHand)))
{
stats.AccumulateUnsafe(character.MainHandEnchant.Stats, true);
}
if (character.OffHand != null && IncludeOffHandInCalculations(character) &&
(
(
character.OffHandEnchant.Slot == ItemSlot.OneHand &&
(character.OffHand.Slot == ItemSlot.OneHand ||
character.OffHand.Slot == ItemSlot.OffHand) &&
character.OffHand.Type != ItemType.None &&
character.OffHand.Type != ItemType.Shield
)
||
(
character.OffHandEnchant.Slot == ItemSlot.TwoHand &&
character.OffHand.Slot == ItemSlot.TwoHand
)
||
(
character.OffHandEnchant.Slot == ItemSlot.OffHand &&
character.OffHand.Slot == ItemSlot.OffHand &&
character.OffHand.Type == ItemType.Shield
)
)
)
{
stats.AccumulateUnsafe(character.OffHandEnchant.Stats, true);
}
stats.AccumulateUnsafe(character.RangedEnchant.Stats, true);
stats.AccumulateUnsafe(character.WristEnchant.Stats, true);
stats.EndUnsafe();
}
}*/
/*public virtual Stats GetEnchantsStats(Character character)
{
Stats stats = new Stats();
AccumulateEnchantsStats(stats, character);
return stats;
}*/
public virtual void AccumulateBuffsStats(Stats stats, List<string> buffs)
{
foreach (string buffName in buffs)
if (!string.IsNullOrEmpty(buffName))
{
Buff buff = Buff.GetBuffByName(buffName);
if (buff != null)
{
stats.Accumulate(buff.Stats);
}
}
}
示例7: GetBaseStats
public static Stats GetBaseStats(int level, CharacterClass characterClass, CharacterRace characterRace, DruidForm characterForm)
{ // Health, Mana and some other things are same for every race.
lock (syncLock)
{
#region Cache
if (level == _lastLevel
&& characterClass == _lastClass
&& characterRace == _lastRace
&& characterForm == _lastForm)
return _lastStats.Clone();
_lastLevel = level;
_lastClass = characterClass;
_lastRace = characterRace;
_lastForm = characterForm;
#endregion
Stats S = new Stats();
#region Race, not class benefit
// Most Level 85 Race and Class Stats come from:
// http://code.google.com/p/simulationcraft/source/browse/branches/cataclysm/engine/sc_rating.cpp?r=6207
// When they were still at 80 as of Jan 01st, 2011
// From SimCraft
Stats race = new Stats();
switch (characterRace)
{
// Alliance
case CharacterRace.Human: race.Strength = 20; race.Agility = 20; race.Stamina = 20; race.Intellect = 20; race.Spirit = 20; break;
case CharacterRace.Dwarf: race.Strength = 25; race.Agility = 16; race.Stamina = 21; race.Intellect = 19; race.Spirit = 19; break;
case CharacterRace.NightElf: race.Strength = 16; race.Agility = 24; race.Stamina = 20; race.Intellect = 20; race.Spirit = 20; break;
case CharacterRace.Gnome: race.Strength = 15; race.Agility = 22; race.Stamina = 20; race.Intellect = 24; race.Spirit = 20; break;
case CharacterRace.Draenei: race.Strength = 21; race.Agility = 17; race.Stamina = 20; race.Intellect = 20; race.Spirit = 22; break;
case CharacterRace.Worgen: race.Strength = 23; race.Agility = 22; race.Stamina = 20; race.Intellect = 16; race.Spirit = 19; break;
// Horde
case CharacterRace.Orc: race.Strength = 23; race.Agility = 17; race.Stamina = 21; race.Intellect = 17; race.Spirit = 22; break;
case CharacterRace.Undead: race.Strength = 19; race.Agility = 18; race.Stamina = 20; race.Intellect = 18; race.Spirit = 25; break;
case CharacterRace.Tauren: race.Strength = 25; race.Agility = 16; race.Stamina = 21; race.Intellect = 16; race.Spirit = 22; break;
case CharacterRace.Troll: race.Strength = 21; race.Agility = 22; race.Stamina = 20; race.Intellect = 16; race.Spirit = 21; break;
case CharacterRace.BloodElf: race.Strength = 17; race.Agility = 22; race.Stamina = 20; race.Intellect = 23; race.Spirit = 18; break;
case CharacterRace.Goblin: race.Strength = 17; race.Agility = 22; race.Stamina = 20; race.Intellect = 23; race.Spirit = 20; break;
default: { break; }
};
// From Chardev (85)
//Class Str Agi Sta Int Spi
//Druid 76 69 86 136 153
//Shaman 111 60 128 119 136
//Death Knight 171 101 154 16 44
//Hunter 60 178 119 77 88
//Mage 17 26 43 187 175
//Paladin 144 77 136 86 97
//Priest 26 34 51 188 183
//Rogue 102 186 94 26 53
//Warlock 43 51 76 161 166
//Warrior 169 103 153 17 44
#endregion
#region Base Stats
#region All Classes
S.Miss = 0.05f;
S.Block = 0.00f;
S.Parry = 0.00f;
#endregion
switch (characterClass)
{
#region Death Knight
case CharacterClass.DeathKnight:
Stats dk = new Stats() {
Strength = 171, Agility = 101, Stamina = 274, Intellect = 16, Spirit = 44,
Health = 43025f,
Dodge = 0.05f, Parry = 0.05f, Block = 0.00f,
PhysicalCrit = 0.0049f, AttackPower = 595f,
};
S.Accumulate(race);
S.Accumulate(dk);
break;
#endregion
#region Druid
case CharacterClass.Druid:
Stats druid = new Stats() {
Strength = 76, Agility = 69, Stamina = 86, Intellect = 136, Spirit = 153,
Health = 39533f, Mana = 18635f,
Dodge = 0.03758f, Parry = 0.05f, Block = 0.05f,
PhysicalCrit = 0.03192f, AttackPower = 613f,
SpellCrit = 0.0185f, Mp5 = 931f,
};
S.Accumulate(race);
S.Accumulate(druid);
switch (characterForm)
{
case DruidForm.Moonkin:
case DruidForm.Caster:
S.AttackPower = -10;
S.PhysicalCrit = 0.0743f;
S.Dodge = 0.0556970f; //??
break;
case DruidForm.Bear:
S.AttackPower = 255;
S.PhysicalCrit = 0.074755f;
S.Dodge = 0.0556970f;
S.BonusStaminaMultiplier = 0.2f;
//.........这里部分代码省略.........
示例8: GetCharacterStats
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;
}
示例9: computeStats
void computeStats()
{
RandomIntellectEffects = new List<RandomIntellectEffect>();
RandomIntellectEffects.Add(new RandomIntellectEffect(0, null, 0, 0));
OnUseIntellectProcsMana = 0.0f;
calc.MeanMana = calc.BasicStats.Mana;
List<KeyValuePair<double, SpecialEffect>> hasteProcsList = new List<KeyValuePair<double, SpecialEffect>>();
// ToL, NG, Heroism, Shard of Woe, etc.
List<SpecialEffect> dividingEffectsList = new List<SpecialEffect>();
List<int> dividingEffectBucketsList = new List<int>();
KeyValuePair<double, SpecialEffect>[] hasteProcs;
Stats statsDividing = new Stats();
Stats statsProcs = new Stats();
Dictionary<Trigger, float> triggerIntervals = new Dictionary<Trigger,float>();
Dictionary<Trigger, float> triggerChances = new Dictionary<Trigger, float>();
triggerIntervals[Trigger.Use] = 0;
triggerIntervals[Trigger.HealingSpellCast] = triggerIntervals[Trigger.HealingSpellCrit] = triggerIntervals[Trigger.HealingSpellHit] =
triggerIntervals[Trigger.SpellCast] = triggerIntervals[Trigger.SpellCrit] = triggerIntervals[Trigger.SpellHit] =
triggerIntervals[Trigger.DamageOrHealingDone] = (float)calc.ProcTriggerInterval;
triggerIntervals[Trigger.HoTTick] = (float)calc.ProcPeriodicTriggerInterval;
foreach(Trigger trigger in triggerIntervals.Keys)
triggerChances[trigger] = 1;
// NOTE: this ignores crit from procs, but hopefully this shouldn't matter much
triggerChances[Trigger.HealingSpellCrit] = triggerChances[Trigger.SpellCrit] =
StatConversion.GetSpellCritFromIntellect(calc.BasicStats.Intellect) + StatConversion.GetSpellCritFromRating(calc.BasicStats.CritRating) + calc.BasicStats.SpellCrit;
if(opts.TriggerDamageEffects)
{
foreach (SpecialEffect effect in calc.BasicStats.SpecialEffects())
{
if (effect.Trigger == Trigger.DamageSpellCast || effect.Trigger == Trigger.DamageSpellHit || effect.Trigger == Trigger.DoTTick || effect.Trigger == Trigger.DamageSpellCrit)
InsectSwarm = true;
}
}
if (InsectSwarm)
{
triggerIntervals[Trigger.DamageSpellCast] = triggerIntervals[Trigger.DamageSpellHit] = triggerIntervals[Trigger.DoTTick] = triggerIntervals[Trigger.DamageSpellCrit] = (float)calc.DamageProcPeriodicTriggerInterval;
triggerChances[Trigger.DamageSpellCast] = triggerChances[Trigger.DamageSpellHit] = triggerChances[Trigger.DoTTick] = 1;
triggerChances[Trigger.DamageSpellCrit] = StatConversion.GetSpellCritFromIntellect(calc.BasicStats.Intellect) + StatConversion.GetSpellCritFromRating(calc.BasicStats.CritRating) + calc.BasicStats.SpellCrit;
}
foreach (SpecialEffect effect in calc.BasicStats.SpecialEffects())
{
if (triggerIntervals.ContainsKey(effect.Trigger))
{
if (effect.Stats.Intellect > 0 || effect.Stats.HighestStat > 0)
{
double mana = StatConversion.GetManaFromIntellect((effect.Stats.Intellect + effect.Stats.HighestStat) * (1 + calc.BasicStats.BonusIntellectMultiplier)) * (1 + calc.BasicStats.BonusManaMultiplier);
double avgMana = mana * effect.GetAverageFactor(triggerIntervals[effect.Trigger], triggerChances[effect.Trigger], 3.0f, character.BossOptions.BerserkTimer);
if (effect.Trigger != Trigger.Use)
RandomIntellectEffects.Add(new RandomIntellectEffect(mana - avgMana, effect, triggerIntervals[effect.Trigger], triggerChances[effect.Trigger]));
if (effect.Trigger == Trigger.Use && effect.Cooldown <= 180.0f)
OnUseIntellectProcsMana += mana - avgMana;
calc.MeanMana += avgMana;
}
Stats stats = effect.GetAverageStats(triggerIntervals, triggerChances, 3.0f, character.BossOptions.BerserkTimer);
if (effect.Trigger == Trigger.Use
&& effect.MaxStack <= 1
&& (effect.Stats is CalculationsTree.TreeOfLifeStats || effect.Stats.HasteRating > 0 || effect.Stats.SpellHaste > 0 || effect.Stats.Intellect > 0 || effect.Stats.SpellPower > 0 || effect.Stats.CritRating > 0 || effect.Stats.SpellCrit > 0 || effect.Stats.MasteryRating > 0 || effect.Stats.NatureSpellsManaCostReduction != 0 || effect.Stats.SpellsManaCostReduction != 0 || effect.Stats.ManaCostReductionMultiplier != 0)
)
{
dividingEffectsList.Add(effect);
int bucket = -1;
if(opts.SeparateHasteEffects && (effect.Stats.HasteRating > 0 || effect.Stats.SpellHaste > 0))
bucket = 0;
dividingEffectBucketsList.Add(bucket);
statsDividing.Accumulate(stats);
}
else
{
if (effect.Stats.HasteRating > 0 || effect.Stats.SpellHaste > 0)
{
double uptime = effect.GetAverageUptime(triggerIntervals[effect.Trigger], triggerChances[effect.Trigger], 3.0f, character.BossOptions.BerserkTimer);
hasteProcsList.Add(new KeyValuePair<double, SpecialEffect>(uptime, effect));
stats.HasteRating = 0;
stats.SpellHaste = 0;
}
statsProcs.Accumulate(stats);
}
}
}
MeanStats = new Stats();
MeanStats.Accumulate(statsProcs);
//.........这里部分代码省略.........
示例10: AccumulateAverageStats
/// <summary>
/// Computes average scaled stats given the frequency of triggers; also computers average effect
/// </summary>
/// <param name="stats">Stats object into which the average stats will be accumulated.</param>
/// <param name="triggerInterval">Average time interval between triggers in seconds.</param>
/// <param name="triggerChance">Chance that trigger of correct type is produced (for example for
/// SpellCrit trigger you would set triggerInterval to average time between hits and set
/// triggerChance to crit chance)</param>
/// <param name="attackSpeed">Average unhasted attack speed, used in PPM calculations.</param>
/// <param name="fightDuration">Duration of fight in seconds.</param>
/// <param name="scale">Scale factor.</param>
public float AccumulateAverageStats(Stats stats, Dictionary<Trigger, float> triggerIntervals, Dictionary<Trigger, float> triggerChances, float attackSpeed = 3.0f, float fightDuration = 0.0f, float scale = 1.0f)
{
float factor = scale;
if (triggerIntervals.ContainsKey(Trigger) && triggerChances.ContainsKey(Trigger))
factor *= GetAverageFactor(triggerIntervals[Trigger], triggerChances[Trigger], attackSpeed, fightDuration);
else
factor *= 0;
Stats.GenerateSparseData();
if (Stats.ContainsSpecialEffect())
{
if (Stats.sparseIndices.Length != 0)
{
Stats effectStats = Stats.Clone();
effectStats.ClearSpecialEffects();
effectStats.InvalidateSparseData();
foreach (SpecialEffect effect in Stats.SpecialEffects())
{
// this assumes that the child effect gets consumed at the end of the duration
// this assumes that the child effect is off cooldown before the next occurrence of the parent effect
effect.AccumulateAverageStats(effectStats, triggerIntervals, triggerChances, attackSpeed, Duration);
}
stats.Accumulate(effectStats, factor);
}
else
{
// this path is an optimization to avoid intermediate dense storage
foreach (SpecialEffect effect in Stats.SpecialEffects())
{
// this assumes that the child effect gets consumed at the end of the duration
// this assumes that the child effect is off cooldown before the next occurrence of the parent effect
effect.AccumulateAverageStats(stats, triggerIntervals, triggerChances, attackSpeed, Duration, factor);
}
}
}
else
stats.Accumulate(Stats, factor);
return factor;
}
示例11: GetSpecialEffectStats
private StatsWarrior GetSpecialEffectStats(Player player)
{
StatsWarrior statsSpecialEffects = new StatsWarrior();
Dictionary<Trigger, float> triggerIntervals = new Dictionary<Trigger, float>();
Dictionary<Trigger, float> triggerChances = new Dictionary<Trigger, float>();
player.DefendModel = new DefendModel(player);
player.AttackModel = new AttackModel(player, AttackModelMode.Optimal);
float effectiveMasteryRating = Lookup.MaxEffectiveMasteryRating(player);
float effectiveBuffedMasteryRating = effectiveMasteryRating * (1.0f - 10.0f / player.CalcOpts.ShieldBlockInterval) +
Lookup.MaxEffectiveBuffedMasteryRating(player) * (10.0f / player.CalcOpts.ShieldBlockInterval);
triggerIntervals[Trigger.Use] = 0.0f;
triggerIntervals[Trigger.MeleeAttack] = player.AttackModel.WeaponAttacksPerSecond;
triggerIntervals[Trigger.MeleeHit] = triggerIntervals[Trigger.MeleeAttack];
triggerIntervals[Trigger.MeleeCrit] = triggerIntervals[Trigger.MeleeAttack];
triggerIntervals[Trigger.PhysicalHit] = triggerIntervals[Trigger.MeleeAttack];
triggerIntervals[Trigger.PhysicalAttack] = triggerIntervals[Trigger.MeleeAttack];
triggerIntervals[Trigger.PhysicalCrit] = triggerIntervals[Trigger.MeleeAttack];
triggerIntervals[Trigger.ExecuteHit] = triggerIntervals[Trigger.MeleeAttack];
triggerIntervals[Trigger.DoTTick] = (player.Talents.DeepWounds > 0) ? 2.0f : 0.0f;
triggerIntervals[Trigger.DamageDone] = triggerIntervals[Trigger.MeleeAttack] + triggerIntervals[Trigger.DoTTick];
triggerIntervals[Trigger.DamageOrHealingDone] = triggerIntervals[Trigger.DamageDone];
triggerIntervals[Trigger.DamageTaken] = 1.0f / player.DefendModel.AttackerSwingsPerSecond;
triggerIntervals[Trigger.DamageAvoided] = triggerIntervals[Trigger.DamageTaken];
triggerIntervals[Trigger.DamageParried] = triggerIntervals[Trigger.DamageTaken];
triggerIntervals[Trigger.DamageTakenPutsMeBelow35PercHealth] = triggerIntervals[Trigger.DamageTaken];
triggerIntervals[Trigger.ShieldBlock] = 60f - (player.Talents.ShieldMastery * 10f);
triggerChances[Trigger.Use] = 1.0f;
triggerChances[Trigger.MeleeAttack] = 1.0f;
triggerChances[Trigger.MeleeHit] = player.AttackModel.HitsPerSecond / player.AttackModel.WeaponAttacksPerSecond;
triggerChances[Trigger.MeleeCrit] = player.AttackModel.CritsPerSecond / player.AttackModel.WeaponAttacksPerSecond;
triggerChances[Trigger.PhysicalAttack] = 1.0f;
triggerChances[Trigger.PhysicalHit] = triggerChances[Trigger.MeleeHit];
triggerChances[Trigger.PhysicalCrit] = triggerChances[Trigger.MeleeCrit];
triggerChances[Trigger.ExecuteHit] = triggerChances[Trigger.MeleeHit];
triggerChances[Trigger.DoTTick] = (player.Talents.DeepWounds > 0) ? 1.0f : 0.0f;
triggerChances[Trigger.DamageDone] = (player.AttackModel.HitsPerSecond + ((player.Talents.DeepWounds > 0) ? 2.0f : 0.0f))
/ (player.AttackModel.WeaponAttacksPerSecond + ((player.Talents.DeepWounds > 0) ? 1.0f : 0.0f));
triggerChances[Trigger.DamageOrHealingDone] = triggerChances[Trigger.DamageDone];
triggerChances[Trigger.DamageTaken] = player.DefendModel.AttackerHitsPerSecond / player.DefendModel.AttackerSwingsPerSecond;
triggerChances[Trigger.DamageAvoided] = player.DefendModel.DefendTable.AnyAvoid;
triggerChances[Trigger.DamageParried] = player.DefendModel.DefendTable.Parry;
triggerChances[Trigger.DamageTakenPutsMeBelow35PercHealth] = triggerChances[Trigger.DamageTaken] * 0.35f;
triggerChances[Trigger.ShieldBlock] = 1.0f;
foreach (SpecialEffect effect in player.Stats.SpecialEffects())
{
if (RelevantTriggers.Contains(effect.Trigger))
{
// Effective Mastery Capping on Large Proc Effects
if ((effect.Trigger == Trigger.Use && effect.Stats.MasteryRating > effectiveMasteryRating) || effect.Stats.MasteryRating > effectiveBuffedMasteryRating)
{
Stats cappedStats = new Stats();
cappedStats.Accumulate(effect.Stats);
// Assume Use Effects Bypass Shield Block Collision
if (effect.Trigger == Trigger.Use)
cappedStats.MasteryRating = effectiveMasteryRating;
else
cappedStats.MasteryRating = effectiveBuffedMasteryRating;
// calculate average up-time of this trinket
float averageUpTime = 0.0f;
if (effect.Trigger == Trigger.ExecuteHit)
averageUpTime = effect.GetAverageFactor(triggerIntervals[effect.Trigger], triggerChances[effect.Trigger], player.AttackModel.WeaponSpeed, player.BossOpts.BerserkTimer * (float)player.BossOpts.Under20Perc);
else
averageUpTime = effect.GetAverageFactor(triggerIntervals[effect.Trigger], triggerChances[effect.Trigger], player.AttackModel.WeaponSpeed, player.BossOpts.BerserkTimer);
// accumulate the capped stats from the trinket into our final stats
statsSpecialEffects.Accumulate(cappedStats, averageUpTime);
}
else
{
if (effect.Trigger == Trigger.ExecuteHit)
effect.AccumulateAverageStats(statsSpecialEffects, triggerIntervals, triggerChances, player.AttackModel.WeaponSpeed, player.BossOpts.BerserkTimer * (float)player.BossOpts.Under20Perc);
else
effect.AccumulateAverageStats(statsSpecialEffects, triggerIntervals, triggerChances, player.AttackModel.WeaponSpeed, player.BossOpts.BerserkTimer);
}
}
}
// Base Stats
statsSpecialEffects.Stamina = (float)Math.Floor(statsSpecialEffects.Stamina * (1.0f + player.Stats.BonusStaminaMultiplier));
statsSpecialEffects.Strength = (float)Math.Floor(statsSpecialEffects.Strength * (1.0f + player.Stats.BonusStrengthMultiplier));
statsSpecialEffects.Agility = (float)Math.Floor(statsSpecialEffects.Agility * (1.0f + player.Stats.BonusAgilityMultiplier));
return statsSpecialEffects;
}
示例12: RenderScalingGraph
public static void RenderScalingGraph(Graphics g, int graphWidth, int graphHeight, Character character, Stats[] statsList, Stats baseStat, bool requiresReferenceCalculations, Color[] colors, int scale, string explanatoryText, string calculation, Style style)
{
CharacterCalculationsBase baseCalc = Calculations.GetCharacterCalculations(character);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
float graphOffset = graphWidth / 2.0f, graphStep = (graphWidth - 100) / 2.0f / scale;
if (statsList.Length == 0 || statsList.Length > colors.Length) return; // more than 12 elements for the array would run out of colours
float minDpsChange = 0f, maxDpsChange = 0f;
PointF[][] points = new PointF[statsList.Length][];
// extract property data for relative stats calculations
KeyValuePair<PropertyInfo, float>[] properties = new KeyValuePair<PropertyInfo,float>[statsList.Length];
for (int index = 0; index < statsList.Length; index++)
{
var p = statsList[index].Values(x => x > 0);
foreach (var kvp in p)
{
properties[index] = kvp;
}
points[index] = new PointF[2 * scale + 1];
}
for (int count = -scale; count <= scale; count++)
{
Stats newStats = new Stats();
newStats.Accumulate(baseStat, count);
Item item = new Item() { Stats = newStats };
if (requiresReferenceCalculations)
{
Calculations.GetCharacterCalculations(character, item, true, false, false);
}
for (int index = 0; index < statsList.Length; index++)
{
ComparisonCalculationBase currentCalc = CalculationsBase.GetRelativeStatValue(character, properties[index].Key, item, properties[index].Value);
float dpsChange = GetCalculationValue(currentCalc, calculation);
points[index][count + scale] = new PointF(graphOffset + count * graphStep, dpsChange);
if (dpsChange < minDpsChange)
minDpsChange = dpsChange;
if (dpsChange > maxDpsChange)
maxDpsChange = dpsChange;
}
}
// restore reference calculation
if (requiresReferenceCalculations)
{
Stats newStats = new Stats();
Item item = new Item() { Stats = newStats };
Calculations.GetCharacterCalculations(character, item, true, false, false);
}
// increase the spread a bit to so that you can see if something is at the edges and straight
float DpsVariance = maxDpsChange - minDpsChange;
minDpsChange -= DpsVariance * 0.05f;
maxDpsChange += DpsVariance * 0.05f;
DpsVariance = maxDpsChange - minDpsChange;
if (DpsVariance == 0)
DpsVariance = 1;
for (int index = 0; index < statsList.Length; index++)
{
for (int count = -scale; count <= scale; count++)
{
points[index][count + scale].Y = (int)((maxDpsChange - points[index][count + scale].Y) * (graphHeight - 48) / DpsVariance) + 20;
}
Brush statBrush = new SolidBrush(colors[index]);
switch (style)
{
case Style.DpsWarr:
g.DrawLines(new Pen(statBrush, 3), points[index]);
break;
case Style.Mage:
g.DrawLines(new Pen(statBrush, 1), points[index]);
break;
}
}
float unit = 1f;
var bp = baseStat.Values(x => x > 0);
foreach (var kvp in bp)
{
unit = kvp.Value;
}
RenderGrid(g, graphWidth, graphHeight, character, statsList, colors, scale, unit, "F", explanatoryText, calculation, style, minDpsChange, maxDpsChange, DpsVariance, false);
}
示例13: GetCharacterStatsWithTemporaryEffects
private Stats GetCharacterStatsWithTemporaryEffects(Character character, Item additionalItem, /*out WeightedStat[] armorPenetrationUptimes,*/ out WeightedStat[] critRatingUptimes)
{
RogueTalents talents = character.RogueTalents;
#region Spec determination
int spec;
int assCounter = 0, combatCounter = 0, subtCounter = 0;
for (int i = 0; i <= 18; i++) assCounter += int.Parse(talents.ToString()[i].ToString());
for (int i = 19; i <= 37; i++) combatCounter += int.Parse(talents.ToString()[i].ToString());
for (int i = 38; i <= 56; i++) subtCounter += int.Parse(talents.ToString()[i].ToString());
if (assCounter > combatCounter && assCounter > subtCounter) spec = 0;
else if (combatCounter > subtCounter) spec = 1;
else spec = 2;
#endregion
CalculationOptionsRogue calcOpts = character.CalculationOptions as CalculationOptionsRogue;
BossOptions bossOpts = character.BossOptions;
int targetLevel = bossOpts.Level;
bool targetPoisonable = calcOpts.TargetPoisonable;
Stats statsRace = BaseStats.GetBaseStats(character.Level, character.Class, character.Race);
Stats statsItems = GetItemStats(character, additionalItem);
Stats statsBuffs = GetBuffsStats(character, calcOpts);
SpecialEffect LegendarySpecialEffect = new SpecialEffect(Trigger.MeleeHit, new Stats() { Agility = 2f }, 20f, 0f, 1f, 50);
Stats statsSetBonus = new Stats();
int LegendaryPartA;
character.SetBonusCount.TryGetValue("Jaws of Retribution", out LegendaryPartA);
if (LegendaryPartA >= 2)
{
statsSetBonus.AddSpecialEffect(LegendarySpecialEffect);
}
LegendarySpecialEffect = new SpecialEffect(Trigger.MeleeHit, new Stats() { Agility = 5f }, 20f, 0f, 1f, 50);
int LegendaryPartB;
character.SetBonusCount.TryGetValue("Maw of Oblivion", out LegendaryPartB);
if (LegendaryPartB >= 2)
{
statsSetBonus.AddSpecialEffect(LegendarySpecialEffect);
}
// Needs work....
LegendarySpecialEffect = new SpecialEffect(Trigger.MeleeHit, new Stats() { Agility = 17f }, 20f, 0f, 1f, 50);
Stats LegendaryStats = new Stats();
LegendaryStats.AddSpecialEffect(LegendarySpecialEffect);
// Assume it resets every 45 seconds
LegendarySpecialEffect = new SpecialEffect(Trigger.MeleeHit, LegendaryStats, 45f, 45f);
int LegendaryPartC;
character.SetBonusCount.TryGetValue("Fangs of the Father", out LegendaryPartC);
if (LegendaryPartC >= 2)
{
statsSetBonus.AddSpecialEffect(LegendarySpecialEffect);
LegendarySpecialEffect = new SpecialEffect(Trigger.MeleeHit, new Stats() { FangsoftheFather = 1f }, 6f, 45f);
statsSetBonus.AddSpecialEffect(LegendarySpecialEffect);
}
Stats statsTalents = new Stats()
{
BonusAgilityMultiplier = (1f + (spec == 2 ? RV.Mastery.SinisterCallingMult : 0f)) * (1f + RV.LeatherSpecialization) - 1f,
BonusAttackPowerMultiplier = (1f + (spec == 1 ? RV.Mastery.VitalityAPMult : 0f)) * (1f + RV.Talents.SavageCombatMult * talents.SavageCombat) - 1f,
BonusCritChance = character.ActiveBuffs.Contains(Buff.GetBuffByName("Rampage")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Leader of the Pack")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Honor Among Thieves")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Terrifying Roar")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Furious Howl")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Elemental Oath")) ? 0f : RV.Talents.HonorAmongThievesCritBonus * talents.HonorAmongThieves,
BonusDamageMultiplier = RV.Vendetta.DmgMult * talents.Vendetta * (RV.Vendetta.Duration * (talents.GlyphOfVendetta ? 1f + RV.Glyph.VendettaDurationMult : 1f)) / RV.Vendetta.CD +
talents.SanguinaryVein * RV.Talents.SanguinaryVein +
RV.Mastery.MasterOfSubtletyDmgMult * RV.Mastery.MasterOfSubtletyDuration / (RV.Vanish.CD - RV.Talents.ElusivenessVanishCDReduc * talents.Elusiveness) +
(talents.Preparation > 0 ? RV.Mastery.MasterOfSubtletyDmgMult * RV.Mastery.MasterOfSubtletyDuration / (RV.Talents.PreparationCD * talents.Preparation) : 0f),
BonusPhysicalDamageMultiplier = character.ActiveBuffs.Contains(Buff.GetBuffByName("Ravage")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Acid Spit")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Brittle Bones")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Blood Frenzy")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Savage Combat")) ? 0f : RV.Talents.SavageCombatMult * talents.SavageCombat,
BonusBleedDamageMultiplier = character.ActiveBuffs.Contains(Buff.GetBuffByName("Mangle")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Hemorrhage")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Blood Frenzy")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Gore")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Stampede")) || character.ActiveBuffs.Contains(Buff.GetBuffByName("Tendon Rip")) ? 0f : RV.Hemo.BleedDmgMult * talents.Hemorrhage,
PhysicalHit = RV.Talents.PrecisionMult * talents.Precision,
SpellHit = RV.Talents.PrecisionMult * talents.Precision,
};
Stats statsGearEnchantsBuffs = statsItems + statsBuffs + statsSetBonus;
Stats statsTotal = statsRace + statsItems;
statsTotal.Accumulate(statsBuffs);
statsTotal.Accumulate(statsTalents);
statsTotal.Stamina = (float)Math.Floor(statsTotal.Stamina * (1f + statsTotal.BonusStaminaMultiplier));
statsTotal.Strength = (float)Math.Floor(statsTotal.Strength * (1f + statsTotal.BonusStrengthMultiplier));
statsTotal.Agility = (float)Math.Floor((statsTotal.Agility - statsRace.Agility) * (1f + statsTotal.BonusAgilityMultiplier)) + statsRace.Agility;
statsTotal.AttackPower += (statsTotal.Strength - RV.BaseStatCalcReduc / 2) + RV.APperAgi * (statsTotal.Agility - RV.BaseStatCalcReduc) + RV.BaseStatCalcReduc;
statsTotal.AttackPower = (float)Math.Floor(statsTotal.AttackPower * (1f + statsTotal.BonusAttackPowerMultiplier));
statsTotal.Health += (float)Math.Floor((statsTotal.Stamina - RV.BaseStatCalcReduc) * RV.HPPerStam + RV.BaseStatCalcReduc);
statsTotal.Armor = (float)Math.Floor(statsTotal.Armor * (1f + statsTotal.BonusArmorMultiplier));
statsTotal.NatureResistance += statsTotal.NatureResistanceBuff;
statsTotal.FireResistance += statsTotal.FireResistanceBuff;
statsTotal.FrostResistance += statsTotal.FrostResistanceBuff;
statsTotal.ShadowResistance += statsTotal.ShadowResistanceBuff;
statsTotal.ArcaneResistance += statsTotal.ArcaneResistanceBuff;
float hasteBonus = (1f + StatConversion.GetPhysicalHasteFromRating(statsTotal.HasteRating, CharacterClass.Rogue)) * (1f + statsTotal.PhysicalHaste) - 1f;
float speedBonus = (1f + hasteBonus) * (1f + RV.SnD.SpeedBonus) * (1f + (spec == 2 ? RV.Mastery.Executioner + RV.Mastery.ExecutionerPerMast * StatConversion.GetMasteryFromRating(statsTotal.MasteryRating) : 0f)) - 1f;
float mHSpeed = (character.MainHand == null ? 2 : character.MainHand.Speed);
float oHSpeed = (character.OffHand == null ? 2 : character.OffHand.Speed);
float meleeHitInterval = 1f / ((mHSpeed + oHSpeed) / speedBonus);
//To calculate the Poison hit interval only white attacks are taken into account, IP is assumed on the slowest and DP on the fastest weapon
float dPPS = bossOpts.BerserkTimer / (Math.Min(mHSpeed, oHSpeed) / speedBonus) * RV.DP.Chance + (spec == 0 ? RV.Mastery.ImprovedPoisonsDPBonus : 0);
float poisonHitInterval = 1 / (Math.Max(mHSpeed, mHSpeed) * RV.IP.Chance * (1f + RV.Mastery.ImprovedPoisonsIPFreqMult) / RV.IP.NormWeapSpeed + dPPS);
float hitBonus = StatConversion.GetPhysicalHitFromRating(statsTotal.HitRating) + statsTotal.PhysicalHit;
//.........这里部分代码省略.........
示例14: CalcRemainingProcs
private float CalcRemainingProcs()
{
if (CalcOpts.NoProcs)
{
return 0f;
}
Dictionary<int, float> periods = new Dictionary<int, float>();
Dictionary<int, float> chances = new Dictionary<int, float>();
PopulateTriggers(periods, chances);
float procdDamage = 0f;
Stats procStats = new Stats();
foreach (SpecialEffect effect in Stats.SpecialEffects())
{
if (!periods.ContainsKey((int)effect.Trigger))
{
continue;
}
Stats effectStats = effect.Stats;
if (effectStats.HolySummonedDamage > 0)
{
SpellModifiers mods = new SpellModifiers();
mods.AddCritChance(.05f + Stats.SpellCritOnTarget);
mods.AddMultiplicativeMultiplier(Stats.BonusHolyDamageMultiplier);
procdDamage += CalcDamageProc(effect, effect.Stats.HolySummonedDamage, periods, chances, mods);
}
else if (
effectStats.ShadowDamage > 0
|| effectStats.FireDamage > 0
|| effectStats.NatureDamage > 0
|| effectStats.HolyDamage > 0
|| effectStats.FrostDamage > 0)
{
SpellModifiers mods = new SpellModifiers();
mods.Accumulate(SpellModifiers);
if (effectStats.ShadowDamage > 0)
{
AddShadowModifiers(mods);
}
else if (effectStats.FireDamage > 0)
{
AddFireModifiers(mods);
}
procdDamage += CalcDamageProc(
effect,
effectStats.ShadowDamage
+ effectStats.FireDamage
+ effectStats.NatureDamage
+ effectStats.HolyDamage
+ effectStats.FrostDamage,
periods,
chances,
mods);
}
else
{
procStats.Accumulate(CalcNormalProc(effect, periods, chances));
}
}
procStats.HasteRating
= procStats.SpellHaste
= procStats.Mana
= procStats.ManaRestore
= procStats.ManaRestoreFromMaxManaPerSecond
= procStats.Mp5
= procStats.CritRating
= procStats.SpellCrit
= procStats.SpellCritOnTarget
= procStats.PhysicalCrit
= 0;
Stats.Accumulate(procStats);
return procdDamage;
}
示例15: UpdateScalingGraph
public void UpdateScalingGraph(Character character, Stats[] statsList, Stats baseStat, bool requiresReferenceCalculations, Color[] colors, int scale, string explanatoryText, string calculation)
{
CharacterCalculationsBase baseCalc = Calculations.GetCharacterCalculations(character);
if (statsList.Length == 0 || statsList.Length > colors.Length) return; // more than 12 elements for the array would run out of colours
Point[][] points = new Point[statsList.Length][];
// extract property data for relative stats calculations
KeyValuePair<PropertyInfo, float>[] properties = new KeyValuePair<PropertyInfo, float>[statsList.Length];
for (int index = 0; index < statsList.Length; index++)
{
var p = statsList[index].Values(x => x > 0);
foreach (var kvp in p)
{
properties[index] = kvp;
}
points[index] = new Point[2 * scale + 1];
}
float unit = 1f;
var bp = baseStat.Values(x => x > 0);
foreach (var kvp in bp)
{
unit = kvp.Value;
}
Chart.Series.Clear();
for (int count = -scale; count <= scale; count++)
{
Stats newStats = new Stats();
newStats.Accumulate(baseStat, count);
Item item = new Item() { Stats = newStats };
if (requiresReferenceCalculations)
{
Calculations.GetCharacterCalculations(character, item, true, false, false);
}
for (int index = 0; index < statsList.Length; index++)
{
ComparisonCalculationBase currentCalc = CalculationsBase.GetRelativeStatValue(character, properties[index].Key, item, properties[index].Value);
float dpsChange = GetCalculationValue(currentCalc, calculation);
points[index][count + scale] = new Point(count * unit, dpsChange);
}
}
for (int index = 0; index < statsList.Length; index++)
{
Style dataPointStyle = new Style(typeof(LineDataPoint));
dataPointStyle.Setters.Add(new Setter(DataPoint.TemplateProperty, Resources["InvisibleDataPointTemplate"]));
dataPointStyle.Setters.Add(new Setter(DataPoint.BackgroundProperty, new SolidColorBrush(colors[index])));
Chart.Series.Add(new LineSeries()
{
Title = statsList[index].ToString(),
ItemsSource = points[index],
IndependentValuePath = "X",
DependentValuePath = "Y",
DataPointStyle = dataPointStyle,
});
}
Chart.Axes.Clear();
Chart.Axes.Add(new LinearAxis()
{
Orientation = AxisOrientation.X,
Title = "Stat Change",
ShowGridLines = true,
});
Chart.Axes.Add(new LinearAxis()
{
Orientation = AxisOrientation.Y,
Title = calculation,
ShowGridLines = true,
});
// restore reference calculation
if (requiresReferenceCalculations)
{
Stats newStats = new Stats();
Item item = new Item() { Stats = newStats };
Calculations.GetCharacterCalculations(character, item, true, false, false);
}
orgDataDirty = true;
}