diff --git a/src/game/AI/ScriptDevAI/base/BossAI.cpp b/src/game/AI/ScriptDevAI/base/BossAI.cpp index a802640985f..3d340146a23 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.cpp +++ b/src/game/AI/ScriptDevAI/base/BossAI.cpp @@ -32,15 +32,26 @@ void BossAI::AddOnAggroText(uint32 text) m_onAggroTexts.push_back(text); } +void BossAI::Reset() +{ + CombatAI::Reset(); + m_creature->SetSpellList(m_creature->GetCreatureInfo()->SpellList); +} + void BossAI::JustDied(Unit* killer) { + CombatAI::JustDied(killer); if (!m_onKilledTexts.empty()) DoBroadcastText(m_onKilledTexts[urand(0, m_onKilledTexts.size() - 1)], m_creature, killer); + for (QueuedCast& cast : m_castOnDeath) + { + Unit* target = m_creature->GetMap()->GetUnit(cast.target); + m_creature->CastSpell(target, cast.spellId, cast.flags); + } if (m_instanceDataType == -1) return; if (ScriptedInstance* instance = static_cast(m_creature->GetInstanceData())) instance->SetData(m_instanceDataType, DONE); - CombatAI::JustDied(killer); OpenEntrances(); OpenExits(); } @@ -77,4 +88,30 @@ void BossAI::AddEntranceObject(uint32 value) void BossAI::AddExitObject(uint32 value) { m_exitObjects.push_back(value); +} + +void BossAI::EnterEvadeMode() +{ + if (m_instanceDataType == -1) + return; + if (ScriptedInstance* instance = static_cast(m_creature->GetInstanceData())) + instance->SetData(m_instanceDataType, FAIL); + OpenEntrances(); + if (m_respawnDelay == -1) + { + CombatAI::EnterEvadeMode(); + return; + } + m_creature->SetRespawnDelay(m_respawnDelay, true); + m_creature->ForcedDespawn(); +} + +void BossAI::AddCastOnDeath(QueuedCast cast) +{ + m_castOnDeath.push_back(cast); +} + +void BossAI::AddRespawnOnEvade(std::chrono::seconds delay) +{ + m_respawnDelay = delay.count(); } \ No newline at end of file diff --git a/src/game/AI/ScriptDevAI/base/BossAI.h b/src/game/AI/ScriptDevAI/base/BossAI.h index 6b9e5e6e550..43f96ef7c5b 100644 --- a/src/game/AI/ScriptDevAI/base/BossAI.h +++ b/src/game/AI/ScriptDevAI/base/BossAI.h @@ -27,6 +27,13 @@ enum InstanceActions INSTANCE_CLOSE_ENTRANCE_DOOR = 250, }; +struct QueuedCast +{ + ObjectGuid target; + uint32 spellId; + uint32 flags; +}; + class BossAI : public CombatAI { public: @@ -56,6 +63,7 @@ class BossAI : public CombatAI for (auto& id : m_exitObjects) instance->DoUseOpenableObject(id, true); } + /** * Adds one or more Broadcast Texts to possibly emit when Unit dies * This function is not called if JustDied is overridden. Add CombatAI::JustDied(); to your overriding function. @@ -83,6 +91,7 @@ class BossAI : public CombatAI void SetDataType(uint32 type) { m_instanceDataType = type; } + void Reset() override; void JustDied(Unit* killer = nullptr) override; void JustReachedHome() override; void Aggro(Unit* who = nullptr) override; @@ -101,6 +110,17 @@ class BossAI : public CombatAI AddExitObject(fargs...); } void SetGateDelay(std::chrono::milliseconds delay) { m_gateDelay = delay; } + void EnterEvadeMode() override; + + void AddCastOnDeath(QueuedCast cast); + template + void AddCastOnDeath(QueuedCast cast, Targs... fargs) + { + AddCastOnDeath(cast); + AddCastOnDeath(fargs...); + } + + void AddRespawnOnEvade(std::chrono::seconds delay); std::chrono::seconds TimeSinceEncounterStart() { @@ -118,9 +138,12 @@ class BossAI : public CombatAI std::vector m_entranceObjects; std::vector m_exitObjects; std::chrono::milliseconds m_gateDelay = 3s; + std::vector m_castOnDeath; uint32 m_instanceDataType = -1; + uint32 m_respawnDelay = -1; + std::chrono::steady_clock::time_point m_combatStartTimestamp; };