From 3f531024f7c6a4a4006a79c8a3edc884db9898b5 Mon Sep 17 00:00:00 2001 From: Lynx3d Date: Sat, 7 May 2011 20:11:58 +0200 Subject: [PATCH] [11434] Implemented diminishing returns (DR) for dodge and parry chances. Also updated base dodge and agility=>dodge conversion values for 3.2 and later Base stats and percentage based talents/buffs are not affected by DR, it basically prevents items and stat buffs becoming disproportionally powerful in terms of survivability as characters approach 100% avoidance. TODO: implement DR for chance to be missed from defense rating --- src/game/Player.cpp | 64 +++++++++++++++++--------------- src/game/Player.h | 6 ++- src/game/StatSystem.cpp | 80 ++++++++++++++++++++++++++++++++++------ src/shared/revision_nr.h | 2 +- 4 files changed, 109 insertions(+), 43 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 47b15b863..ebf0243e0 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -5100,35 +5100,37 @@ float Player::GetMeleeCritFromAgility() return crit*100.0f; } -float Player::GetDodgeFromAgility() +void Player::GetDodgeFromAgility(float &diminishing, float &nondiminishing) { // Table for base dodge values - float dodge_base[MAX_CLASSES] = { - 0.0075f, // Warrior - 0.00652f, // Paladin - -0.0545f, // Hunter - -0.0059f, // Rogue - 0.03183f, // Priest - 0.0114f, // DK - 0.0167f, // Shaman - 0.034575f, // Mage - 0.02011f, // Warlock + const float dodge_base[MAX_CLASSES] = + { + 0.036640f, // Warrior + 0.034943f, // Paladin + -0.040873f, // Hunter + 0.020957f, // Rogue + 0.034178f, // Priest + 0.036640f, // DK + 0.021080f, // Shaman + 0.036587f, // Mage + 0.024211f, // Warlock 0.0f, // ?? - -0.0187f // Druid + 0.056097f // Druid }; - // Crit/agility to dodge/agility coefficient multipliers - float crit_to_dodge[MAX_CLASSES] = { - 1.1f, // Warrior - 1.0f, // Paladin - 1.6f, // Hunter - 2.0f, // Rogue - 1.0f, // Priest - 1.0f, // DK? - 1.0f, // Shaman - 1.0f, // Mage - 1.0f, // Warlock - 0.0f, // ?? - 1.7f // Druid + // Crit/agility to dodge/agility coefficient multipliers; 3.2.0 increased required agility by 15% + const float crit_to_dodge[MAX_CLASSES] = + { + 0.85f/1.15f, // Warrior + 1.00f/1.15f, // Paladin + 1.11f/1.15f, // Hunter + 2.00f/1.15f, // Rogue + 1.00f/1.15f, // Priest + 0.85f/1.15f, // DK + 1.60f/1.15f, // Shaman + 1.00f/1.15f, // Mage + 0.97f/1.15f, // Warlock (?) + 0.0f, // ?? + 2.00f/1.15f // Druid }; uint32 level = getLevel(); @@ -5136,13 +5138,17 @@ float Player::GetDodgeFromAgility() if (level>GT_MAX_LEVEL) level = GT_MAX_LEVEL; - // Dodge per agility for most classes equal crit per agility (but for some classes need apply some multiplier) + // Dodge per agility is proportional to crit per agility, which is available from DBC files GtChanceToMeleeCritEntry const *dodgeRatio = sGtChanceToMeleeCritStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); if (dodgeRatio==NULL || pclass > MAX_CLASSES) - return 0.0f; + return; - float dodge=dodge_base[pclass-1] + GetStat(STAT_AGILITY) * dodgeRatio->ratio * crit_to_dodge[pclass-1]; - return dodge*100.0f; + // TODO: research if talents/effects that increase total agility by x% should increase non-diminishing part + float base_agility = GetCreateStat(STAT_AGILITY) * m_auraModifiersGroup[UNIT_MOD_STAT_START + STAT_AGILITY][BASE_PCT]; + float bonus_agility = GetStat(STAT_AGILITY) - base_agility; + // calculate diminishing (green in char screen) and non-diminishing (white) contribution + diminishing = 100.0f * bonus_agility * dodgeRatio->ratio * crit_to_dodge[pclass-1]; + nondiminishing = 100.0f * (dodge_base[pclass-1] + base_agility * dodgeRatio->ratio * crit_to_dodge[pclass-1]); } float Player::GetSpellCritFromIntellect() diff --git a/src/game/Player.h b/src/game/Player.h index 90339e808..817bfc53a 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1798,7 +1798,7 @@ class MANGOS_DLL_SPEC Player : public Unit void UpdateDefenseBonusesMod(); float GetMeleeCritFromAgility(); - float GetDodgeFromAgility(); + void GetDodgeFromAgility(float &diminishing, float &nondiminishing); float GetSpellCritFromIntellect(); float OCTRegenHPPerSpirit(); float OCTRegenMPPerSpirit(); @@ -2561,6 +2561,10 @@ class MANGOS_DLL_SPEC Player : public Unit DeclinedName *m_declinedname; Runes *m_runes; EquipmentSets m_EquipmentSets; + + /// class dependent melee diminishing constant for dodge/parry/missed chances + static const float m_diminishing_k[MAX_CLASSES]; + private: void _HandleDeadlyPoison(Unit* Target, WeaponAttackType attType, SpellEntry const *spellInfo); // internal common parts for CanStore/StoreItem functions diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index 446a0fcd9..e8eea707c 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -552,20 +552,55 @@ void Player::UpdateAllCritPercentages() UpdateCritPercentage(RANGED_ATTACK); } +const float Player::m_diminishing_k[MAX_CLASSES] = +{ + 0.9560f, // Warrior + 0.9560f, // Paladin + 0.9880f, // Hunter + 0.9880f, // Rogue + 0.9830f, // Priest + 0.9560f, // DK + 0.9880f, // Shaman + 0.9830f, // Mage + 0.9830f, // Warlock + 0.0f, // ?? + 0.9720f // Druid +}; + void Player::UpdateParryPercentage() { + const float parry_cap[MAX_CLASSES] = + { + 47.003525f, // Warrior + 47.003525f, // Paladin + 145.560408f, // Hunter + 145.560408f, // Rogue + 0.0f, // Priest + 47.003525f, // DK + 145.560408f, // Shaman + 0.0f, // Mage + 0.0f, // Warlock + 0.0f, // ?? + 0.0f // Druid + }; + // No parry float value = 0.0f; - if (CanParry()) + uint32 pclass = getClass()-1; + if (CanParry() && parry_cap[pclass] > 0.0f) { // Base parry - value = 5.0f; - // Modify value from defense skill - value += (int32(GetDefenseSkillValue()) - int32(GetMaxSkillValueForLevel())) * 0.04f; - // Parry from SPELL_AURA_MOD_PARRY_PERCENT aura - value += GetTotalAuraModifier(SPELL_AURA_MOD_PARRY_PERCENT); + float nondiminishing = 5.0f; // Parry from rating - value += GetRatingBonusValue(CR_PARRY); + float diminishing = GetRatingBonusValue(CR_PARRY); + // Modify value from defense skill (only bonus from defense rating diminishes) + nondiminishing += (GetSkillValue(SKILL_DEFENSE) - GetMaxSkillValueForLevel()) * 0.04f; + diminishing += (int32(GetRatingBonusValue(CR_DEFENSE_SKILL))) * 0.04f; + // Parry from SPELL_AURA_MOD_PARRY_PERCENT aura + nondiminishing += GetTotalAuraModifier(SPELL_AURA_MOD_PARRY_PERCENT); + // apply diminishing formula to diminishing parry chance + value = nondiminishing + diminishing * parry_cap[pclass] / + (diminishing + parry_cap[pclass] * m_diminishing_k[pclass]); value = value < 0.0f ? 0.0f : value; } SetStatFloatValue(PLAYER_PARRY_PERCENTAGE, value); @@ -573,14 +608,35 @@ void Player::UpdateParryPercentage() void Player::UpdateDodgePercentage() { + const float dodge_cap[MAX_CLASSES] = + { + 88.129021f, // Warrior + 88.129021f, // Paladin + 145.560408f, // Hunter + 145.560408f, // Rogue + 150.375940f, // Priest + 88.129021f, // DK + 145.560408f, // Shaman + 150.375940f, // Mage + 150.375940f, // Warlock + 0.0f, // ?? + 116.890707f // Druid + }; + + float diminishing = 0.0f, nondiminishing = 0.0f; // Dodge from agility - float value = GetDodgeFromAgility(); - // Modify value from defense skill - value += (int32(GetDefenseSkillValue()) - int32(GetMaxSkillValueForLevel())) * 0.04f; + GetDodgeFromAgility(diminishing, nondiminishing); + // Modify value from defense skill (only bonus from defense rating diminishes) + nondiminishing += (GetSkillValue(SKILL_DEFENSE) - GetMaxSkillValueForLevel()) * 0.04f; + diminishing += (int32(GetRatingBonusValue(CR_DEFENSE_SKILL))) * 0.04f; // Dodge from SPELL_AURA_MOD_DODGE_PERCENT aura - value += GetTotalAuraModifier(SPELL_AURA_MOD_DODGE_PERCENT); + nondiminishing += GetTotalAuraModifier(SPELL_AURA_MOD_DODGE_PERCENT); // Dodge from rating - value += GetRatingBonusValue(CR_DODGE); + diminishing += GetRatingBonusValue(CR_DODGE); + // apply diminishing formula to diminishing dodge chance + uint32 pclass = getClass()-1; + float value = nondiminishing + (diminishing * dodge_cap[pclass] / + (diminishing + dodge_cap[pclass] * m_diminishing_k[pclass])); value = value < 0.0f ? 0.0f : value; SetStatFloatValue(PLAYER_DODGE_PERCENTAGE, value); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c670d30b6..3a1f77807 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11433" + #define REVISION_NR "11434" #endif // __REVISION_NR_H__