All pastes #824304 Raw Edit

Rating Fixes

public cpp v1 · immutable
·published 2007-12-19 22:03 UTC
rendered paste body
Index: game/Player.cpp===================================================================--- game/Player.cpp	(revision 4874)+++ game/Player.cpp	(working copy)@@ -4044,6 +4044,38 @@     return value; } +uint32 Player::GetMeleeCritDamageReduction(uint32 damage) const+{+    float melee  = GetRatingBonusValue(PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING)*2.0f;+    if (melee>25.0f) melee = 25.0f;+    return uint32 (melee * damage /100.0f);+}++uint32 Player::GetRangedCritDamageReduction(uint32 damage) const+{+    float ranged = GetRatingBonusValue(PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING)*2.0f;+    if (ranged>25.0f) ranged=25.0f;+    return uint32 (ranged * damage /100.0f);+}++uint32 Player::GetSpellCritDamageReduction(uint32 damage) const+{+    float spell = GetRatingBonusValue(PLAYER_FIELD_CRIT_TAKEN_SPELL_RATING)*2.0f;+    if (spell>25.0f) spell = 25.0f;+    return uint32 (spell * damage / 100.0f);+}++uint32 Player::GetDotDamageReduction(uint32 damage) const+{+    float spellDot = GetRatingBonusValue(PLAYER_FIELD_CRIT_TAKEN_SPELL_RATING);+    return uint32 (spellDot * damage / 100.0f);+}++float Player::GetExpertiseDodgeOrParryReduction() const+{+    return GetUInt32Value(PLAYER_EXPERTISE) / 4.0f;+}+ float Player::OCTRegenHPPerSpirit() {     uint32 level = getLevel();@@ -4097,62 +4129,58 @@      switch (index)     {-        case PLAYER_FIELD_MELEE_WEAPON_SKILL_RATING:-        case PLAYER_FIELD_OFFHAND_WEAPON_SKILL_RATING:-        case PLAYER_FIELD_RANGED_WEAPON_SKILL_RATING:-        {-            //Weapon skill: 2.5-            //RatingChange = value/(2.5 * RatingCoeffecient);-            /*uint16  slot;-            switch (index)-            {-                case PLAYER_FIELD_MELEE_WEAPON_SKILL_RATING: slot = EQUIPMENT_SLOT_MAINHAND; break;-                case PLAYER_FIELD_OFFHAND_WEAPON_SKILL_RATING: slot = EQUIPMENT_SLOT_OFFHAND; break;-                case PLAYER_FIELD_RANGED_WEAPON_SKILL_RATING: slot = EQUIPMENT_SLOT_RANGED; break;+//         Implemended in Unit::RollMeleeOutcomeAgainst+//         case PLAYER_FIELD_ALL_WEAPONS_SKILL_RATING:+//            break;+//         Implemended in Unit::RollMeleeOutcomeAgainst+//         case PLAYER_FIELD_DEFENCE_RATING:+//            break;+         case PLAYER_FIELD_DODGE_RATING:                  UpdateDodgePercentage();                        break;+         case PLAYER_FIELD_PARRY_RATING:                  UpdateParryPercentage();                        break;+         case PLAYER_FIELD_BLOCK_RATING:                  UpdateBlockPercentage();                        break;+         case PLAYER_FIELD_MELEE_HIT_RATING:+             RatingChange = value/ RatingCoeffecient;+             m_modMeleeHitChance += apply?RatingChange:-RatingChange;+            break;+         case PLAYER_FIELD_RANGED_HIT_RATING:+             RatingChange = value/ RatingCoeffecient;+             m_modRangedHitChance += apply?RatingChange:-RatingChange;+             break;+         case PLAYER_FIELD_SPELL_HIT_RATING:+             RatingChange = value/ RatingCoeffecient;+             m_modSpellHitChance += apply?RatingChange:-RatingChange;+             break;+         case PLAYER_FIELD_MELEE_CRIT_RATING:+             if(affectStats)+             {+                UpdateCritPercentage(BASE_ATTACK);+                UpdateCritPercentage(OFF_ATTACK);              }-            Item *item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot);-            uint32 skill = item && !item->IsBroken() && ((Player*)this)->IsUseEquipedWeapon()-                ? item->GetSkill() : SKILL_UNARMED;-            ModifySkillBonus(skill, (apply ? (int32)RatingChange: -(int32)RatingChange));*/-        }-        break;-        case PLAYER_FIELD_DEFENCE_RATING:-            //Defense: 1.5+             break;+         case PLAYER_FIELD_RANGED_CRIT_RATING:+             if(affectStats)+                 UpdateCritPercentage(RANGED_ATTACK);                                                 +             break;+         case PLAYER_FIELD_SPELL_CRIT_RATING:+             if(affectStats)+                 UpdateAllSpellCritChances();                                                              +             break;+//         Implemended in Unit::MeleeMissChanceCalc+//         case PLAYER_FIELD_HIT_TAKEN_MELEE_RATING:+//         case PLAYER_FIELD_HIT_TAKEN_RANGED_RATING:+//             break;+//         Implemended in Unit::SpellMissChanceCalc+//         case PLAYER_FIELD_HIT_TAKEN_SPELL_RATING:+//             break;+//         Implemended in Unit::RollMeleeOutcomeAgainst (only for chance to crit) +//         case PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING:+//         case PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING:+//             break;+//         Implemented in Unit::SpellCriticalBonus (only for chance to crit)+//         case PLAYER_FIELD_CRIT_TAKEN_SPELL_RATING:+//             break;+         case PLAYER_FIELD_MELEE_HASTE_RATING:             RatingChange = value/ RatingCoeffecient;-            ModifySkillBonus(SKILL_DEFENSE,(apply ? (int32)RatingChange: -(int32)RatingChange));-            if(affectStats)-                UpdateDefenseBonusesMod();-            break;-        case PLAYER_FIELD_DODGE_RATING:                  UpdateDodgePercentage();                        break;-        case PLAYER_FIELD_PARRY_RATING:                  UpdateParryPercentage();                        break;-        case PLAYER_FIELD_BLOCK_RATING:                  UpdateBlockPercentage();                        break;-        case PLAYER_FIELD_MELEE_HIT_RATING:-            //Hit (melee): 10-            RatingChange = value/ RatingCoeffecient;-            m_modHitChance += apply ? RatingChange : -RatingChange;-            break;-        case PLAYER_FIELD_RANGED_HIT_RATING:-            //Hit (melee): 10-            RatingChange = value/ RatingCoeffecient;-            m_modHitChance += apply ? RatingChange : -RatingChange;-            break;-        case PLAYER_FIELD_SPELL_HIT_RATING:-            //Hit (spells): 8-            RatingChange = value/ RatingCoeffecient;-            m_modSpellHitChance += apply ? RatingChange : -RatingChange;-            break;-        case PLAYER_FIELD_MELEE_CRIT_RATING:-            if(affectStats)-                UpdateCritPercentage(BASE_ATTACK);                                                        break;-        case PLAYER_FIELD_RANGED_CRIT_RATING:-            if(affectStats)-                UpdateCritPercentage(RANGED_ATTACK);                                                      break;-        case PLAYER_FIELD_SPELL_CRIT_RATING:-            if(affectStats)-                UpdateAllSpellCritChances();                                                              break;-        case PLAYER_FIELD_MELEE_HASTE_RATING:-            //Haste: 6.67-            RatingChange = value/ RatingCoeffecient;             if(RatingChange > 0)             {                 ApplyAttackTimePercentMod(BASE_ATTACK,RatingChange,apply);@@ -4164,45 +4192,26 @@                 ApplyAttackTimePercentMod(OFF_ATTACK,-RatingChange,!apply);             }             break;-        case PLAYER_FIELD_RANGED_HASTE_RATING:-            //Haste: 6.67+         case PLAYER_FIELD_RANGED_HASTE_RATING:             RatingChange = value/ RatingCoeffecient;             if(RatingChange >= 0)                 ApplyAttackTimePercentMod(RANGED_ATTACK, RatingChange, apply);             else                 ApplyAttackTimePercentMod(RANGED_ATTACK, -RatingChange, !apply);             break;-        case PLAYER_FIELD_SPELL_HASTE_RATING:-            //Haste: 6.67+         case PLAYER_FIELD_SPELL_HASTE_RATING:             RatingChange = value/ RatingCoeffecient;             ApplyPercentModFloatValue(UNIT_MOD_CAST_SPEED,-RatingChange,apply);             break;-        case PLAYER_FIELD_HIT_RATING:-            //Hit (melee): 10-            RatingChange = value/ RatingCoeffecient;-            ApplyModUInt32Value(PLAYER_FIELD_MELEE_HIT_RATING, value, apply);-            ApplyModUInt32Value(PLAYER_FIELD_RANGED_HIT_RATING, value, apply);-            m_modHitChance += apply ? RatingChange : -RatingChange;-            break;-        case PLAYER_FIELD_CRIT_RATING:-            ApplyModUInt32Value(PLAYER_FIELD_MELEE_CRIT_RATING, value, apply);-            ApplyModUInt32Value(PLAYER_FIELD_RANGED_CRIT_RATING, value, apply);-            if(affectStats)-                UpdateAllCritPercentages();-            break;-            /*-            case PLAYER_FIELD_HIT_AVOIDANCE_RATING:-                break;-            case PLAYER_FIELD_CRIT_AVOIDANCE_RATING:-                break;-            */-        case PLAYER_FIELD_RESILIENCE_RATING:-            //Resilience: 25-            RatingChange = value/ RatingCoeffecient;-            ApplyModUInt32Value(PLAYER_FIELD_UNK4_RATING, value, apply);-            ApplyModUInt32Value(PLAYER_FIELD_UNK5_RATING, value, apply);-            m_modResilience += apply ? RatingChange :-RatingChange;-            break;+//         Implemended in Unit::RollMeleeOutcomeAgainst+//         case PLAYER_FIELD_MELEE_WEAPON_SKILL_RATING:+//         case PLAYER_FIELD_OFFHAND_WEAPON_SKILL_RATING:+//         case PLAYER_FIELD_RANGED_WEAPON_SKILL_RATING:+//            break;+         case PLAYER_FIELD_EXPERTISE_RATING:+             if(affectStats)+                 UpdateExpertise();                                                      +             break;     } } @@ -5924,7 +5933,6 @@                     ApplyNegStatMod(STAT_STAMINA,        -val, apply);                 //typestr = "STAMINA";                 break;-             case ITEM_MOD_DEFENSE_SKILL_RATING:                 ApplyRatingMod(PLAYER_FIELD_DEFENCE_RATING, int32(val), apply);                 break;@@ -5956,22 +5964,22 @@                 ApplyRatingMod(PLAYER_FIELD_SPELL_CRIT_RATING, int32(val), apply);                 break;             case ITEM_MOD_HIT_TAKEN_MELEE_RATING:-                //ApplyRatingMod(PLAYER_FIELD_MELEE_HA_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_HIT_TAKEN_MELEE_RATING, int32(val), apply);                 break;             case ITEM_MOD_HIT_TAKEN_RANGED_RATING:-                //ApplyRatingMod(PLAYER_FIELD_RANGED_HA_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_HIT_TAKEN_RANGED_RATING, int32(val), apply);                 break;             case ITEM_MOD_HIT_TAKEN_SPELL_RATING:-                //ApplyRatingMod(PLAYER_FIELD_SPELL_HA_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_HIT_TAKEN_SPELL_RATING, int32(val), apply);                 break;             case ITEM_MOD_CRIT_TAKEN_MELEE_RATING:-                //ApplyRatingMod(PLAYER_FIELD_MELEE_CA_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING, int32(val), apply);                 break;             case ITEM_MOD_CRIT_TAKEN_RANGED_RATING:-                //ApplyRatingMod(PLAYER_FIELD_RANGED_CA_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING, int32(val), apply);                 break;             case ITEM_MOD_CRIT_TAKEN_SPELL_RATING:-                //ApplyRatingMod(PLAYER_FIELD_SPELL_CA_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_SPELL_RATING, int32(val), apply);                 break;             case ITEM_MOD_HASTE_MELEE_RATING:                 ApplyRatingMod(PLAYER_FIELD_MELEE_HASTE_RATING, int32(val), apply);@@ -5983,19 +5991,29 @@                 ApplyRatingMod(PLAYER_FIELD_SPELL_HASTE_RATING, int32(val), apply);                 break;             case ITEM_MOD_HIT_RATING:-                ApplyRatingMod(PLAYER_FIELD_HIT_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_MELEE_HIT_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_RANGED_HIT_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_SPELL_HIT_RATING, int32(val), apply);                 break;             case ITEM_MOD_CRIT_RATING:-                ApplyRatingMod(PLAYER_FIELD_CRIT_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_MELEE_CRIT_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_RANGED_CRIT_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_SPELL_CRIT_RATING, int32(val), apply);                 break;             case ITEM_MOD_HIT_TAKEN_RATING:-                //ApplyRatingMod(PLAYER_FIELD_HA_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_HIT_TAKEN_MELEE_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_HIT_TAKEN_RANGED_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_HIT_TAKEN_SPELL_RATING, int32(val), apply);                 break;             case ITEM_MOD_CRIT_TAKEN_RATING:-                //ApplyRatingMod(PLAYER_FIELD_CA_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_SPELL_RATING, int32(val), apply);                 break;             case ITEM_MOD_RESILIENCE_RATING:-                ApplyRatingMod(PLAYER_FIELD_RESILIENCE_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING, int32(val), apply);+                ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_SPELL_RATING, int32(val), apply);                 break;             case ITEM_MOD_HASTE_RATING:                 ApplyRatingMod(PLAYER_FIELD_MELEE_HASTE_RATING, int32(val), apply);@@ -10428,19 +10446,62 @@                         ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_SPELL_CRIT_RATING, enchant_amount, apply);                         sLog.outDebug("+ %u SPELL_CRIT", enchant_amount);                         break;-                        // Values from ITEM_STAT_MELEE_HA_RATING to ITEM_STAT_SPELL_HASTE_RATING are never used-                        // in Enchantments+//                    Values from ITEM_STAT_MELEE_HA_RATING to ITEM_STAT_SPELL_HASTE_RATING are never used+//                    in Enchantments+//                    case ITEM_MOD_HIT_TAKEN_MELEE_RATING:+//                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_HIT_TAKEN_MELEE_RATING, enchant_amount, apply);+//                        break;+//                    case ITEM_MOD_HIT_TAKEN_RANGED_RATING:+//                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_HIT_TAKEN_RANGED_RATING, enchant_amount, apply);+//                        break;+//                    case ITEM_MOD_HIT_TAKEN_SPELL_RATING:+//                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_HIT_TAKEN_SPELL_RATING, enchant_amount, apply);+//                        break;+//                    case ITEM_MOD_CRIT_TAKEN_MELEE_RATING:+//                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING, enchant_amount, apply);+//                        break;+//                    case ITEM_MOD_CRIT_TAKEN_RANGED_RATING:+//                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING, enchant_amount, apply);+//                        break;+//                    case ITEM_MOD_CRIT_TAKEN_SPELL_RATING:+//                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_SPELL_RATING, enchant_amount, apply);+//                        break;+//                    case ITEM_MOD_HASTE_MELEE_RATING:+//                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_MELEE_HASTE_RATING, enchant_amount, apply);+//                        break;+//                    case ITEM_MOD_HASTE_RANGED_RATING:+//                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_RANGED_HIT_RATING, enchant_amount, apply);+//                        break;+//                    case ITEM_MOD_HASTE_SPELL_RATING:+//                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_SPELL_HIT_RATING, enchant_amount, apply);+//                        break;                     case ITEM_MOD_HIT_RATING:-                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_HIT_RATING, enchant_amount, apply);+                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_MELEE_HIT_RATING, enchant_amount, apply);+                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_RANGED_HIT_RATING, enchant_amount, apply);+                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_SPELL_HIT_RATING, enchant_amount, apply);                         sLog.outDebug("+ %u HIT", enchant_amount);                         break;                     case ITEM_MOD_CRIT_RATING:-                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_CRIT_RATING, enchant_amount, apply);+                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_MELEE_CRIT_RATING, enchant_amount, apply);+                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_RANGED_CRIT_RATING, enchant_amount, apply);+                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_SPELL_CRIT_RATING, enchant_amount, apply);                         sLog.outDebug("+ %u CRITICAL", enchant_amount);                         break;-                        // Values ITEM_STAT_HA_RATING and ITEM_STAT_CA_RATING are never used in Enchantment+//                    Values ITEM_MOD_HIT_TAKEN_RATING and ITEM_MOD_CRIT_TAKEN_RATING are never used in Enchantment+//                    case ITEM_MOD_HIT_TAKEN_RATING:+//                          ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_HIT_TAKEN_MELEE_RATING, enchant_amount, apply);+//                          ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_HIT_TAKEN_RANGED_RATING, enchant_amount, apply);+//                          ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_HIT_TAKEN_SPELL_RATING, enchant_amount, apply);+//                        break;+//                    case ITEM_MOD_CRIT_TAKEN_RATING:+//                          ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING, enchant_amount, apply);+//                          ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING, enchant_amount, apply);+//                          ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_SPELL_RATING, enchant_amount, apply);+//                        break;                     case ITEM_MOD_RESILIENCE_RATING:-                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_RESILIENCE_RATING, enchant_amount, apply);+                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING, enchant_amount, apply);+                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING, enchant_amount, apply);+                        ((Player*)this)->ApplyRatingMod(PLAYER_FIELD_CRIT_TAKEN_SPELL_RATING, enchant_amount, apply);                         sLog.outDebug("+ %u RESILIENCE", enchant_amount);                         break;                         // Value ITEM_STAT_HASTE_RATING is never used in EnchantmentIndex: game/Player.h===================================================================--- game/Player.h	(revision 4874)+++ game/Player.h	(working copy)@@ -1357,12 +1357,19 @@         float OCTRegenMPPerSpirit();         float GetRatingCoefficient(uint16 index) const;         float GetRatingBonusValue(uint16 index) const;+        uint32 GetMeleeCritDamageReduction(uint32 damage) const;+        uint32 GetRangedCritDamageReduction(uint32 damage) const;+        uint32 GetSpellCritDamageReduction(uint32 damage) const;+        uint32 GetDotDamageReduction(uint32 damage) const;++        float GetExpertiseDodgeOrParryReduction() const;         void UpdateBlockPercentage();         void UpdateCritPercentage(WeaponAttackType attType);         void UpdateAllCritPercentages();         void UpdateParryPercentage();         void UpdateDodgePercentage();         void UpdateAllSpellCritChances();+        void UpdateExpertise();         void UpdateManaRegen();         void UpdateSpellCritChance(uint32 school);         uint32 GetSpellSchoolByBaseGroup(BaseModGroup baseGroup) const;Index: game/Spell.h===================================================================--- game/Spell.h	(revision 4874)+++ game/Spell.h	(working copy)@@ -123,33 +123,32 @@  enum Rating {-    SPELL_RATING_SKILL                      = 0x0000001,    // 0-    SPELL_RATING_DEFENCE                    = 0x0000002,    // 1-    SPELL_RATING_DODGE                      = 0x0000004,    // 2-    SPELL_RATING_PARRY                      = 0x0000008,    // 3-    SPELL_RATING_BLOCK                      = 0x0000010,    // 4-    SPELL_RATING_MELEE_HIT                  = 0x0000020,    // 5-    SPELL_RATING_RANGED_HIT                 = 0x0000040,    // 6-    SPELL_RATING_SPELL_HIT                  = 0x0000080,    // 7-    SPELL_RATING_MELEE_CRIT_HIT             = 0x0000100,    // 8-    SPELL_RATING_RANGED_CRIT_HIT            = 0x0000200,    // 9-    SPELL_RATING_SPELL_CRIT_HIT             = 0x0000400,    // 10-    //SPELL_RATING_MELEE_HIT_TAKEN            = 0x0000800,    // 11-    //SPELL_RATING_RANGED_HIT_TAKEN           = 0x0001000,    // 12-    //SPELL_RATING_SPELL_HIT_TAKEN            = 0x0002000,    // 13-    //SPELL_RATING_MELEE_CRIT_TAKEN           = 0x0004000,    // 14-    //SPELL_RATING_RANGED_CRIT_TAKEN          = 0x0008000,    // 15-    //SPELL_RATING_SPELL_CRIT_TAKEN           = 0x0010000,    // 16-    SPELL_RATING_MELEE_HASTE                = 0x0020000,    // 17-    SPELL_RATING_RANGED_HASTE               = 0x0040000,    // 18-    SPELL_RATING_SPELL_HASTE                = 0x0080000,    // 19-    SPELL_RATING_HIT                        = 0x0100000,    // 20-    SPELL_RATING_CRIT_HIT                   = 0x0200000,    // 21-    SPELL_RATING_HIT_AVOIDANCE              = 0x0400000,    // 22-    SPELL_RATING_CRIT_AVOIDANCE             = 0x0800000,    // 23-    SPELL_RATING_RESILIENCE                 = 0x1000000     // 24-    //SPELL_RATING_EXPERTISE+    CR_WEAPON_SKILL = 1,+    CR_DEFENSE_SKILL = 2,+    CR_DODGE = 3,+    CR_PARRY = 4,+    CR_BLOCK = 5,+    CR_HIT_MELEE = 6,+    CR_HIT_RANGED = 7,+    CR_HIT_SPELL = 8,+    CR_CRIT_MELEE = 9,+    CR_CRIT_RANGED = 10,+    CR_CRIT_SPELL = 11,+    CR_HIT_TAKEN_MELEE = 12,+    CR_HIT_TAKEN_RANGED = 13,+    CR_HIT_TAKEN_SPELL = 14,+    CR_CRIT_TAKEN_MELEE = 15,+    CR_CRIT_TAKEN_RANGED = 16,+    CR_CRIT_TAKEN_SPELL = 17,+    CR_HASTE_MELEE = 18,+    CR_HASTE_RANGED = 19,+    CR_HASTE_SPELL = 20,+    CR_WEAPON_SKILL_MAINHAND = 21,+    CR_WEAPON_SKILL_OFFHAND = 22,+    CR_WEAPON_SKILL_RANGED = 23,+    CR_EXPERTISE = 24 };+#define MAX_RATINGS 24  bool IsQuestTameSpell(uint32 spellId); Index: game/SpellAuraDefines.h===================================================================--- game/SpellAuraDefines.h	(revision 4874)+++ game/SpellAuraDefines.h	(working copy)@@ -277,7 +277,7 @@     SPELL_AURA_237 = 237,     SPELL_AURA_238 = 238,     SPELL_AURA_239 = 239,-    SPELL_AURA_240 = 240,+    SPELL_AURA_MOD_EXPERTISE = 240,     SPELL_AURA_241 = 241,     SPELL_AURA_242 = 242,     SPELL_AURA_243 = 243,Index: game/SpellAuras.cpp===================================================================--- game/SpellAuras.cpp	(revision 4874)+++ game/SpellAuras.cpp	(working copy)@@ -289,7 +289,7 @@     &Aura::HandleNULL,                                      //237     &Aura::HandleNULL,                                      //238     &Aura::HandleNULL,                                      //239-    &Aura::HandleNULL,                                      //240+    &Aura::HandleAuraModExpertise,                          //240 SPELL_AURA_MOD_EXPERTISE      &Aura::HandleNULL,                                      //241     &Aura::HandleNULL,                                      //242     &Aura::HandleNULL,                                      //243@@ -3431,7 +3431,8 @@  void Aura::HandleModHitChance(bool Apply, bool Real) {-    m_target->m_modHitChance += Apply ? m_modifier.m_amount : (-m_modifier.m_amount);+    m_target->m_modMeleeHitChance += Apply ? m_modifier.m_amount : (-m_modifier.m_amount);+    m_target->m_modRangedHitChance += Apply ? m_modifier.m_amount : (-m_modifier.m_amount); }  void Aura::HandleModSpellHitChance(bool Apply, bool Real)@@ -4057,74 +4058,18 @@ {     if(m_target->GetTypeId() == TYPEID_PLAYER)     {-        if (m_modifier.m_miscvalue & SPELL_RATING_SKILL)-        {-            /*Item* pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);-            if (pItem && pItem->IsFitToSpellRequirements(GetSpellProto()))-                ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_MELEE_WEAPON_SKILL_RATING,m_modifier.m_amount,apply);+     uint32 mask=1;+     for (uint32 rating=0;rating<MAX_RATINGS;rating++, mask<<=1)+        if (m_modifier.m_miscvalue & mask)+            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_COMBAT_RATING_1 + rating, m_modifier.m_amount, apply);+    }+} -            pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);-            if (pItem && pItem->IsFitToSpellRequirements(GetSpellProto()))-                ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_OFFHAND_WEAPON_SKILL_RATING,m_modifier.m_amount,apply);--            pItem = ((Player*)m_target)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED);-            if (pItem && pItem->IsFitToSpellRequirements(GetSpellProto()))-                ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_RANGED_WEAPON_SKILL_RATING,m_modifier.m_amount,apply);*/-        }--        if (m_modifier.m_miscvalue & SPELL_RATING_DEFENCE)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_DEFENCE_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_DODGE)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_DODGE_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_PARRY)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_PARRY_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_BLOCK)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_BLOCK_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_MELEE_HIT)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_MELEE_HIT_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_RANGED_HIT)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_RANGED_HIT_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_SPELL_HIT)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_SPELL_HIT_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_MELEE_CRIT_HIT)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_MELEE_CRIT_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_RANGED_CRIT_HIT)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_RANGED_CRIT_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_SPELL_CRIT_HIT)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_SPELL_CRIT_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_MELEE_HASTE)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_MELEE_HASTE_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_RANGED_HASTE)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_RANGED_HASTE_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_SPELL_HASTE)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_SPELL_HASTE_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_HIT)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_HIT_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_CRIT_HIT)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_CRIT_RATING,m_modifier.m_amount,apply);--        /*if (m_modifier.m_miscvalue & SPELL_RATING_HIT_AVOIDANCE)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_HIT_AVOIDANCE_RATING,m_modifier.m_amount,apply);--        if (m_modifier.m_miscvalue & SPELL_RATING_CRIT_AVOIDANCE)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_CRIT_AVOIDANCE_RATING,m_modifier.m_amount,apply);*/--        if (m_modifier.m_miscvalue & SPELL_RATING_RESILIENCE)-            ((Player*)m_target)->ApplyRatingMod(PLAYER_FIELD_RESILIENCE_RATING,m_modifier.m_amount,apply);+void Aura::HandleAuraModExpertise(bool apply, bool Real)+{+    if(m_target->GetTypeId() == TYPEID_PLAYER)+    {+         ((Player*)m_target)->ApplyModInt32Value(PLAYER_EXPERTISE, m_modifier.m_amount, apply);     } } Index: game/SpellAuras.h===================================================================--- game/SpellAuras.h	(revision 4874)+++ game/SpellAuras.h	(working copy)@@ -188,6 +188,7 @@         void HandleAuraRetainComboPoints(bool apply, bool Real);         void HandleModSpellDamagePercent(bool apply, bool Real);         void HandleModSpellHealingPercent(bool apply, bool Real);+        void HandleAuraModExpertise(bool apply, bool Real);          Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL);         virtual ~Aura();Index: game/StatSystem.cpp===================================================================--- game/StatSystem.cpp	(revision 4874)+++ game/StatSystem.cpp	(working copy)@@ -424,6 +424,13 @@         UpdateSpellCritChance(i); } +void Player::UpdateExpertise()+{+    uint32 expertise = GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE);+    expertise+= uint32(GetRatingBonusValue(PLAYER_FIELD_EXPERTISE_RATING));+    SetUInt32Value(PLAYER_EXPERTISE, expertise);+}+ void Player::UpdateManaRegen() {     uint8 PlayerClass = getClass();Index: game/Unit.cpp===================================================================--- game/Unit.cpp	(revision 4874)+++ game/Unit.cpp	(working copy)@@ -174,10 +174,11 @@         m_createStats[i] = 0.0f;      m_attacking = NULL;-    m_modHitChance = 0.0f;+    m_modMeleeHitChance = 0.0f;+    m_modRangedHitChance = 0.0f;     m_modSpellHitChance = 0.0f;     m_baseSpellCritChance = 5;-    m_modResilience = 0.0f;+     m_CombatTimer = 0;     //m_victimThreat = 0.0f;     for (int i = 0; i < MAX_SPELL_SCHOOL; ++i)@@ -1077,10 +1078,13 @@                 case MELEE_HIT_CRIT:                 {                     *damage *= 2;-                    // Resilience - reduce crit damage by 2x%-                    uint32 resilienceReduction = uint32(pVictim->m_modResilience * 2/100 * (*damage));-                    cleanDamage->damage += resilienceReduction;-                    *damage -=  resilienceReduction;+                    // Resilience - reduce crit damage+                    if (pVictim->GetTypeId()==TYPEID_PLAYER)+                    {+                     uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage);+                     cleanDamage->damage += resilienceReduction;+                     *damage -=  resilienceReduction;+                    }                     *crit = true;                     hitInfo |= HITINFO_CRITICALHIT;                     break;@@ -1218,10 +1222,13 @@                 {                     *crit = true;                     *damage *= 2;-                    // Resilience - reduce crit damage by 2x%-                    uint32 resilienceReduction = uint32(pVictim->m_modResilience * 2/100 * (*damage));-                    cleanDamage->damage += resilienceReduction;-                    *damage -=  resilienceReduction;+                    // Resilience - reduce crit damage by+                    if (pVictim->GetTypeId()==TYPEID_PLAYER)+                    {+                     uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage);+                     cleanDamage->damage += resilienceReduction;+                     *damage -=  resilienceReduction;+                    }                 }             }             else@@ -1348,6 +1355,9 @@             if(mod->m_auraname == SPELL_AURA_PERIODIC_DAMAGE)             {                 pdamage = mod->m_amount;+                // Reduce dot damage from resilience for players+                if (pVictim->GetTypeId()==TYPEID_PLAYER)+                  pdamage-=((Player*)pVictim)->GetDotDamageReduction(pdamage);                  //Calculate armor mitigation if it is a physical spell                 if (spellProto->School == SPELL_SCHOOL_NORMAL)@@ -1390,6 +1400,9 @@             CleanDamage cleanDamage =  CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL );              uint32 pdamage = mod->m_amount;+            // Reduce dot damage from resilience for players+            if (pVictim->GetTypeId()==TYPEID_PLAYER)+               pdamage-=((Player*)pVictim)->GetDotDamageReduction(pdamage);              //Calculate armor mitigation if it is a physical spell             if (spellProto->School == SPELL_SCHOOL_NORMAL)@@ -1825,6 +1838,7 @@     switch (outcome)     {         case MELEE_HIT_CRIT:+        {             //*hitInfo = 0xEA;             // 0xEA             *hitInfo  = HITINFO_CRITICALHIT | HITINFO_NORMALSWING2 | 0x8;@@ -1841,21 +1855,23 @@             }              *damage += crit_bonus;-+            uint32 resilienceReduction = 0;             if(attType == RANGED_ATTACK)             {                 int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE);                 *damage = int32((*damage) * float((100.0f + mod)/100.0f));+                // Resilience - reduce crit damage+                if (pVictim->GetTypeId()==TYPEID_PLAYER)+                  resilienceReduction = ((Player*)pVictim)->GetRangedCritDamageReduction(*damage);             }             else             {                 int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE);                 *damage = int32((*damage) * float((100.0f + mod)/100.0f));+                // Resilience - reduce crit damage+                if (pVictim->GetTypeId()==TYPEID_PLAYER)+                  resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage);             }--            // Resilience - reduce crit damage by 2x%-            uint32 resilienceReduction;-            resilienceReduction = uint32(pVictim->m_modResilience * 2/100 * (*damage));             *damage -= resilienceReduction;             cleanDamage->damage += resilienceReduction; @@ -1873,7 +1889,7 @@              pVictim->HandleEmoteCommand(EMOTE_ONESHOT_WOUNDCRITICAL);             break;-+        }         case MELEE_HIT_PARRY:             if(attType == RANGED_ATTACK || unavoidable)                    //range attack - no parry                 break;@@ -2246,7 +2262,7 @@ MeleeHitOutcome Unit::RollPhysicalOutcomeAgainst (Unit const *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo) {     // Miss chance based on melee-    int32 miss_chance = (int32)(MeleeMissChanceCalc(pVictim));+    int32 miss_chance = (int32)(MeleeMissChanceCalc(pVictim, attType));      // Critical hit chance     float crit_chance = GetUnitCriticalChance(attType);@@ -2269,10 +2285,12 @@     // Spellmods     if(Player* modOwner = GetSpellModOwner())         modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRITICAL_CHANCE, crit_chance);+    float modHitChance = 0.0f;+    if (attType == RANGED_ATTACK) modHitChance = m_modRangedHitChance;+    else                          modHitChance = m_modMeleeHitChance;+    DEBUG_LOG("PHYSICAL OUTCOME: hit %f crit %f miss %u",modHitChance,crit_chance,miss_chance); -    DEBUG_LOG("PHYSICAL OUTCOME: hit %f crit %f miss %u",m_modHitChance,crit_chance,miss_chance);--    return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance * 100 ), miss_chance, int32(m_modHitChance));+    return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance * 100 ), miss_chance, int32(modHitChance)); }  MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType) const@@ -2280,7 +2298,7 @@     // This is only wrapper      // Miss chance based on melee-    int32 miss_chance = (int32)(MeleeMissChanceCalc(pVictim));+    int32 miss_chance = (int32)(MeleeMissChanceCalc(pVictim, attType));      // Critical hit chance     float crit_chance = GetUnitCriticalChance(attType);@@ -2290,9 +2308,12 @@     for(AuraList::const_iterator i = mAttackerSWCrit.begin(); i != mAttackerSWCrit.end(); ++i)         crit_chance += (*i)->GetModifier()->m_amount; +    float modHitChance = 0.0f;+    if (attType == RANGED_ATTACK) modHitChance = m_modRangedHitChance;+    else                          modHitChance = m_modMeleeHitChance;     // Useful if want to specify crit & miss chances for melee, else it could be removed-    DEBUG_LOG("MELEE OUTCOME: hit %f crit %u miss %u", m_modHitChance,crit_chance,miss_chance);-    return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance * 100 ), miss_chance, int32(m_modHitChance));+    DEBUG_LOG("MELEE OUTCOME: hit %f crit %u miss %u", modHitChance,crit_chance,miss_chance);+    return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance * 100 ), miss_chance, int32(modHitChance)); }  MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 hit_chance) const@@ -2301,6 +2322,21 @@         return MELEE_HIT_EVADE;      int32 skillDiff =  GetWeaponSkillValue(attType) - pVictim->GetDefenseSkillValue();+    // Add rating bonuses for attacker+    if(GetTypeId() == TYPEID_PLAYER)+    {+       skillDiff+=((Player*)this)->GetRatingBonusValue(PLAYER_FIELD_ALL_WEAPONS_SKILL_RATING);+       switch (attType)+       {+        case BASE_ATTACK:   skillDiff+=((Player*)this)->GetRatingBonusValue(PLAYER_FIELD_MELEE_WEAPON_SKILL_RATING);break;+        case OFF_ATTACK:    skillDiff+=((Player*)this)->GetRatingBonusValue(PLAYER_FIELD_OFFHAND_WEAPON_SKILL_RATING);break;+        case RANGED_ATTACK: skillDiff+=((Player*)this)->GetRatingBonusValue(PLAYER_FIELD_RANGED_WEAPON_SKILL_RATING);break;+       }+    }+    // Add rating bonuses for victim+    if(pVictim->GetTypeId() == TYPEID_PLAYER)+       skillDiff-=((Player*)pVictim)->GetRatingBonusValue(PLAYER_FIELD_DEFENCE_RATING);+     // bonus from skills is 0.04%     int32    skillBonus = skillDiff * 4;     int32    skillBonus2 = 4 * ( GetWeaponSkillValue(attType) - pVictim->GetPureDefenseSkillValue() );@@ -2343,7 +2379,11 @@     }      // stunned target cannot dodge and this is check in GetUnitDodgeChance()-    tmp = (int32)(pVictim->GetUnitDodgeChance()*100);+    float dodge = pVictim->GetUnitDodgeChance();+    // Reduce dodge chance by attacker expertise rating+    if (GetTypeId() == TYPEID_PLAYER)+         dodge-=((Player*)this)->GetExpertiseDodgeOrParryReduction();+    tmp = (int32)(dodge*100.0f);     if (   (tmp > 0)                                        // check if unit _can_ dodge         && ((tmp -= skillBonus2) > 0)         && roll < (sum += tmp))@@ -2364,7 +2404,11 @@     else     {         // cannot parry or block attacks from behind, but can from forward-        tmp = (int32)(pVictim->GetUnitParryChance()*100);+        float parry = pVictim->GetUnitParryChance();+        // Reduce parry chance by attacker expertise rating+        if (GetTypeId() == TYPEID_PLAYER)+            parry-=((Player*)this)->GetExpertiseDodgeOrParryReduction();+        int32 tmp = int32(parry * 100.0f);         if (   (tmp > 0)                                    // check if unit _can_ parry             && ((tmp -= skillBonus2) > 0)             && (roll < (sum += tmp)))@@ -2383,8 +2427,14 @@         }     } -    // Resilience - reduce crit chance by x%-    modCrit -= int32(pVictim->m_modResilience*100);+    // reduce crit chance from Rating for players+    if (pVictim->GetTypeId()==TYPEID_PLAYER)+    {+     if (attType==RANGED_ATTACK)+      modCrit -= int32(((Player*)pVictim)->GetRatingBonusValue(PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING)*100);+     else+      modCrit -= int32(((Player*)pVictim)->GetRatingBonusValue(PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING)*100);+    }      // Critical chance     tmp = crit_chance + skillBonus + modCrit;@@ -2515,11 +2565,13 @@      int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE);     misschance -= mod * 100;-+    // Add victim rating bonus+    if (pVictim->GetTypeId()==TYPEID_PLAYER)+        misschance+=((Player*)pVictim)->GetRatingBonusValue(PLAYER_FIELD_HIT_TAKEN_SPELL_RATING)*100.0f;     return misschance < 100 ? 100 : misschance; } -int32 Unit::MeleeMissChanceCalc(const Unit *pVictim) const+int32 Unit::MeleeMissChanceCalc(const Unit *pVictim, WeaponAttackType attType) const {     if(!pVictim)         return 0;@@ -2555,12 +2607,26 @@     int32 leveldif = pVictim->getLevel() - getLevel();     if(leveldif < 0)         leveldif = 0;+    // Hit chance from attacker based on ratings and auras+    uint32 m_modHitChance;+    if (attType == RANGED_ATTACK)+      m_modHitChance = m_modRangedHitChance * 100.0f;+    else+      m_modHitChance = m_modMeleeHitChance * 100.0f;      if(leveldif < 3)-        misschance += leveldif * 100 - int32(m_modHitChance*100);+        misschance += leveldif * 100 - m_modHitChance;     else-        misschance += (leveldif - 2) * chance - int32(m_modHitChance*100);+        misschance += (leveldif - 2) * chance - m_modHitChance; +    // Hit chance for victim based on ratings+    if (pVictim->GetTypeId()==TYPEID_PLAYER)+    {+      if (attType == RANGED_ATTACK) +          misschance+=((Player*)pVictim)->GetRatingBonusValue(PLAYER_FIELD_HIT_TAKEN_RANGED_RATING)*100.0f;+      else                          +          misschance+=((Player*)pVictim)->GetRatingBonusValue(PLAYER_FIELD_HIT_TAKEN_MELEE_RATING)*100.0f;+    }     return misschance > 6000 ? 6000 : misschance; } @@ -5242,8 +5308,8 @@             if((*i)->GetModifier()->m_miscvalue == -2 || ((*i)->GetModifier()->m_miscvalue & (int32)(1<<spellProto->School)) != 0)                 crit_chance += (*i)->GetModifier()->m_amount; -        // flat: Resilience - reduce crit chance by x%-        crit_chance -= pVictim->m_modResilience;+        if (pVictim->GetTypeId() == TYPEID_PLAYER)+          crit_chance -= ((Player*)pVictim)->GetRatingBonusValue(PLAYER_FIELD_CRIT_TAKEN_SPELL_RATING);          // flat: scripted (increase crit chance ... against ... target by x%         AuraList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);@@ -5282,10 +5348,10 @@         if(crit_bonus> 0)             *damage += crit_bonus; -        // Resilience - reduce crit damage by 2x%-        if (pVictim)+        // Resilience - reduce crit damage+        if (pVictim && pVictim->GetTypeId()==TYPEID_PLAYER)         {-            *damage -= uint32(pVictim->m_modResilience * 2/100 * (*damage));+            *damage -= ((Player *)pVictim)->GetSpellCritDamageReduction(*damage);         }          return true;Index: game/Unit.h===================================================================--- game/Unit.h	(revision 4874)+++ game/Unit.h	(working copy)@@ -850,7 +850,7 @@         void HandleEmoteCommand(uint32 anim_id);         void AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType = BASE_ATTACK, bool isTriggered = false);         uint32 SpellMissChanceCalc(Unit *pVictim) const;-        int32 MeleeMissChanceCalc(const Unit *pVictim) const;+        int32 MeleeMissChanceCalc(const Unit *pVictim, WeaponAttackType attType) const;          float GetUnitDodgeChance()    const;         float GetUnitParryChance()    const;@@ -1048,10 +1048,11 @@         uint32 m_invisibilityMask;         uint32 m_ShapeShiftForm;         uint32 m_form;-        float m_modHitChance;+        float m_modMeleeHitChance;+        float m_modRangedHitChance;         float m_modSpellHitChance;         int32 m_baseSpellCritChance;-        float m_modResilience;+         float m_threatModifier[MAX_SPELL_SCHOOL];         float m_modAttackSpeedPct[3]; Index: game/UpdateFields.h===================================================================--- game/UpdateFields.h	(revision 4874)+++ game/UpdateFields.h	(working copy)@@ -371,17 +371,17 @@                                                             // CR_CRIT_SPELL     PLAYER_FIELD_SPELL_CRIT_RATING            = PLAYER_FIELD_COMBAT_RATING_1+10,                                                             // CR_HIT_TAKEN_MELEE-    PLAYER_FIELD_HIT_RATING                   = PLAYER_FIELD_COMBAT_RATING_1+11,+    PLAYER_FIELD_HIT_TAKEN_MELEE_RATING       = PLAYER_FIELD_COMBAT_RATING_1+11,                                                             // CR_HIT_TAKEN_RANGED-    PLAYER_FIELD_CRIT_RATING                  = PLAYER_FIELD_COMBAT_RATING_1+12,+    PLAYER_FIELD_HIT_TAKEN_RANGED_RATING      = PLAYER_FIELD_COMBAT_RATING_1+12,                                                             // CR_HIT_TAKEN_SPELL-    PLAYER_FIELD_UNK3_RATING                  = PLAYER_FIELD_COMBAT_RATING_1+13,+    PLAYER_FIELD_HIT_TAKEN_SPELL_RATING       = PLAYER_FIELD_COMBAT_RATING_1+13,                                                             // CR_CRIT_TAKEN_MELEE-    PLAYER_FIELD_UNK4_RATING                  = PLAYER_FIELD_COMBAT_RATING_1+14,+    PLAYER_FIELD_CRIT_TAKEN_MELEE_RATING      = PLAYER_FIELD_COMBAT_RATING_1+14,                                                             // CR_CRIT_TAKEN_RANGED-    PLAYER_FIELD_UNK5_RATING                  = PLAYER_FIELD_COMBAT_RATING_1+15,+    PLAYER_FIELD_CRIT_TAKEN_RANGED_RATING     = PLAYER_FIELD_COMBAT_RATING_1+15,                                                             // CR_CRIT_TAKEN_SPELL-    PLAYER_FIELD_RESILIENCE_RATING            = PLAYER_FIELD_COMBAT_RATING_1+16,+    PLAYER_FIELD_CRIT_TAKEN_SPELL_RATING      = PLAYER_FIELD_COMBAT_RATING_1+16,                                                             // CR_HASTE_MELEE     PLAYER_FIELD_MELEE_HASTE_RATING           = PLAYER_FIELD_COMBAT_RATING_1+17,                                                             // CR_HASTE_RANGED