Index: game/SpellEffects.cpp =================================================================== --- game/SpellEffects.cpp (revision 5293) +++ game/SpellEffects.cpp (working copy) @@ -409,7 +409,8 @@ // Steady Shot else if((m_spellInfo->SpellFamilyFlags & 0x100000000LL)) { - damage += m_caster->CalculateDamage(RANGED_ATTACK)+int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.2); + int32 base =(m_caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE)+m_caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE))/2; + damage += base + int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.2); } break; } @@ -3298,8 +3299,13 @@ //if miss/parry, no eff=0 automatically by func DoAttackDamage //if crit eff = (bonus + weapon) * 2 //In a word, bonus + weapon will be calculated together in cases of miss, armor reduce, crit, etc. - bonus += m_caster->CalculateDamage (attType); + bool normalized = false; + for (j = 0; j <3;j++) + if (m_spellInfo->Effect[j] == SPELL_EFFECT_NORMALIZED_WEAPON_DMG) + normalized = true; + bonus += m_caster->CalculateDamage (attType, normalized); + switch(m_spellInfo->SpellFamilyName) { case SPELLFAMILY_WARRIOR: @@ -3309,7 +3315,7 @@ { Item* item = ((Player*)m_caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); if (item && item->GetProto()->Class == ITEM_CLASS_WEAPON && !item->IsBroken() && ((Player*)m_caster)->IsUseEquipedWeapon(false)) - bonus += m_caster->CalculateDamage (OFF_ATTACK); + bonus += m_caster->CalculateDamage (OFF_ATTACK, normalized); } break; } Index: game/Unit.cpp =================================================================== --- game/Unit.cpp (revision 5293) +++ game/Unit.cpp (working copy) @@ -2412,7 +2412,7 @@ return; } - uint32 damage = CalculateDamage (attType); + uint32 damage = CalculateDamage (attType, false); DoAttackDamage (pVictim, &damage, &cleanDamage, &blocked_dmg, meleeSchool, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, attType); @@ -2665,11 +2665,46 @@ return MELEE_HIT_NORMAL; } -uint32 Unit::CalculateDamage (WeaponAttackType attType) + +uint32 Unit::CalculateDamage (WeaponAttackType attType, bool normalized) { float min_damage, max_damage; - switch (attType) + if ( normalized ) + { + UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND; + int32 attPower = GetTotalAttackPowerValue(attType); + float APMod=1.0f; + float base_value = GetModifierValue(unitMod, BASE_VALUE); + float base_pct = GetModifierValue(unitMod, BASE_PCT); + float total_value = GetModifierValue(unitMod, TOTAL_VALUE); + float total_pct = GetModifierValue(unitMod, TOTAL_PCT); + + if (attType == RANGED_ATTACK) + { + unitMod = UNIT_MOD_DAMAGE_RANGED; + APMod = 2.8f; + } + else + { + Item *Weapon = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, attType == BASE_ATTACK ? EQUIPMENT_SLOT_MAINHAND : EQUIPMENT_SLOT_OFFHAND); + + if ( attType == OFF_ATTACK ) + unitMod = UNIT_MOD_DAMAGE_OFFHAND; + + if ( Weapon && Weapon->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER ) + APMod = 1.7f; + else if ( Weapon && Weapon->GetProto()->InventoryType == INVTYPE_2HWEAPON ) + APMod = 3.3f; + else + APMod = 2.4f; + } + + base_value += GetTotalAttackPowerValue(attType)/ 14.0f * APMod; + min_damage = ((base_value + GetWeaponDamageRange(attType, MINDAMAGE)) * base_pct + total_value) * total_pct; + max_damage = ((base_value + GetWeaponDamageRange(attType, MAXDAMAGE)) * base_pct + total_value) * total_pct; + } + else switch (attType) { case RANGED_ATTACK: min_damage = GetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE); Index: game/Unit.h =================================================================== --- game/Unit.h (revision 5293) +++ game/Unit.h (working copy) @@ -952,7 +952,7 @@ void RemoveGameObject(uint32 spellid, bool del); DynamicObject *GetDynObject(uint32 spellId, uint32 effIndex); DynamicObject *GetDynObject(uint32 spellId); - uint32 CalculateDamage(WeaponAttackType attType); + uint32 CalculateDamage(WeaponAttackType attType, bool normalized); void ModifyAuraState(AuraState flag, bool apply); bool HasAuraState(AuraState flag) const { return HasFlag(UNIT_FIELD_AURASTATE, 1<<(flag-1)); } void UnsummonAllTotems();