public void CalculateDamage(DamageCalcType damageCalcType) { spell_damage = 0; switch (damageCalcType) { case DamageCalcType.Default: damage = unit.get_naked_damage(); bonus_damage = ((int)unit.statsDamage - (int)damage) + unit.bonus_damage; break; case DamageCalcType.Stats: damage = unit.statsDamage; bonus_damage = (int)unit.bonus_damage; break; case DamageCalcType.DPA: damage = unit.damage; bonus_damage = (double)onAttackStats.GetDamage("ATTACK_DAMAGE"); // get full damage from crits or smth like that ... if (bonus_damage != 0) { bonus_damage -= onAttackStats.GetKeyProbability("ATTACK_DAMAGE") * damage; // bonus damage = full_damage - base_damage } bonus_damage += (double)onAttackStats.GetDamage("ATTACK_BONUS_DAMAGE"); // some other damage bonuses (from range bash) ///////////////// // spell damage ///////////////// spell_damage += (double)onAttackStats.GetDamage("DAMAGE_SPELL"); spell_damage += onEnemyStats.GetDouble("DPS_SPELL") * unit.cooldown; break; default: damage = 0; bonus_damage = 0; break; } //currentHeroDamage = damage; //currentHeroBonusDamage = bonus_damage; total_damage = damage + bonus_damage; additional_damage = total_damage - (Damage)unit.damage; }
public void CalculateGeneralInfo(bool calculateEhp, bool calculateDps, ArmorCalcType armorCalcType) { if (calculateEhp) { hpFactor = 1.0 / (1.0 + Current.unit.hpFactor); ///////////////////////////// // normal damage reduction ///////////////////////////// double original_damage = (double)armorDamage; // calculating average damage received after it was blocked by Shield Block abilities DBDAMAGE reduced_damage = onNormalDefenseStats.GetDbDamage("DAMAGE"); // use original damage for cases that do not trigger damage reducing abilities reduced_damage += original_damage * (1 - onNormalDefenseStats.GetKeyProbability("DAMAGE")); int bonus_ehp = (int)(unit.armor * (unit.max_hp * 0.06)); if (original_damage != reduced_damage) { // total ehp total_ehp_normal = ((unit.max_hp + bonus_ehp) * hpFactor) * (original_damage / reduced_damage); total_ehp_normal = Math.Round(total_ehp_normal); ehp_increase_normal = total_ehp_normal - (unit.max_hp * hpFactor); // ehp bonuses from items bonus_ehp = (int)(unit.get_naked_armor() * (unit.max_hp * 0.06)); double total_ehp_naked = ((unit.max_hp + bonus_ehp) * hpFactor); ehp_increase_normal_items = total_ehp_normal - total_ehp_naked; // damage reduction damage_reduction_normal = ((0.06 * unit.armor) / (1 + (0.06 * unit.armor))) * hpFactor; damage_reduction_normal = (1 - (reduced_damage / original_damage) * (1 - damage_reduction_normal)) * 100; } else { // total ehp total_ehp_normal = ((unit.max_hp + bonus_ehp) * hpFactor); ehp_increase_normal = bonus_ehp * hpFactor; // ehp bonuses from items ehp_increase_normal_items = (int)((unit.armor - unit.get_naked_armor()) * (unit.max_hp * 0.06)); // damage reduction damage_reduction_normal = ((6 * unit.armor) / (1 + (0.06 * unit.armor))) * hpFactor; } // recalculate ehp considering opponent's damage // if required "Armor:" switch is set // Formula: EHP = damage * ceiling(HP/damage) if ((armorCalcType & ArmorCalcType.SurvivabilityMeasure) != 0) { total_ehp_normal = original_damage * Math.Ceiling(total_ehp_normal / original_damage); } // calculate evasion-to-ehp if required "Armor:" switch is set if ((armorCalcType & ArmorCalcType.Evasion) != 0) { DBEVASIONABILITY evasion = unit.onDefenceAbilities.GetByType <DBEVASIONABILITY>(); if (evasion != null && evasion.Chance != 0) { total_ehp_normal = Math.Round(total_ehp_normal / (1 - evasion.Chance)); } } /////////////////////////// // spell damage reduction /////////////////////////// DBDAMAGE spellDamage = new DBDAMAGE(100, AttackType.Spell, DamageType.Magic); AbilityResults ar = new AbilityResults(); ar.SetDbDamage("DAMAGE", spellDamage); foreach (DBABILITY a in unit.onDefenceAbilities) { a.Apply(ar); } ar.Rename("RESISTED_DAMAGE", "DAMAGE"); double resisted_damage = (double)(ar.GetDbDamage("DAMAGE").convert_to_double() * (1.0 - unit.spell_resistance)); spell_resistance = 100 - resisted_damage; ehp_increase_spell = (int)(unit.max_hp * (spell_resistance / resisted_damage)); total_ehp_spell = (unit.max_hp + ehp_increase_spell) * hpFactor; double baseSpellResistance = (double)unit.baseSpellResistance; ehp_increase_spell_items = ehp_increase_spell - (int)((double)((double)baseSpellResistance / (1.0 - baseSpellResistance)) * (double)(int)unit.max_hp); spell_resistance *= hpFactor; ehp_increase_spell *= hpFactor; ehp_increase_spell_items *= hpFactor; } if (calculateDps) { //////////////////////////////// // normal dps //////////////////////////////// dps_normal = unit.get_dps(this.additional_damage); //////////////////////////////// // spell dps //////////////////////////////// dps_spell = (double)onAttackStats.GetDamage("DAMAGE_SPELL") / unit.cooldown; dps_spell += onEnemyStats.GetDouble("DPS_SPELL"); } }
public void CalculateGeneralInfo(bool calculateEhp, bool calculateDps, ArmorCalcType armorCalcType) { if (calculateEhp) { hpFactor = 1.0 / (1.0 + Current.unit.hpFactor); ///////////////////////////// // normal damage reduction ///////////////////////////// double original_damage = (double)armorDamage; // calculating average damage received after it was blocked by Shield Block abilities DBDAMAGE reduced_damage = onNormalDefenseStats.GetDbDamage("DAMAGE"); // use original damage for cases that do not trigger damage reducing abilities reduced_damage += original_damage * (1 - onNormalDefenseStats.GetKeyProbability("DAMAGE")); int bonus_ehp = (int)(unit.armor * (unit.max_hp * 0.06)); if (original_damage != reduced_damage) { // total ehp total_ehp_normal = ((unit.max_hp + bonus_ehp) * hpFactor) * (original_damage / reduced_damage); total_ehp_normal = Math.Round(total_ehp_normal); ehp_increase_normal = total_ehp_normal - (unit.max_hp * hpFactor); // ehp bonuses from items bonus_ehp = (int)(unit.get_naked_armor() * (unit.max_hp * 0.06)); double total_ehp_naked = ((unit.max_hp + bonus_ehp) * hpFactor); ehp_increase_normal_items = total_ehp_normal - total_ehp_naked; // damage reduction damage_reduction_normal = ((0.06 * unit.armor) / (1 + (0.06 * unit.armor))) * hpFactor; damage_reduction_normal = (1 - (reduced_damage / original_damage) * (1 - damage_reduction_normal)) * 100; } else { // total ehp total_ehp_normal = ((unit.max_hp + bonus_ehp) * hpFactor); ehp_increase_normal = bonus_ehp * hpFactor; // ehp bonuses from items ehp_increase_normal_items = (int)((unit.armor - unit.get_naked_armor()) * (unit.max_hp * 0.06)); // damage reduction damage_reduction_normal = ((6 * unit.armor) / (1 + (0.06 * unit.armor))) * hpFactor; } // recalculate ehp considering opponent's damage // if required "Armor:" switch is set // Formula: EHP = damage * ceiling(HP/damage) if ((armorCalcType & ArmorCalcType.SurvivabilityMeasure) != 0) total_ehp_normal = original_damage * Math.Ceiling(total_ehp_normal / original_damage); // calculate evasion-to-ehp if required "Armor:" switch is set if ((armorCalcType & ArmorCalcType.Evasion) != 0) { DBEVASIONABILITY evasion = unit.onDefenceAbilities.GetByType<DBEVASIONABILITY>(); if (evasion != null && evasion.Chance != 0) total_ehp_normal = Math.Round(total_ehp_normal / (1 - evasion.Chance)); } /////////////////////////// // spell damage reduction /////////////////////////// DBDAMAGE spellDamage = new DBDAMAGE(100, AttackType.Spell, DamageType.Magic); AbilityResults ar = new AbilityResults(); ar.SetDbDamage("DAMAGE", spellDamage); foreach (DBABILITY a in unit.onDefenceAbilities) a.Apply(ar); ar.Rename("RESISTED_DAMAGE", "DAMAGE"); double resisted_damage = (double)(ar.GetDbDamage("DAMAGE").convert_to_double() * (1.0 - unit.spell_resistance)); spell_resistance = 100 - resisted_damage; ehp_increase_spell = (int)(unit.max_hp * (spell_resistance / resisted_damage)); total_ehp_spell = (unit.max_hp + ehp_increase_spell) * hpFactor; double baseSpellResistance = (double)unit.baseSpellResistance; ehp_increase_spell_items = ehp_increase_spell - (int)((double)((double)baseSpellResistance / (1.0 - baseSpellResistance)) * (double)(int)unit.max_hp); spell_resistance *= hpFactor; ehp_increase_spell *= hpFactor; ehp_increase_spell_items *= hpFactor; } if (calculateDps) { //////////////////////////////// // normal dps //////////////////////////////// dps_normal = unit.get_dps(this.additional_damage); //////////////////////////////// // spell dps //////////////////////////////// dps_spell = (double)onAttackStats.GetDamage("DAMAGE_SPELL") / unit.cooldown; dps_spell += onEnemyStats.GetDouble("DPS_SPELL"); } }
internal void DisplayCustomInfo() { if (Current.unit != null) { RichTextBox bufferRTB = new RichTextBox(); bufferRTB.Font = heroInfoRTB.Font; bufferRTB.Clear(); //////////////////////// // E V A S I O N //////////////////////// DBEVASIONABILITY evasion = Current.unit.onDefenceAbilities.GetByType<DBEVASIONABILITY>(); if (evasion != null && evasion.Chance != 0) { addText(bufferRTB, "Evasion: " + evasion.Chance * 100 + "%", Color.Lime); addLineInterval(bufferRTB); } /////////////////////////////////////////// // D A M A G E B L O C K /////////////////////////////////////////// List<DBBLOCKDAMAGEABILITY> blocks = Current.unit.onDefenceAbilities.GetRangeByType<DBBLOCKDAMAGEABILITY>(); if (blocks.Count != 0) { DBDOUBLE chance = usc.defenseStacked.GetProbabilityOfType<DBBLOCKDAMAGEABILITY>(); addText(bufferRTB, "Damage Block sources: " + blocks.Count, Color.Lime); if (blocks.Count > 1) { addText(bufferRTB, "\nChance to block: " + (int)(Math.Round(chance * 100.0)) + "%", Color.Lime); DBDOUBLE maxDamageBlock = new DBDOUBLE(null); DBDOUBLE maxBlockChance = new DBDOUBLE(null); foreach (StackedAbilities sa in usc.defenseStacked) { DBBLOCKDAMAGEABILITY block = sa.GetFirstByType<DBBLOCKDAMAGEABILITY>(); if (block != null) { if (maxDamageBlock < block.BlockDamage) { maxDamageBlock = block.BlockDamage; maxBlockChance = sa.probability; } else if (maxDamageBlock == block.BlockDamage) maxBlockChance += sa.probability; } } addText(bufferRTB, "\nMax block/chance: " + maxDamageBlock + "/" + maxBlockChance, Color.Lime); } else addText(bufferRTB, "\nBlock/chance: " + blocks[0].BlockDamage + "/" + chance, Color.Lime); addLineInterval(bufferRTB); } /////////////////////////////////////////// // C R I T I C A L S T R I K E /////////////////////////////////////////// List<DBCRITICALSTRIKEABILITY> crits = Current.unit.onAttackAbilities.GetRangeByType<DBCRITICALSTRIKEABILITY>(); if (crits.Count != 0) { DBDOUBLE chance = usc.attackStacked.GetProbabilityOfType<DBCRITICALSTRIKEABILITY>(); addText(bufferRTB, "Critical Strike sources: " + crits.Count, Color.Lime); if (crits.Count > 1) { addText(bufferRTB, "\nChance to crit: " + (int)(Math.Round(chance * 100.0)) + "%", Color.Lime); DBDOUBLE maxCritMultiplier = new DBDOUBLE(null); DBDOUBLE maxCritChance = new DBDOUBLE(null); foreach (StackedAbilities sa in usc.attackStacked) { DBCRITICALSTRIKEABILITY crit = sa.GetFirstByType<DBCRITICALSTRIKEABILITY>(); if (crit != null) { if (maxCritMultiplier < crit.CritMultiplier) { maxCritMultiplier = crit.CritMultiplier; maxCritChance = sa.probability; } else if (maxCritMultiplier == crit.CritMultiplier) maxCritChance += sa.probability; } } addText(bufferRTB, "\nMax crit/chance: " + maxCritMultiplier + "/" + maxCritChance, Color.Lime); } else addText(bufferRTB, "\nCrit/chance: " + crits[0].CritMultiplier + "/" + chance, Color.Lime); addLineInterval(bufferRTB); } /////////////////////////////////// // B A S H /////////////////////////////////// List<DBBASHABILITY> bashes = Current.unit.onAttackAbilities.GetRangeByType<DBBASHABILITY>(); if (bashes.Count != 0) { DBDOUBLE chance; if (Current.unit.attackMethod == AttackMethod.Melee) chance = usc.attackStacked.GetProbabilityOfType<DBBASHABILITY>(); else chance = usc.onAttackStats.GetResultAbilityTypeProbability<DBBASHABILITY>("APPLIED_EFFECT"); addText(bufferRTB, "Bash sources: " + bashes.Count, Color.Lime); if (bashes.Count > 1) { addText(bufferRTB, "\nChance to bash: " + (int)(Math.Round(chance * 100.0)) + "%", Color.Lime); DBDOUBLE maxStunTime = new DBDOUBLE(null); DBDOUBLE maxStunChance = new DBDOUBLE(null); bool changed; foreach (StackedAbilities sa in usc.attackStacked) { changed = false; foreach (DBABILITY a in sa) if (a is DBBASHABILITY) { if (maxStunTime < (a as DBBASHABILITY).StunTime) { maxStunTime = (a as DBBASHABILITY).StunTime; maxStunChance = sa.probability; changed = true; } else if (maxStunTime == (a as DBBASHABILITY).StunTime && !changed) { maxStunChance += sa.probability; changed = true; } } } addText(bufferRTB, "\nMax stun/chance: " + maxStunTime + "/" + maxStunChance, Color.Lime); } else addText(bufferRTB, "\nStun/chance: " + bashes[0].StunTime + "/" + chance, Color.Lime); addLineInterval(bufferRTB); } heroInfoRTB.Rtf = bufferRTB.Rtf; } else { heroInfoRTB.Text = ""; } }
public void CalculateDamage(DamageCalcType damageCalcType) { spell_damage = 0; switch (damageCalcType) { case DamageCalcType.Default: damage = unit.get_naked_damage(); bonus_damage = ((int)unit.statsDamage - (int)damage) + unit.bonus_damage; break; case DamageCalcType.Stats: damage = unit.statsDamage; bonus_damage = (int)unit.bonus_damage; break; case DamageCalcType.DPA: damage = unit.damage; bonus_damage = (double)onAttackStats.GetDamage("ATTACK_DAMAGE"); // get full damage from crits or smth like that ... if (bonus_damage != 0) bonus_damage -= onAttackStats.GetKeyProbability("ATTACK_DAMAGE") * damage; // bonus damage = full_damage - base_damage bonus_damage += (double)onAttackStats.GetDamage("ATTACK_BONUS_DAMAGE"); // some other damage bonuses (from range bash) ///////////////// // spell damage ///////////////// spell_damage += (double)onAttackStats.GetDamage("DAMAGE_SPELL"); spell_damage += onEnemyStats.GetDouble("DPS_SPELL") * unit.cooldown; break; default: damage = 0; bonus_damage = 0; break; } //currentHeroDamage = damage; //currentHeroBonusDamage = bonus_damage; total_damage = damage + bonus_damage; additional_damage = total_damage - (Damage)unit.damage; }