From 0cdddca21022aee007fbc248e93bb8db32221678 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Tue, 10 Dec 2019 15:23:43 +0100 Subject: [PATCH] Core/Spells: corrected haste rune cooldown reduction behaivior * the haste regeneration modifier will now act multiplicative on the base regeneration rate rather than modifying it directly * renamed some functions for clarification --- src/server/game/Entities/Player/Player.cpp | 26 +++++++---- src/server/game/Entities/Player/Player.h | 3 +- src/server/game/Entities/Unit/Unit.cpp | 43 ++++++------------- src/server/game/Entities/Unit/Unit.h | 2 +- .../game/Spells/Auras/SpellAuraEffects.cpp | 22 +++++----- src/server/game/Spells/Spell.cpp | 8 ++-- 6 files changed, 46 insertions(+), 58 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 3f69e731431..fed69a7be46 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5470,16 +5470,16 @@ void Player::ApplyRatingMod(CombatRating combatRating, int32 value, bool apply) 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); + ApplyHasteRegenMod(BASE_ATTACK, m_baseRatingValue[combatRating] * GetRatingMultiplier(combatRating), false); + ApplyHasteRegenMod(BASE_ATTACK, (m_baseRatingValue[combatRating] + (apply ? value : -value)) * GetRatingMultiplier(combatRating), true); break; } case CR_HASTE_RANGED: { 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); + ApplyHasteRegenMod(RANGED_ATTACK, m_baseRatingValue[combatRating] * GetRatingMultiplier(combatRating), false); + ApplyHasteRegenMod(RANGED_ATTACK, (m_baseRatingValue[combatRating] + (apply ? value : -value)) * GetRatingMultiplier(combatRating), true); break; } case CR_HASTE_SPELL: @@ -25752,11 +25752,6 @@ bool Player::isTotalImmunity() const return false; } -uint32 Player::GetRuneTypeBaseCooldown(RuneType /*runeType*/) const -{ - return RUNE_BASE_COOLDOWN; -} - void Player::SetRuneConvertAura(uint8 index, AuraEffect const* aura, AuraType auraType, SpellInfo const* spellInfo) { m_runes->runes[index].ConvertAura = aura; @@ -25873,6 +25868,19 @@ void Player::InitRunes() SetFloatValue(PLAYER_RUNE_REGEN_1 + i, 0.1f); // set a base regen timer equal to 10 sec } +void Player::UpdateRuneRegeneration() +{ + // Formular: base cooldown / (1 - haste) + float regeneration = 0.1f; + float haste = GetFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN); + if (haste) + regeneration /= haste; + + if (getClass() == CLASS_DEATH_KNIGHT) + for (uint8 i = 0; i < NUM_RUNE_TYPES; i++) + SetFloatValue(PLAYER_RUNE_REGEN_1 + i, regeneration); +} + bool Player::IsBaseRuneSlotsOnCooldown(RuneType runeType) const { for (uint8 i = 0; i < MAX_RUNES; ++i) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a0192fe4e20..11bd626c235 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2298,8 +2298,6 @@ class TC_GAME_API Player : public Unit, public GridObject RuneType GetBaseRune(uint8 index) const { return RuneType(m_runes->runes[index].BaseRune); } RuneType GetCurrentRune(uint8 index) const { return RuneType(m_runes->runes[index].CurrentRune); } uint32 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; } - uint32 GetRuneBaseCooldown(uint8 index) const { return GetRuneTypeBaseCooldown(GetBaseRune(index)); } - uint32 GetRuneTypeBaseCooldown(RuneType runeType) const; bool IsBaseRuneSlotsOnCooldown(RuneType runeType) const; RuneType GetLastUsedRune() { return m_runes->lastUsedRune; } uint8 GetLastUsedRuneMask() { return m_runes->lastUsedRuneMask; } @@ -2317,6 +2315,7 @@ class TC_GAME_API Player : public Unit, public GridObject void ResyncRunes(uint8 count); void AddRunePower(uint8 mask); void InitRunes(); + void UpdateRuneRegeneration(); void SendRespondInspectAchievements(Player* player) const; uint32 GetAchievementPoints() const; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 874cbfaf066..55b43c7a59c 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11254,47 +11254,28 @@ void Unit::ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply m_attackTimer[att] = uint32(GetAttackTime(att) * m_modAttackSpeedPct[att] * remainingTimePct); } -void Unit::ApplyRegenMod(WeaponAttackType att, float val, bool apply) +void Unit::ApplyHasteRegenMod(WeaponAttackType att, float val, bool apply) { if (GetTypeId() != TYPEID_PLAYER) return; if (val > 0) { - if (att == BASE_ATTACK) - { - // 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); - - if (getClass() != CLASS_HUNTER) - ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, val, !apply); - } - else if (att == RANGED_ATTACK) - { - if (getClass() == CLASS_HUNTER) - ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, val, !apply); - } + if (att == BASE_ATTACK && getClass() != CLASS_HUNTER) + ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, val, !apply); + else if (att == RANGED_ATTACK && getClass() == CLASS_HUNTER) + ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, val, !apply); } else { - if (att == BASE_ATTACK) - { - // 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); - - if (getClass() != CLASS_HUNTER) - ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, -val, apply); - } - else if (att == RANGED_ATTACK) - { - if (getClass() == CLASS_HUNTER) - ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, -val, apply); - } + if (att == BASE_ATTACK && getClass() != CLASS_HUNTER) + ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, -val, apply); + else if (att == RANGED_ATTACK && getClass() == CLASS_HUNTER) + ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE_REGEN, -val, apply); } + + if (getClass() == CLASS_DEATH_KNIGHT) + ToPlayer()->UpdateRuneRegeneration(); } void Unit::ApplyCastTimePercentMod(float val, bool apply) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 4aac0e00a5e..092bc3d22b5 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1106,7 +1106,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 ApplyHasteRegenMod(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 8344328c5cc..a583e20db6c 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -3975,8 +3975,8 @@ void AuraEffect::HandleModMeleeRangedSpeedPct(AuraApplication const* aurApp, uin 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); + target->ApplyHasteRegenMod(BASE_ATTACK, (float)GetAmount(), apply); + target->ApplyHasteRegenMod(RANGED_ATTACK, (float)GetAmount(), apply); } } @@ -4003,8 +4003,8 @@ void AuraEffect::HandleModCombatSpeedPct(AuraApplication const* aurApp, uint8 mo 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); + target->ApplyHasteRegenMod(BASE_ATTACK, (float)GetAmount(), apply); + target->ApplyHasteRegenMod(RANGED_ATTACK, (float)GetAmount(), apply); } } @@ -4017,7 +4017,7 @@ void AuraEffect::HandleModAttackSpeed(AuraApplication const* aurApp, uint8 mode, 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->ApplyHasteRegenMod(BASE_ATTACK, (float)GetAmount(), apply); target->UpdateDamagePhysical(BASE_ATTACK); } @@ -4036,25 +4036,25 @@ void AuraEffect::HandleModMeleeSpeedPct(AuraApplication const* aurApp, uint8 mod if (spellGroupVal) { if (target->GetTypeId() == TYPEID_PLAYER && applyRegenPct && GetBase()->HasEffectType(SPELL_AURA_MOD_MELEE_HASTE_3)) - target->ApplyRegenMod(BASE_ATTACK, (float)GetAmount(), !apply); + target->ApplyHasteRegenMod(BASE_ATTACK, (float)GetAmount(), !apply); else { target->ApplyAttackTimePercentMod(BASE_ATTACK, (float)GetAmount(), !apply); target->ApplyAttackTimePercentMod(OFF_ATTACK, (float)GetAmount(), !apply); if (applyRegenPct) - target->ApplyRegenMod(BASE_ATTACK, (float)GetAmount(), !apply); + target->ApplyHasteRegenMod(BASE_ATTACK, (float)GetAmount(), !apply); } } // 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); + target->ApplyHasteRegenMod(BASE_ATTACK, (float)GetAmount(), apply); else { target->ApplyAttackTimePercentMod(BASE_ATTACK, (float)GetAmount(), apply); target->ApplyAttackTimePercentMod(OFF_ATTACK, (float)GetAmount(), apply); if (applyRegenPct) - target->ApplyRegenMod(BASE_ATTACK, (float)GetAmount(), apply); + target->ApplyHasteRegenMod(BASE_ATTACK, (float)GetAmount(), apply); } } @@ -4072,12 +4072,12 @@ void AuraEffect::HandleAuraModRangedHaste(AuraApplication const* aurApp, uint8 m { 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); + target->ApplyHasteRegenMod(RANGED_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(RANGED_ATTACK, (float)GetAmount(), apply); + target->ApplyHasteRegenMod(RANGED_ATTACK, (float)GetAmount(), apply); } /********************************/ diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 0434bac5e1b..b5f32412c1a 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4194,7 +4194,7 @@ void Spell::SendSpellStart() for (uint8 i = 0; i < MAX_RUNES; ++i) { // float casts ensure the division is performed on floats as we need float result - float baseCd = float(player->GetRuneBaseCooldown(i)); + float baseCd = float(uint32(RUNE_BASE_COOLDOWN)); data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed } } @@ -4320,7 +4320,7 @@ void Spell::SendSpellGo() for (uint8 i = 0; i < MAX_RUNES; ++i) { // float casts ensure the division is performed on floats as we need float result - float baseCd = float(player->GetRuneBaseCooldown(i)); + float baseCd = float(uint32(RUNE_BASE_COOLDOWN)); data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed } } @@ -5048,7 +5048,7 @@ void Spell::TakeRunePower(SpellMissInfo hitInfo) RuneType rune = player->GetCurrentRune(i); if (!player->GetRuneCooldown(i) && runeCost[rune] > 0) { - player->SetRuneCooldown(i, consumeRunes ? player->GetRuneBaseCooldown(i) : uint32(RUNE_MISS_COOLDOWN)); + player->SetRuneCooldown(i, consumeRunes ? uint32(RUNE_BASE_COOLDOWN) : uint32(RUNE_MISS_COOLDOWN)); player->SetLastUsedRune(rune); player->SetLastUsedRuneIndex(i); runeCost[rune]--; @@ -5065,7 +5065,7 @@ void Spell::TakeRunePower(SpellMissInfo hitInfo) RuneType rune = player->GetCurrentRune(i); if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH) { - player->SetRuneCooldown(i, consumeRunes ? player->GetRuneBaseCooldown(i) : uint32(RUNE_MISS_COOLDOWN)); + player->SetRuneCooldown(i, consumeRunes ? uint32(RUNE_BASE_COOLDOWN) : uint32(RUNE_MISS_COOLDOWN)); player->SetLastUsedRune(rune); player->SetLastUsedRuneIndex(i); runeCost[rune]--;