aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOvahlord <dreadkiller@gmx.de>2024-04-27 13:43:50 +0200
committerOvahlord <dreadkiller@gmx.de>2024-05-28 16:45:22 +0200
commit42a51761901217ae6309a7a220a9997f1334a8dd (patch)
treedb98d39ec79b7fd322772f5e40d5565d2d04bb94
parentf28011735862eac1808edc14869ecda5143cc35b (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. (cherry picked from commit d60b4e5b199d56477010941fc1d3aff9eb7064a2)
-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 f9cd980ec24..d9c4ba27122 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -178,7 +178,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);
@@ -1620,7 +1619,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)
@@ -1657,35 +1655,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 0bb801fe4f5..f69fda8d30c 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2835,7 +2835,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 9d2da4e89da..3e3210838d6 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 eb13ed67849..bef14e1f976 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -687,6 +687,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 d363daa22f5..da09f519130 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -2621,6 +2621,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