public override Stats GetCharacterStats(Character character, Item additionalItem) { Stats statsRace = new Stats() { Health = 3197, Mana = 2673, Stamina = 118, Intellect = 86, Spirit = 88, Agility = 79, DodgeRating = 12.3f }; Stats statsBaseGear = GetItemStats(character, additionalItem); Stats statsEnchants = GetEnchantsStats(character); Stats statsBuffs = GetBuffsStats(character.ActiveBuffs); Talents talents = new Talents(); Stats statsTotal = statsBaseGear + statsEnchants + statsBuffs + statsRace; statsTotal.Agility = (float)Math.Floor(statsTotal.Agility * (1 + statsBuffs.BonusAgilityMultiplier)); statsTotal.Stamina = (float)Math.Round(statsTotal.Stamina * (1 + statsBuffs.BonusStaminaMultiplier) * talents.SacredDuty * talents.CombatExpertise); statsTotal.Health = (float)Math.Round(statsTotal.Health + (statsTotal.Stamina * 10)); statsTotal.Armor = (float)Math.Round((statsTotal.Armor + (statsTotal.Agility * 2f)) * (1 + statsBuffs.BonusArmorMultiplier) * talents.Thoughness); return(statsTotal); }
public override CharacterCalculationsBase GetCharacterCalculations(Character character, Item additionalItem) { CalculationOptionsTankadin calcOpts = character.CalculationOptions as CalculationOptionsTankadin; //_cachedCharacter = character; int targetLevel = calcOpts.TargetLevel; Stats stats = GetCharacterStats(character, additionalItem); Talents talents = new Talents(); float targetDefense = targetLevel * 5; CharacterCalculationsTankadin calculatedStats = new CharacterCalculationsTankadin(); calculatedStats.BasicStats = stats; calculatedStats.TargetLevel = targetLevel; //Avoidance calculations calculatedStats.Defense = 350 + (float)Math.Floor(stats.DefenseRating / (123f / 52f)) + talents.Anticipation; calculatedStats.Miss = 5 + (calculatedStats.Defense - targetDefense) * .04f + stats.Miss; calculatedStats.Parry = 5 + (calculatedStats.Defense - targetDefense) * .04f + stats.ParryRating / 23.6538461538462f + talents.Deflection; calculatedStats.Dodge = (calculatedStats.Defense - targetDefense) * .04f + stats.Agility / 25f + (stats.DodgeRating / (984f / 52f)); calculatedStats.Avoidance = calculatedStats.Dodge + calculatedStats.Miss + calculatedStats.Parry; calculatedStats.Block = 5 + (calculatedStats.Defense - targetDefense) * .04f + stats.BlockRating / 7.884614944458f; calculatedStats.BlockValue = stats.BlockValue * talents.ShieldSpecializaiton; calculatedStats.CrushAvoidance = calculatedStats.Avoidance + calculatedStats.Block + 30; calculatedStats.CritAvoidance = (calculatedStats.Defense - targetDefense) * .04f + stats.Resilience / 39.423f; calculatedStats.Mitigation = Math.Min(75f, (stats.Armor / (stats.Armor - 22167.5f + (467.5f * targetLevel))) * 100f); float reduction = (1f - (calculatedStats.Mitigation * .01f)) * .96f; float attacks = calcOpts.NumberAttackers / calcOpts.AttackSpeed * 10; //Apply armor and multipliers for each attack type... float miss = Math.Min(0.01f * attacks * calculatedStats.Avoidance, attacks); float block = Math.Min(Math.Min(8, attacks * (.3f + 0.01f * calculatedStats.Block)), attacks - miss); if (block > 8) { block += Math.Min((attacks - block) * .01f * calculatedStats.Block, attacks - miss - block); } float crit = Math.Min(0.01f * Math.Max(5 - calculatedStats.CritAvoidance, 0) * attacks, attacks - miss - block); float crush = Math.Min((targetLevel == 73 ? .15f : 0f) * attacks, attacks - miss - block - crit); float hit = attacks - miss - block - crit - crush; float modifier = talents.OneHandSpec * (1 + (.6f * talents.ImpRF)); calculatedStats.HolyShieldTPS = modifier * Math.Min(block, 8f) * 1.2f * 1.35f * (155 + .05f * stats.SpellDamageRating) / 10f; crit *= calcOpts.AverageHit * reduction * 2f; crush *= calcOpts.AverageHit * reduction * 1.5f; hit *= calcOpts.AverageHit * reduction; block *= calcOpts.AverageHit * reduction * Math.Max(1f - (calculatedStats.BlockValue / calcOpts.AverageHit / reduction), 0); calculatedStats.DamageTaken = (hit + crush + crit + block) / (attacks * calcOpts.AverageHit) * 100; calculatedStats.TotalMitigation = 100f - calculatedStats.DamageTaken; calculatedStats.SurvivalPoints = stats.Health / reduction; calculatedStats.MitigationPoints = calcOpts.MitigationScale * (1f * (1f / (calculatedStats.DamageTaken / 100f))); float ws = character.MainHand == null ? 0 : character.MainHand.Speed; float wd = character.MainHand == null ? 0 : ((character.MainHand.MinDamage + character.MainHand.MaxDamage) / 2f); calculatedStats.SoRTPS = ws == 0 ? 0 : ((0.85f * (2610.43f * ws / 100f) + 0.03f * wd - 1f + (0.108f * ws * stats.SpellDamageRating * ws)) / ws) * modifier; calculatedStats.ConsecrateTPS = calcOpts.NumberAttackers * (512 + .9524f * stats.SpellDamageRating) / 8f * modifier; calculatedStats.JoRTPS = (218f + stats.SpellDamageRating * .7143f) / 9f * modifier; calculatedStats.OverallTPS = calculatedStats.SoRTPS + calculatedStats.JoRTPS + calculatedStats.HolyShieldTPS + calculatedStats.ConsecrateTPS + calculatedStats.MiscTPS; calculatedStats.ThreatPoints = calculatedStats.OverallTPS * calcOpts.ThreatScale; calculatedStats.OverallPoints = calculatedStats.MitigationPoints + calculatedStats.SurvivalPoints + calculatedStats.ThreatPoints; return(calculatedStats); }