diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 111 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 4 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/StatSystem.cpp | 25 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 132 | ||||
| -rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 2 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 126 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 22 | 
7 files changed, 133 insertions, 289 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index f4fca5038d2..81c0a1ba2fb 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7391,15 +7391,13 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply)      if (proto->Socket[0].Color)                              //only (un)equipping of items with sockets can influence metagems, so no need to waste time with normal items          CorrectMetaGemEnchants(slot, apply); -    if (attacktype < MAX_ATTACK) -        _ApplyWeaponDependentAuraMods(item, WeaponAttackType(attacktype), apply); -      _ApplyItemBonuses(proto, slot, apply);      if (slot == EQUIPMENT_SLOT_RANGED)          _ApplyAmmoBonuses();      ApplyItemEquipSpell(item, apply); +    ApplyItemDependentAuras(item, apply);      ApplyEnchantment(item, apply);      TC_LOG_DEBUG("entities.player.items", "Player::_ApplyItemMods: completed"); @@ -7753,86 +7751,26 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt          UpdateDamagePhysical(attType);  } -void Player::_ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply) -{ -    AuraEffectList const& auraCritList = GetAuraEffectsByType(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT); -    for (AuraEffectList::const_iterator itr = auraCritList.begin(); itr != auraCritList.end(); ++itr) -        _ApplyWeaponDependentAuraCritMod(item, attackType, *itr, apply); - -    AuraEffectList const& auraDamageFlatList = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE); -    for (AuraEffectList::const_iterator itr = auraDamageFlatList.begin(); itr != auraDamageFlatList.end(); ++itr) -        _ApplyWeaponDependentAuraDamageMod(item, attackType, *itr, apply); - -    AuraEffectList const& auraDamagePctList = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); -    for (AuraEffectList::const_iterator itr = auraDamagePctList.begin(); itr != auraDamagePctList.end(); ++itr) -        _ApplyWeaponDependentAuraDamageMod(item, attackType, *itr, apply); -} - -void Player::_ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply) +void Player::ApplyItemDependentAuras(Item* item, bool apply)  { -    // don't apply mod if item is broken or cannot be used -    if (item->IsBroken() || !CanUseAttackType(attackType)) -        return; - -    // generic not weapon specific case processes in aura code -    if (aura->GetSpellInfo()->EquippedItemClass == -1) -        return; - -    BaseModGroup mod; -    switch (attackType) -    { -        case BASE_ATTACK:   mod = CRIT_PERCENTAGE;        break; -        case OFF_ATTACK:    mod = OFFHAND_CRIT_PERCENTAGE;break; -        case RANGED_ATTACK: mod = RANGED_CRIT_PERCENTAGE; break; -        default: return; -    } - -    if (item->IsFitToSpellRequirements(aura->GetSpellInfo())) -        HandleBaseModValue(mod, FLAT_MOD, float (aura->GetAmount()), apply); -} - -void Player::_ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply) -{ -    // don't apply mod if item is broken or cannot be used -    if (item->IsBroken() || !CanUseAttackType(attackType)) -        return; - -    // ignore spell mods for not wands -    if ((aura->GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) && (!(getClassMask() & CLASSMASK_WAND_USERS))) -        return; - -    // generic not weapon specific case processed in AuraEffect handler -    if (aura->GetSpellInfo()->EquippedItemClass == -1) -        return; - -    UnitMods unitMod; -    switch (attackType) +    if (apply)      { -        case BASE_ATTACK:   unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; -        case OFF_ATTACK:    unitMod = UNIT_MOD_DAMAGE_OFFHAND;  break; -        case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED;   break; -        default: return; -    } +        PlayerSpellMap const& spells = GetSpellMap(); +        for (auto itr = spells.begin(); itr != spells.end(); ++itr) +        { +            if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled) +                continue; -    UnitModifierType unitModType; -    switch (aura->GetAuraType()) -    { -        case SPELL_AURA_MOD_DAMAGE_DONE:         unitModType = TOTAL_VALUE; break; -        case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: unitModType = TOTAL_PCT;   break; -        default: return; -    } +            SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); +            if (!spellInfo || !spellInfo->IsPassive() || spellInfo->EquippedItemClass < 0) +                continue; -    if (item->IsFitToSpellRequirements(aura->GetSpellInfo())) -    { -        HandleStatModifier(unitMod, unitModType, float(aura->GetAmount()), apply); -        if (unitModType == TOTAL_VALUE) -        { -            if (aura->GetAmount() > 0) -                ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS, aura->GetAmount(), apply); -            else -                ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG, aura->GetAmount(), apply); +            if (!HasAura(itr->first) && HasItemFitToSpellRequirements(spellInfo)) +                AddAura(itr->first, this);  // no SMSG_SPELL_GO in sniff found          }      } +    else +        RemoveItemDependentAurasAndCasts(item);  }  void Player::ApplyItemEquipSpell(Item* item, bool apply, bool form_change) @@ -8207,10 +8145,7 @@ void Player::_RemoveAllItemMods()              if (!proto)                  continue; -            uint32 attacktype = Player::GetAttackBySlot(i); -            if (attacktype < MAX_ATTACK) -                _ApplyWeaponDependentAuraMods(m_items[i], WeaponAttackType(attacktype), false); - +            ApplyItemDependentAuras(m_items[i], false);              _ApplyItemBonuses(proto, i, false);              if (i == EQUIPMENT_SLOT_RANGED) @@ -8237,9 +8172,7 @@ void Player::_ApplyAllItemMods()                  continue;              uint32 attacktype = Player::GetAttackBySlot(i); -            if (attacktype < MAX_ATTACK) -                _ApplyWeaponDependentAuraMods(m_items[i], WeaponAttackType(attacktype), true); - +            ApplyItemDependentAuras(m_items[i], true);              _ApplyItemBonuses(proto, i, true);              if (i == EQUIPMENT_SLOT_RANGED) @@ -12230,9 +12163,6 @@ void Player::RemoveItem(uint8 bag, uint8 slot, bool update)                  // remove item dependent auras and casts (only weapon and armor slots)                  if (slot < EQUIPMENT_SLOT_END)                  { -                    if (update) -                        RemoveItemDependentAurasAndCasts(pItem); -                      // remove held enchantments, update expertise                      if (slot == EQUIPMENT_SLOT_MAINHAND)                      { @@ -12383,9 +12313,6 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)              if (slot < EQUIPMENT_SLOT_END)              { -                // remove item dependent auras and casts (only weapon and armor slots) -                RemoveItemDependentAurasAndCasts(pItem); -                  // update expertise and armor penetration - passive auras may need it                  switch (slot)                  { @@ -23591,9 +23518,9 @@ void Player::RemoveItemDependentAurasAndCasts(Item* pItem)      {          Aura* aura = itr->second; -        // skip passive (passive item dependent spells work in another way) and not self applied auras +        // skip not self applied auras          SpellInfo const* spellInfo = aura->GetSpellInfo(); -        if (aura->IsPassive() ||  aura->GetCasterGUID() != GetGUID()) +        if (aura->GetCasterGUID() != GetGUID())          {              ++itr;              continue; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 565d4f4ac2f..ed5dc7e954f 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1958,9 +1958,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>          void ResetAllPowers(); -        void _ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply); -        void _ApplyWeaponDependentAuraCritMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply); -        void _ApplyWeaponDependentAuraDamageMod(Item* item, WeaponAttackType attackType, AuraEffect const* aura, bool apply); +        void ApplyItemDependentAuras(Item* item, bool apply);          void _ApplyItemMods(Item* item, uint8 slot, bool apply);          void _RemoveAllItemMods(); diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 699709fabb1..0cad0b2cb05 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -184,8 +184,17 @@ void Player::UpdateSpellDamageAndHealingBonus()      // Get healing bonus for all schools      SetStatInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, SpellBaseHealingBonusDone(SPELL_SCHOOL_MASK_ALL));      // Get damage bonus for all schools -    for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) -        SetStatInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, SpellBaseDamageBonusDone(SpellSchoolMask(1 << i))); +    Unit::AuraEffectList const& modDamageAuras = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE); +    for (uint16 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) +    { +        SetInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + i, std::accumulate(modDamageAuras.begin(), modDamageAuras.end(), 0, [i](int32 negativeMod, AuraEffect const* aurEff) +        { +            if (aurEff->GetAmount() < 0 && aurEff->GetMiscValue() & (1 << i)) +                negativeMod += aurEff->GetAmount(); +            return negativeMod; +        })); +        SetStatInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + i, SpellBaseDamageBonusDone(SpellSchoolMask(1 << i)) - GetInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + i)); +    }  }  bool Player::UpdateAllStats() @@ -530,9 +539,9 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo              break;      } -    float attackSpeedMod = GetAPMultiplier(attType, normalized); +    float const attackPowerMod = std::max(GetAPMultiplier(attType, normalized), 0.25f); -    float baseValue  = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * attackSpeedMod; +    float baseValue  = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * attackPowerMod;      float basePct    = GetModifierValue(unitMod, BASE_PCT);      float totalValue = GetModifierValue(unitMod, TOTAL_VALUE);      float totalPct   = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; @@ -546,8 +555,8 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo          if (lvl > 60)              lvl = 60; -        weaponMinDamage = lvl * 0.85f * attackSpeedMod; -        weaponMaxDamage = lvl * 1.25f * attackSpeedMod; +        weaponMinDamage = lvl * 0.85f * attackPowerMod; +        weaponMaxDamage = lvl * 1.25f * attackPowerMod;      }      else if (!CanUseAttackType(attType)) // check if player not in form but still can't use (disarm case)      { @@ -563,8 +572,8 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo      }      else if (attType == RANGED_ATTACK) // add ammo DPS to ranged damage      { -        weaponMinDamage += GetAmmoDPS() * attackSpeedMod; -        weaponMaxDamage += GetAmmoDPS() * attackSpeedMod; +        weaponMinDamage += GetAmmoDPS() * attackPowerMod; +        weaponMaxDamage += GetAmmoDPS() * attackPowerMod;      }      minDamage = ((weaponMinDamage + baseValue) * basePct + totalValue) * totalPct; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 46bb247a6e8..b259bd1444f 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -6685,11 +6685,12 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin              // Impurity (dummy effect)              if (GetTypeId() == TYPEID_PLAYER)              { -                PlayerSpellMap playerSpells = ToPlayer()->GetSpellMap(); -                for (PlayerSpellMap::const_iterator itr = playerSpells.begin(); itr != playerSpells.end(); ++itr) +                PlayerSpellMap const& playerSpells = ToPlayer()->GetSpellMap(); +                for (auto itr = playerSpells.begin(); itr != playerSpells.end(); ++itr)                  {                      if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled)                          continue; +                      switch (itr->first)                      {                          case 49220: @@ -6698,7 +6699,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin                          case 49636:                          case 49638:                              if (SpellInfo const* proto = sSpellMgr->GetSpellInfo(itr->first)) -                                AddPct(ApCoeffMod, proto->Effects[0].CalcValue()); +                                AddPct(ApCoeffMod, proto->Effects[EFFECT_0].CalcValue());                          break;                      }                  } @@ -6711,14 +6712,14 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin      // Pets just add their bonus damage to their spell damage      // note that their spell damage is just gain of their own auras      if (HasUnitTypeMask(UNIT_MASK_GUARDIAN)) -        DoneAdvertisedBenefit += static_cast<Guardian const*>(this)->GetBonusDamage(); +        DoneAdvertisedBenefit += ((Guardian*)this)->GetBonusDamage();      // Check for table values -    float coeff = 0.f; +    float coeff = 0.0f;      SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);      if (bonus)      { -        WeaponAttackType const attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK; +        WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;          float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));          APbonus += GetTotalAttackPowerValue(attType); @@ -6735,6 +6736,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin                  DoneTotal += int32(bonus->ap_bonus * stack * ApCoeffMod * APbonus);          }      } +      // Default calculation      if (DoneAdvertisedBenefit)      { @@ -6788,24 +6790,17 @@ float Unit::SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, Damage      if (GetTypeId() == TYPEID_UNIT && !IsPet())          DoneTotalMod *= ToCreature()->GetSpellDamageMod(ToCreature()->GetCreatureTemplate()->rank); -    AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); -    for (AuraEffect const* aurEff : mModDamagePercentDone) +    float maxModDamagePercentSchool = 0.0f; +    if (GetTypeId() == TYPEID_PLAYER)      { -        SpellInfo const* aurSpellInfo = aurEff->GetSpellInfo(); - -        if (spellProto->EquippedItemClass == -1 && aurSpellInfo->EquippedItemClass != -1)    // prevent apply mods from weapon specific case to non weapon specific spells (Example: thunder clap and two-handed weapon specialization) -            continue; - -        if ((aurEff->GetMiscValue() & spellProto->GetSchoolMask()) != 0) -        { -            if (aurSpellInfo->EquippedItemClass == -1) -                AddPct(DoneTotalMod, aurEff->GetAmount()); -            else if (!aurSpellInfo->HasAttribute(SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && (aurSpellInfo->EquippedItemSubClassMask == 0)) -                AddPct(DoneTotalMod, aurEff->GetAmount()); -            else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements(aurSpellInfo)) -                AddPct(DoneTotalMod, aurEff->GetAmount()); -        } +        for (uint32 i = 0; i < MAX_SPELL_SCHOOL; ++i) +            if (spellProto->GetSchoolMask() & (1 << i)) +                maxModDamagePercentSchool = std::max(maxModDamagePercentSchool, GetFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + i));      } +    else +        maxModDamagePercentSchool = GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, spellProto->GetSchoolMask()); + +    DoneTotalMod *= maxModDamagePercentSchool;      uint32 creatureTypeMask = victim->GetCreatureTypeMask(); @@ -7187,14 +7182,8 @@ int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const      AuraEffectList const& mDamageDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE);      for (AuraEffect const* aurEff : mDamageDone) -    { -        if (!(aurEff->GetMiscValue() & schoolMask)) -            continue; - -        // only apply generic bonus here, weapon requiring mods are not applicable to non-melee spells -        if (aurEff->GetSpellInfo()->EquippedItemClass == -1 && aurEff->GetSpellInfo()->EquippedItemInventoryTypeMask == 0) +        if (aurEff->GetMiscValue() & schoolMask)              DoneAdvertisedBenefit += aurEff->GetAmount(); -    }      if (GetTypeId() == TYPEID_PLAYER)      { @@ -7215,7 +7204,6 @@ int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const          // ... and attack power          DoneAdvertisedBenefit += static_cast<int32>(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER, schoolMask))); -      }      return DoneAdvertisedBenefit; @@ -8084,35 +8072,22 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType      float DoneTotalMod = 1.0f;      // Some spells don't benefit from pct done mods -    if (spellProto && !spellProto->HasAttribute(SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS)) +    if (spellProto)      { -        AuraEffectList const& mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); -        for (AuraEffect const* aurEff : mModDamagePercentDone) +        // mods for SPELL_SCHOOL_MASK_NORMAL are already factored in base melee damage calculation +        if (!spellProto->HasAttribute(SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS) && !(spellProto->GetSchoolMask() & SPELL_SCHOOL_MASK_NORMAL))          { -            // Apply mod if schoolmask matches... -            if ((aurEff->GetMiscValue() & spellProto->GetSchoolMask()) != 0) +            float maxModDamagePercentSchool = 0.0f; +            if (GetTypeId() == TYPEID_PLAYER)              { -                SpellInfo const* aurSpellInfo = aurEff->GetSpellInfo(); - -                // ... but not for SCHOOL_MASK_NORMAL, or generic weapon bonus, or creatures (creatures don't have equiped items check) -                // for these types the damage was already calculated in AuraEffect handler, and stored into TOTAL_PCT -                // if we include them, we'll be multiplying twice (one in Unit::CalculateDamage, the other here) -                if ((aurEff->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) && (aurSpellInfo->EquippedItemClass == -1 || GetTypeId() != TYPEID_PLAYER)) -                    continue; - -                // generic weapon bonus (magic) -                if (aurSpellInfo->EquippedItemClass == -1) -                    AddPct(DoneTotalMod, aurEff->GetAmount()); -                // skips subclassmask check/has generic subclassmask set -                else if (!aurSpellInfo->HasAttribute(SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK) && (aurSpellInfo->EquippedItemSubClassMask == 0)) -                    AddPct(DoneTotalMod, aurEff->GetAmount()); - -                // This one is already applied in Player::_ApplyWeaponDependentAuraDamageMod -                /* -                else if (ToPlayer() && ToPlayer()->HasItemFitToSpellRequirements(aurSpellInfo)) -                    AddPct(DoneTotalMod, aurEff->GetAmount()); -                */ +                for (uint32 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) +                    if (spellProto->GetSchoolMask() & (1 << i)) +                        maxModDamagePercentSchool = std::max(maxModDamagePercentSchool, GetFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + i));              } +            else +                maxModDamagePercentSchool = GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, spellProto->GetSchoolMask()); + +            DoneTotalMod *= maxModDamagePercentSchool;          }      } @@ -8191,7 +8166,6 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType      // Custom scripted damage      if (spellProto) -    {          switch (spellProto->SpellFamilyName)          {              case SPELLFAMILY_DEATHKNIGHT: @@ -8200,9 +8174,8 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType                      if (AuraEffect* aurEff = GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 196, 0))                          if (victim->GetDiseasesByCaster(owner->GetGUID()) > 0)                              AddPct(DoneTotalMod, aurEff->GetAmount()); -                break; +            break;          } -    }      float tmpDamage = float(int32(pdamage) + DoneFlatBenefit) * DoneTotalMod; @@ -11467,26 +11440,41 @@ float Unit::CalculateDefaultCoefficient(SpellInfo const* spellInfo, DamageEffect  float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized)  { -    if (!normalized || GetTypeId() != TYPEID_PLAYER) -        return float(GetAttackTime(attType)) / 1000.0f; +    if (GetTypeId() != TYPEID_PLAYER) +        return GetAttackTime(attType) / 1000.0f; + +    Item* weapon = ToPlayer()->GetWeaponForAttack(attType, true); +    if (!weapon) +        return BASE_ATTACK_TIME / 1000.0f; -    Item* Weapon = ToPlayer()->GetWeaponForAttack(attType, true); -    if (!Weapon) -        return 2.4f;                                         // fist attack +    if (!normalized) +        return weapon->GetTemplate()->Delay / 1000.0f; -    switch (Weapon->GetTemplate()->InventoryType) +    switch (weapon->GetTemplate()->SubClass)      { -        case INVTYPE_2HWEAPON: +        case ITEM_SUBCLASS_WEAPON_AXE2: +        case ITEM_SUBCLASS_WEAPON_MACE2: +        case ITEM_SUBCLASS_WEAPON_POLEARM: +        case ITEM_SUBCLASS_WEAPON_SWORD2: +        case ITEM_SUBCLASS_WEAPON_STAFF: +        case ITEM_SUBCLASS_WEAPON_FISHING_POLE:              return 3.3f; -        case INVTYPE_RANGED: -        case INVTYPE_RANGEDRIGHT: -        case INVTYPE_THROWN: +        case ITEM_SUBCLASS_WEAPON_BOW: +        case ITEM_SUBCLASS_WEAPON_GUN: +        case ITEM_SUBCLASS_WEAPON_CROSSBOW: +        case ITEM_SUBCLASS_WEAPON_THROWN:              return 2.8f; -        case INVTYPE_WEAPON: -        case INVTYPE_WEAPONMAINHAND: -        case INVTYPE_WEAPONOFFHAND: +        case ITEM_SUBCLASS_WEAPON_AXE: +        case ITEM_SUBCLASS_WEAPON_MACE: +        case ITEM_SUBCLASS_WEAPON_SWORD: +        case ITEM_SUBCLASS_WEAPON_EXOTIC: +        case ITEM_SUBCLASS_WEAPON_EXOTIC2: +        case ITEM_SUBCLASS_WEAPON_FIST: +            return 2.4f; +        case ITEM_SUBCLASS_WEAPON_DAGGER: +            return 1.7f;          default: -            return Weapon->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER ? 1.7f : 2.4f; +            return weapon->GetTemplate()->Delay / 1000.0f;      }  } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index bc84e3fde29..bf913081fef 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -472,7 +472,7 @@ enum SpellAttr5      SPELL_ATTR5_HASTE_AFFECT_DURATION            = 0x00002000, // 13 haste effects decrease duration of this      SPELL_ATTR5_UNK14                            = 0x00004000, // 14      SPELL_ATTR5_UNK15                            = 0x00008000, // 15 Inflits on multiple targets? -    SPELL_ATTR5_SPECIAL_ITEM_CLASS_CHECK         = 0x00010000, // 16 this allows spells with EquippedItemClass to affect spells from other items if the required item is equipped +    SPELL_ATTR5_UNK16                            = 0x00010000, // 16      SPELL_ATTR5_USABLE_WHILE_FEARED              = 0x00020000, // 17 usable while feared      SPELL_ATTR5_USABLE_WHILE_CONFUSED            = 0x00040000, // 18 usable while confused      SPELL_ATTR5_DONT_TURN_DURING_CAST            = 0x00080000, // 19 Blocks caster's turning when casting (client does not automatically turn caster's model to face UNIT_FIELD_TARGET) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 6db6abd5177..2b4e2e4177d 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2307,11 +2307,9 @@ void AuraEffect::HandleAuraModDisarm(AuraApplication const* aurApp, uint8 mode,          {              uint8 attacktype = Player::GetAttackBySlot(slot); +            player->ApplyItemDependentAuras(item, !apply);              if (attacktype < MAX_ATTACK) -            {                  player->_ApplyWeaponDamage(slot, item->GetTemplate(), NULL, !apply); -                player->_ApplyWeaponDependentAuraMods(item, WeaponAttackType(attacktype), !apply); -            }          }      } @@ -3768,29 +3766,14 @@ void AuraEffect::HandleAuraModWeaponCritPercent(AuraApplication const* aurApp, u      if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))          return; -    Unit* target = aurApp->GetTarget(); +    Player* target = aurApp->GetTarget()->ToPlayer(); -    if (target->GetTypeId() != TYPEID_PLAYER) +    if (!target)          return; -    for (int i = 0; i < MAX_ATTACK; ++i) -        if (Item* pItem = target->ToPlayer()->GetWeaponForAttack(WeaponAttackType(i), true)) -            target->ToPlayer()->_ApplyWeaponDependentAuraCritMod(pItem, WeaponAttackType(i), this, apply); - -    // mods must be applied base at equipped weapon class and subclass comparison -    // with spell->EquippedItemClass and  EquippedItemSubClassMask and EquippedItemInventoryTypeMask -    // GetMiscValue() comparison with item generated damage types - -    if (GetSpellInfo()->EquippedItemClass == -1) -    { -        target->ToPlayer()->HandleBaseModValue(CRIT_PERCENTAGE,         FLAT_MOD, float (GetAmount()), apply); -        target->ToPlayer()->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply); -        target->ToPlayer()->HandleBaseModValue(RANGED_CRIT_PERCENTAGE,  FLAT_MOD, float (GetAmount()), apply); -    } -    else -    { -        // done in Player::_ApplyWeaponDependentAuraMods -    } +    target->HandleBaseModValue(CRIT_PERCENTAGE,         FLAT_MOD, float(GetAmount()), apply); +    target->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float(GetAmount()), apply); +    target->HandleBaseModValue(RANGED_CRIT_PERCENTAGE,  FLAT_MOD, float(GetAmount()), apply);  }  void AuraEffect::HandleModHitChance(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -4091,6 +4074,7 @@ void AuraEffect::HandleAuraModAttackPowerOfArmor(AuraApplication const* aurApp,      if (target->GetTypeId() == TYPEID_PLAYER)          target->ToPlayer()->UpdateAttackPowerAndDamage(false);  } +  /********************************/  /***        DAMAGE BONUS      ***/  /********************************/ @@ -4101,76 +4085,22 @@ void AuraEffect::HandleModDamageDone(AuraApplication const* aurApp, uint8 mode,      Unit* target = aurApp->GetTarget(); -    // apply item specific bonuses for already equipped weapon -    if (target->GetTypeId() == TYPEID_PLAYER) -    { -        for (int i = 0; i < MAX_ATTACK; ++i) -            if (Item* pItem = target->ToPlayer()->GetWeaponForAttack(WeaponAttackType(i), true)) -                target->ToPlayer()->_ApplyWeaponDependentAuraDamageMod(pItem, WeaponAttackType(i), this, apply); -    } - -    // GetMiscValue() is bitmask of spell schools -    // 1 (0-bit) - normal school damage (SPELL_SCHOOL_MASK_NORMAL) -    // 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wands -    // 127 - full bitmask any damages -    // -    // mods must be applied base at equipped weapon class and subclass comparison -    // with spell->EquippedItemClass and  EquippedItemSubClassMask and EquippedItemInventoryTypeMask -    // GetMiscValue() comparison with item generated damage types - -    // apply generic physical damage bonuses including wand case -    if ((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) && (GetSpellInfo()->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER)) +    if (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)      {          target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(GetAmount()), apply);          target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(GetAmount()), apply);          target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(GetAmount()), apply); - -        if (target->GetTypeId() == TYPEID_PLAYER) -        { -            if (GetAmount() > 0) -                target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS, GetAmount(), apply); -            else -                target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG, GetAmount(), apply); -        }      } -    else -    { -        // done in Player::_ApplyWeaponDependentAuraMods -    } - -    // Skip non magic case for speedup -    if ((GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) == 0) -        return; - -    if (GetSpellInfo()->EquippedItemClass != -1 || GetSpellInfo()->EquippedItemInventoryTypeMask != 0) -    { -        // wand magic case (skip generic to all item spell bonuses) -        // done in Player::_ApplyWeaponDependentAuraMods -        // Skip item specific requirements for not wand magic damage -        return; -    } - -    // Magic damage modifiers implemented in Unit::SpellDamageBonus +    // Magic damage modifiers implemented in Unit::SpellBaseDamageBonusDone      // This information for client side use only      if (target->GetTypeId() == TYPEID_PLAYER)      { -        if (GetAmount() > 0) -        { -            for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++) -            { -                if ((GetMiscValue() & (1<<i)) != 0) -                    target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, GetAmount(), apply); -            } -        } -        else -        { -            for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++) -            { -                if ((GetMiscValue() & (1<<i)) != 0) -                    target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i, GetAmount(), apply); -            } -        } +        uint16 baseField = GetAmount() >= 0 ? PLAYER_FIELD_MOD_DAMAGE_DONE_POS : PLAYER_FIELD_MOD_DAMAGE_DONE_NEG; +        for (uint16 i = 0; i < MAX_SPELL_SCHOOL; ++i) +            if (GetMiscValue() & (1 << i)) +                target->ApplyModUInt32Value(baseField + i, GetAmount(), apply); +          if (Guardian* pet = target->ToPlayer()->GetGuardianPet())              pet->UpdateAttackPowerAndDamage();      } @@ -4186,14 +4116,7 @@ void AuraEffect::HandleModDamagePercentDone(AuraApplication const* aurApp, uint8      if (abs(spellGroupVal) >= abs(GetAmount()))          return; -    if (target->GetTypeId() == TYPEID_PLAYER) -    { -        for (int i = 0; i < MAX_ATTACK; ++i) -            if (Item* item = target->ToPlayer()->GetWeaponForAttack(WeaponAttackType(i), false)) -                target->ToPlayer()->_ApplyWeaponDependentAuraDamageMod(item, WeaponAttackType(i), this, apply); -    } - -    if ((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) && (GetSpellInfo()->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER)) +    if (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)      {          if (spellGroupVal)          { @@ -4201,22 +4124,25 @@ void AuraEffect::HandleModDamagePercentDone(AuraApplication const* aurApp, uint8              target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(spellGroupVal), !apply);              target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(spellGroupVal), !apply);          } +          target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(GetAmount()), apply);          target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND,  TOTAL_PCT, float(GetAmount()), apply);          target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED,   TOTAL_PCT, float(GetAmount()), apply); +    } -        if (Player* player = target->ToPlayer()) +    if (target->GetTypeId() == TYPEID_PLAYER) +    { +        for (uint16 i = 0; i < MAX_SPELL_SCHOOL; ++i)          { -            if (spellGroupVal) -                player->ApplyPercentModFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT, float(spellGroupVal), !apply); +            if (GetMiscValue() & (1 << i)) +            { +                if (spellGroupVal) +                    target->ApplyPercentModFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + i, float(spellGroupVal), !apply); -            player->ApplyPercentModFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT, float(GetAmount()), apply); +                target->ApplyPercentModFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT + i, float(GetAmount()), apply); +            }          }      } -    else -    { -        // done in Player::_ApplyWeaponDependentAuraMods for SPELL_SCHOOL_MASK_NORMAL && EquippedItemClass != -1 and also for wand case -    }  }  void AuraEffect::HandleModOffhandDamagePercent(AuraApplication const* aurApp, uint8 mode, bool apply) const diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 21950a1385b..7afcf52172a 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3380,8 +3380,10 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)          }      } -    // apply to non-weapon bonus weapon total pct effect, weapon total flat effect included in weapon damage -    if (fixed_bonus || spell_bonus) +    // if (addPctMods) { percent mods are added in Unit::CalculateDamage } else { percent mods are added in Unit::MeleeDamageBonusDone } +    // this distinction is neccessary to properly inform the client about his autoattack damage values from Script_UnitDamage +    bool addPctMods = !m_spellInfo->HasAttribute(SPELL_ATTR6_NO_DONE_PCT_DAMAGE_MODS) && (m_spellSchoolMask & SPELL_SCHOOL_MASK_NORMAL); +    if (addPctMods)      {          UnitMods unitMod;          switch (m_attackType) @@ -3392,17 +3394,14 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)              case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED;   break;          } -        float weapon_total_pct = 1.0f; -        if (m_spellInfo->SchoolMask & SPELL_SCHOOL_MASK_NORMAL) -             weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT); - +        float weapon_total_pct = m_caster->GetModifierValue(unitMod, TOTAL_PCT);          if (fixed_bonus)              fixed_bonus = int32(fixed_bonus * weapon_total_pct);          if (spell_bonus)              spell_bonus = int32(spell_bonus * weapon_total_pct);      } -    int32 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, true); +    int32 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, addPctMods);      // Sequence is important      for (int j = 0; j < MAX_SPELL_EFFECTS; ++j) @@ -3417,17 +3416,14 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)                  weaponDamage += fixed_bonus;                  break;              case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: -                weaponDamage = int32(weaponDamage* weaponDamagePercentMod); +                weaponDamage = int32(weaponDamage * weaponDamagePercentMod);              default:                  break;                                      // not weapon damage effect, just skip          }      } -    if (spell_bonus) -        weaponDamage += spell_bonus; - -    if (totalDamagePercentMod != 1.0f) -        weaponDamage = int32(weaponDamage* totalDamagePercentMod); +    weaponDamage += spell_bonus; +    weaponDamage = int32(weaponDamage * totalDamagePercentMod);      // prevent negative damage      uint32 eff_damage(std::max(weaponDamage, 0));  | 
