From 4539f848aca0deb2c005493d583ce9bdb606e7d7 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Thu, 19 Jun 2025 23:18:17 +0200 Subject: [PATCH] Core/Units: ported base attack time refactors from master branch --- .../game/Entities/Creature/Creature.cpp | 6 +-- src/server/game/Entities/Pet/Pet.cpp | 10 ++-- src/server/game/Entities/Player/Player.cpp | 16 +++--- src/server/game/Entities/Unit/StatSystem.cpp | 2 +- src/server/game/Entities/Unit/Unit.cpp | 53 +++++++++++++------ src/server/game/Entities/Unit/Unit.h | 9 ++-- src/server/game/Spells/Auras/SpellAuras.cpp | 2 +- src/server/game/Spells/SpellInfo.cpp | 2 +- .../Karazhan/boss_prince_malchezaar.cpp | 2 +- src/server/scripts/Pet/pet_hunter.cpp | 2 +- src/server/scripts/Spells/spell_paladin.cpp | 2 +- src/server/scripts/Spells/spell_shaman.cpp | 4 +- src/server/scripts/Spells/spell_warrior.cpp | 2 +- .../scripts/World/mob_generic_creature.cpp | 2 +- 14 files changed, 69 insertions(+), 45 deletions(-) diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index b1c3f3c17c..eb343c44bc 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -605,9 +605,9 @@ bool Creature::UpdateEntry(uint32 entry, CreatureData const* data /*= nullptr*/, SetCanDualWield(cInfo->flags_extra & CREATURE_FLAG_EXTRA_USE_OFFHAND_ATTACK); - SetAttackTime(BASE_ATTACK, cInfo->BaseAttackTime); - SetAttackTime(OFF_ATTACK, cInfo->BaseAttackTime); - SetAttackTime(RANGED_ATTACK, cInfo->RangeAttackTime); + SetBaseAttackTime(BASE_ATTACK, cInfo->BaseAttackTime); + SetBaseAttackTime(OFF_ATTACK, cInfo->BaseAttackTime); + SetBaseAttackTime(RANGED_ATTACK, cInfo->RangeAttackTime); if (updateLevel) SelectLevel(); diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index e5d9d7b4b0..e49947432b 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -743,9 +743,9 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool)); - SetAttackTime(BASE_ATTACK, BASE_ATTACK_TIME); - SetAttackTime(OFF_ATTACK, BASE_ATTACK_TIME); - SetAttackTime(RANGED_ATTACK, BASE_ATTACK_TIME); + SetBaseAttackTime(BASE_ATTACK, BASE_ATTACK_TIME); + SetBaseAttackTime(OFF_ATTACK, BASE_ATTACK_TIME); + SetBaseAttackTime(RANGED_ATTACK, BASE_ATTACK_TIME); SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); SetFloatValue(UNIT_MOD_CAST_HASTE, 1.0f); @@ -887,7 +887,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) SetBonusDamage(int32(m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier)); // wolf attack speed is 1.5s - SetAttackTime(BASE_ATTACK, cinfo->BaseAttackTime); + SetBaseAttackTime(BASE_ATTACK, cinfo->BaseAttackTime); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float((petlevel * 4 - petlevel))); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float((petlevel * 4 + petlevel))); @@ -923,7 +923,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) case ENTRY_BLOODWORM: { SetCreateHealth(m_owner->CountPctFromMaxHealth(18)); - SetAttackTime(BASE_ATTACK, 1400); + SetBaseAttackTime(BASE_ATTACK, 1400); SetBonusDamage(int32(m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.006f)); float minDamage = m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.05f; float maxDamage = m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.05f; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 15a96fef00..abb9d68a01 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5064,10 +5064,10 @@ void Player::SetRegularAttackTime() { ItemTemplate const* proto = tmpitem->GetTemplate(); if (proto->GetDelay()) - SetAttackTime(WeaponAttackType(i), proto->GetDelay()); + SetBaseAttackTime(WeaponAttackType(i), proto->GetDelay()); } else - SetAttackTime(WeaponAttackType(i), BASE_ATTACK_TIME); // If there is no weapon reset attack time to base (might have been changed from forms) + SetBaseAttackTime(WeaponAttackType(i), BASE_ATTACK_TIME); // If there is no weapon reset attack time to base (might have been changed from forms) } } @@ -7583,7 +7583,7 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, bool appl } if (proto->GetDelay() && !IsInFeralForm()) - SetAttackTime(attType, apply ? proto->GetDelay() : BASE_ATTACK_TIME); + SetBaseAttackTime(attType, apply ? proto->GetDelay() : BASE_ATTACK_TIME); // No need to modify any physical damage for ferals as it is calculated from stats only if (IsInFeralForm()) @@ -7906,7 +7906,7 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT if (proto->SpellPPMRate) { - uint32 WeaponSpeed = GetAttackTime(damageInfo.GetAttackType()); + uint32 WeaponSpeed = GetBaseAttackTime(damageInfo.GetAttackType()); chance = GetPPMProcChance(WeaponSpeed, proto->SpellPPMRate, spellInfo); } else if (chance > 100.0f) @@ -19911,7 +19911,7 @@ void Player::outDebugValues() const TC_LOG_DEBUG("entities.unit", "MIN_DAMAGE is: \t\t%f\tMAX_DAMAGE is: \t\t%f", GetFloatValue(UNIT_FIELD_MINDAMAGE), GetFloatValue(UNIT_FIELD_MAXDAMAGE)); TC_LOG_DEBUG("entities.unit", "MIN_OFFHAND_DAMAGE is: \t%f\tMAX_OFFHAND_DAMAGE is: \t%f", GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE), GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE)); TC_LOG_DEBUG("entities.unit", "MIN_RANGED_DAMAGE is: \t%f\tMAX_RANGED_DAMAGE is: \t%f", GetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE), GetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE)); - TC_LOG_DEBUG("entities.unit", "ATTACK_TIME is: \t%u\t\tRANGE_ATTACK_TIME is: \t%u", GetAttackTime(BASE_ATTACK), GetAttackTime(RANGED_ATTACK)); + TC_LOG_DEBUG("entities.unit", "ATTACK_TIME is: \t%u\t\tRANGE_ATTACK_TIME is: \t%u", GetBaseAttackTime(BASE_ATTACK), GetBaseAttackTime(RANGED_ATTACK)); } /*********************************************************/ @@ -21464,9 +21464,9 @@ void Player::InitDataForForm(bool reapplyMods) SpellShapeshiftFormEntry const* ssEntry = sSpellShapeshiftFormStore.LookupEntry(form); if (ssEntry && ssEntry->CombatRoundTime) { - SetAttackTime(BASE_ATTACK, ssEntry->CombatRoundTime); - SetAttackTime(OFF_ATTACK, ssEntry->CombatRoundTime); - SetAttackTime(RANGED_ATTACK, BASE_ATTACK_TIME); + SetBaseAttackTime(BASE_ATTACK, ssEntry->CombatRoundTime); + SetBaseAttackTime(OFF_ATTACK, ssEntry->CombatRoundTime); + SetBaseAttackTime(RANGED_ATTACK, BASE_ATTACK_TIME); } else SetRegularAttackTime(); diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 3d5b221fac..a982ba99b4 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -1271,7 +1271,7 @@ void Guardian::UpdateDamagePhysical(WeaponAttackType attType) UnitMods unitMod = UNIT_MOD_DAMAGE_MAINHAND; - float att_speed = float(GetAttackTime(BASE_ATTACK))/1000.0f; + float att_speed = float(GetBaseAttackTime(BASE_ATTACK))/1000.0f; float base_value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * att_speed + bonusDamage; float base_pct = GetPctModifierValue(unitMod, BASE_PCT); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index aafa68c104..70e11e0f5f 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -313,6 +313,7 @@ Unit::Unit(bool isWorldObject) : m_updateFlag.MovementUpdate = true; + m_baseAttackSpeed = { }; m_attackTimer = { }; m_modAttackSpeedPct.fill(1.0f); @@ -612,7 +613,7 @@ void Unit::DisableSpline() void Unit::resetAttackTimer(WeaponAttackType type) { - m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]); + m_attackTimer[type] = uint32(GetBaseAttackTime(type) * m_modAttackSpeedPct[type]); } bool Unit::IsWithinCombatRange(Unit const* obj, float dist2compare) const @@ -1362,7 +1363,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) // Reduce attack time if (victim->haveOffhandWeapon() && offtime < basetime) { - float percent20 = victim->GetAttackTime(OFF_ATTACK) * 0.20f; + float percent20 = victim->GetBaseAttackTime(OFF_ATTACK) * 0.20f; float percent60 = 3.0f * percent20; if (offtime > percent20 && offtime <= percent60) victim->setAttackTimer(OFF_ATTACK, uint32(percent20)); @@ -1374,7 +1375,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) } else { - float percent20 = victim->GetAttackTime(BASE_ATTACK) * 0.20f; + float percent20 = victim->GetBaseAttackTime(BASE_ATTACK) * 0.20f; float percent60 = 3.0f * percent20; if (basetime > percent20 && basetime <= percent60) victim->setAttackTimer(BASE_ATTACK, uint32(percent20)); @@ -7829,9 +7830,9 @@ float Unit::GetWeaponProcChance() const // normalized proc chance for weapon attack speed // (odd formula...) if (isAttackReady(BASE_ATTACK)) - return (GetAttackTime(BASE_ATTACK) * 1.8f / 1000.0f); + return (GetBaseAttackTime(BASE_ATTACK) * 1.8f / 1000.0f); else if (haveOffhandWeapon() && isAttackReady(OFF_ATTACK)) - return (GetAttackTime(OFF_ATTACK) * 1.6f / 1000.0f); + return (GetBaseAttackTime(OFF_ATTACK) * 1.6f / 1000.0f); return 0; } @@ -8250,12 +8251,6 @@ float Unit::GetPowerRegen(Powers powerType, bool isInCombat) const return result; } -uint32 Unit::GetAttackTime(WeaponAttackType att) const -{ - float f_BaseAttackTime = GetFloatValue(UNIT_FIELD_BASEATTACKTIME + AsUnderlyingType(att)) / m_modAttackSpeedPct[att]; - return (uint32)f_BaseAttackTime; -} - bool Unit::IsAlwaysVisibleFor(WorldObject const* seer) const { if (WorldObject::IsAlwaysVisibleFor(seer)) @@ -10340,13 +10335,40 @@ void ApplyPercentModFloatVar(float& var, float val, bool apply) var *= (apply ? (100.0f + val) / 100.0f : 100.0f / (100.0f + val)); } +uint32 Unit::GetBaseAttackTime(WeaponAttackType att) const +{ + return m_baseAttackSpeed[att]; +} + +void Unit::SetBaseAttackTime(WeaponAttackType att, uint32 val) +{ + m_baseAttackSpeed[att] = val; + UpdateAttackTimeField(att); +} + +void Unit::UpdateAttackTimeField(WeaponAttackType att) +{ + switch (att) + { + case BASE_ATTACK: + case OFF_ATTACK: + SetFloatValue(UNIT_FIELD_BASEATTACKTIME + att, uint32(m_baseAttackSpeed[att] * m_modAttackSpeedPct[att])); + break; + case RANGED_ATTACK: + SetFloatValue(UNIT_FIELD_RANGEDATTACKTIME, uint32(m_baseAttackSpeed[RANGED_ATTACK] * m_modAttackSpeedPct[RANGED_ATTACK])); + break; + default: + break; + } +} + void Unit::ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply) { float amount = GetFloatValue(UNIT_FIELD_BASEATTACKTIME + AsUnderlyingType(att)); float hasteAmount = GetTypeId() == TYPEID_PLAYER ? GetFloatValue(PLAYER_FIELD_MOD_HASTE) : 0.f; float rangedHasteAmount = GetTypeId() == TYPEID_PLAYER ? GetFloatValue(PLAYER_FIELD_MOD_RANGED_HASTE) : 0.f; - float remainingTimePct = (float)m_attackTimer[att] / (GetAttackTime(att) * m_modAttackSpeedPct[att]); + float remainingTimePct = float(m_attackTimer[att]) / (m_baseAttackSpeed[att] * m_modAttackSpeedPct[att]); if (val > 0.f) { ApplyPercentModFloatVar(m_modAttackSpeedPct[att], val, !apply); @@ -10382,7 +10404,8 @@ void Unit::ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply SetFloatValue(PLAYER_FIELD_MOD_RANGED_HASTE, rangedHasteAmount); } - m_attackTimer[att] = uint32(GetAttackTime(att) * m_modAttackSpeedPct[att] * remainingTimePct); + UpdateAttackTimeField(att); + m_attackTimer[att] = uint32(m_baseAttackSpeed[att] * m_modAttackSpeedPct[att] * remainingTimePct); } void Unit::ApplyHasteRegenMod(float val, bool apply) @@ -10592,11 +10615,11 @@ float Unit::CalculateDefaultCoefficient(SpellInfo const* spellInfo, DamageEffect float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized) const { if (GetTypeId() != TYPEID_PLAYER || (IsInFeralForm() && !normalized)) - return GetAttackTime(attType) / 1000.0f; + return GetBaseAttackTime(attType) / 1000.0f; Item* weapon = ToPlayer()->GetWeaponForAttack(attType, true); if (!weapon) - return BASE_ATTACK_TIME / 1000.0f; + return 2.0f; if (!normalized) return weapon->GetTemplate()->GetDelay() / 1000.0f; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 7a0c839dfb..d5a66cdf49 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -821,8 +821,9 @@ class TC_GAME_API Unit : public WorldObject virtual void RegenerateHealth() { } - uint32 GetAttackTime(WeaponAttackType att) const; - void SetAttackTime(WeaponAttackType att, uint32 val) { SetFloatValue(UNIT_FIELD_BASEATTACKTIME + AsUnderlyingType(att), val * m_modAttackSpeedPct[att]); } + uint32 GetBaseAttackTime(WeaponAttackType att) const; + void SetBaseAttackTime(WeaponAttackType att, uint32 val); + void UpdateAttackTimeField(WeaponAttackType att); void ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply); void ApplyHasteRegenMod(float val, bool apply); void ApplyCastTimePercentMod(float val, bool apply, bool withCastHaste = true, bool withCastSpeed = true); @@ -1328,7 +1329,9 @@ class TC_GAME_API Unit : public WorldObject float m_modSpellHitChance; int32 m_baseSpellCritChance; + std::array m_baseAttackSpeed; std::array m_modAttackSpeedPct; + std::array m_attackTimer; // stat system void HandleStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float amount, bool apply); @@ -1655,8 +1658,6 @@ class TC_GAME_API Unit : public WorldObject void _UpdateAutoRepeatSpell(); - std::array m_attackTimer; - std::array m_createStats; AttackerSet m_attackers; diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 4fe3d81382..ce627d314f 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1962,7 +1962,7 @@ float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& event // calculate ppm chance if present and we're using weapon if (eventInfo.GetDamageInfo() && procEntry.ProcsPerMinute != 0) { - uint32 WeaponSpeed = caster->GetAttackTime(eventInfo.GetDamageInfo()->GetAttackType()); + uint32 WeaponSpeed = caster->GetBaseAttackTime(eventInfo.GetDamageInfo()->GetAttackType()); chance = caster->GetPPMProcChance(WeaponSpeed, procEntry.ProcsPerMinute, GetSpellInfo()); } // apply chance modifer aura, applies also to ppm chance (see improved judgement of light spell) diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 41cd7b7dd5..ef63512d1b 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -3741,7 +3741,7 @@ int32 SpellInfo::CalcPowerCost(WorldObject const* caster, SpellSchoolMask school if (!HasAttribute(SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON) && HasAttribute(SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON)) slot = OFF_ATTACK; - speed = unitCaster->GetAttackTime(slot); + speed = unitCaster->GetBaseAttackTime(slot); } powerCost += speed / 100; diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp index a5927e86d5..5094c60e62 100644 --- a/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp +++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_prince_malchezaar.cpp @@ -419,7 +419,7 @@ public: //models SetEquipmentSlots(false, EQUIP_ID_AXE, EQUIP_ID_AXE, EQUIP_NO_CHANGE); - me->SetAttackTime(OFF_ATTACK, (me->GetAttackTime(BASE_ATTACK)*150)/100); + me->SetBaseAttackTime(OFF_ATTACK, (me->GetBaseAttackTime(BASE_ATTACK)*150)/100); me->SetCanDualWield(true); } } diff --git a/src/server/scripts/Pet/pet_hunter.cpp b/src/server/scripts/Pet/pet_hunter.cpp index 0aeb1afa3e..8b91a8137b 100644 --- a/src/server/scripts/Pet/pet_hunter.cpp +++ b/src/server/scripts/Pet/pet_hunter.cpp @@ -69,7 +69,7 @@ class npc_pet_hunter_snake_trap : public CreatureScript me->SetMaxHealth(uint32(107 * (me->getLevel() - 40) * 0.025f)); // Add delta to make them not all hit the same time - me->SetAttackTime(BASE_ATTACK, me->GetAttackTime(BASE_ATTACK) + urandms(0,6)); + me->SetBaseAttackTime(BASE_ATTACK, me->GetBaseAttackTime(BASE_ATTACK) + urandms(0,6)); if (!_isViper && !me->HasAura(SPELL_HUNTER_DEADLY_POISON_PASSIVE)) DoCast(me, SPELL_HUNTER_DEADLY_POISON_PASSIVE, true); diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index aad19345fe..486a3a016e 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -888,7 +888,7 @@ class spell_pal_seal_of_righteousness : public AuraScript float ap = target->GetTotalAttackPowerValue(BASE_ATTACK); int32 holy = target->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_HOLY); - int32 bp = int32((ap * 0.011f + 0.022f * holy) * target->GetAttackTime(BASE_ATTACK) / 1000); + int32 bp = int32((ap * 0.011f + 0.022f * holy) * target->GetBaseAttackTime(BASE_ATTACK) / 1000); if (target->GetDummyAuraEffect(SPELLFAMILY_PALADIN, PALADIN_ICON_ID_SEALS_OF_COMMAND, EFFECT_1)) target->CastSpell(target, SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS_DAMAGE_AOE, CastSpellExtraArgs(aurEff).AddSpellBP0(bp)); diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 7dafa3492e..b009b493f9 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -1423,7 +1423,7 @@ class spell_sha_flametongue_weapon : public AuraScript return; float basePoints = spell->Effects[EFFECT_1].CalcValue(player); - float attackSpeed = player->GetAttackTime(attType) / 1000.f; + float attackSpeed = player->GetBaseAttackTime(attType) / 1000.f; float fireDamage = basePoints / 100.0f; fireDamage *= attackSpeed; @@ -1497,7 +1497,7 @@ class spell_sha_windfury_weapon : public AuraScript return; int32 attackPower = spell->Effects[EFFECT_1].CalcValue(player); - int32 amount = static_cast(attackPower / 14.f * player->GetAttackTime(attType) / 1000.f); + int32 amount = static_cast(attackPower / 14.f * player->GetBaseAttackTime(attType) / 1000.f); uint32 spellId = attType == BASE_ATTACK ? SPELL_SHAMAN_WINDFURY_ATTACK_MAINHAND : SPELL_SHAMAN_WINDFURY_ATTACK_OFFHAND; for (uint8 i = 0; i < 3; i++) diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index c29faa0b13..69ec05852d 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -435,7 +435,7 @@ class spell_warr_rend : public AuraScript // $0.25 * (($MWB + $mwb) / 2 + $AP / 14 * $MWS) bonus per tick float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 mws = caster->GetAttackTime(BASE_ATTACK); + int32 mws = caster->GetBaseAttackTime(BASE_ATTACK); float mwbMin = caster->GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE); float mwbMax = caster->GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE); float mwb = ((mwbMin + mwbMax) / 2 + ap * mws / 14000) * 0.25f; diff --git a/src/server/scripts/World/mob_generic_creature.cpp b/src/server/scripts/World/mob_generic_creature.cpp index fccd6f48a5..86887435cc 100644 --- a/src/server/scripts/World/mob_generic_creature.cpp +++ b/src/server/scripts/World/mob_generic_creature.cpp @@ -34,7 +34,7 @@ public: trigger_periodicAI(Creature* creature) : NullCreatureAI(creature) { spell = me->m_spells[0] ? sSpellMgr->GetSpellInfo(me->m_spells[0]) : nullptr; - interval = me->GetAttackTime(BASE_ATTACK); + interval = me->GetBaseAttackTime(BASE_ATTACK); timer = interval; }