diff options
author | Shauren <shauren.trinity@gmail.com> | 2025-03-19 00:03:38 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2025-03-19 00:03:38 +0100 |
commit | fa75f635669df6f0aab4abef074f9e8da4b5bf06 (patch) | |
tree | 64aacb5246beaa5a6b21143b0dd462a6694c5b3c | |
parent | e0d3781989c3e9339bfc14981a57683d3010f4e0 (diff) |
Core/Auras: Implemented SPELL_AURA_MOD_CHARGE_RECOVERY_RATE, SPELL_AURA_MOD_CHARGE_RECOVERY_RATE_BY_TYPE_MASK and SPELL_AURA_MOD_CHARGE_RECOVERY_BY_TYPE_MASK
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 3 | ||||
-rw-r--r-- | src/server/game/Server/Packets/SpellPackets.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Server/Packets/SpellPackets.h | 13 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraDefines.h | 6 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 15 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/SpellHistory.cpp | 54 | ||||
-rw-r--r-- | src/server/game/Spells/SpellHistory.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 2 |
10 files changed, 99 insertions, 9 deletions
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index 8342b9cbe1b..054c4bbdebd 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -2085,7 +2085,8 @@ enum SpellCategoryFlags { SPELL_CATEGORY_FLAG_COOLDOWN_SCALES_WITH_WEAPON_SPEED = 0x01, // unused SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT = 0x04, - SPELL_CATEGORY_FLAG_COOLDOWN_EXPIRES_AT_DAILY_RESET = 0x08 + SPELL_CATEGORY_FLAG_COOLDOWN_EXPIRES_AT_DAILY_RESET = 0x08, + SPELL_CATEGORY_FLAG_IGNORE_FOR_MOD_TIME_RATE = 0x40 }; enum class SpellEffectAttributes diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp index 23391e57175..e7bb499d85b 100644 --- a/src/server/game/Server/Packets/SpellPackets.cpp +++ b/src/server/game/Server/Packets/SpellPackets.cpp @@ -704,6 +704,17 @@ WorldPacket const* SetSpellCharges::Write() return &_worldPacket; } +WorldPacket const* UpdateChargeCategoryCooldown::Write() +{ + _worldPacket << int32(Category); + _worldPacket << float(ModChange); + _worldPacket << float(ModRate); + _worldPacket << Bits<1>(Snapshot); + _worldPacket.FlushBits(); + + return &_worldPacket; +} + ByteBuffer& operator<<(ByteBuffer& data, SpellChargeEntry const& chargeEntry) { data << uint32(chargeEntry.Category); diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index 63798895ebb..5893496f13d 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -658,6 +658,19 @@ namespace WorldPackets float ChargeModRate = 1.0f; }; + class UpdateChargeCategoryCooldown final : public ServerPacket + { + public: + UpdateChargeCategoryCooldown() : ServerPacket(SMSG_UPDATE_CHARGE_CATEGORY_COOLDOWN, 4 + 4 + 4 + 1) { } + + WorldPacket const* Write() override; + + int32 Category = 0; + float ModChange = 1.0f; + float ModRate = 1.0f; + bool Snapshot = false; + }; + struct SpellChargeEntry { uint32 Category = 0; diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index c1ebd755f4c..6192dce193e 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -2202,7 +2202,7 @@ void OpcodeTable::InitializeServerOpcodes() DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CAPTURE_POINT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CELESTIAL_BODY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CHARACTER_FLAGS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CHARGE_CATEGORY_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CHARGE_CATEGORY_COOLDOWN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_COOLDOWN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CRAFTING_NPC_RECIPES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_DAILY_MISSION_COUNTER, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h index 662f7d3a07f..d502faaaa67 100644 --- a/src/server/game/Spells/Auras/SpellAuraDefines.h +++ b/src/server/game/Spells/Auras/SpellAuraDefines.h @@ -239,7 +239,7 @@ enum AuraType : uint32 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT2 = 145, SPELL_AURA_ALLOW_TAME_PET_TYPE = 146, SPELL_AURA_MECHANIC_IMMUNITY_MASK = 147, - SPELL_AURA_MOD_CHARGE_RECOVERY_RATE = 148, // NYI + SPELL_AURA_MOD_CHARGE_RECOVERY_RATE = 148, SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150, SPELL_AURA_TRACK_STEALTHED = 151, // Track Stealthed @@ -264,7 +264,7 @@ enum AuraType : uint32 SPELL_AURA_DETECT_AMORE = 170, SPELL_AURA_MOD_SPEED_NOT_STACK = 171, SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK = 172, - SPELL_AURA_MOD_RECOVERY_RATE_2 = 173, // NYI + SPELL_AURA_MOD_CHARGE_RECOVERY_RATE_BY_TYPE_MASK = 173, SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT = 174, // by defeult intelect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT = 175, SPELL_AURA_SPIRIT_OF_REDEMPTION = 176, @@ -296,7 +296,7 @@ enum AuraType : uint32 SPELL_AURA_IGNORE_COMBAT_RESULT = 202, SPELL_AURA_PREVENT_INTERRUPT = 203, SPELL_AURA_PREVENT_CORPSE_RELEASE = 204, // NYI - SPELL_AURA_MOD_CHARGE_COOLDOWN = 205, // NYI + SPELL_AURA_MOD_CHARGE_RECOVERY_BY_TYPE_MASK = 205, SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED = 206, SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED = 207, SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED = 208, diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 061a55c5002..7b1ef3d960a 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -217,7 +217,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandleAuraModIncreaseHealthPercent, //145 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT2 &AuraEffect::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE &AuraEffect::HandleModMechanicImmunityMask, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK - &AuraEffect::HandleNULL, //148 SPELL_AURA_MOD_CHARGE_RECOVERY_RATE + &AuraEffect::HandleModChargeRecoveryRate, //148 SPELL_AURA_MOD_CHARGE_RECOVERY_RATE also implemented in SpellHistory::GetChargeRecoveryTime &AuraEffect::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK &AuraEffect::HandleShieldBlockValuePercent, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT &AuraEffect::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED @@ -242,7 +242,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandleDetectAmore, //170 SPELL_AURA_DETECT_AMORE used to detect various spells that change visual of units for aura target &AuraEffect::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK &AuraEffect::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK - &AuraEffect::HandleUnused, //173 unused (4.3.4) no spells, old SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell + &AuraEffect::HandleNoImmediateEffect, //173 SPELL_AURA_MOD_CHARGE_RECOVERY_RATE_BY_TYPE_MASK implemented in SpellHistory::GetChargeRecoveryTime &AuraEffect::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus &AuraEffect::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus &AuraEffect::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end @@ -274,7 +274,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst &AuraEffect::HandleNoImmediateEffect, //203 SPELL_AURA_PREVENT_INTERRUPT implemented in SpellInfo::CanBeInterrupted &AuraEffect::HandleNULL, //204 SPELL_AURA_PREVENT_CORPSE_RELEASE - &AuraEffect::HandleNULL, //205 SPELL_AURA_MOD_CHARGE_COOLDOWN + &AuraEffect::HandleNoImmediateEffect, //205 SPELL_AURA_MOD_CHARGE_RECOVERY_BY_TYPE_MASK implemented in SpellHistory::GetChargeRecoveryTime &AuraEffect::HandleAuraModIncreaseFlightSpeed, //206 SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED &AuraEffect::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED &AuraEffect::HandleAuraModIncreaseFlightSpeed, //208 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED @@ -6266,6 +6266,15 @@ void AuraEffect::HandleModRecoveryRateBySpellLabel(AuraApplication const* aurApp }, rate, apply); } +void AuraEffect::HandleModChargeRecoveryRate(AuraApplication const* aurApp, uint8 mode, bool apply) const +{ + if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK)) + return; + + float rate = 100.0f / (std::max<float>(GetAmount(), -99.0f) + 100.0f); + aurApp->GetTarget()->GetSpellHistory()->UpdateChargeRecoveryRate(GetMiscValue(), rate, apply); +} + void AuraEffect::HandleShowConfirmationPrompt(AuraApplication const* aurApp, uint8 mode, bool apply) const { if (!(mode & AURA_EFFECT_HANDLE_REAL)) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index c9d27770593..f141df6e1de 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -326,6 +326,7 @@ class TC_GAME_API AuraEffect void HandleModSpellCategoryCooldown(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleModRecoveryRate(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleModRecoveryRateBySpellLabel(AuraApplication const* aurApp, uint8 mode, bool apply) const; + void HandleModChargeRecoveryRate(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleShowConfirmationPrompt(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleOverridePetSpecs(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleAllowUsingGameobjectsWhileMounted(AuraApplication const* aurApp, uint8 mode, bool apply) const; diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index b6e7160ebaa..10df8b51c0f 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -900,6 +900,43 @@ void SpellHistory::ModifyChargeRecoveryTime(uint32 chargeCategoryId, Duration co SendSetSpellCharges(chargeCategoryId, itr->second); } +void SpellHistory::UpdateChargeRecoveryRate(uint32 chargeCategoryId, float modChange, bool apply) +{ + auto itr = _categoryCharges.find(chargeCategoryId); + if (itr == _categoryCharges.end() || itr->second.empty()) + return; + + if (modChange <= 0.0f) + return; + + if (!apply) + modChange = 1.0f / modChange; + + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); + + auto chargeItr = itr->second.begin(); + + chargeItr->RechargeEnd = now + duration_cast<Duration>((chargeItr->RechargeEnd - now) * modChange); + + TimePoint prevEnd = chargeItr->RechargeEnd; + + while (++chargeItr != itr->second.end()) + { + Duration rechargeTime = duration_cast<Duration>((chargeItr->RechargeEnd - chargeItr->RechargeStart) * modChange); + chargeItr->RechargeStart = prevEnd; + chargeItr->RechargeEnd = prevEnd + rechargeTime; + prevEnd = chargeItr->RechargeEnd; + } + + if (Player* playerOwner = GetPlayerOwner()) + { + WorldPackets::Spells::UpdateChargeCategoryCooldown updateChargeCategoryCooldown; + updateChargeCategoryCooldown.Category = chargeCategoryId; + updateChargeCategoryCooldown.ModChange = modChange; + playerOwner->SendDirectMessage(updateChargeCategoryCooldown.Write()); + } +} + void SpellHistory::RestoreCharge(uint32 chargeCategoryId) { auto itr = _categoryCharges.find(chargeCategoryId); @@ -974,6 +1011,10 @@ int32 SpellHistory::GetChargeRecoveryTime(uint32 chargeCategoryId) const int32 recoveryTime = chargeCategoryEntry->ChargeRecoveryTime; recoveryTime += _owner->GetTotalAuraModifierByMiscValue(SPELL_AURA_CHARGE_RECOVERY_MOD, chargeCategoryId); + for (AuraEffect const* modRecoveryRate : _owner->GetAuraEffectsByType(SPELL_AURA_MOD_CHARGE_RECOVERY_BY_TYPE_MASK)) + if (modRecoveryRate->GetMiscValue() & chargeCategoryEntry->TypeMask) + recoveryTime += modRecoveryRate->GetAmount(); + float recoveryTimeF = float(recoveryTime); recoveryTimeF *= _owner->GetTotalAuraMultiplierByMiscValue(SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER, chargeCategoryId); @@ -983,6 +1024,19 @@ int32 SpellHistory::GetChargeRecoveryTime(uint32 chargeCategoryId) const if (_owner->HasAuraTypeWithMiscvalue(SPELL_AURA_CHARGE_RECOVERY_AFFECTED_BY_HASTE_REGEN, chargeCategoryId)) recoveryTimeF *= _owner->m_unitData->ModHasteRegen; + for (AuraEffect const* modRecoveryRate : _owner->GetAuraEffectsByType(SPELL_AURA_MOD_CHARGE_RECOVERY_RATE)) + if (modRecoveryRate->GetMiscValue() == int32(chargeCategoryId)) + recoveryTimeF *= 100.0f / (std::max<float>(modRecoveryRate->GetAmount(), -99.0f) + 100.0f); + + for (AuraEffect const* modRecoveryRate : _owner->GetAuraEffectsByType(SPELL_AURA_MOD_CHARGE_RECOVERY_RATE_BY_TYPE_MASK)) + if (modRecoveryRate->GetMiscValue() & chargeCategoryEntry->TypeMask) + recoveryTimeF *= 100.0f / (std::max<float>(modRecoveryRate->GetAmount(), -99.0f) + 100.0f); + + if (Milliseconds(chargeCategoryEntry->ChargeRecoveryTime) <= 1h + && !(chargeCategoryEntry->Flags & SPELL_CATEGORY_FLAG_IGNORE_FOR_MOD_TIME_RATE) + && !(chargeCategoryEntry->Flags & SPELL_CATEGORY_FLAG_COOLDOWN_EXPIRES_AT_DAILY_RESET)) + recoveryTimeF *= *_owner->m_unitData->ModTimeRate; + return int32(std::floor(recoveryTimeF)); } diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h index b731cbfc329..5deae792ba9 100644 --- a/src/server/game/Spells/SpellHistory.h +++ b/src/server/game/Spells/SpellHistory.h @@ -184,6 +184,7 @@ public: // Charges bool ConsumeCharge(uint32 chargeCategoryId); void ModifyChargeRecoveryTime(uint32 chargeCategoryId, Duration cooldownMod); + void UpdateChargeRecoveryRate(uint32 chargeCategoryId, float modChange, bool apply); void RestoreCharge(uint32 chargeCategoryId); void ResetCharges(uint32 chargeCategoryId); void ResetAllCharges(); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index f6e0561dfc7..ff1c34de729 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -4831,7 +4831,7 @@ bool _isPositiveEffectImpl(SpellInfo const* spellInfo, SpellEffectInfo const& ef case SPELL_AURA_MOD_WEAPON_CRIT_PERCENT: case SPELL_AURA_POWER_BURN: case SPELL_AURA_MOD_COOLDOWN: - case SPELL_AURA_MOD_CHARGE_COOLDOWN: + case SPELL_AURA_MOD_CHARGE_RECOVERY_BY_TYPE_MASK: case SPELL_AURA_MOD_INCREASE_SPEED: case SPELL_AURA_MOD_PARRY_PERCENT: case SPELL_AURA_SET_VEHICLE_ID: |