rendered paste bodyIndex: game/SpellEffects.cpp
===================================================================
--- game/SpellEffects.cpp (revision 5609)
+++ game/SpellEffects.cpp (working copy)
@@ -3451,7 +3451,12 @@
//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 (m_attackType);
+ 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)
{
@@ -3462,7 +3467,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 5609)
+++ game/Unit.cpp (working copy)
@@ -2456,7 +2456,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);
@@ -2741,13 +2741,107 @@
return MELEE_HIT_NORMAL;
}
-uint32 Unit::CalculateDamage (WeaponAttackType attType)
+float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized)
{
- float min_damage, max_damage;
+ uint8 slot = EQUIPMENT_SLOT_MAINHAND;
+ if (!normalized || GetTypeId() != TYPEID_PLAYER)
+ return (float(GetAttackTime(attType))/1000.0f);
+
switch (attType)
{
+ case OFF_ATTACK:
+ slot = EQUIPMENT_SLOT_OFFHAND;
+ break;
case RANGED_ATTACK:
+ slot = EQUIPMENT_SLOT_RANGED;
+ break;
+ }
+
+ Item *Weapon = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0,slot);
+
+ if (!Weapon)
+ return 2.5;
+
+ switch (Weapon->GetProto()->SubClass)
+ {
+ case ITEM_SUBCLASS_WEAPON_DAGGER:
+ return 1.7;
+ case ITEM_SUBCLASS_WEAPON_BOW:
+ case ITEM_SUBCLASS_WEAPON_GUN:
+ case ITEM_SUBCLASS_WEAPON_THROWN:
+ case ITEM_SUBCLASS_WEAPON_CROSSBOW:
+ return 2.8;
+ case ITEM_SUBCLASS_WEAPON_SWORD2:
+ case ITEM_SUBCLASS_WEAPON_POLEARM:
+ case ITEM_SUBCLASS_WEAPON_AXE2:
+ case ITEM_SUBCLASS_WEAPON_MACE2:
+ case ITEM_SUBCLASS_WEAPON_STAFF:
+ case ITEM_SUBCLASS_WEAPON_SPEAR:
+ return 3.3;
+ }
+
+ return 2.4;
+
+}
+
+uint32 Unit::CalculateDamage (WeaponAttackType attType, bool normalized)
+{
+ float min_damage, max_damage;
+
+ if (GetTypeId()==TYPEID_PLAYER)
+ {
+ UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND;
+ UnitMods attPower = UNIT_MOD_ATTACK_POWER;
+
+ switch(attType)
+ {
+ case BASE_ATTACK: break;
+ case OFF_ATTACK:
+ unitMod = UNIT_MOD_DAMAGE_OFFHAND;
+ break;
+ case RANGED_ATTACK:
+ unitMod = UNIT_MOD_DAMAGE_RANGED;
+ attPower = UNIT_MOD_ATTACK_POWER_RANGED;
+ break;
+ }
+
+ float att_speed = GetAPMultiplier(attType,normalized);
+
+ float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed;
+ float base_pct = GetModifierValue(unitMod, BASE_PCT);
+ float total_value = GetModifierValue(unitMod, TOTAL_VALUE);
+ float total_pct = GetModifierValue(unitMod, TOTAL_PCT);
+
+ float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE);
+ float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE);
+
+ if (((Player *)this)->IsInFeralForm()) //check if player is druid and in cat or bear forms
+ {
+ uint32 lvl = getLevel();
+ if ( lvl > 60 ) lvl = 60;
+
+ weapon_mindamage = lvl*0.85*att_speed;
+ weapon_maxdamage = lvl*1.25*att_speed;
+ }
+ else if(!((Player *)this)->IsUseEquipedWeapon(attType==BASE_ATTACK)) //check if player not in form but still can't use weapon (broken/etc)
+ {
+ weapon_mindamage = BASE_MINDAMAGE;
+ weapon_maxdamage = BASE_MAXDAMAGE;
+ }
+ else if(attType == RANGED_ATTACK) //add ammo DPS to ranged damage
+ {
+ weapon_mindamage += ((Player *)this)->GetAmmoDPS() * att_speed;
+ weapon_maxdamage += ((Player *)this)->GetAmmoDPS() * att_speed;
+ }
+
+ min_damage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct ;
+ max_damage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct ;
+
+ }
+ else switch (attType)
+ {
+ case RANGED_ATTACK:
min_damage = GetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE);
max_damage = GetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE);
break;
@@ -7675,8 +7769,13 @@
APbonus += (*i)->GetModifier()->m_amount;
}
+ bool normalized = false;
+ for (uint8 i = 0; i<3;i++)
+ if (spellProto->Effect[i] == SPELL_EFFECT_NORMALIZED_WEAPON_DMG)
+ normalized = true;
+
if (APbonus!=0) // Can be negative
- DoneFlatBenefit += int32(APbonus/14.0f * GetAttackTime(attType)/1000);
+ DoneFlatBenefit += int32(APbonus/14.0f * GetAPMultiplier(attType,normalized)/1000);
// ..taken
AuraList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
Index: game/Unit.h
===================================================================
--- game/Unit.h (revision 5609)
+++ game/Unit.h (working copy)
@@ -1015,7 +1015,8 @@
void RemoveGameObject(uint32 spellid, bool del);
DynamicObject *GetDynObject(uint32 spellId, uint32 effIndex);
DynamicObject *GetDynObject(uint32 spellId);
- uint32 CalculateDamage(WeaponAttackType attType);
+ float GetAPMultiplier(WeaponAttackType attType, bool normalized);
+ 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();