diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c15fc47cb7..f487d8da1f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2197,6 +2197,7 @@ void Player::RegenerateAll() Regenerate(POWER_ENERGY); Regenerate(POWER_MANA); + Regenerate(POWER_FOCUS); // Runes act as cooldowns, and they don't need to send any data if (getClass() == CLASS_DEATH_KNIGHT) @@ -2206,6 +2207,7 @@ void Player::RegenerateAll() uint8 runeToRegen = i; uint32 cd = GetRuneCooldown(i); uint32 secondRuneCd = GetRuneCooldown(i + 1); + float cdmod = GetFloatValue(PLAYER_RUNE_REGEN_1) * 10.0f; // Regenerate second rune of the same type only after first rune is off the cooldown if (secondRuneCd && (cd > secondRuneCd || !cd)) { @@ -2214,16 +2216,10 @@ void Player::RegenerateAll() } if (cd) - SetRuneCooldown(runeToRegen, (cd > m_regenTimer) ? cd - m_regenTimer : 0); + SetRuneCooldown(runeToRegen, (cd > (m_regenTimer * cdmod)) ? cd - (m_regenTimer * cdmod) : 0); } } - if (m_focusRegenTimerCount >= 1000 && getClass() == CLASS_HUNTER) - { - Regenerate(POWER_FOCUS); - m_focusRegenTimerCount -= 1000; - } - if (m_regenTimerCount >= 2000) { // Not in combat or they have regeneration @@ -2284,8 +2280,8 @@ void Player::Regenerate(Powers power) addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * ((0.001f * m_regenTimer) + CalculatePct(0.001f, spellHaste)); else addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * ((0.001f * m_regenTimer) + CalculatePct(0.001f, spellHaste)); + break; } - break; case POWER_RAGE: // Regenerate rage { if (!IsInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN)) @@ -2293,14 +2289,21 @@ void Player::Regenerate(Powers power) float RageDecreaseRate = sWorld->getRate(RATE_POWER_RAGE_LOSS); addvalue += -25 * RageDecreaseRate / meleeHaste; // 2.5 rage by tick (= 2 seconds => 1.25 rage/sec) } + break; } - break; case POWER_FOCUS: - addvalue += (6.0f + CalculatePct(6.0f, rangedHaste)) * sWorld->getRate(RATE_POWER_FOCUS); + { + float haste = (1.0f / GetFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN) - 1.0f) * 100.0f; + addvalue += (5.0f + CalculatePct(5.0f, haste)) * (m_regenTimer / 1000.0f); + addvalue *= GetTotalAuraMultiplier(SPELL_AURA_HASTE_SPELLS); break; + } case POWER_ENERGY: // Regenerate energy (rogue) - addvalue += ((0.01f * m_regenTimer) + CalculatePct(0.01f, meleeHaste)) * sWorld->getRate(RATE_POWER_ENERGY); + { + float haste = (1.0f / GetFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN) - 1.0f) * 100.0f; + addvalue += (10.0f + CalculatePct(10.0f, haste)) * (m_regenTimer / 1000.0f); break; + } case POWER_RUNIC_POWER: { if (!IsInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN)) @@ -2308,14 +2311,14 @@ void Player::Regenerate(Powers power) float RunicPowerDecreaseRate = sWorld->getRate(RATE_POWER_RUNICPOWER_LOSS); addvalue += -30 * RunicPowerDecreaseRate; // 3 RunicPower by tick } + break; } - break; case POWER_HOLY_POWER: // Regenerate holy power { if (!IsInCombat()) addvalue += -1.0f; // remove 1 each 10 sec + break; } - break; case POWER_RUNE: break; case POWER_HEALTH: @@ -2325,7 +2328,7 @@ void Player::Regenerate(Powers power) } // Mana regen calculated in Player::UpdateManaRegen() - if (power != POWER_MANA) + if (power != POWER_MANA && power != POWER_FOCUS && power != POWER_ENERGY) { AuraEffectList const& ModPowerRegenPCTAuras = GetAuraEffectsByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT); for (AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i) @@ -3000,6 +3003,7 @@ void Player::InitStatsForLevel(bool reapplyMods) } SetFloatValue(PLAYER_FIELD_MOD_SPELL_POWER_PCT, 1.0f); + SetFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, 1.0f); //reset attack power, damage and attack speed fields SetFloatValue(UNIT_FIELD_BASEATTACKTIME, 2000.0f); @@ -5497,35 +5501,39 @@ float Player::OCTRegenMPPerSpirit() const void Player::ApplyRatingMod(CombatRating combatRating, int32 value, bool apply) { - float oldRating = m_baseRatingValue[combatRating]; - m_baseRatingValue[combatRating] += (apply ? value : -value); - // explicit affected values - float const multiplier = GetRatingMultiplier(combatRating); - float const oldVal = oldRating * multiplier; - float const newVal = m_baseRatingValue[combatRating] * multiplier; switch (combatRating) { case CR_HASTE_MELEE: - ApplyAttackTimePercentMod(BASE_ATTACK, oldVal, false); - ApplyAttackTimePercentMod(OFF_ATTACK, oldVal, false); - ApplyAttackTimePercentMod(BASE_ATTACK, newVal, true); - ApplyAttackTimePercentMod(OFF_ATTACK, newVal, true); - if (getClass() == CLASS_DEATH_KNIGHT) - UpdateAllRunesRegen(); + { + ApplyAttackTimePercentMod(BASE_ATTACK, m_baseRatingValue[combatRating] * GetRatingMultiplier(combatRating), false); + ApplyAttackTimePercentMod(BASE_ATTACK, (m_baseRatingValue[combatRating] + (apply ? value : -value)) * GetRatingMultiplier(combatRating), true); + ApplyAttackTimePercentMod(OFF_ATTACK, m_baseRatingValue[combatRating] * GetRatingMultiplier(combatRating), false); + ApplyAttackTimePercentMod(OFF_ATTACK, (m_baseRatingValue[combatRating] + (apply ? value : -value)) * GetRatingMultiplier(combatRating), true); + ApplyRegenMod(BASE_ATTACK, m_baseRatingValue[combatRating] * GetRatingMultiplier(combatRating), false); + ApplyRegenMod(BASE_ATTACK, (m_baseRatingValue[combatRating] + (apply ? value : -value)) * GetRatingMultiplier(combatRating), true); break; + } case CR_HASTE_RANGED: - ApplyAttackTimePercentMod(RANGED_ATTACK, oldVal, false); - ApplyAttackTimePercentMod(RANGED_ATTACK, newVal, true); + { + ApplyAttackTimePercentMod(RANGED_ATTACK, m_baseRatingValue[combatRating] * GetRatingMultiplier(combatRating), false); + ApplyAttackTimePercentMod(RANGED_ATTACK, (m_baseRatingValue[combatRating] + (apply ? value : -value)) * GetRatingMultiplier(combatRating), true); + ApplyRegenMod(RANGED_ATTACK, m_baseRatingValue[combatRating] * GetRatingMultiplier(combatRating), false); + ApplyRegenMod(RANGED_ATTACK, (m_baseRatingValue[combatRating] + (apply ? value : -value)) * GetRatingMultiplier(combatRating), true); break; + } case CR_HASTE_SPELL: - ApplyCastTimePercentMod(oldVal, false); - ApplyCastTimePercentMod(newVal, true); + { + ApplyCastTimePercentMod(m_baseRatingValue[combatRating] * GetRatingMultiplier(combatRating), false); + ApplyCastTimePercentMod((m_baseRatingValue[combatRating] + (apply ? value : -value)) * GetRatingMultiplier(combatRating), true); break; + } default: break; } + m_baseRatingValue[combatRating] +=(apply ? value : -value); + UpdateRating(combatRating); } @@ -24959,25 +24967,7 @@ bool Player::isTotalImmunity() const uint32 Player::GetRuneTypeBaseCooldown(RuneType runeType) const { - float cooldown = RUNE_BASE_COOLDOWN; - float hastePct = 0.0f; - - AuraEffectList const& regenAura = GetAuraEffectsByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT); - for (AuraEffectList::const_iterator i = regenAura.begin();i != regenAura.end(); ++i) - if ((*i)->GetMiscValue() == POWER_RUNE && (*i)->GetMiscValueB() == runeType) - cooldown *= 1.0f - (*i)->GetAmount() / 100.0f; - - // Runes cooldown are now affected by player's haste from equipment ... - hastePct = GetRatingBonusValue(CR_HASTE_MELEE); - - // ... and some auras. - hastePct += GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_HASTE); - hastePct += GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_HASTE_2); - hastePct += GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_HASTE_3); - - cooldown *= 1.0f - (hastePct / 100.0f); - - return cooldown; + return RUNE_BASE_COOLDOWN; } void Player::SetRuneCooldown(uint8 index, uint32 cooldown, bool casted /*= false*/) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 0d6eb33c28..8be5ca484c 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2013,12 +2013,10 @@ class TC_GAME_API Player : public Unit, public GridObject void ApplyManaRegenBonus(int32 amount, bool apply); void ApplyHealthRegenBonus(int32 amount, bool apply); void UpdateManaRegen(); - void UpdateRuneRegen(RuneType rune); uint32 GetRuneTimer(uint8 index) const { return m_runeGraceCooldown[index]; } void SetRuneTimer(uint8 index, uint32 timer) { m_runeGraceCooldown[index] = timer; } uint32 GetLastRuneGraceTimer(uint8 index) const { return m_lastRuneGraceTimers[index]; } void SetLastRuneGraceTimer(uint8 index, uint32 timer) { m_lastRuneGraceTimers[index] = timer; } - void UpdateAllRunesRegen(); ObjectGuid GetLootGUID() const { return m_lootGuid; } void SetLootGUID(ObjectGuid guid) { m_lootGuid = guid; } diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index ae07fcfb0c..f01b613e2b 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -765,51 +765,28 @@ void Player::ApplyHealthRegenBonus(int32 amount, bool apply) void Player::UpdateManaRegen() { - // Mana regen from spirit - float spirit_regen = OCTRegenMPPerSpirit(); - // Apply PCT bonus from SPELL_AURA_MOD_POWER_REGEN_PERCENT aura on spirit base regen - spirit_regen *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, POWER_MANA); + if (getPowerType() == POWER_MANA) + { + // Mana regen from spirit + float spirit_regen = OCTRegenMPPerSpirit(); + // Apply PCT bonus from SPELL_AURA_MOD_POWER_REGEN_PERCENT aura on spirit base regen + spirit_regen *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, POWER_MANA); - // SpiritRegen(SPI, INT, LEVEL) = (0.001 + (SPI x sqrt(INT) x BASE_REGEN[LEVEL])) x 5 - if (GetStat(STAT_INTELLECT) > 0.0f) - spirit_regen *= std::sqrt(GetStat(STAT_INTELLECT)); + // SpiritRegen(SPI, INT, LEVEL) = (0.001 + (SPI x sqrt(INT) x BASE_REGEN[LEVEL])) x 5 + if (GetStat(STAT_INTELLECT) > 0.0f) + spirit_regen *= std::sqrt(GetStat(STAT_INTELLECT)); - // CombatRegen = 5% of Base Mana - float base_regen = GetCreateMana() * 0.01f + GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) / 5.0f; + // CombatRegen = 5% of Base Mana + float base_regen = GetCreateMana() * 0.01f + GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) / 5.0f; - // Set regen rate in cast state apply only on spirit based regen - int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT); + // Set regen rate in cast state apply only on spirit based regen + int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT); - SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, base_regen + CalculatePct(spirit_regen, modManaRegenInterrupt)); - SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER, 0.001f + spirit_regen + base_regen); -} - -void Player::UpdateRuneRegen(RuneType rune) -{ - if (rune >= NUM_RUNE_TYPES) - return; - - uint32 cooldown = 0; - - for (uint32 i = 0; i < MAX_RUNES; ++i) - if (GetBaseRune(i) == rune) - { - cooldown = GetRuneBaseCooldown(i); - break; - } - - if (cooldown <= 0) - return; - - float regen = float(1 * IN_MILLISECONDS) / float(cooldown); - SetFloatValue(PLAYER_RUNE_REGEN_1 + uint8(rune), regen); -} - -void Player::UpdateAllRunesRegen() -{ - for (uint8 i = 0; i < NUM_RUNE_TYPES; ++i) - if (uint32 cooldown = GetRuneTypeBaseCooldown(RuneType(i))) - SetFloatValue(PLAYER_RUNE_REGEN_1 + i, float(1 * IN_MILLISECONDS) / float(cooldown)); + SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, base_regen + CalculatePct(spirit_regen, modManaRegenInterrupt)); + SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER, 0.001f + spirit_regen + base_regen); + } + else if (getClass() == CLASS_HUNTER) + SetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, -0.2f); } void Player::_ApplyAllStatBonuses() diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index ff5af332fb..92cc11459b 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -9343,11 +9343,14 @@ void Unit::ModSpellCastTime(SpellInfo const* spellInfo, int32 & castTime, Spell* if (Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellInfo->Id, castTime, spell); + float castSpeedMod = 1; + castSpeedMod = castSpeedMod - GetTotalAuraMultiplier(SPELL_AURA_HASTE_SPELLS) + 1.0f; + if (!(spellInfo->HasAttribute(SPELL_ATTR0_ABILITY) || spellInfo->HasAttribute(SPELL_ATTR0_TRADESPELL) || spellInfo->HasAttribute(SPELL_ATTR3_NO_DONE_BONUS)) && ((GetTypeId() == TYPEID_PLAYER && spellInfo->SpellFamilyName) || GetTypeId() == TYPEID_UNIT)) castTime = int32(float(castTime) * GetFloatValue(UNIT_MOD_CAST_SPEED)); else if (spellInfo->HasAttribute(SPELL_ATTR0_REQ_AMMO) && !spellInfo->HasAttribute(SPELL_ATTR2_AUTOREPEAT_FLAG)) - castTime = int32(float(castTime) * m_modAttackSpeedPct[RANGED_ATTACK]); + castTime = int32(float(castTime) * m_modAttackSpeedPct[RANGED_ATTACK] * castSpeedMod); else if (spellInfo->SpellVisual[0] == 3881 && HasAura(67556)) // cooking with Chef Hat. castTime = 500; } @@ -10964,7 +10967,7 @@ void Unit::ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply if (val > 0) { ApplyPercentModFloatVar(m_modAttackSpeedPct[att], val, !apply); - ApplyPercentModFloatValue(UNIT_FIELD_BASEATTACKTIME+att, val, !apply); + ApplyPercentModFloatValue(UNIT_FIELD_BASEATTACKTIME + att, val, !apply); if (GetTypeId() == TYPEID_PLAYER) { @@ -10977,7 +10980,7 @@ void Unit::ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply else { ApplyPercentModFloatVar(m_modAttackSpeedPct[att], -val, apply); - ApplyPercentModFloatValue(UNIT_FIELD_BASEATTACKTIME+att, -val, apply); + ApplyPercentModFloatValue(UNIT_FIELD_BASEATTACKTIME + att, -val, apply); if (GetTypeId() == TYPEID_PLAYER) { @@ -10987,9 +10990,56 @@ void Unit::ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply ApplyPercentModFloatValue(PLAYER_FIELD_MOD_RANGED_HASTE, -val, apply); } } + m_attackTimer[att] = uint32(GetAttackTime(att) * m_modAttackSpeedPct[att] * remainingTimePct); } +void Unit::ApplyRegenMod(WeaponAttackType att, float val, bool apply) +{ + if (val > 0) + { + if (GetTypeId() == TYPEID_PLAYER) + { + if (att == BASE_ATTACK) + { + if (GetTypeId() == TYPEID_PLAYER && getClass() != CLASS_HUNTER) + ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, val, !apply); + + // Modify rune regeneration based on haste + if (getClass() == CLASS_DEATH_KNIGHT) + for (uint8 i = 0; i < NUM_RUNE_TYPES; i++) + ApplyPercentModFloatValue(PLAYER_RUNE_REGEN_1 + i, val, apply); + } + else if (att == RANGED_ATTACK) + { + if (getClass() == CLASS_HUNTER) + ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, val, !apply); + } + } + } + else + { + if (GetTypeId() == TYPEID_PLAYER) + { + if (att == BASE_ATTACK) + { + if (GetTypeId() == TYPEID_PLAYER && getClass() != CLASS_HUNTER) + ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, -val, apply); + + // Modify rune regeneration based on haste + if (getClass() == CLASS_DEATH_KNIGHT) + for (uint8 i = 0; i < NUM_RUNE_TYPES; i++) + ApplyPercentModFloatValue(PLAYER_RUNE_REGEN_1 + i, val, !apply); + } + else if (att == RANGED_ATTACK) + { + if (getClass() == CLASS_HUNTER) + ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, -val, apply); + } + } + } +} + void Unit::ApplyCastTimePercentMod(float val, bool apply) { if (val > 0) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index ff2743c689..5ea863a88d 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1433,6 +1433,7 @@ class TC_GAME_API Unit : public WorldObject uint32 GetAttackTime(WeaponAttackType att) const; void SetAttackTime(WeaponAttackType att, uint32 val) { SetFloatValue(UNIT_FIELD_BASEATTACKTIME+att, val*m_modAttackSpeedPct[att]); } void ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply); + void ApplyRegenMod(WeaponAttackType att, float val, bool apply); void ApplyCastTimePercentMod(float val, bool apply); SheathState GetSheath() const { return SheathState(GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_SHEATH_STATE)); } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index f39d50a23f..6aae2023c6 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -3675,7 +3675,7 @@ void AuraEffect::HandleAuraModExpertise(AuraApplication const* aurApp, uint8 mod /********************************/ /*** HEAL & ENERGIZE ***/ /********************************/ -void AuraEffect::HandleModPowerRegen(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const +void AuraEffect::HandleModPowerRegen(AuraApplication const* aurApp, uint8 mode, bool apply) const { if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT))) return; @@ -3689,12 +3689,18 @@ void AuraEffect::HandleModPowerRegen(AuraApplication const* aurApp, uint8 mode, if (GetMiscValue() == POWER_MANA) target->ToPlayer()->UpdateManaRegen(); else if (GetMiscValue() == POWER_RUNE) - target->ToPlayer()->UpdateRuneRegen(RuneType(GetMiscValueB())); + target->ApplyPercentModFloatValue(PLAYER_RUNE_REGEN_1 + GetMiscValueB(), float(GetAmount()), apply); // other powers are not immediate effects - implemented in Player::Regenerate, Creature::Regenerate } void AuraEffect::HandleModPowerRegenPCT(AuraApplication const* aurApp, uint8 mode, bool apply) const { + Unit* target = aurApp->GetTarget(); + + if (target->GetTypeId() == TYPEID_PLAYER) + target->ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, GetAmount(), !apply); + + HandleModPowerRegen(aurApp, mode, apply); } @@ -4001,6 +4007,12 @@ void AuraEffect::HandleModMeleeRangedSpeedPct(AuraApplication const* aurApp, uin target->ApplyAttackTimePercentMod(BASE_ATTACK, (float)GetAmount(), apply); target->ApplyAttackTimePercentMod(OFF_ATTACK, (float)GetAmount(), apply); target->ApplyAttackTimePercentMod(RANGED_ATTACK, (float)GetAmount(), apply); + + if (GetAuraType() != SPELL_AURA_MOD_MELEE_RANGED_HASTE_2 && GetAuraType() != SPELL_AURA_MOD_RANGED_HASTE_2) + { + target->ApplyRegenMod(BASE_ATTACK, (float)GetAmount(), apply); + target->ApplyRegenMod(RANGED_ATTACK, (float)GetAmount(), apply); + } } void AuraEffect::HandleModCombatSpeedPct(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -4024,6 +4036,11 @@ void AuraEffect::HandleModCombatSpeedPct(AuraApplication const* aurApp, uint8 mo target->ApplyAttackTimePercentMod(BASE_ATTACK, float(GetAmount()), apply); target->ApplyAttackTimePercentMod(OFF_ATTACK, float(GetAmount()), apply); target->ApplyAttackTimePercentMod(RANGED_ATTACK, float(GetAmount()), apply); + if (GetAuraType() != SPELL_AURA_MOD_MELEE_RANGED_HASTE_2 && GetAuraType() != SPELL_AURA_MOD_RANGED_HASTE_2) + { + target->ApplyRegenMod(BASE_ATTACK, (float)GetAmount(), apply); + target->ApplyRegenMod(RANGED_ATTACK, (float)GetAmount(), apply); + } } void AuraEffect::HandleModAttackSpeed(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -4034,6 +4051,8 @@ void AuraEffect::HandleModAttackSpeed(AuraApplication const* aurApp, uint8 mode, Unit* target = aurApp->GetTarget(); target->ApplyAttackTimePercentMod(BASE_ATTACK, float(GetAmount()), apply); + if (GetAuraType() != SPELL_AURA_MOD_MELEE_RANGED_HASTE_2 && GetAuraType() != SPELL_AURA_MOD_RANGED_HASTE_2) + target->ApplyRegenMod(BASE_ATTACK, (float)GetAmount(), apply); target->UpdateDamagePhysical(BASE_ATTACK); } @@ -4044,17 +4063,17 @@ void AuraEffect::HandleModMeleeSpeedPct(AuraApplication const* aurApp, uint8 mod //! ToDo: Haste auras with the same handler _CAN'T_ stack together Unit* target = aurApp->GetTarget(); - int32 spellGroupVal = target->GetHighestExclusiveSameEffectSpellGroupValue(this, SPELL_AURA_MOD_MELEE_HASTE); - if (abs(spellGroupVal) >= abs(GetAmount())) - return; + bool applyRegenPct = GetAuraType() != SPELL_AURA_MOD_MELEE_HASTE_3 && GetAuraType() != SPELL_AURA_MOD_RANGED_HASTE_2; - if (spellGroupVal) + // Auras that only increase regeneration + if (target->GetTypeId() == TYPEID_PLAYER && applyRegenPct && GetBase()->HasEffectType(SPELL_AURA_MOD_MELEE_HASTE_3)) + target->ApplyRegenMod(BASE_ATTACK, (float)GetAmount(), apply); + else { - target->ApplyAttackTimePercentMod(BASE_ATTACK, float(spellGroupVal), !apply); - target->ApplyAttackTimePercentMod(OFF_ATTACK, float(spellGroupVal), !apply); + target->ApplyAttackTimePercentMod(BASE_ATTACK, (float)GetAmount(), apply); + target->ApplyAttackTimePercentMod(OFF_ATTACK, (float)GetAmount(), apply); + target->ApplyRegenMod(BASE_ATTACK, (float)GetAmount(), apply); } - target->ApplyAttackTimePercentMod(BASE_ATTACK, float(GetAmount()), apply); - target->ApplyAttackTimePercentMod(OFF_ATTACK, float(GetAmount()), apply); } void AuraEffect::HandleAuraModRangedHaste(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -4066,6 +4085,8 @@ void AuraEffect::HandleAuraModRangedHaste(AuraApplication const* aurApp, uint8 m Unit* target = aurApp->GetTarget(); target->ApplyAttackTimePercentMod(RANGED_ATTACK, (float)GetAmount(), apply); + if (GetAuraType() != SPELL_AURA_MOD_MELEE_RANGED_HASTE_2 && GetAuraType() != SPELL_AURA_MOD_RANGED_HASTE_2) + target->ApplyRegenMod(RANGED_ATTACK, (float)GetAmount(), apply); } /********************************/