aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOvahlord <dreadkiller@gmx.de>2024-04-27 13:43:50 +0200
committerGitHub <noreply@github.com>2024-04-27 13:43:50 +0200
commitd60b4e5b199d56477010941fc1d3aff9eb7064a2 (patch)
tree6021bf8108e130d53c39bf81568e112d2d7fe8b5 /src
parent072e6ff9cc0c21b1b90ab5abd291187a1681a618 (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.cpp31
-rw-r--r--src/server/game/Entities/Player/Player.h1
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp11
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp22
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h4
-rw-r--r--src/server/game/Spells/SpellMgr.h2
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