diff options
author | Ovahlord <dreadkiller@gmx.de> | 2024-04-27 13:43:50 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-27 13:43:50 +0200 |
commit | d60b4e5b199d56477010941fc1d3aff9eb7064a2 (patch) | |
tree | 6021bf8108e130d53c39bf81568e112d2d7fe8b5 /src | |
parent | 072e6ff9cc0c21b1b90ab5abd291187a1681a618 (diff) |
Core/Auras: implemented PROC_FLAG_HEARTBEAT and moved food/drink emote mechanic into heartbeat handling (#29943)
* also fixed an false assumption that only one of the food emotes can be played. They can in fact be both done at the same time.
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 31 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 22 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.h | 4 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.h | 2 |
7 files changed, 39 insertions, 33 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index a1383c2ee44..0d59ce555ac 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -182,7 +182,6 @@ Player::Player(WorldSession* session) : Unit(true), m_sceneMgr(this) m_regenInterruptTimestamp = GameTime::Now(); m_regenTimer = 0; m_regenTimerCount = 0; - m_foodEmoteTimerCount = 0; m_weaponChangeTimer = 0; m_zoneUpdateId = uint32(-1); @@ -1624,7 +1623,6 @@ bool Player::IsImmunedToSpellEffect(SpellInfo const* spellInfo, SpellEffectInfo void Player::RegenerateAll() { m_regenTimerCount += m_regenTimer; - m_foodEmoteTimerCount += m_regenTimer; for (Powers power = POWER_MANA; power < MAX_POWERS; power = Powers(power + 1)) if (power != POWER_RUNES) @@ -1661,35 +1659,6 @@ void Player::RegenerateAll() } m_regenTimer = 0; - - // Handles the emotes for drinking and eating. - // According to sniffs there is a background timer going on that repeats independed from the time window where the aura applies. - // That's why we dont need to reset the timer on apply. In sniffs I have seen that the first call for the spell visual is totally random, then after - // 5 seconds over and over again which confirms my theory that we have a independed timer. - if (m_foodEmoteTimerCount >= 5000) - { - auto findInterruptibleEffect = [](AuraEffect const* aurEff) - { - return aurEff->GetSpellInfo()->HasAuraInterruptFlag(SpellAuraInterruptFlags::Standing); - }; - - // Food emote comes above drinking emote if we have to decide (mage regen food for example) - AuraEffectList const& ModRegenAuras = GetAuraEffectsByType(SPELL_AURA_MOD_REGEN); - auto itr = std::find_if(ModRegenAuras.cbegin(), ModRegenAuras.cend(), findInterruptibleEffect); - if (itr != ModRegenAuras.end()) - { - SendPlaySpellVisualKit(SPELL_VISUAL_KIT_FOOD, 0, 0); - } - else - { - AuraEffectList const& ModPowerRegenAuras = GetAuraEffectsByType(SPELL_AURA_MOD_POWER_REGEN); - itr = std::find_if(ModPowerRegenAuras.cbegin(), ModPowerRegenAuras.cend(), findInterruptibleEffect); - if (itr != ModPowerRegenAuras.end()) - SendPlaySpellVisualKit(SPELL_VISUAL_KIT_DRINK, 0, 0); - } - - m_foodEmoteTimerCount -= 5000; - } } void Player::Regenerate(Powers power) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 2eee223ef21..5b8d4ed20e0 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2884,7 +2884,6 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> GuidList WhisperList; TimePoint m_regenInterruptTimestamp; uint32 m_regenTimerCount; - uint32 m_foodEmoteTimerCount; std::array<float, MAX_POWERS_PER_CLASS> m_powerFraction; uint32 m_contestedPvPTimer; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 63274ff2dfd..86d81c67c3b 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -501,6 +501,17 @@ void Unit::Heartbeat() // SMSG_FLIGHT_SPLINE_SYNC for cyclic splines SendFlightSplineSyncUpdate(); + + // Trigger heartbeat procs and generic aura behavior such as food emotes + TriggerAuraHeartbeat(); +} + +void Unit::TriggerAuraHeartbeat() +{ + for (auto const& [_, auraApplication] : m_appliedAuras) + auraApplication->GetBase()->Heartbeat(); + + Unit::ProcSkillsAndAuras(this, nullptr, PROC_FLAG_HEARTBEAT, PROC_FLAG_NONE, PROC_SPELL_TYPE_MASK_ALL, PROC_SPELL_PHASE_NONE, PROC_HIT_NONE, nullptr, nullptr, nullptr); } bool Unit::haveOffhandWeapon() const diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 1bb17c0560f..3a01deadd62 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -685,6 +685,7 @@ class TC_GAME_API Unit : public WorldObject virtual void Update(uint32 time) override; void Heartbeat() override; + void TriggerAuraHeartbeat(); void setAttackTimer(WeaponAttackType type, uint32 time) { m_attackTimer[type] = time; } void resetAttackTimer(WeaponAttackType type = BASE_ATTACK); diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index d40c41e373b..fe00aba82b6 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2614,6 +2614,28 @@ void UnitAura::AddStaticApplication(Unit* target, uint32 effMask) _staticApplications[target->GetGUID()] |= effMask; } +void UnitAura::Heartbeat() +{ + Aura::Heartbeat(); + + // Periodic food and drink emote animation + HandlePeriodicFoodSpellVisualKit(); +} + +void UnitAura::HandlePeriodicFoodSpellVisualKit() +{ + SpellSpecificType specificType = GetSpellInfo()->GetSpellSpecific(); + + bool food = specificType == SPELL_SPECIFIC_FOOD || specificType == SPELL_SPECIFIC_FOOD_AND_DRINK; + bool drink = specificType == SPELL_SPECIFIC_DRINK || specificType == SPELL_SPECIFIC_FOOD_AND_DRINK; + + if (food) + GetUnitOwner()->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_FOOD, 0, 0); + + if (drink) + GetUnitOwner()->SendPlaySpellVisualKit(SPELL_VISUAL_KIT_DRINK, 0, 0); +} + DynObjAura::DynObjAura(AuraCreateInfo const& createInfo) : Aura(createInfo) { diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index c38f8ee78ec..08621eed649 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -257,6 +257,7 @@ class TC_GAME_API Aura float CalcPPMProcChance(Unit* actor) const; void SetLastProcAttemptTime(TimePoint lastProcAttemptTime) { m_lastProcAttemptTime = lastProcAttemptTime; } void SetLastProcSuccessTime(TimePoint lastProcSuccessTime) { m_lastProcSuccessTime = lastProcSuccessTime; } + virtual void Heartbeat() { } // AuraScript void LoadScripts(); @@ -383,6 +384,9 @@ class TC_GAME_API UnitAura : public Aura void AddStaticApplication(Unit* target, uint32 effMask); + void Heartbeat() override; + void HandlePeriodicFoodSpellVisualKit(); + private: DiminishingGroup m_AuraDRGroup; // Diminishing std::unordered_map<ObjectGuid, uint32> _staticApplications; // non-area auras diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index e9097afffd6..1771e04676b 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -134,7 +134,7 @@ enum ProcFlags : uint32 { PROC_FLAG_NONE = 0x00000000, - PROC_FLAG_HEARTBEAT = 0x00000001, // 00 Killed by agressor - not sure about this flag + PROC_FLAG_HEARTBEAT = 0x00000001, // 00 Heartbeat PROC_FLAG_KILL = 0x00000002, // 01 Kill target (in most cases need XP/Honor reward) PROC_FLAG_DEAL_MELEE_SWING = 0x00000004, // 02 Done melee auto attack |